Skip to content

Commit 8659b37

Browse files
authored
Add files via upload
1 parent c5eca72 commit 8659b37

15 files changed

Lines changed: 1359 additions & 0 deletions

File tree

UncomplicatedCustomTeams.sln

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.8.34330.188
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UncomplicatedCustomTeams", "UncomplicatedCustomTeams\UncomplicatedCustomTeams.csproj", "{9A1249DD-1F71-40D0-AB1E-D6477BA9EBF7}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Debug|x64 = Debug|x64
12+
Release|Any CPU = Release|Any CPU
13+
Release|x64 = Release|x64
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{9A1249DD-1F71-40D0-AB1E-D6477BA9EBF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17+
{9A1249DD-1F71-40D0-AB1E-D6477BA9EBF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
18+
{9A1249DD-1F71-40D0-AB1E-D6477BA9EBF7}.Debug|x64.ActiveCfg = Debug|x64
19+
{9A1249DD-1F71-40D0-AB1E-D6477BA9EBF7}.Debug|x64.Build.0 = Debug|x64
20+
{9A1249DD-1F71-40D0-AB1E-D6477BA9EBF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
21+
{9A1249DD-1F71-40D0-AB1E-D6477BA9EBF7}.Release|Any CPU.Build.0 = Release|Any CPU
22+
{9A1249DD-1F71-40D0-AB1E-D6477BA9EBF7}.Release|x64.ActiveCfg = Release|x64
23+
{9A1249DD-1F71-40D0-AB1E-D6477BA9EBF7}.Release|x64.Build.0 = Release|x64
24+
EndGlobalSection
25+
GlobalSection(SolutionProperties) = preSolution
26+
HideSolutionNode = FALSE
27+
EndGlobalSection
28+
GlobalSection(ExtensibilityGlobals) = postSolution
29+
SolutionGuid = {C5A5EFFF-7D54-4E4C-8D61-8987BE2FD5A9}
30+
EndGlobalSection
31+
EndGlobal
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.ComponentModel;
2+
3+
namespace UncomplicatedCustomTeams.API.Features
4+
{
5+
public class CustomRole : UncomplicatedCustomRoles.Elements.CustomRole
6+
{
7+
/// <summary>
8+
/// The maximum number of players that can have this role in this wave
9+
/// </summary>
10+
[Description("The maximum number of players that can have this role in this wave")]
11+
public int MaxPlayers { get; set; }
12+
}
13+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using Exiled.API.Features;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using UncomplicatedCustomRoles.Extensions;
5+
using UncomplicatedCustomTeams.Utilities;
6+
using UnityEngine.Rendering;
7+
8+
namespace UncomplicatedCustomTeams.API.Features
9+
{
10+
public class SummonedCustomRole
11+
{
12+
/// <summary>
13+
/// The <see cref="Exiled.API.Features.Player"/> instance
14+
/// </summary>
15+
public Player Player { get; }
16+
17+
/// <summary>
18+
/// The CustomRole instance for the given player
19+
/// </summary>
20+
public CustomRole CustomRole { get; }
21+
22+
public SummonedTeam Team { get; }
23+
24+
/// <summary>
25+
/// Indicate wether the custom role has been assigned or not
26+
/// </summary>
27+
public bool IsRoleSet { get; private set; } = false;
28+
29+
public SummonedCustomRole(SummonedTeam team, Player player, CustomRole role)
30+
{
31+
Team = team;
32+
Player = player;
33+
CustomRole = role;
34+
}
35+
36+
public void Destroy()
37+
{
38+
if (Player.IsAlive)
39+
Player.TryRemoveCustomRole();
40+
}
41+
42+
#pragma warning disable CS0618 // A class member was marked with the Obsolete attribute -> the [Obsolete()] attribute is only there to avoid users to use this in a wrong way!
43+
public void AddRole()
44+
{
45+
LogManager.Debug($"Changing role to player {Player.Nickname} ({Player.Id}) to {CustomRole.Name} ({CustomRole.Id}) from team {Team.Team.Name}");
46+
Player.SetCustomRoleAttributes(CustomRole);
47+
IsRoleSet = true;
48+
}
49+
}
50+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
using Exiled.API.Features;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Runtime.Remoting.Messaging;
6+
7+
namespace UncomplicatedCustomTeams.API.Features
8+
{
9+
public class SummonedTeam
10+
{
11+
/// <summary>
12+
/// Gets a list of every spawned <see cref="Team"/> as <see cref="SummonedTeam"/>
13+
/// </summary>
14+
public static List<SummonedTeam> List { get; } = new();
15+
16+
public string Id { get; }
17+
18+
public List<SummonedCustomRole> Players { get; } = new();
19+
20+
public Team Team { get; }
21+
22+
public long Time { get; }
23+
24+
public SummonedTeam(Team team)
25+
{
26+
Team = team;
27+
Time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
28+
Id = Guid.NewGuid().ToString();
29+
30+
List.Add(this);
31+
}
32+
33+
public void Destroy()
34+
{
35+
foreach (SummonedCustomRole role in Players) { role.Destroy(); }
36+
Players.Clear();
37+
List.Remove(this);
38+
}
39+
40+
public static SummonedTeam Summon(Team team, IEnumerable<Player> players)
41+
{
42+
SummonedTeam SummonedTeam = new(team);
43+
44+
foreach (Player Player in players)
45+
{
46+
foreach (CustomRole Role in team.Roles)
47+
{
48+
if (SummonedTeam.SummonedPlayersCount(Role) < Role.MaxPlayers)
49+
{
50+
SummonedTeam.Players.Add(new(SummonedTeam, Player, Role));
51+
break;
52+
}
53+
}
54+
}
55+
56+
return SummonedTeam;
57+
}
58+
59+
60+
public int SummonedPlayersCount(CustomRole role)
61+
{
62+
return Players.Where(cr => cr.CustomRole == role).Count();
63+
}
64+
65+
public IEnumerable<SummonedCustomRole> SummonedPlayersGet(CustomRole role) => Players.Where(cr => cr.CustomRole == role);
66+
67+
public SummonedCustomRole SummonedPlayersGet(Player player) => Players.Where(cr => cr.Player.Id == player.Id).FirstOrDefault();
68+
69+
public bool SummonedPlayersTryGet(Player player, out SummonedCustomRole role)
70+
{
71+
role = SummonedPlayersGet(player);
72+
return role != null;
73+
}
74+
75+
public void TrySpawnPlayer(Player player) => SummonedPlayersGet(player)?.AddRole();
76+
77+
public static SummonedTeam Get(string Id) => List.Where(st => st.Id == Id).FirstOrDefault();
78+
79+
public static bool TryGet(string Id, out SummonedTeam team)
80+
{
81+
team = Get(Id);
82+
return team != null;
83+
}
84+
}
85+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
using Exiled.API.Extensions;
2+
using Exiled.API.Features;
3+
using Respawning;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.ComponentModel;
7+
using System.Linq;
8+
using UncomplicatedCustomTeams.Utilities;
9+
10+
namespace UncomplicatedCustomTeams.API.Features
11+
{
12+
public class Team
13+
{
14+
/// <summary>
15+
/// Gets a complete list of every custom <see cref="Team"/> registered
16+
/// </summary>
17+
public static List<Team> List { get; } = new();
18+
19+
/// <summary>
20+
/// The Id of the custom <see cref="Team"/>
21+
/// </summary>
22+
[Description("The Id of the custom Team")]
23+
public uint Id { get; set; } = 1;
24+
25+
/// <summary>
26+
/// The name of the custom <see cref="Team"/>
27+
/// </summary>
28+
public string Name { get; set; } = "GOC";
29+
30+
/// <summary>
31+
/// The minimum number of players that are required to be on the server to make this custom <see cref="Team"/> spawn
32+
/// </summary>
33+
public int MinPlayers { get; set; } = 1;
34+
35+
/// <summary>
36+
/// The chance of spawning of this custom <see cref="Team"/>.
37+
/// 0 is 0% and 100 is 100%!
38+
/// </summary>
39+
public uint SpawnChance { get; set; } = 100;
40+
41+
/// <summary>
42+
/// The wave that will be replaced by this custom wave
43+
/// </summary>
44+
public SpawnableTeamType SpawnWave { get; set; } = SpawnableTeamType.NineTailedFox;
45+
46+
/// <summary>
47+
/// The list of every role that will be a part of this wave
48+
/// </summary>
49+
public List<CustomRole> Roles { get; set; } = new()
50+
{
51+
new()
52+
{
53+
SpawnSettings = null,
54+
MaxPlayers = 1,
55+
},
56+
new()
57+
{
58+
Id = 2,
59+
SpawnSettings = null,
60+
MaxPlayers = 500
61+
}
62+
};
63+
64+
public static Team EvaluateSpawn(SpawnableTeamType wave)
65+
{
66+
List<Team> Teams = new();
67+
68+
foreach (Team Team in List.Where(t => t.SpawnWave == wave))
69+
for (int a = 0; a < Team.SpawnChance; a++)
70+
Teams.Add(Team);
71+
72+
LogManager.Debug($"Evaluated team count, found {Teams.Count}/100 elements [{List.Where(t => t.SpawnWave == wave).Count()}]!\nIf the number is less than 100 THERE's A PROBLEM!");
73+
74+
int Chance = new Random().Next(0, 99);
75+
if (Teams.Count > Chance)
76+
return Teams[Chance];
77+
78+
return null;
79+
}
80+
}
81+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Exiled.API.Features;
2+
using PlayerRoles;
3+
using System.Collections.Generic;
4+
using UncomplicatedCustomTeams.API.Features;
5+
6+
namespace UncomplicatedCustomTeams.API.Storage
7+
{
8+
internal class Bucket
9+
{
10+
public static List<int> SpawnBucket { get; set; } = new();
11+
12+
public static SummonedTeam Team { get; set; }
13+
}
14+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using CommandSystem;
2+
using Newtonsoft.Json;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Net.Http;
6+
using System.Net;
7+
using UncomplicatedCustomTeams.Utilities;
8+
9+
namespace UncomplicatedCustomTeams.Commands
10+
{
11+
[CommandHandler(typeof(GameConsoleCommandHandler))]
12+
internal class UCTLogShare : ParentCommand
13+
{
14+
public UCTLogShare() => LoadGeneratedCommands();
15+
16+
public override string Command { get; } = "uctlogs";
17+
18+
public override string[] Aliases { get; } = new string[] { };
19+
20+
public override string Description { get; } = "Share the UCT Debug logs with the developers";
21+
22+
public override void LoadGeneratedCommands() { }
23+
24+
protected override bool ExecuteParent(ArraySegment<string> arguments, ICommandSender sender, out string response)
25+
{
26+
if (sender.LogName is not "SERVER CONSOLE")
27+
{
28+
response = "Sorry but this command is reserved to the game console!";
29+
return false;
30+
}
31+
32+
long Start = DateTimeOffset.Now.ToUnixTimeMilliseconds();
33+
34+
HttpStatusCode Response = LogManager.SendReport(out HttpContent Content);
35+
Dictionary<string, string> Data = JsonConvert.DeserializeObject<Dictionary<string, string>>(Plugin.HttpManager.RetriveString(Content));
36+
37+
if (Response is HttpStatusCode.OK && Data.ContainsKey("id"))
38+
{
39+
response = $"Successfully shared the UCT logs with the developers!\nSend this Id to the developers: {Data["id"]}\n\nTook {DateTimeOffset.Now.ToUnixTimeMilliseconds() - Start}ms";
40+
}
41+
else
42+
{
43+
response = $"Failed to share the UCT logs with the developers: Server says: {Response}";
44+
}
45+
46+
47+
return true;
48+
}
49+
}
50+
}

UncomplicatedCustomTeams/Config.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Exiled.API.Interfaces;
2+
using System.ComponentModel;
3+
4+
namespace UncomplicatedCustomTeams
5+
{
6+
internal class Config : IConfig
7+
{
8+
[Description("Is the plugin enabled?")]
9+
public bool IsEnabled { get; set; } = true;
10+
11+
[Description("Do enable the developer (debug) mode?")]
12+
public bool Debug { get; set; } = false;
13+
}
14+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using Exiled.API.Features;
2+
using Exiled.Events.EventArgs.Player;
3+
using Exiled.Events.EventArgs.Server;
4+
using UncomplicatedCustomTeams.API.Features;
5+
using UncomplicatedCustomTeams.API.Storage;
6+
using UncomplicatedCustomTeams.Utilities;
7+
8+
namespace UncomplicatedCustomTeams
9+
{
10+
internal class Handler
11+
{
12+
public void OnRespawningTeam(RespawningTeamEventArgs ev)
13+
{
14+
Bucket.SpawnBucket = new();
15+
16+
LogManager.Debug($"Respawning team event, let's propose our team\nTeams: {API.Features.Team.List.Count}");
17+
18+
foreach (Player Player in ev.Players)
19+
Bucket.SpawnBucket.Add(Player.Id);
20+
21+
LogManager.Debug($"Next team for respawn is {ev.NextKnownTeam}");
22+
23+
// Evaluate the team
24+
Team Team = Team.EvaluateSpawn(ev.NextKnownTeam);
25+
26+
if (Team is null)
27+
Plugin.NextTeam = null; // No next team
28+
else
29+
{
30+
Plugin.NextTeam = SummonedTeam.Summon(Team, ev.Players);
31+
UncomplicatedCustomRoles.API.Features.SpawnBehaviour.DisableSpawnWave();
32+
}
33+
34+
LogManager.Debug($"Next team selected: {Plugin.NextTeam?.Team?.Name}");
35+
}
36+
37+
public void OnChangingRole(ChangingRoleEventArgs ev)
38+
{
39+
if (Plugin.NextTeam is not null && Bucket.SpawnBucket.Contains(ev.Player.Id))
40+
{
41+
LogManager.Debug($"Player {ev.Player} is changing role, let's do something to it!");
42+
Bucket.SpawnBucket.Remove(ev.Player.Id);
43+
44+
Plugin.NextTeam.TrySpawnPlayer(ev.Player);
45+
}
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)