This repository was archived by the owner on Sep 3, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 441
/
Copy pathAPIMapFunctionManager.cs
446 lines (408 loc) · 18.9 KB
/
APIMapFunctionManager.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
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
using Force.Crc32;
using GameServerCore.Domain;
using GameServerCore.Enums;
using GameServerCore.Packets.Enums;
using GameServerLib.GameObjects;
using GameServerLib.GameObjects.AttackableUnits;
using LeaguePackets.Game.Common;
using LeagueSandbox.GameServer.GameObjects;
using LeagueSandbox.GameServer.GameObjects.AttackableUnits;
using LeagueSandbox.GameServer.GameObjects.AttackableUnits.AI;
using LeagueSandbox.GameServer.GameObjects.AttackableUnits.Buildings.AnimatedBuildings;
using LeagueSandbox.GameServer.GameObjects.StatsNS;
using LeagueSandbox.GameServer.Handlers;
using LeagueSandbox.GameServer.Logging;
using log4net;
using System.Collections.Generic;
using System.Numerics;
using System.Text;
using System.Timers;
namespace LeagueSandbox.GameServer.API
{
public static class ApiMapFunctionManager
{
// Required variables.
private static Game _game;
private static ILog _logger = LoggerProvider.GetLogger();
private static MapScriptHandler _map;
/// <summary>
/// Sets the Game instance of ApiFunctionManager to the given instance.
/// Also assigns the debug logger.
/// </summary>
/// <param name="game">Game instance to set.</param>
internal static void SetGame(Game game, MapScriptHandler mapScriptHandler)
{
_game = game;
_map = mapScriptHandler;
}
public static void AddProtection(AttackableUnit unit, AttackableUnit[] dependOnAll, AttackableUnit[] dependOnSingle)
{
_game.ProtectionManager.AddProtection(unit, dependOnAll, dependOnSingle);
}
public static void AddProtection(AttackableUnit unit, bool dependOnAll, params AttackableUnit[] dependOn)
{
_game.ProtectionManager.AddProtection(unit, dependOnAll, dependOn);
}
public static GameObject CreateShop(string name, Vector2 position, TeamId team)
{
var shop = new GameObject(_game, position, team: team, netId: Crc32Algorithm.Compute(Encoding.UTF8.GetBytes(name)) | 0xFF000000);
_game.ObjectManager.SpawnObject(shop);
return shop;
}
/// <summary>
/// Creates and returns a nexus
/// </summary>
/// <param name="name"></param>
/// <param name="model"></param>
/// <param name="position"></param>
/// <param name="team"></param>
/// <param name="nexusRadius"></param>
/// <param name="sightRange"></param>
/// <returns></returns>
public static Nexus CreateNexus(string name, string model, Vector2 position, TeamId team, int nexusRadius, int sightRange, Stats stats = null)
{
return new Nexus(_game, model, team, nexusRadius, position, sightRange, stats, Crc32Algorithm.Compute(Encoding.UTF8.GetBytes(name)) | 0xFF000000);
}
/// <summary>
/// Creates and returns an inhibitor
/// </summary>
/// <param name="name"></param>
/// <param name="model"></param>
/// <param name="position"></param>
/// <param name="team"></param>
/// <param name="lane"></param>
/// <param name="inhibRadius"></param>
/// <param name="sightRange"></param>
/// <returns></returns>
public static Inhibitor CreateInhibitor(string name, string model, Vector2 position, TeamId team, Lane lane, int inhibRadius, int sightRange, Stats stats = null)
{
return new Inhibitor(_game, model, lane, team, inhibRadius, position, sightRange, stats, Crc32Algorithm.Compute(Encoding.UTF8.GetBytes(name)) | 0xFF000000);
}
public static MapObject CreateLaneMinionSpawnPos(string name, Vector3 position)
{
return new MapObject(name, position, _map.Id);
}
/// <summary>
/// Creates a tower
/// </summary>
/// <param name="name"></param>
/// <param name="model"></param>
/// <param name="position"></param>
/// <param name="team"></param>
/// <param name="turretType"></param>
/// <param name="turretItems"></param>
/// <param name="lane"></param>
/// <param name="aiScript"></param>
/// <param name="mapObject"></param>
/// <param name="netId"></param>
/// <returns></returns>
public static LaneTurret CreateLaneTurret(string name, string model, Vector2 position, TeamId team, TurretType turretType, Lane lane, string aiScript, MapObject mapObject = default, uint netId = 0)
{
return new LaneTurret(_game, name, model, position, team, turretType, netId, lane, mapObject, null, aiScript);
}
/// <summary>
/// Gets the turret item list from MapScripts
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static int[] GetTurretItems(Dictionary<TurretType, int[]> turretItemList, TurretType type)
{
if (!turretItemList.ContainsKey(type))
{
return new int[] { };
}
return turretItemList[type];
}
/// <summary>
/// Spawns a LaneMinion
/// </summary>
/// <param name="list"></param>
/// <param name="minionNo"></param>
/// <param name="barracksName"></param>
/// <param name="waypoints"></param>
public static void CreateLaneMinion(List<MinionSpawnType> list, Vector2 position, TeamId team, int minionNo, string barracksName, List<Vector2> waypoints, string laneMinionAI)
{
if (list.Count <= minionNo)
{
return;
}
var m = new LaneMinion(_game, list[minionNo], position, barracksName, waypoints, _map.MapScript.MinionModels[team][list[minionNo]], 0, team, null, laneMinionAI);
_game.ObjectManager.AddObject(m);
}
/// <summary>
/// Creates and returns a minion
/// </summary>
/// <param name="name"></param>
/// <param name="model"></param>
/// <param name="position"></param>
/// <param name="netId"></param>
/// <param name="team"></param>
/// <param name="skinId"></param>
/// <param name="ignoreCollision"></param>
/// <param name="isTargetable"></param>
/// <param name="aiScript"></param>
/// <param name="damageBonus"></param>
/// <param name="healthBonus"></param>
/// <param name="initialLevel"></param>
/// <returns></returns>
public static Minion CreateMinion(
string name, string model, Vector2 position, ObjAIBase owner = null, uint netId = 0,
TeamId team = TeamId.TEAM_NEUTRAL, int skinId = 0, bool ignoreCollision = false,
bool isTargetable = false, bool isWard = false, string aiScript = "", int damageBonus = 0,
int healthBonus = 0, int initialLevel = 1)
{
var m = new Minion(_game, owner, position, model, name, netId, team, skinId, ignoreCollision, isTargetable, isWard, null, null, aiScript, damageBonus, healthBonus, initialLevel);
_game.ObjectManager.AddObject(m);
return m;
}
public static Minion CreateMinionTemplete(
string name, string model, Vector2 position, uint netId = 0,
TeamId team = TeamId.TEAM_NEUTRAL, int skinId = 0, bool ignoreCollision = false,
bool isTargetable = false, bool isWard = false, string aiScript = "", int damageBonus = 0,
int healthBonus = 0, int initialLevel = 1)
{
return new Minion(_game, null, position, model, name, netId, team, skinId, ignoreCollision, isTargetable, isWard, null, null, aiScript, damageBonus, healthBonus, initialLevel);
}
/// <summary>
/// Checks if minion spawn is enabled
/// </summary>
/// <returns></returns>
public static bool IsMinionSpawnEnabled()
{
return _game.Config.GameFeatures.HasFlag(FeatureFlags.EnableLaneMinions);
}
/// <summary>
/// Creates and returns a jungle camp
/// </summary>
/// <param name="position"></param>
/// <param name="groupNumber"></param>
/// <param name="teamSideOfTheMap"></param>
/// <param name="campTypeIcon"></param>
/// <param name="respawnTimer"></param>
/// <param name="doPlayVO"></param>
/// <param name="revealEvent"></param>
/// <param name="spawnDuration"></param>
/// <returns></returns>
public static MonsterCamp CreateJungleCamp(Vector3 position, byte groupNumber, TeamId teamSideOfTheMap, string campTypeIcon, float respawnTimer, bool doPlayVO = false, byte revealEvent = 74, float spawnDuration = 0.0f)
{
var camp = new MonsterCamp(_game, position, groupNumber, teamSideOfTheMap, campTypeIcon, respawnTimer, doPlayVO, revealEvent, spawnDuration);
_game.ObjectManager.AddObject(camp);
return camp;
}
/// <summary>
/// Creates and returns a jungle monster
/// </summary>
/// <param name="name"></param>
/// <param name="model"></param>
/// <param name="position"></param>
/// <param name="faceDirection"></param>
/// <param name="monsterCamp"></param>
/// <param name="team"></param>
/// <param name="spawnAnimation"></param>
/// <param name="netId"></param>
/// <param name="isTargetable"></param>
/// <param name="ignoresCollision"></param>
/// <param name="aiScript"></param>
/// <param name="damageBonus"></param>
/// <param name="healthBonus"></param>
/// <param name="initialLevel"></param>
public static Monster CreateJungleMonster
(
string name, string model, Vector2 position, Vector3 faceDirection,
MonsterCamp monsterCamp, TeamId team = TeamId.TEAM_NEUTRAL, string spawnAnimation = "", uint netId = 0,
bool isTargetable = true, bool ignoresCollision = false, string aiScript = "",
int damageBonus = 0, int healthBonus = 0, int initialLevel = 1
)
{
return new Monster(_game, name, model, position, faceDirection, monsterCamp, team, netId, spawnAnimation, isTargetable, ignoresCollision, null, aiScript, damageBonus, healthBonus, initialLevel);
}
/// <summary>
/// Adds a prop to the map
/// </summary>
/// <param name="name"></param>
/// <param name="model"></param>
/// <param name="position"></param>
/// <param name="height"></param>
/// <param name="direction"></param>
/// <param name="posOffset"></param>
/// <param name="scale"></param>
/// <param name="skinId"></param>
/// <param name="skillLevel"></param>
/// <param name="rank"></param>
/// <param name="type"></param>
/// <param name="netId"></param>
/// <param name="netNodeId"></param>
/// <returns></returns>
public static LevelProp AddLevelProp(string name, string model, Vector3 position, Vector3 direction, Vector3 posOffset, Vector3 scale, int skinId = 0, byte skillLevel = 0, byte rank = 0, byte type = 2, uint netId = 0, byte netNodeId = 64)
{
var prop = new LevelProp(_game, netNodeId, name, model, position, direction, posOffset, scale, skinId, skillLevel, rank, type, netId);
_game.ObjectManager.AddObject(prop);
return prop;
}
/// <summary>
/// Notifies prop animations (Such as the stairs at the beginning on Dominion)
/// </summary>
/// <param name="prop"></param>
/// <param name="animation"></param>
/// <param name="animationFlag"></param>
/// <param name="duration"></param>
/// <param name="destroyPropAfterAnimation"></param>
public static void NotifyPropAnimation(LevelProp prop, string animation, AnimationFlags animationFlag, float duration, bool destroyPropAfterAnimation)
{
var animationData = new UpdateLevelPropDataPlayAnimation
{
AnimationName = animation,
AnimationFlags = (uint)animationFlag,
Duration = duration,
DestroyPropAfterAnimation = destroyPropAfterAnimation,
StartMissionTime = _game.GameTime,
NetID = prop.NetId
};
_game.PacketNotifier.NotifyUpdateLevelPropS2C(animationData);
}
/// <summary>
/// Sets up the surrender functionality
/// </summary>
/// <param name="time"></param>
/// <param name="restTime"></param>
/// <param name="length"></param>
public static void AddSurrender(float time, float restTime, float length)
{
_map.Surrenders.Add(TeamId.TEAM_BLUE, new SurrenderHandler(_game, TeamId.TEAM_BLUE, time, restTime, length));
_map.Surrenders.Add(TeamId.TEAM_PURPLE, new SurrenderHandler(_game, TeamId.TEAM_PURPLE, time, restTime, length));
}
public static void HandleSurrender(int userId, Champion who, bool vote)
{
if (_map.Surrenders.ContainsKey(who.Team))
_map.Surrenders[who.Team].HandleSurrender(userId, who, vote);
}
/// <summary>
/// Adds a fountain
/// </summary>
/// <param name="team"></param>
/// <param name="position"></param>
public static Fountain CreateFountain(TeamId team, Vector2 position, float radius = 1000.0f)
{
return new Fountain(_game, team, position, radius);
}
/// <summary>
/// Sets the features which should be enabled for this map. EX: Mana, Cooldowns, Lane Minions, etc. Refer to FeatureFlags enum.
/// </summary>
/// <returns></returns>
public static void SetGameFeatures(FeatureFlags featureFlag, bool isEnabled)
{
_game.Config.SetGameFeatures(featureFlag, isEnabled);
}
/// <summary>
/// Returns current game time.
/// </summary>
/// <returns></returns>
public static float GameTime()
{
return _game.GameTime;
}
/// <summary>
/// Sets the game to exit
/// </summary>
/// <param name="losingTeam">The team who lost the game</param>
/// <param name="finalCameraPosition">The position which the camera has to move to for the end-game screen</param>
/// <param name="endGameTimer">Offset for the Endgame screend (victory or defeat) to be actually announced</param>
/// <param name="moveCamera">Wether or not the camera should move</param>
/// <param name="cameraTimer">The ammount of time the camera has to arrive to it's destination</param>
/// <param name="disableUI">Whether or not the UI should get disabled</param>
/// <param name="deathData">DeathData of what triggered the End of the Game, such as necus death</param>
public static void EndGame(TeamId losingTeam, Vector3 finalCameraPosition, float endGameTimer = 5000.0f, bool moveCamera = true, float cameraTimer = 3.0f, bool disableUI = true, GameServerLib.GameObjects.AttackableUnits.DeathData deathData = null)
{
//TODO: check if mapScripts should handle this directly
if (deathData != null)
{
_game.PacketNotifier.NotifyBuilding_Die(deathData);
_game.PacketNotifier.NotifyS2C_SetGreyscaleEnabledWhenDead(false, deathData.Killer);
}
else
{
_game.PacketNotifier.NotifyS2C_SetGreyscaleEnabledWhenDead(false);
}
var players = _game.PlayerManager.GetPlayers(false);
foreach (var player in players)
{
if (disableUI)
{
_game.PacketNotifier.NotifyS2C_DisableHUDForEndOfGame(player);
}
if (moveCamera)
{
_game.PacketNotifier.NotifyS2C_MoveCameraToPoint(player, Vector3.Zero, finalCameraPosition, cameraTimer);
}
}
//The way we handle the end of a game has to be reworked
var timer = new Timer(endGameTimer) { AutoReset = false };
timer.Elapsed += (a, b) =>
{
_game.Stop();
_game.PacketNotifier.NotifyS2C_EndGame(losingTeam);
_game.SetGameToExit();
};
timer.Start();
}
public static void AddTurretItems(BaseTurret turret, int[] items)
{
foreach (var item in items)
{
turret.Inventory.AddItem(_game.ItemManager.SafeGetItemType(item), turret);
}
}
public static void NotifySpawnBroadcast(GameObject obj)
{
//Just a workaround for our current vision problem.
_game.PacketNotifier.NotifySpawn(obj, TeamId.TEAM_PURPLE, -1, _game.GameTime, true);
_game.PacketNotifier.NotifySpawn(obj, TeamId.TEAM_BLUE, -1, _game.GameTime, true);
}
public static void AddObject(GameObject obj)
{
_game.ObjectManager.AddObject(obj);
}
/// <summary>
/// Returns the average level of all players in the game
/// </summary>
/// <returns></returns>
public static int GetPlayerAverageLevel()
{
float average = 0;
var players = _game.PlayerManager.GetPlayers(true);
foreach (var player in players)
{
average += player.Champion.Stats.Level / players.Count;
}
return (int)average;
}
public static void NotifyGameScore(TeamId team, float score)
{
_game.PacketNotifier.NotifyS2C_HandleGameScore(team, (int)score);
}
/// <summary>
/// I couldn't tell the functionality for this besides Notifying the scoreboard at the start of the match
/// </summary>
/// <param name="capturePointIndex"></param>
/// <param name="otherNetId"></param>
/// <param name="PARType"></param>
/// <param name="attackTeam"></param>
/// <param name="capturePointUpdateCommand"></param>
public static void NotifyHandleCapturePointUpdate(byte capturePointIndex, uint otherNetId, byte PARType, byte attackTeam, CapturePointUpdateCommand capturePointUpdateCommand)
{
_game.PacketNotifier.NotifyS2C_HandleCapturePointUpdate(capturePointIndex, otherNetId, PARType, attackTeam, capturePointUpdateCommand);
}
public static void TeleportCamera(Champion target, Vector3 position)
{
_game.PacketNotifier.NotifyS2C_CameraBehavior(target, position);
}
public static void NotifyAscendant(ObjAIBase ascendant = null)
{
_game.PacketNotifier.NotifyS2C_UpdateAscended(ascendant);
}
public static void NotifyMapPing(Vector2 position, PingCategory ping)
{
_game.PacketNotifier.NotifyS2C_MapPing(position, (Pings)ping);
}
}
}