-
Notifications
You must be signed in to change notification settings - Fork 5
/
Commands.cs
160 lines (143 loc) · 6.43 KB
/
Commands.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
using CommandSystem;
using Exiled.API.Extensions;
using Exiled.API.Features;
using Exiled.CustomRoles.API;
using Exiled.CustomRoles.API.Features;
using MEC;
using PlayerRoles;
using System;
using System.Linq;
namespace SCPReplacer
{
[CommandHandler(typeof(ClientCommandHandler))]
public class Volunteer : ICommand
{
public string Command => "volunteer";
public string[] Aliases => new[] { "v" };
public string Description => "Volunteer to become a SCP that left at the beginning of the round";
public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
{
if (arguments.Count != 1)
{
response = Plugin.Singleton.Translation.WrongUsageMessage;
return false;
}
if (Plugin.Singleton.HasReplacementCutoffPassed())
{
response = Plugin.Singleton.Translation.TooLateMessage;
return false;
}
// Remove non-digits from input so they can type e.g. "SCP-079" and have it still work
var requestedScp = arguments.FirstElement().ScpNumber();
// Look in our list of SCPs awaiting replacement and see if any matches
foreach (var role in Plugin.Singleton.ScpsAwaitingReplacement)
{
if (role.Name == requestedScp && Player.Get(sender) is Player player)
{
if (player.IsScp && player.Role != RoleTypeId.Scp0492)
{
response = "SCPs cannot use this command.";
return false;
}
if (role.Volunteers.Contains(player))
{
response = "You have already volunteered to replace this SCP";
return false;
}
role.Volunteers.Add(player);
if (role.LotteryTimeout == null)
{
role.LotteryTimeout = Timing.CallDelayed(Plugin.Singleton.Config.LotteryPeriodSeconds, () =>
{
role.Replace();
});
}
response = $"You have entered the lottery to become SCP {role.Name}.";
player.Broadcast(5,
Plugin.Singleton.Translation.BroadcastHeader +
Plugin.Singleton.Translation.EnteredLotteryBroadcast.Replace("%NUMBER%", requestedScp),
Broadcast.BroadcastFlags.Normal,
true
);
// replacement successful
return true;
}
}
// SCP was not in our list of SCPs awaiting replacement
if (Plugin.Singleton.ScpsAwaitingReplacement.IsEmpty())
{
response = Plugin.Singleton.Translation.NoEligibleSCPsError;
}
else
{
response = Plugin.Singleton.Translation.InvalidSCPError
+ string.Join(", ", Plugin.Singleton.ScpsAwaitingReplacement); // display available SCP numbers
}
return false;
}
}
[CommandHandler(typeof(ClientCommandHandler))]
public class HumanCommand : ICommand
{
public string Command => "human";
public string[] Aliases => new string[] { "no" };
public string Description => "Forfeit being an SCP and become a random human class instead (must be used near the start of the round)";
public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
{
if (Player.Get(sender) is Player scpPlayer)
{
if (!scpPlayer.IsScp)
{
response = "You must be an SCP to use this command.";
return false;
}
if (scpPlayer.Role == RoleTypeId.Scp0492)
{
response = "SCP 049-2 cannot use this command.";
return false;
}
var config = Plugin.Singleton.Config;
var elapsedSeconds = Round.ElapsedTime.TotalSeconds;
// Minimum required health (configurable percentage) of the SCP
// when they quit to be eligible for replacement
var requiredHealth = (int)(config.RequiredHealthPercentage / 100.0 * scpPlayer.MaxHealth);
var customRole = scpPlayer.GetCustomRoles().FirstOrDefault();
var scpNumber = customRole?.Name.ScpNumber() ?? scpPlayer.Role.ScpNumber();
Log.Info($"{scpPlayer.Nickname} left {elapsedSeconds} seconds into the round, was SCP-{scpNumber} with {scpPlayer.Health}/{scpPlayer.MaxHealth} HP ({requiredHealth} required for replacement)");
if (elapsedSeconds > config.QuitCutoff)
{
response = "This command must be used closer to the start of the round.";
return false;
}
if (scpPlayer.Health < requiredHealth)
{
response = "You are too low health to use this command.";
return false;
}
Plugin.Singleton.ScpLeft(scpPlayer);
var newRole = UnityEngine.Random.value switch
{
< 0.45f => RoleTypeId.ClassD,
< 0.9f => RoleTypeId.Scientist,
_ => RoleTypeId.FacilityGuard
};
response = $"You became a {newRole}";
scpPlayer.Role.Set(newRole, Exiled.API.Enums.SpawnReason.LateJoin, RoleSpawnFlags.All);
if (newRole is RoleTypeId.ClassD)
{
scpPlayer.AddItem(ItemType.Flashlight);
scpPlayer.AddItem(ItemType.Coin);
}
foreach (CustomRole custom in scpPlayer.GetCustomRoles())
custom.RemoveRole(scpPlayer);
scpPlayer.Broadcast(10, Plugin.Singleton.Translation.BroadcastHeader + $"You became a <color={newRole.GetColor().ToHex()}>{newRole.GetFullName()}</color>");
return true;
}
else
{
response = "You must be a player to use this command";
return false;
}
}
}
}