Skip to content

Commit f7e9cb2

Browse files
committed
More methods for CustomTeams, added CustomTeams wave timers
1 parent d598f60 commit f7e9cb2

4 files changed

Lines changed: 245 additions & 13 deletions

File tree

LabExtended/API/CustomTeams/CustomTeamHandler.cs

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,15 @@ public override void OnUnregistered()
6767
WaveTimer?.Dispose();
6868
}
6969

70-
internal override void Internal_RemoveInstance(int id)
70+
/// <summary>
71+
/// Despawns all active instances.
72+
/// </summary>
73+
/// <param name="playerRole">The role to set alive players to.</param>
74+
public override void DespawnAll(RoleTypeId playerRole = RoleTypeId.Spectator)
7175
{
72-
if (Instances.TryGetValue(id, out var instance))
76+
while (Instances.Count > 0)
7377
{
74-
Instances.Remove(id);
75-
76-
OnDespawned(instance);
78+
Despawn(Instances.First().Value, playerRole);
7779
}
7880
}
7981

@@ -102,6 +104,20 @@ public void Despawn(TInstance instance, RoleTypeId playerRole = RoleTypeId.Spect
102104
player.Role.Set(playerRole);
103105
}
104106

107+
for (var i = 0; i < instance.OriginalPlayers.Count; i++)
108+
{
109+
var player = instance.OriginalPlayers[i];
110+
111+
if (player?.ReferenceHub != null)
112+
{
113+
if (!string.IsNullOrWhiteSpace(Name))
114+
{
115+
player.CustomInfo = string.Empty;
116+
player.InfoArea &= ~PlayerInfoArea.CustomInfo;
117+
}
118+
}
119+
}
120+
105121
instance.AlivePlayers.Clear();
106122
instance.OriginalPlayers.Clear();
107123

@@ -117,11 +133,12 @@ public void Despawn(TInstance instance, RoleTypeId playerRole = RoleTypeId.Spect
117133
/// </summary>
118134
/// <param name="maxPlayerCount">The maximum amount of players to spawn.</param>
119135
/// <param name="throwIfNotEnoughPlayers">Whether or not to throw an exception if there aren't enough players to match <paramref name="maxPlayerCount"/></param>
120-
/// <param name="additionalChecks">Delegate used to check potential players, called after <see cref="IsSpawnable"/>.</param>
136+
/// <param name="assignInventory">Whether or not to assign inventory to players with game roles, has no effect on players with custom roles.</param>
137+
/// <param name="additionalChecks">Delegate used to check potential players, called after <see cref="CustomTeamHandlerBase.IsSpawnable"/>.</param>
121138
/// <returns>The spawned team instance (if spawned, null if there weren't enough players).</returns>
122139
/// <exception cref="ArgumentOutOfRangeException"></exception>
123140
/// <exception cref="Exception"></exception>
124-
public TInstance? Spawn(int maxPlayerCount, bool throwIfNotEnoughPlayers = false, Predicate<ExPlayer>? additionalChecks = null)
141+
public TInstance? Spawn(int maxPlayerCount, bool throwIfNotEnoughPlayers = false, bool assignInventory = true, Predicate<ExPlayer>? additionalChecks = null)
125142
{
126143
if (maxPlayerCount < 1)
127144
throw new ArgumentOutOfRangeException(nameof(maxPlayerCount));
@@ -153,7 +170,7 @@ public void Despawn(TInstance instance, RoleTypeId playerRole = RoleTypeId.Spect
153170
return null;
154171
}
155172

156-
var instance = Spawn(spawnablePlayers);
173+
var instance = Spawn(spawnablePlayers, assignInventory);
157174

158175
ListPool<ExPlayer>.Shared.Return(spawnablePlayers);
159176
return instance;
@@ -163,8 +180,9 @@ public void Despawn(TInstance instance, RoleTypeId playerRole = RoleTypeId.Spect
163180
/// Spawns a new team instance.
164181
/// </summary>
165182
/// <param name="players">The list of players to spawn.</param>
183+
/// <param name="assignInventory">Whether or not to assign inventory to players with game roles, has no effect on players with custom roles.</param>
166184
/// <returns>The spawned team instance (if spawned, null if there weren't enough players).</returns>
167-
public TInstance? Spawn(IList<ExPlayer> players)
185+
public TInstance? Spawn(IList<ExPlayer> players, bool assignInventory = true)
168186
{
169187
if (players is null)
170188
throw new ArgumentNullException(nameof(players));
@@ -199,8 +217,12 @@ public void Despawn(TInstance instance, RoleTypeId playerRole = RoleTypeId.Spect
199217
if (pair.Value is RoleTypeId roleType)
200218
{
201219
pair.Key.Role.Set(roleType, RoleChangeReason.Respawn, spawnPosition.HasValue
202-
? RoleSpawnFlags.AssignInventory
203-
: RoleSpawnFlags.All);
220+
? (assignInventory
221+
? RoleSpawnFlags.AssignInventory
222+
: RoleSpawnFlags.None)
223+
: (assignInventory
224+
? RoleSpawnFlags.AssignInventory
225+
: RoleSpawnFlags.UseSpawnpoint));
204226
}
205227
else if (pair.Value is CustomRoleData customRoleData)
206228
{
@@ -212,7 +234,7 @@ public void Despawn(TInstance instance, RoleTypeId playerRole = RoleTypeId.Spect
212234

213235
if (!string.IsNullOrWhiteSpace(Name))
214236
{
215-
pair.Key.CustomInfo = Name;
237+
pair.Key.CustomInfo = Name!;
216238

217239
if ((pair.Key.InfoArea & PlayerInfoArea.CustomInfo) != PlayerInfoArea.CustomInfo)
218240
pair.Key.InfoArea |= PlayerInfoArea.CustomInfo;
@@ -233,4 +255,35 @@ public void Despawn(TInstance instance, RoleTypeId playerRole = RoleTypeId.Spect
233255
teamInstance.OnSpawned();
234256
return teamInstance;
235257
}
258+
259+
internal override void Internal_RemoveInstance(int id)
260+
{
261+
if (Instances.TryGetValue(id, out var instance))
262+
{
263+
Instances.Remove(id);
264+
265+
OnDespawned(instance);
266+
}
267+
}
268+
269+
internal override bool Internal_DespawnInstance(int id)
270+
{
271+
if (Instances.TryGetValue(id, out var instance))
272+
{
273+
Despawn(instance);
274+
return true;
275+
}
276+
277+
return false;
278+
}
279+
280+
internal override IEnumerable<CustomTeamInstance> Internal_GetInstances()
281+
{
282+
return Instances.Values;
283+
}
284+
285+
internal override CustomTeamInstance Internal_SpawnInstance(int playerCount)
286+
{
287+
return Spawn(playerCount)!;
288+
}
236289
}

LabExtended/API/CustomTeams/CustomTeamInstance.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public abstract class CustomTeamInstance
4242
/// <summary>
4343
/// Gets the amounts of seconds passed since the team spawned.
4444
/// </summary>
45-
public float PassedTime => UnityEngine.Time.realtimeSinceStartup - SpawnTime;
45+
public float PassedTime => Time.realtimeSinceStartup - SpawnTime;
4646

4747
/// <summary>
4848
/// Whether or not this wave was spawned by the timer.

LabExtended/API/CustomTeams/Internal/CustomTeamHandlerBase.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,21 @@ public virtual void OnUnregistered() { }
6161
/// <param name="target">The player being attacked.</param>
6262
/// <returns>true if the friendly fire should be allowed</returns>
6363
public virtual bool CanDamage(ExPlayer attacker, ExPlayer target) => true;
64+
65+
/// <summary>
66+
/// Despawns all active instances.
67+
/// </summary>
68+
/// <param name="playerRole">The role to set alive players to.</param>
69+
public abstract void DespawnAll(RoleTypeId playerRole = RoleTypeId.Spectator);
70+
71+
// I realize that this way of doings things may be a bit stupid, but it works.
6472

6573
internal abstract void Internal_RemoveInstance(int id);
74+
internal abstract bool Internal_DespawnInstance(int id);
75+
76+
internal abstract IEnumerable<CustomTeamInstance> Internal_GetInstances();
77+
78+
internal abstract CustomTeamInstance Internal_SpawnInstance(int playerCount);
6679

6780
private static void Internal_OnLeft(ExPlayer player)
6881
{
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
using LabExtended.API.CustomTeams;
2+
using LabExtended.API.CustomTeams.Internal;
3+
4+
using LabExtended.Commands.Attributes;
5+
using LabExtended.Commands.Interfaces;
6+
7+
using LabExtended.Extensions;
8+
9+
using UnityEngine;
10+
11+
namespace LabExtended.Commands.Custom.CustomTeams;
12+
13+
[Command("customteam", "Manages the CustomTeams API", "ct")]
14+
public class CustomTeamsCommand : CommandBase, IServerSideCommand
15+
{
16+
[CommandOverload("list", "Lists all custom teams.")]
17+
public void List()
18+
{
19+
if (CustomTeamRegistry.RegisteredHandlers.Count == 0)
20+
{
21+
Fail("No CustomTeams registered.");
22+
return;
23+
}
24+
25+
Ok(x =>
26+
{
27+
foreach (var pair in CustomTeamRegistry.RegisteredHandlers)
28+
{
29+
x.AppendLine($"- {pair.Key}: {pair.Value.Name ?? "(null)"}");
30+
}
31+
});
32+
}
33+
34+
[CommandOverload("waves", "Lists all spawned waves of a team.")]
35+
public void Waves(
36+
[CommandParameter("Name", "Name of the team.")] string name)
37+
{
38+
if (!CustomTeamRegistry.TryGet(name, out CustomTeamHandlerBase handler))
39+
{
40+
Fail($"Could not find custom team '{name}'");
41+
return;
42+
}
43+
44+
var instances = handler.Internal_GetInstances();
45+
46+
if (instances.Count() == 0)
47+
{
48+
Fail($"Team '{handler.GetType().Name}' has no active waves.");
49+
return;
50+
}
51+
52+
Ok(x =>
53+
{
54+
foreach (var instance in instances)
55+
{
56+
x.AppendLine($"- {instance.Id}: Remaining players: {instance.AlivePlayers.Count} (spawned {Mathf.CeilToInt(instance.PassedTime)} seconds ago)");
57+
}
58+
});
59+
}
60+
61+
[CommandOverload("wave", "Shows information about an active wave.")]
62+
public void Wave(
63+
[CommandParameter("Name", "Name of the team.")] string name,
64+
[CommandParameter("ID", "ID of the wave.")] int id)
65+
{
66+
if (!CustomTeamRegistry.TryGet(name, out CustomTeamHandlerBase handler))
67+
{
68+
Fail($"Could not find custom team '{name}'");
69+
return;
70+
}
71+
72+
var instances = handler.Internal_GetInstances();
73+
74+
if (instances.Count() == 0)
75+
{
76+
Fail($"Team '{handler.GetType().Name}' has no active waves.");
77+
return;
78+
}
79+
80+
if (!instances.TryGetFirst(x => x.Id == id, out var instance))
81+
{
82+
Fail($"Could not find active wave '{id}' in team '{handler.GetType().Name}'");
83+
return;
84+
}
85+
86+
Ok(x =>
87+
{
88+
x.AppendLine($"ID: {instance.Id}");
89+
x.AppendLine($"Spawned At: {DateTime.Now.ToLocalTime().Subtract(TimeSpan.FromSeconds(instance.PassedTime)).ToString("HH:mm:ss zz")}");
90+
x.AppendLine($"Active For: {Mathf.CeilToInt(instance.PassedTime)} seconds");
91+
x.AppendLine($"Is By Timer: {instance.IsByTimer}");
92+
93+
x.AppendLine($"Alive Players ({instance.AlivePlayers.Count}):");
94+
95+
foreach (var ply in instance.AlivePlayers)
96+
{
97+
if (ply?.ReferenceHub != null)
98+
{
99+
x.AppendLine($" - [{ply.Role.Name}] |{ply.PlayerId}| {ply.Nickname} ({ply.UserId})");
100+
}
101+
}
102+
103+
x.AppendLine($"Original Players ({instance.OriginalPlayers.Count}):");
104+
105+
foreach (var ply in instance.OriginalPlayers)
106+
{
107+
if (ply?.ReferenceHub != null)
108+
{
109+
x.AppendLine($" - [{ply.Role.Name}] |{ply.PlayerId}| {ply.Nickname} ({ply.UserId})");
110+
}
111+
}
112+
});
113+
}
114+
115+
[CommandOverload("spawn", "Spawns a new wave of a custom team.")]
116+
public void Spawn(
117+
[CommandParameter("Name", "Name of the team to spawn.")] string name,
118+
[CommandParameter("Players", "The maximum amount of players to spawn.")] int players)
119+
{
120+
if (!CustomTeamRegistry.TryGet(name, out CustomTeamHandlerBase handler))
121+
{
122+
Fail($"Could not find custom team '{name}'");
123+
return;
124+
}
125+
126+
var instance = handler.Internal_SpawnInstance(players);
127+
128+
if (instance is null)
129+
{
130+
Fail($"Could not spawn a new wave.");
131+
return;
132+
}
133+
134+
Ok($"Spawned a new wave of '{handler.GetType().Name}' with '{instance.AlivePlayers.Count}' player(s) (ID: {instance.Id})");
135+
}
136+
137+
[CommandOverload("despawn", "Despawns an active wave of a custom team.")]
138+
public void Despawn(
139+
[CommandParameter("Name", "Name of the team to despawn.")] string name,
140+
[CommandParameter("ID", "ID of the instance to despawn (or * for all).")] string id)
141+
{
142+
if (!CustomTeamRegistry.TryGet(name, out CustomTeamHandlerBase handler))
143+
{
144+
Fail($"Could not find custom team '{name}'");
145+
return;
146+
}
147+
148+
if (int.TryParse(id, out var instanceId))
149+
{
150+
if (!handler.Internal_DespawnInstance(instanceId))
151+
{
152+
Fail($"Could not despawn team instance '{instanceId}' of team '{handler.GetType().Name}'");
153+
}
154+
else
155+
{
156+
Ok($"Despawned team instance '{instanceId}' of team '{handler.GetType().Name}'");
157+
}
158+
}
159+
else
160+
{
161+
handler.DespawnAll();
162+
163+
Ok($"Despawned all active team instances of '{handler.GetType().Name}'");
164+
}
165+
}
166+
}

0 commit comments

Comments
 (0)