-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSimpleTPAPlugin.cs
287 lines (259 loc) · 13.5 KB
/
SimpleTPAPlugin.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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
extern alias UnityEngineCoreModule;
using Rocket.API.Collections;
using Rocket.Core.Plugins;
using Rocket.Unturned.Chat;
using Rocket.Unturned.Player;
using SDG.Unturned;
using UnityEngine;
using UnityCoreModule = UnityEngineCoreModule.UnityEngine;
namespace SimpleTPA
{
public class SimpleTPAPlugin : RocketPlugin<SimpleTPAConfiguration>
{
public static SimpleTPAPlugin? instance;
public SimpleTPASystem? tpaSystem;
public override void LoadPlugin()
{
base.LoadPlugin();
tpaSystem = gameObject.AddComponent<SimpleTPASystem>();
Rocket.Unturned.Events.UnturnedPlayerEvents.OnPlayerUpdatePosition += tpaSystem.PositionUpdated;
instance = this;
}
public override TranslationList DefaultTranslations => new()
{
{"Invalid_Player", "Cannot use this command because you are invalid"},
{"Request_Self", "Cannot Tpa to yourself"},
{"Invalid_Arguments", "Invalid Arguments"},
{"Request_Aborted_By_Other", "Your Tpa request has been aborted because other player has requested"},
{"Already_Requested", "You already have a Tpa request"},
{"Pending_Request_Expired", "Tpa request has been expired"},
{"Request_Send", "Tpa to {0} has been send"},
{"Request_Received", "Tpa from {0}, accept using /tpa a"},
{"Request_Accepted", "Tpa accepted don't move for {0} seconds"},
{"Accepted_Request", "Tpa accepted"},
{"No_Request_To_Accept", "No Tpa request to accept"},
{"No_Request_To_Deny", "No Tpa request to deny"},
{"No_Request_To_Abort", "No Tpa request to abort"},
{"Tpa_Aborted_Moving", "Tpa aborted because you moved"},
{"Tpa_Denied", "Tpa request has been denied"},
{"Denied_Tpa", "You denied the Tpa from {0}"},
{"Tpa_Aborted", "Tpa request has been aborted"},
};
}
public class SimpleTPASystem : MonoBehaviour
{
private Dictionary<UnturnedPlayer, Dictionary<string, object>> tpaPlayers = new();
public void Update()
{
#region tpa request
List<UnturnedPlayer> tpaPlayersToRemove = new();
Dictionary<UnturnedPlayer, Dictionary<string, object>> tpaPlayersNew = new(tpaPlayers);
// Swipe all pending tpa
foreach (KeyValuePair<UnturnedPlayer, Dictionary<string, object>> playerData in tpaPlayers)
{
#region requisting expiration
// Check requesting status
if (playerData.Value["Status"] is ETPAStatus reqStatus && reqStatus == ETPAStatus.Requesting)
{
// Get default value
Dictionary<string, object> updatedData = new(playerData.Value);
// Reduce expiration data
updatedData["Time"] = (uint)updatedData["Time"] - 1;
// Check if is expirated
if ((uint)updatedData["Time"] <= 0)
{
UnturnedChat.Say(playerData.Key, SimpleTPAPlugin.instance!.Translate("Pending_Request_Expired"), Palette.COLOR_Y);
tpaPlayersToRemove.Add(playerData.Key);
}
// Update data
tpaPlayersNew[playerData.Key] = updatedData;
}
#endregion
#region accepted delay
// Check requesting status
if (playerData.Value["Status"] is ETPAStatus acStatus && acStatus == ETPAStatus.Accepted)
{
// Get default value
Dictionary<string, object> updatedData = new(playerData.Value);
// Reduce delay data
updatedData["Time"] = (uint)updatedData["Time"] - 1;
// Check if is finished
if ((uint)updatedData["Time"] <= 0)
{
// Teleport the player
if (updatedData["To"] is UnturnedPlayer playerReceiving)
playerData.Key.Teleport(playerReceiving);
tpaPlayersToRemove.Add(playerData.Key);
}
// Update data
tpaPlayersNew[playerData.Key] = updatedData;
}
#endregion
}
// Remove finished requests outside the iteration
foreach (UnturnedPlayer player in tpaPlayersToRemove) tpaPlayersNew.Remove(player);
// Finally we update the real tpaPlayers requests
tpaPlayers = tpaPlayersNew;
#endregion
}
public void TpaRequest(UnturnedPlayer playerGoing, UnturnedPlayer playerReceiving)
{
// Check if player is requesting to self
if (playerGoing.CharacterName == playerReceiving.CharacterName)
{
// Inform him
UnturnedChat.Say(playerGoing, SimpleTPAPlugin.instance!.Translate("Request_Self"), Palette.COLOR_Y);
return;
}
// Check if player already requested
if (tpaPlayers.TryGetValue(playerGoing, out _))
{
// Inform him
UnturnedChat.Say(playerGoing, SimpleTPAPlugin.instance!.Translate("Already_Requested"), Palette.COLOR_Y);
return;
}
// Check other requests for this player, if exist we need to remove it
foreach (KeyValuePair<UnturnedPlayer, Dictionary<string, object>> playerData in tpaPlayers)
{
// Check the status requesting
if (playerData.Value["Status"] is ETPAStatus status && status == ETPAStatus.Requesting)
{
// Check if the receiver is the same as the player command
if (playerData.Value["To"] is UnturnedPlayer player && player.Id == playerReceiving.Id)
{
// Remove the old request
tpaPlayers.Remove(playerData.Key);
// Inform the player about their request cancelled
UnturnedChat.Say(playerData.Key, SimpleTPAPlugin.instance!.Translate("Request_Aborted_By_Other"), Palette.COLOR_Y);
break;
}
}
}
// Add pending request
tpaPlayers.Add(playerGoing, new()
{
{"To", playerReceiving},
{"Time", SimpleTPAPlugin.instance!.Configuration.Instance.TickrateToExpire },
{"Status", ETPAStatus.Requesting},
});
// Inform the going player
UnturnedChat.Say(playerGoing, SimpleTPAPlugin.instance.Translate("Request_Send", playerGoing.CharacterName), Palette.COLOR_Y);
// Inform the receiving player
UnturnedChat.Say(playerReceiving, SimpleTPAPlugin.instance.Translate("Request_Received", playerGoing.CharacterName), Palette.COLOR_Y);
}
public void TpaAccept(UnturnedPlayer playerReceiving)
{
// Check if player has been requested
foreach (KeyValuePair<UnturnedPlayer, Dictionary<string, object>> playerData in tpaPlayers)
{
// Check the status requesting
if (playerData.Value["Status"] is ETPAStatus status && status == ETPAStatus.Requesting)
{
// Check if player receiving is you
if (playerData.Value["To"] is UnturnedPlayer player && player.Id == playerReceiving.Id)
{
// Get default value
Dictionary<string, object> updatedData = playerData.Value;
// Change values
updatedData["Status"] = ETPAStatus.Accepted;
updatedData["Time"] = SimpleTPAPlugin.instance!.Configuration.Instance.TickrateToTeleport;
// Update data
tpaPlayers[playerData.Key] = updatedData;
// Inform the receiving player
UnturnedChat.Say(playerReceiving, SimpleTPAPlugin.instance!.Translate("Accepted_Request"), Palette.COLOR_Y);
// Inform the going player
UnturnedChat.Say(playerData.Key, SimpleTPAPlugin.instance!.Translate("Request_Accepted", (int)Math.Round((double)SimpleTPAPlugin.instance.Configuration.Instance.TickrateToTeleport / SimpleTPAPlugin.instance.Configuration.Instance.ServerTickrate)), Palette.COLOR_Y);
return;
}
}
}
// If the function goes here is because theres no request for this player, lets inform him
UnturnedChat.Say(playerReceiving, SimpleTPAPlugin.instance!.Translate("No_Request_To_Accept"), Palette.COLOR_Y);
}
public void TpaDeny(UnturnedPlayer playerReceiving)
{
// Check if player has been requested
foreach (KeyValuePair<UnturnedPlayer, Dictionary<string, object>> playerData in tpaPlayers)
{
// Check the status requesting
if (playerData.Value["Status"] is ETPAStatus status && status == ETPAStatus.Requesting)
{
// Check if player receiving is you
if (playerData.Value["To"] is UnturnedPlayer player && player.Id == playerReceiving.Id)
{
// Inform the receiving player
UnturnedChat.Say(playerReceiving, SimpleTPAPlugin.instance!.Translate("Denied_Tpa", playerData.Key.CharacterName), Palette.COLOR_Y);
// Inform the going player
UnturnedChat.Say(playerData.Key, SimpleTPAPlugin.instance!.Translate("Tpa_Denied"), Palette.COLOR_R);
// Remove it from requests
tpaPlayers.Remove(playerData.Key);
return;
}
}
}
// If the function goes here is because theres no request for this player, lets inform him
UnturnedChat.Say(playerReceiving, SimpleTPAPlugin.instance!.Translate("No_Request_To_Deny"), Palette.COLOR_Y);
}
public void TpaAbort(UnturnedPlayer playerCalled)
{
foreach (KeyValuePair<UnturnedPlayer, Dictionary<string, object>> playerData in tpaPlayers)
{
// Check the status requesting
if (playerData.Value["Status"] is ETPAStatus status && status == ETPAStatus.Accepted)
{
// Check if player receiving is you
if (playerData.Value["To"] is UnturnedPlayer player && player.Id == playerCalled.Id)
{
// Inform the receiving player
UnturnedChat.Say(playerCalled, SimpleTPAPlugin.instance!.Translate("Tpa_Aborted"), Palette.COLOR_R);
// Inform the going player
UnturnedChat.Say(playerData.Key, SimpleTPAPlugin.instance!.Translate("Tpa_Aborted"), Palette.COLOR_R);
// Remove it from requests
tpaPlayers.Remove(playerData.Key);
return;
}
}
// Check if the player going is you
if (playerData.Key.Id == playerCalled.Id)
{
// Check if receiving player is valid
if (playerData.Value["To"] is UnturnedPlayer playerReceiving)
{
// Inform the receiving player
UnturnedChat.Say(playerReceiving, SimpleTPAPlugin.instance!.Translate("Tpa_Aborted"), Palette.COLOR_R);
}
// Inform the going player
UnturnedChat.Say(playerCalled, SimpleTPAPlugin.instance!.Translate("Tpa_Aborted"), Palette.COLOR_R);
// Remove it from requests
tpaPlayers.Remove(playerData.Key);
return;
}
}
// If the function goes here is because theres no request for this player, lets inform him
UnturnedChat.Say(playerCalled, SimpleTPAPlugin.instance!.Translate("No_Request_To_Abort"), Palette.COLOR_Y);
}
public void PositionUpdated(UnturnedPlayer player, UnityCoreModule.Vector3 _)
{
// Check if player has a tpa request
if (tpaPlayers.TryGetValue(player, out var updatedData))
{
// Check if request is accepted
if (updatedData["Status"] is ETPAStatus acStatus && acStatus == ETPAStatus.Accepted)
{
// Remove request
tpaPlayers.Remove(player);
// Inform hes moved during request acception
UnturnedChat.Say(player, SimpleTPAPlugin.instance!.Translate("Tpa_Aborted_Moving"), Palette.COLOR_R);
return;
}
}
}
public void PlayerInCombat(string playerId) {
}
}
public enum ETPAStatus
{
Requesting = 0,
Accepted = 1,
}
}