Skip to content

Commit f303e34

Browse files
committed
Ready for UCT v1.0.0 Pre-Release 2
1 parent a043fc3 commit f303e34

File tree

9 files changed

+386
-57
lines changed

9 files changed

+386
-57
lines changed

UncomplicatedCustomTeams/API/Features/SummonedTeam.cs

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,16 @@ public void ForceSpawnPlayer(Player player, RoleTypeId fallbackRole = RoleTypeId
152152
}
153153
}
154154

155-
156155
/// <summary>
157156
/// Summons a new team and assigns players to available roles.
158157
/// </summary>
159158
public static SummonedTeam Summon(Team team, IEnumerable<Player> players)
160159
{
160+
if (team == null)
161+
{
162+
LogManager.Debug("Summon: Attempted to create a SummonedTeam with a null team! Returning...");
163+
return null;
164+
}
161165
SummonedTeam SummonedTeam = new(team);
162166

163167
foreach (Player Player in players)
@@ -170,28 +174,48 @@ public static SummonedTeam Summon(Team team, IEnumerable<Player> players)
170174
break;
171175
}
172176
}
173-
174177
}
175-
if (!string.IsNullOrEmpty(team.CassieTranslation))
176-
{
177-
Cassie.MessageTranslated(team.CassieMessage, team.CassieTranslation, isNoisy: team.IsNoisy, isSubtitles: true);
178-
}
179-
180-
if (!string.IsNullOrEmpty(team.SoundPath))
181-
{
178+
if (!string.IsNullOrEmpty(team.CassieTranslation))
179+
{
180+
Cassie.MessageTranslated(team.CassieMessage, team.CassieTranslation, isNoisy: team.IsNoisy, isSubtitles: true);
181+
}
182+
if (!string.IsNullOrEmpty(team.SoundPath))
183+
{
182184
AudioPlayer audioPlayer = AudioPlayer.CreateOrGet($"Global_Audio_{team.Id}", onIntialCreation: (p) =>
183185
{
184186
Speaker speaker = p.AddSpeaker("Main", isSpatial: false, maxDistance: 5000f);
185187
});
186-
187188
float volume = Clamp(team.SoundVolume, 1f, 100f);
188-
189189
audioPlayer.AddClip($"sound_{team.Id}", volume);
190-
}
191-
190+
}
192191
return SummonedTeam;
193192
}
194193

194+
195+
/// <summary>
196+
/// Checks if a team can spawn based on the number of spectators.
197+
/// </summary>
198+
public static List<Player> CanSpawnTeam(Team team)
199+
{
200+
if (team == null)
201+
return new List<Player>();
202+
203+
List<Player> allPlayers = Player.List.ToList();
204+
int totalPlayers = allPlayers.Count;
205+
LogManager.Debug($"Total players: {totalPlayers}, MinPlayers required: {team.MinPlayers}");
206+
if (totalPlayers < team.MinPlayers)
207+
{
208+
LogManager.Debug($"Not enough players on the server to spawn team {team.Name}.");
209+
return new List<Player>();
210+
}
211+
List<Player> spectators = allPlayers
212+
.Where(p => !p.IsAlive && p.Role.Type == RoleTypeId.Spectator && !p.IsOverwatchEnabled)
213+
.ToList();
214+
LogManager.Debug($"Spectators available: {spectators.Count}");
215+
LogManager.Debug($"Spawning all {spectators.Count} spectators for team {team.Name}.");
216+
return spectators;
217+
}
218+
195219
/// <summary>
196220
/// Refreshes the players list, ensuring that the maximum allowed players per role is respected.
197221
/// </summary>

UncomplicatedCustomTeams/API/Features/Team.cs

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using Exiled.API.Enums;
2+
using Exiled.API.Features.Items;
23
using PlayerRoles;
34
using Respawning;
5+
using System;
46
using System.Collections.Generic;
57
using System.ComponentModel;
68
using System.Linq;
@@ -131,25 +133,64 @@ public static void Register(Team team)
131133
public static Team EvaluateSpawn(string wave)
132134
{
133135
List<Team> Teams = new();
134-
135136
foreach (Team Team in List.Where(t => t.SpawnConditions.SpawnWave == wave))
137+
{
136138
for (int a = 0; a < Team.SpawnChance; a++)
137139
Teams.Add(Team);
140+
}
141+
LogManager.Debug($"Evaluated team count, found {Teams.Count}/100 elements [{List.Count(t => t.SpawnConditions.SpawnWave == wave)}]! If the number is less than 100 THERE'S A PROBLEM!");
138142

139-
LogManager.Debug($"Evaluated team count, found {Teams.Count}/100 elements [{List.Count(t => t.SpawnConditions.SpawnWave == wave)}]!\nIf the number is less than 100 THERE's A PROBLEM!");
140-
143+
if (Teams.Count == 0)
144+
{
145+
LogManager.Debug("No valid team found, returning...");
146+
return null;
147+
}
141148
int Chance = new System.Random().Next(0, 99);
142-
if (Teams.Count > Chance)
143-
return Teams[Chance];
144-
145-
return null;
149+
return Teams.Count > Chance ? Teams[Chance] : null;
146150
}
151+
147152
public class SpawnData
148153
{
149154
public string SpawnWave { get; set; } = "NtfWave";
150155
public Vector3 SpawnPosition { get; set; } = Vector3.zero;
151-
[Description("Setting an offset greater than 0 will not work when using NtfWave or ChaosWave!")]
152-
public float Offset { get; set; } = 0f;
156+
157+
private ItemType _usedItem = ItemType.None;
158+
private int? _customItemId = null;
159+
160+
[Description("This setting will be applied only if the SpawnWave is set to 'UsedItem'.")]
161+
public string UsedItem
162+
{
163+
get
164+
{
165+
if (_customItemId.HasValue)
166+
return _customItemId.Value.ToString();
167+
return _usedItem.ToString();
168+
}
169+
set
170+
{
171+
if (int.TryParse(value, out int customItemId))
172+
{
173+
_customItemId = customItemId;
174+
_usedItem = ItemType.None;
175+
}
176+
else if (Enum.TryParse(value, true, out ItemType itemType))
177+
{
178+
_usedItem = itemType;
179+
_customItemId = null;
180+
}
181+
else
182+
{
183+
LogManager.Error($"Invalid UsedItem value: {value}");
184+
}
185+
}
186+
}
187+
188+
public ItemType GetUsedItemType() => _usedItem;
189+
public int? GetCustomItemId() => _customItemId;
190+
191+
[Description("Setting a SpawnDelay greater than 0 will not work when using NtfWave or ChaosWave!")]
192+
public float SpawnDelay { get; set; } = 0f;
153193
}
194+
154195
}
155196
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using CommandSystem;
2+
using Exiled.Loader;
3+
using System.Collections.Generic;
4+
using System.IO;
5+
using UncomplicatedCustomTeams.API.Features;
6+
using UncomplicatedCustomTeams.Interfaces;
7+
8+
namespace UncomplicatedCustomTeams.Commands
9+
{
10+
internal class Generate : IUCTCommand
11+
{
12+
public string Name { get; } = "generate";
13+
14+
public string Description { get; } = "Generates a default YAML file for a new team.";
15+
16+
public string RequiredPermission { get; } = "uct.generate";
17+
18+
public bool Executor(List<string> arguments, ICommandSender sender, out string response)
19+
{
20+
if (arguments.Count < 1 || arguments.Count > 2)
21+
{
22+
response = "Unexpected number of args!\nUsage: uct generate (FileName) (Server-port)";
23+
return false;
24+
}
25+
26+
string fileName = arguments[0].Replace(".yml", "") + ".yml";
27+
string directory = Plugin.Instance.FileConfigs.Dir;
28+
string filePath = Path.Combine(directory, fileName);
29+
30+
if (arguments.Count == 2 && int.TryParse(arguments[1], out int port))
31+
{
32+
directory = Path.Combine(directory, port.ToString());
33+
}
34+
35+
if (!Directory.Exists(directory))
36+
Directory.CreateDirectory(directory);
37+
38+
if (File.Exists(filePath))
39+
{
40+
response = $"File {fileName} already exists!";
41+
return false;
42+
}
43+
44+
var defaultTeamConfig = new Dictionary<string, List<Team>>
45+
{
46+
{
47+
"teams", new List<Team>
48+
{
49+
new() {
50+
Id = 1,
51+
Name = "NewTeam",
52+
}
53+
}
54+
}
55+
};
56+
57+
File.WriteAllText(filePath, Loader.Serializer.Serialize(defaultTeamConfig));
58+
59+
response = $"A new YAML file has been generated at {filePath}, but it has not been loaded yet!";
60+
return true;
61+
}
62+
}
63+
}

UncomplicatedCustomTeams/Commands/Reload.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
namespace UncomplicatedCustomTeams.Commands
1111
{
12-
[CommandHandler(typeof(GameConsoleCommandHandler))]
1312
[CommandHandler(typeof(RemoteAdminCommandHandler))]
1413
internal class ReloadCommand : IUCTCommand
1514
{
@@ -22,12 +21,14 @@ public bool Executor(List<string> arguments, ICommandSender sender, out string r
2221
if (!Round.IsStarted)
2322
{
2423
response = "Round is not started yet!";
24+
sender.Respond(response, false);
2525
return false;
2626
}
2727

2828
if (SummonedTeam.List.Any(team => team.HasAlivePlayers()))
2929
{
3030
response = "An active custom team has been detected. Reloading has been cancelled.";
31+
sender.Respond(response, false);
3132
return false;
3233
}
3334

@@ -44,23 +45,24 @@ public bool Executor(List<string> arguments, ICommandSender sender, out string r
4445

4546
if (Team.List.Count == 0)
4647
{
47-
string warningMessage = "! WARNING !: No teams were loaded! Check your config files!";
48-
LogManager.Warn(warningMessage);
49-
response = warningMessage;
48+
response = "! WARNING !: No teams were loaded! Check your config files!";
49+
LogManager.Warn(response);
50+
sender.Respond(response, false);
5051
return false;
5152
}
5253

5354
LogManager.Info($"✔️ Successfully loaded {Team.List.Count} teams.");
5455
response = $"✔️ All custom teams have been reloaded successfully. Loaded {Team.List.Count} teams.";
56+
sender.Respond(response, true);
5557
return true;
5658
}
5759
catch (System.Exception ex)
5860
{
59-
string errorMessage = $"An error occurred while reloading teams: {ex.Message}. This was likely caused by a configuration mistake.";
60-
LogManager.Error(errorMessage);
61+
response = $"An error occurred while reloading teams: {ex.Message}. This was likely caused by a configuration mistake.";
62+
LogManager.Error(response);
6163
LogManager.Error($"Stack Trace:\n{ex.StackTrace}");
6264

63-
response = "An error occurred while reloading teams. This was likely caused by a configuration mistake.";
65+
sender.Respond(response, false);
6466
return false;
6567
}
6668
}

0 commit comments

Comments
 (0)