@bf6mods/cli 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/README.md +70 -0
  2. package/dist/cli/index.js +541 -76
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/resources/prepare/bf6.d.ts +2 -0
  5. package/dist/resources/prepare/tsconfig.json +14 -15
  6. package/dist/resources/prepare/types/config.ts +139 -4
  7. package/dist/resources/templates/All/package.json +1 -1
  8. package/dist/resources/templates/Basic/bf6.config.ts +5 -1
  9. package/package.json +48 -41
  10. package/dist/resources/templates/AcePursuit/src/index.ts +0 -3421
  11. package/dist/resources/templates/AcePursuit/src/levels.tscn +0 -6922
  12. package/dist/resources/templates/AcePursuit/src/strings.json +0 -191
  13. package/dist/resources/templates/All/bf6.config.ts +0 -6
  14. package/dist/resources/templates/BombSquad/src/index.ts +0 -3683
  15. package/dist/resources/templates/BombSquad/src/levels.tscn +0 -3212
  16. package/dist/resources/templates/BombSquad/src/strings.json +0 -123
  17. package/dist/resources/templates/Exfil/src/index.ts +0 -2393
  18. package/dist/resources/templates/Exfil/src/levels.tscn +0 -5600
  19. package/dist/resources/templates/Exfil/src/strings.json +0 -185
  20. package/dist/resources/templates/Vertigo/src/index.ts +0 -1948
  21. package/dist/resources/templates/Vertigo/src/levels.tscn +0 -6387
  22. package/dist/resources/templates/Vertigo/src/strings.json +0 -308
  23. /package/dist/resources/templates/{AcePursuit/src/config.json → AcePursuit.json} +0 -0
  24. /package/dist/resources/templates/{BombSquad/src/config.json → BombSquad.json} +0 -0
  25. /package/dist/resources/templates/{Exfil/src/config.json → Exfil.json} +0 -0
  26. /package/dist/resources/templates/{Vertigo/src/config.json → Vertigo.json} +0 -0
@@ -1,2393 +0,0 @@
1
- // === src\Exfil_main.ts ===
2
- const VERSION = [1, 17, 0];
3
- //version format is [ship, delivery, patch/compile]
4
-
5
-
6
- const debugAIBehavior = true;
7
- const debugPlayer = true;
8
- const debugAIEnemy = true;
9
-
10
- const battlefieldWhite = mod.CreateVector(0.733, 0.808, 0.851);
11
- const battlefieldBlue = mod.CreateVector(0.678, 0.753, 0.8);
12
- const battlefieldBlueBg = mod.CreateVector(0.75, 0.75, 0.75);
13
- const battlefieldGrey = mod.CreateVector(0.616, 0.635, 0.647);
14
-
15
- let itemPickupDistance = 3.0;
16
- const itemReturnTime = 20.0;
17
- const enemyRespawnTime = 60;
18
- const aiEngageRange = 17.5;
19
- const aiLeashRange = 5;
20
- let itemCarrySpeedFactor = 1.0;
21
- const itemCarrySpeedFactorCap = 1.5;
22
- const itemCarrySpeedIncrement = 0.05;
23
- let itemCarryHealthFactor = 1.0;
24
- const itemCarryHealthFactorCap = 1.5;
25
- const itemCarryHealthIncrement = 0.05;
26
- let heightToKillAt = 69.8;
27
- const teamAmount = 5;
28
- let teamMemberCount: number[] = [0, 0, 0, 0, 0, 0];
29
- let teamColors: mod.Vector[] = [
30
- mod.CreateVector(1, 0.1, 0),
31
- mod.CreateVector(0, 1, 1),
32
- mod.CreateVector(0.5, 0, 1),
33
- mod.CreateVector(0, 0.8, 0),
34
- mod.CreateVector(0, 0, 0),
35
- ];
36
-
37
- let baseGameStartCountdown: number = 60;
38
- let gameStartCountdown: number = 60;
39
- let requiredPlayersToStart: number = 4;
40
-
41
- let uniqueNameNumber: number = 0;
42
-
43
- const spawnPointsMap: Record<number, Vector3> = {
44
- 7: { x: -9.368, y: 75.369 + 10, z: -107.521 },
45
- 8: { x: -15.409, y: 78.495 + 10, z: -55.039 },
46
- 9: { x: 3.288, y: 76.109 + 10, z: -86.37 },
47
- 10: { x: 15.297, y: 75.933 + 10, z: -44.59 },
48
- 11: { x: -59.808, y: 80.995 + 10, z: -68.389 },
49
- 12: { x: -46.637, y: 76.143 + 10, z: -62.448 },
50
- 13: { x: -18.436, y: 78.738 + 10, z: -68.249 },
51
- 14: { x: -50.068, y: 79.755 + 10, z: -11.267 },
52
- 15: { x: -55.907, y: 76.143 + 10, z: -86.698 },
53
- 16: { x: -54.582, y: 71.972 + 10, z: -72.545 },
54
- 17: { x: -62.288, y: 79.834 + 10, z: -26.115 },
55
- 18: { x: -44.71, y: 75.795 + 10, z: -108.383 },
56
- 19: { x: -24.366, y: 78.332 + 10, z: -129.02 },
57
- };
58
-
59
- const vfxSpawnMap: Record<number, Vector3> = {
60
- 1: { x: -80.0, y: 64, z: 120.0 },
61
- 2: { x: -65.0, y: 64, z: 100.0 },
62
- 3: { x: -80.0, y: 64, z: 80.0 },
63
- 4: { x: -65.0, y: 64, z: 60.0 },
64
- 5: { x: -80.0, y: 64, z: 40.0 },
65
- 6: { x: -65.0, y: 64, z: 20.0 },
66
- 7: { x: -80.0, y: 64, z: 0 },
67
- 8: { x: -65.0, y: 64, z: -20 },
68
- 9: { x: -80.0, y: 64, z: -40.0 },
69
- 10: { x: -65.0, y: 64, z: -60.0 },
70
- 11: { x: -80.0, y: 64, z: -80.0 },
71
- 12: { x: -65.0, y: 64, z: -100.0 },
72
- 13: { x: -50.0, y: 64, z: 80.0 },
73
- 14: { x: -35.0, y: 64, z: 60.0 },
74
- 15: { x: -50.0, y: 64, z: 40.0 },
75
- 16: { x: -35.0, y: 64, z: 20.0 },
76
- 17: { x: -50.0, y: 64, z: 0 },
77
- 18: { x: -35.0, y: 64, z: -20 },
78
- 19: { x: -50.0, y: 64, z: -40.0 },
79
- 20: { x: -35.0, y: 64, z: -60.0 },
80
- 21: { x: -50.0, y: 64, z: -80.0 },
81
- 22: { x: -35.0, y: 64, z: -100.0 },
82
- 23: { x: -20.0, y: 64, z: 80.0 },
83
- 24: { x: -5.0, y: 64, z: 60.0 },
84
- 25: { x: -20.0, y: 64, z: 40.0 },
85
- 26: { x: -5.0, y: 64, z: 20.0 },
86
- 27: { x: -20.0, y: 64, z: 0 },
87
- 28: { x: -5.0, y: 64, z: -20 },
88
- 29: { x: -20.0, y: 64, z: -40.0 },
89
- 30: { x: -5.0, y: 64, z: -60.0 },
90
- 31: { x: -20.0, y: 64, z: -80.0 },
91
- 32: { x: -5.0, y: 64, z: -100.0 },
92
- 33: { x: 10.0, y: 64, z: 40.0 },
93
- 34: { x: 25.0, y: 64, z: 20.0 },
94
- 35: { x: 10.0, y: 64, z: 0 },
95
- 36: { x: 25.0, y: 64, z: -20 },
96
- 37: { x: 10.0, y: 64, z: -40.0 },
97
- 38: { x: 25.0, y: 64, z: -60.0 },
98
- 39: { x: 10.0, y: 64, z: -80.0 },
99
- 40: { x: 25.0, y: 64, z: -100.0 },
100
- 41: { x: 40.0, y: 64, z: 40.0 },
101
- 42: { x: 55.0, y: 64, z: 20.0 },
102
- 43: { x: 40.0, y: 64, z: 0 },
103
- 44: { x: 55.0, y: 64, z: -20 },
104
- 45: { x: 40.0, y: 64, z: -40.0 },
105
- 46: { x: 55.0, y: 64, z: -60.0 },
106
- 47: { x: 40.0, y: 64, z: -80.0 },
107
- 48: { x: 55.0, y: 64, z: -100.0 },
108
- 49: { x: 70.0, y: 64, z: 40.0 },
109
- 50: { x: 85.0, y: 64, z: 20.0 },
110
- 51: { x: 70.0, y: 64, z: 0 },
111
- 52: { x: 85.0, y: 64, z: -20 },
112
- 53: { x: 70.0, y: 64, z: -40.0 },
113
- 54: { x: 85.0, y: 64, z: -60.0 },
114
- 55: { x: 70.0, y: 64, z: -80.0 },
115
- 56: { x: 85.0, y: 64, z: -100.0 },
116
- };
117
-
118
- type Vector3 = { x: number; y: number; z: number };
119
-
120
- function InitializeSpawners() {
121
- for (let index = 7; index < 17; index++) {
122
- mod.SetUnspawnDelayInSeconds(mod.GetSpawner(index), 15);
123
- }
124
- }
125
-
126
- // spawns all necessary initial AI
127
- async function SpawnEnemies() {
128
- AISpawnHandler.SpawnAIEnemyWithBehavior(meleeShooterBehavior, 1, {
129
- soldierClass: mod.SoldierClass.Assault,
130
- spawnPointID: 7,
131
- health: 100,
132
- speedMultiplier: 0.5,
133
- });
134
- AISpawnHandler.SpawnAIEnemyWithBehavior(meleeShooterBehavior, 1, {
135
- soldierClass: mod.SoldierClass.Assault,
136
- spawnPointID: 8,
137
- health: 100,
138
- speedMultiplier: 0.5,
139
- });
140
- AISpawnHandler.SpawnAIEnemyWithBehavior(meleeShooterBehavior, 1, {
141
- soldierClass: mod.SoldierClass.Assault,
142
- spawnPointID: 9,
143
- health: 100,
144
- speedMultiplier: 0.5,
145
- });
146
- AISpawnHandler.SpawnAIEnemyWithBehavior(meleeShooterBehavior, 1, {
147
- soldierClass: mod.SoldierClass.Assault,
148
- spawnPointID: 10,
149
- health: 100,
150
- speedMultiplier: 0.5,
151
- });
152
- AISpawnHandler.SpawnAIEnemyWithBehavior(meleeShooterBehavior, 1, {
153
- soldierClass: mod.SoldierClass.Assault,
154
- spawnPointID: 11,
155
- health: 100,
156
- speedMultiplier: 0.5,
157
- });
158
- AISpawnHandler.SpawnAIEnemyWithBehavior(meleeShooterBehavior, 1, {
159
- soldierClass: mod.SoldierClass.Assault,
160
- spawnPointID: 12,
161
- health: 100,
162
- speedMultiplier: 0.5,
163
- });
164
- AISpawnHandler.SpawnAIEnemyWithBehavior(meleeShooterBehavior, 1, {
165
- soldierClass: mod.SoldierClass.Assault,
166
- spawnPointID: 13,
167
- health: 100,
168
- speedMultiplier: 0.5,
169
- });
170
- AISpawnHandler.SpawnAIEnemyWithBehavior(meleeShooterBehavior, 1, {
171
- soldierClass: mod.SoldierClass.Assault,
172
- spawnPointID: 14,
173
- health: 100,
174
- speedMultiplier: 0.5,
175
- });
176
- AISpawnHandler.SpawnAIEnemyWithBehavior(meleeShooterBehavior, 1, {
177
- soldierClass: mod.SoldierClass.Assault,
178
- spawnPointID: 15,
179
- health: 100,
180
- speedMultiplier: 0.5,
181
- });
182
- AISpawnHandler.SpawnAIEnemyWithBehavior(meleeShooterBehavior, 1, {
183
- soldierClass: mod.SoldierClass.Assault,
184
- spawnPointID: 16,
185
- health: 100,
186
- speedMultiplier: 0.5,
187
- });
188
- AISpawnHandler.SpawnAIEnemyWithBehavior(meleeShooterBehavior, 1, {
189
- soldierClass: mod.SoldierClass.Assault,
190
- spawnPointID: 17,
191
- health: 100,
192
- speedMultiplier: 0.5,
193
- });
194
- AISpawnHandler.SpawnAIEnemyWithBehavior(meleeShooterBehavior, 1, {
195
- soldierClass: mod.SoldierClass.Assault,
196
- spawnPointID: 18,
197
- health: 100,
198
- speedMultiplier: 0.5,
199
- });
200
- AISpawnHandler.SpawnAIEnemyWithBehavior(meleeShooterBehavior, 1, {
201
- soldierClass: mod.SoldierClass.Assault,
202
- spawnPointID: 19,
203
- health: 100,
204
- speedMultiplier: 0.5,
205
- });
206
- }
207
-
208
- export async function OnGameModeStarted() {
209
- mod.EnableInteractPoint(mod.GetInteractPoint(0), true);
210
- console.log("Game Mode Started");
211
- SpawnAllGroundCloudVFX();
212
- InitializeSpawners();
213
- mod.SetAIToHumanDamageModifier(0.1);
214
- ExtractionPoint.Initialize();
215
- ObjectiveItemData.Initialize();
216
- ExtractionPoint.DeactivateAllExtractionPoints();
217
-
218
- gameStartCountdown = baseGameStartCountdown;
219
-
220
- TickUpdate();
221
- SlowerTickUpdate();
222
- SuperSlowTickUpdate();
223
- }
224
-
225
- async function SuperSlowTickUpdate() {
226
- while (true) {
227
- await mod.Wait(0.5);
228
-
229
- if (!ObjectiveItemData.isBeingCarried) continue;
230
-
231
- if (
232
- !mod.HasEquipment(
233
- ObjectiveItemData.carryingPlayer,
234
- mod.Gadgets.Misc_Supply_Pouch
235
- )
236
- ) {
237
- mod.AddEquipment(
238
- ObjectiveItemData.carryingPlayer,
239
- mod.Gadgets.Misc_Supply_Pouch
240
- );
241
- }
242
-
243
- try {
244
- const weapons = Object.values(mod.Weapons) as mod.Weapons[];
245
- const primaryWeapons = weapons.filter(
246
- (weapon) => !weapon.toString().startsWith("Sidearm_")
247
- );
248
- primaryWeapons.forEach((element) => {
249
- if (mod.HasEquipment(ObjectiveItemData.carryingPlayer, element)) {
250
- mod.RemoveEquipment(
251
- ObjectiveItemData.carryingPlayer,
252
- mod.InventorySlots.PrimaryWeapon
253
- );
254
- }
255
- });
256
- } catch { }
257
- }
258
- }
259
-
260
- async function SlowerTickUpdate() {
261
- while (true) {
262
- await mod.Wait(0.05);
263
- ObjectiveItemData.ItemProximityCheck();
264
- BelowHeightDamage();
265
- }
266
- }
267
-
268
- async function TickUpdate() {
269
- while (true) {
270
- await mod.Wait(0.0);
271
- ObjectiveItemData.ItemHeld();
272
- }
273
- }
274
-
275
- export async function OnPlayerJoinGame(player: mod.Player) {
276
- console.log("player " + mod.GetObjId(player) + " joined");
277
- mod.EnablePlayerDeploy(player, false);
278
- await mod.Wait(2.0);
279
- console.log(
280
- "JoinGame playerInstances length check: " +
281
- PlayerProfile.playerInstances.length
282
- );
283
- if (!mod.GetSoldierState(player, mod.SoldierStateBool.IsAISoldier)) {
284
- while (true) {
285
- if (mod.GetObjId(player) > -1) {
286
- break;
287
- }
288
- await mod.Wait(0.5);
289
- }
290
- const playerProfile = PlayerProfile.Get(player);
291
- if (playerProfile) {
292
- AssignTeam(playerProfile);
293
- }
294
- playerProfile?.UpdateUI(
295
- playerProfile.playerLoadoutWarningWidget,
296
- MakeMessage(mod.stringkeys.loading),
297
- true
298
- );
299
- mod.EnablePlayerDeploy(player, false);
300
- mod.SetRedeployTime(player, 5);
301
- console.log(
302
- "player " + mod.GetObjId(player) + " waiting to load for first deploy"
303
- );
304
- await mod.Wait(10.0);
305
- }
306
-
307
- if (!mod.IsPlayerValid(player)) return;
308
-
309
- if (!mod.GetSoldierState(player, mod.SoldierStateBool.IsAISoldier)) {
310
- console.log(
311
- "player " + mod.GetObjId(player) + " running remaining JoinGame code"
312
- );
313
-
314
- const playerProfile = PlayerProfile.Get(player);
315
-
316
- playerProfile?.UpdateUI(
317
- playerProfile.playerHeaderWidget,
318
- MakeMessage(mod.stringkeys.getObjectiveItem),
319
- true
320
- );
321
- playerProfile?.UpdateUI(
322
- playerProfile.playerSubHeaderWidget,
323
- MakeMessage(mod.stringkeys.subGetObjectiveItem),
324
- true
325
- );
326
-
327
-
328
- playerProfile?.ShowLoadoutWarningUI(true);
329
-
330
- ObjectiveItemData.RespawnSupplyVFX();
331
- ExtractionPoint.RespawnVFXForCurrentExtractionPoint();
332
-
333
- mod.EnablePlayerDeploy(player, true);
334
-
335
- console.log("enabled player deploy for player " + mod.GetObjId(player));
336
-
337
- if (!ObjectiveItemData.isBeingCarried) return;
338
-
339
- if (
340
- mod.GetObjId(mod.GetTeam(ObjectiveItemData.carryingPlayer)) ==
341
- mod.GetObjId(mod.GetTeam(player))
342
- ) {
343
- playerProfile?.UpdateUI(
344
- playerProfile.playerHeaderWidget,
345
- MakeMessage(mod.stringkeys.yourTeamHoldsTheItem),
346
- true
347
- );
348
- playerProfile?.UpdateUI(
349
- playerProfile.playerSubHeaderWidget,
350
- MakeMessage(mod.stringkeys.subYourTeamHoldsTheItem),
351
- true
352
- );
353
- playerProfile?.playerHeaderWidget &&
354
- mod.SetUITextColor(
355
- playerProfile.playerHeaderWidget,
356
- teamColors[
357
- GetTrueTeamIDNumberOfPlayer(ObjectiveItemData.carryingPlayer) - 1
358
- ]
359
- );
360
- } else {
361
- playerProfile?.UpdateUI(
362
- playerProfile.playerHeaderWidget,
363
- MakeMessage(
364
- mod.stringkeys.playerHoldingObjectiveItem,
365
- GetAdjustedTeamNumber(ObjectiveItemData.carryingPlayer)
366
- ),
367
- true
368
- );
369
- playerProfile?.UpdateUI(
370
- playerProfile.playerSubHeaderWidget,
371
- MakeMessage(mod.stringkeys.subPlayerHoldingObjectiveItem),
372
- true
373
- );
374
- playerProfile?.playerHeaderWidget &&
375
- mod.SetUITextColor(
376
- playerProfile.playerHeaderWidget,
377
- teamColors[
378
- GetTrueTeamIDNumberOfPlayer(ObjectiveItemData.carryingPlayer) - 1
379
- ]
380
- );
381
- }
382
- } else {
383
- mod.EnablePlayerDeploy(player, true);
384
- mod.SetTeam(player, mod.GetTeam(5)); // sets AI to team 5
385
- }
386
- }
387
-
388
-
389
- function GetAmountOfPlayersOnTheTeams(): Map<number, number> {
390
- const myMap = new Map<number, number>([[1, 0], [2, 0], [3, 0], [4, 0]]);
391
-
392
- const players = mod.AllPlayers();
393
- const n = mod.CountOf(players);
394
-
395
- for (let i = 0; i < n; i++) {
396
- const loopPlayer = mod.ValueInArray(players, i);
397
-
398
- if (
399
- mod.IsPlayerValid(loopPlayer) &&
400
- !mod.GetSoldierState(loopPlayer, mod.SoldierStateBool.IsAISoldier)
401
- ) {
402
- const teamId = PlayerProfile.Get(loopPlayer)?.playerTeamID;
403
-
404
- if (teamId && myMap.has(teamId)) {
405
- myMap.set(teamId, (myMap.get(teamId) ?? 0) + 1);
406
- }
407
- }
408
- }
409
-
410
- return myMap;
411
- }
412
-
413
-
414
- function GetTeamWithFewestPlayers(teamCounts: Map<number, number>): number {
415
- const entries = Array.from(teamCounts.entries());
416
-
417
- if (entries.length === 0) {
418
- return -1; // no teams
419
- }
420
-
421
- let [lowestTeam, lowestCount] = entries[0]; // take the first team as baseline
422
-
423
- for (let i = 1; i < entries.length; i++) {
424
- const [teamId, count] = entries[i];
425
- if (count < lowestCount) {
426
- lowestTeam = teamId;
427
- lowestCount = count;
428
- }
429
- }
430
-
431
- return lowestTeam;
432
- }
433
-
434
- function AssignTeam(player: PlayerProfile) {
435
- let amountInTeams = GetAmountOfPlayersOnTheTeams()
436
-
437
- // Find the team with the fewest players
438
- let minTeamId = GetTeamWithFewestPlayers(amountInTeams)
439
-
440
- // Assign player to that team
441
- player.playerTeamID = minTeamId;
442
-
443
- amountInTeams = GetAmountOfPlayersOnTheTeams()
444
-
445
- mod.SetTeam(player.player, mod.GetTeam(minTeamId));
446
- }
447
-
448
- export function OnPlayerSwitchTeam(
449
- eventPlayer: mod.Player,
450
- eventTeam: mod.Team
451
- ) {
452
- if (!mod.GetSoldierState(eventPlayer, mod.SoldierStateBool.IsAISoldier)) {
453
- const playerprofile = PlayerProfile.Get(eventPlayer);
454
- if (playerprofile) {
455
- // IsPlayerOnRightTeamCheck(playerprofile);
456
- }
457
- }
458
- }
459
-
460
- export async function OnPlayerDeployed(player: mod.Player) {
461
- await mod.Wait(1.0);
462
- if (
463
- mod.IsPlayerValid(player) &&
464
- mod.GetSoldierState(player, mod.SoldierStateBool.IsAlive) &&
465
- !mod.GetSoldierState(player, mod.SoldierStateBool.IsAISoldier)
466
- ) {
467
- const playerProfile = PlayerProfile.Get(player);
468
-
469
- playerProfile && await IsPlayerOnRightTeamCheck(playerProfile);
470
-
471
- console.log("will show player " + mod.GetObjId(player) + " team widget");
472
- playerProfile?.ShowPlayerTeamWidget(true);
473
-
474
- if (playerProfile?.maxHealth != undefined) {
475
- playerProfile.maxHealth = mod.GetSoldierState(
476
- player,
477
- mod.SoldierStateNumber.MaxHealth
478
- );
479
- }
480
-
481
- console.log("will set player " + mod.GetObjId(player) + " loadout");
482
-
483
- SetPlayerLoadout(player);
484
-
485
- console.log(
486
- "will push player " + mod.GetObjId(player) + " to deployedplayers"
487
- );
488
- PlayerProfile.deployedPlayers.push(player);
489
- PlayerProfile.UpdateGameStartCountdown();
490
-
491
- if (!gameStartDebounce) {
492
- mod.EnableAllInputRestrictions(player, true);
493
- } else {
494
- mod.EnableAllInputRestrictions(player, false);
495
- }
496
-
497
- //mod.SkipManDown(player, true);
498
- await mod.Wait(0);
499
- console.log(
500
- "will unshow loadout warning for player " + mod.GetObjId(player)
501
- );
502
- playerProfile?.ShowLoadoutWarningUI(false);
503
- } else {
504
- AISpawnHandler.assignAIBehavior(player);
505
- }
506
- }
507
-
508
- async function IsPlayerOnRightTeamCheck(playerprofile: PlayerProfile) {
509
- const playerTeamID = mod.GetTeam(playerprofile.player)
510
- if ((mod.GetObjId(playerTeamID) != playerprofile.playerTeamID)) {
511
- mod.SetTeam(playerprofile.player, mod.GetTeam(playerprofile.playerTeamID + 1))
512
- console.log("player is not on the right team, reassign them to " + (playerprofile.playerTeamID + 1))
513
- }
514
- await mod.Wait(0.5)
515
- }
516
-
517
- export async function OnPlayerDied(player: mod.Player) {
518
-
519
-
520
- if (mod.GetSoldierState(player, mod.SoldierStateBool.IsAISoldier) == true) {
521
- AISpawnHandler.AiDied(player);
522
- return
523
- }
524
-
525
- if (
526
- ObjectiveItemData.carryingPlayer &&
527
- mod.IsPlayerValid(ObjectiveItemData.carryingPlayer) &&
528
- mod.GetObjId(player) == mod.GetObjId(ObjectiveItemData.carryingPlayer)
529
- ) {
530
- ObjectiveItemData.ItemDropped(ObjectiveItemData.carryingPlayer);
531
- ObjectiveItemData.itemDroppedDebounce = false;
532
- mod.YComponentOf(ObjectiveItemData.currentWorldIconPos) <
533
- heightToKillAt + 2.5 && ObjectiveItemData.ReturnItemToOriginalPosition(); // this is cursed but also very funny
534
- return;
535
- }
536
-
537
- if (
538
- mod.IsPlayerValid(player) &&
539
- mod.GetSoldierState(player, mod.SoldierStateBool.IsAISoldier) == false
540
- ) {
541
- PlayerProfile.RemovePlayerFromDeployedPlayers(player);
542
- if (!gameStartDebounce) {
543
- PlayerProfile.UpdateGameStartCountdown();
544
- }
545
-
546
- CheckToShowLoadoutWarning(player);
547
- }
548
-
549
- }
550
-
551
- async function CheckToShowLoadoutWarning(player: mod.Player) {
552
- let hasManDowned: boolean = false;
553
- try {
554
- while (mod.IsPlayerValid(player)) {
555
- await mod.Wait(0.1);
556
- if (mod.GetSoldierState(player, mod.SoldierStateBool.IsManDown))
557
- hasManDowned = true;
558
- if (
559
- !mod.GetSoldierState(player, mod.SoldierStateBool.IsManDown) &&
560
- !mod.GetSoldierState(player, mod.SoldierStateBool.IsAlive) &&
561
- mod.GetSoldierState(player, mod.SoldierStateBool.IsDead)
562
- ) {
563
- await (hasManDowned ? mod.Wait(2.4) : mod.Wait(6.7));
564
- PlayerProfile.Get(player)?.ShowLoadoutWarningUI(true);
565
- break;
566
- }
567
- continue;
568
- }
569
- } catch {
570
- console.log(
571
- "check to show loadout for player " + mod.GetObjId(player) + " failed"
572
- );
573
- }
574
- }
575
-
576
- export function OnPlayerLeaveGame(eventNumber: number) {
577
-
578
-
579
- try {
580
- if (
581
- (!ObjectiveItemData.carryingPlayer ||
582
- !mod.IsPlayerValid(ObjectiveItemData.carryingPlayer)) &&
583
- ObjectiveItemData.isBeingCarried
584
- ) {
585
- ObjectiveItemData.ItemDropped();
586
- ObjectiveItemData.itemDroppedDebounce = false;
587
- }
588
- } catch {
589
- if (ObjectiveItemData.isBeingCarried) {
590
- ObjectiveItemData.ItemDropped();
591
- ObjectiveItemData.itemDroppedDebounce = false;
592
- }
593
- }
594
-
595
- // iterate through and verify that all players in deployedPlayers are valid
596
- PlayerProfile.deployedPlayers.forEach((element) => {
597
- try {
598
- if (element == undefined || !mod.IsPlayerValid(element) || !element) {
599
- PlayerProfile.RemovePlayerFromDeployedPlayers(element);
600
- }
601
- } catch {
602
- PlayerProfile.RemovePlayerFromDeployedPlayers(element);
603
- }
604
- });
605
-
606
- PlayerProfile.playerInstances.forEach((element) => {
607
- try {
608
- if (element == undefined || !mod.IsPlayerValid(element) || !element) {
609
- PlayerProfile.RemovePlayerFromPlayerInstances(element);
610
- }
611
- } catch {
612
- PlayerProfile.RemovePlayerFromPlayerInstances(element);
613
- }
614
- });
615
- PlayerProfile.removePlayerProfile(eventNumber);
616
- }
617
-
618
- export function OnPlayerEarnedKill(
619
- eventPlayer: mod.Player,
620
- eventOtherPlayer: mod.Player,
621
- eventDeathType: mod.DeathType,
622
- eventWeaponUnlock: mod.WeaponUnlock
623
- ) {
624
- if (
625
- eventPlayer &&
626
- mod.IsPlayerValid(eventPlayer) &&
627
- mod.GetObjId(eventPlayer) != mod.GetObjId(eventOtherPlayer) &&
628
- !mod.GetSoldierState(eventPlayer, mod.SoldierStateBool.IsAISoldier)
629
- ) {
630
- try {
631
- const ammoToGive: number =
632
- mod.GetSoldierState(
633
- eventPlayer,
634
- mod.SoldierStateNumber.CurrentWeaponMagazineAmmo
635
- ) + 10;
636
- mod.SetInventoryMagazineAmmo(
637
- eventPlayer,
638
- mod.InventorySlots.SecondaryWeapon,
639
- ammoToGive
640
- );
641
- PlayerProfile.Get(eventPlayer)?.ShowAmmoFeedback();
642
- } catch { }
643
- }
644
- }
645
-
646
- /* function DoCustomInputRestrictions(player: mod.Player, bool: boolean){
647
- mod.EnableInputRestriction(player, mod.RestrictedInputs.MoveForwardBack, bool);
648
- mod.EnableInputRestriction(player, mod.RestrictedInputs.MoveLeftRight, bool);
649
- } */
650
-
651
- function SpawnAllGroundCloudVFX() {
652
- for (const key in vfxSpawnMap) {
653
- if (vfxSpawnMap.hasOwnProperty(Number(key))) {
654
- const convertedToBFVector = mod.CreateVector(
655
- vfxSpawnMap[Number(key)].x,
656
- vfxSpawnMap[Number(key)].y,
657
- vfxSpawnMap[Number(key)].z
658
- );
659
- const vfxInstance = H.SpawnVFX(
660
- mod.RuntimeSpawn_Common.FX_Airplane_Jetwash_Dirt,
661
- convertedToBFVector,
662
- mod.CreateVector(0, 0, 0),
663
- mod.CreateVector(1, 1, 1)
664
- );
665
- }
666
- }
667
- }
668
-
669
- function SetPlayerLoadout(player: mod.Player) {
670
- try {
671
- if (mod.HasEquipment(player, mod.Gadgets.Deployable_EOD_Bot)) {
672
- mod.RemoveEquipment(player, mod.Gadgets.Deployable_EOD_Bot);
673
- }
674
-
675
- if (mod.HasEquipment(player, mod.Gadgets.Deployable_Deploy_Beacon)) {
676
- mod.RemoveEquipment(player, mod.Gadgets.Deployable_Deploy_Beacon);
677
- }
678
-
679
- if (mod.HasEquipment(player, mod.Gadgets.Misc_Assault_Ladder)) {
680
- mod.RemoveEquipment(player, mod.Gadgets.Misc_Assault_Ladder);
681
- }
682
- } catch { }
683
- }
684
-
685
- function BelowHeightDamage() {
686
- let players = mod.AllPlayers();
687
- let n = mod.CountOf(players);
688
-
689
- for (let i = 0; i < n; i++) {
690
- let loopPlayer = mod.ValueInArray(players, i);
691
- if (
692
- mod.IsPlayerValid(loopPlayer) &&
693
- mod.GetSoldierState(loopPlayer, mod.SoldierStateBool.IsAlive)
694
- ) {
695
- const position = mod.GetSoldierState(
696
- loopPlayer,
697
- mod.SoldierStateVector.GetPosition
698
- );
699
- if (mod.YComponentOf(position) < heightToKillAt) {
700
- mod.Kill(loopPlayer);
701
- }
702
- }
703
- }
704
- }
705
-
706
- function Lerp(a: number, b: number, t: number): number {
707
- return a + (b - a) * t;
708
- }
709
-
710
- function MakeMessage(message: string, ...args: any[]) {
711
- switch (args.length) {
712
- case 0:
713
- return mod.Message(message);
714
- case 1:
715
- return mod.Message(message, args[0]);
716
- case 2:
717
- return mod.Message(message, args[0], args[1]);
718
- case 3:
719
- return mod.Message(message, args[0], args[1], args[2]);
720
- default:
721
- throw new Error("Invalid number of arguments");
722
- }
723
- }
724
-
725
- class ObjectiveItemData {
726
- static defaultWorldIcon: mod.WorldIcon;
727
- static teamWorldIcon1: mod.WorldIcon; // this was intended to use an array, but it did not work out
728
- static teamWorldIcon2: mod.WorldIcon;
729
- static teamWorldIcon3: mod.WorldIcon;
730
- static teamWorldIcon4: mod.WorldIcon;
731
-
732
- static vfxInstance: mod.VFX;
733
-
734
- static itemCurrentlyDropped = false;
735
- static isBeingCarried: boolean = false;
736
- static carryingPlayer: mod.Player;
737
-
738
- // for now, remember to set this every time you set the item's position. It's defined here using its placement in the map editor.
739
- static originalWorldIconPos: mod.Vector = mod.CreateVector(
740
- -62.228,
741
- 81.284,
742
- -69.129
743
- );
744
- static currentWorldIconPos: mod.Vector = this.originalWorldIconPos;
745
- static lastCarryingPlayerPos: mod.Vector = mod.CreateVector(0, 0, 0);
746
-
747
- static itemDroppedDebounce: boolean = true;
748
- static hasBeenPickedUpOnce: boolean = false;
749
-
750
- static dropTime: number = 0;
751
-
752
- static extractionPointsMap: Record<number, mod.Vector>;
753
-
754
- static Initialize() {
755
- this.defaultWorldIcon = mod.GetWorldIcon(1500);
756
- this.teamWorldIcon1 = mod.GetWorldIcon(1501);
757
- this.teamWorldIcon2 = mod.GetWorldIcon(1502);
758
- this.teamWorldIcon3 = mod.GetWorldIcon(1503);
759
- this.teamWorldIcon4 = mod.GetWorldIcon(1504);
760
- mod.SetWorldIconOwner(this.teamWorldIcon1, mod.GetTeam(1));
761
- mod.SetWorldIconOwner(this.teamWorldIcon2, mod.GetTeam(2));
762
- mod.SetWorldIconOwner(this.teamWorldIcon3, mod.GetTeam(3));
763
- mod.SetWorldIconOwner(this.teamWorldIcon4, mod.GetTeam(4));
764
- //this.vfxInstance = H.SpawnVFX(mod.RuntimeSpawn_Common.FX_Smoke_Marker_Custom, this.originalWorldIconPos);
765
- }
766
-
767
- static async RespawnSupplyVFX() {
768
- await mod.Wait(3.0);
769
- if (this.vfxInstance) {
770
- mod.EnableVFX(this.vfxInstance, false);
771
- }
772
- this.vfxInstance = H.SpawnVFX(
773
- mod.RuntimeSpawn_Common.FX_Granite_Strike_Smoke_Marker_Yellow,
774
- this.currentWorldIconPos
775
- );
776
- }
777
-
778
- static RefreshWorldIconOwners() {
779
- mod.SetWorldIconColor(this.teamWorldIcon1, mod.CreateVector(1, 0, 0));
780
- mod.SetWorldIconColor(this.teamWorldIcon2, mod.CreateVector(1, 0, 0));
781
- mod.SetWorldIconColor(this.teamWorldIcon3, mod.CreateVector(1, 0, 0));
782
- mod.SetWorldIconColor(this.teamWorldIcon4, mod.CreateVector(1, 0, 0));
783
-
784
- switch (GetTrueTeamIDNumberOfPlayer(this.carryingPlayer)) {
785
- case 1:
786
- mod.SetWorldIconColor(this.teamWorldIcon1, mod.CreateVector(0, 1, 0));
787
- break;
788
- case 2:
789
- mod.SetWorldIconColor(this.teamWorldIcon2, mod.CreateVector(0, 1, 0));
790
- break;
791
- case 3:
792
- mod.SetWorldIconColor(this.teamWorldIcon3, mod.CreateVector(0, 1, 0));
793
- break;
794
- case 4:
795
- mod.SetWorldIconColor(this.teamWorldIcon4, mod.CreateVector(0, 1, 0));
796
- break;
797
- default:
798
- break;
799
- }
800
- }
801
-
802
- static EnableCarryingWorldIcons(bool: boolean) {
803
- this.RefreshWorldIconOwners();
804
- if (bool) {
805
- mod.EnableWorldIconImage(this.teamWorldIcon1, true);
806
- mod.EnableWorldIconImage(this.teamWorldIcon2, true);
807
- mod.EnableWorldIconImage(this.teamWorldIcon3, true);
808
- mod.EnableWorldIconImage(this.teamWorldIcon4, true);
809
- mod.EnableWorldIconImage(this.defaultWorldIcon, false);
810
- } else {
811
- mod.EnableWorldIconImage(this.teamWorldIcon1, false);
812
- mod.EnableWorldIconImage(this.teamWorldIcon2, false);
813
- mod.EnableWorldIconImage(this.teamWorldIcon3, false);
814
- mod.EnableWorldIconImage(this.teamWorldIcon4, false);
815
- mod.EnableWorldIconImage(this.defaultWorldIcon, true);
816
- }
817
- }
818
-
819
- static async ReturnItemToOriginalPosition() {
820
- this.dropTime = 0; // reset the drop time
821
- this.currentWorldIconPos = this.originalWorldIconPos;
822
- mod.SetWorldIconPosition(this.defaultWorldIcon, this.currentWorldIconPos);
823
- mod.MoveVFX(
824
- this.vfxInstance,
825
- this.currentWorldIconPos,
826
- mod.CreateVector(0, 0, 0)
827
- );
828
- console.log("should have returned to original position");
829
- this.itemCurrentlyDropped = false;
830
-
831
- PlayerProfile.playerInstances.forEach((element, elementIndex) => {
832
- const playerProfile = PlayerProfile.Get(element);
833
- playerProfile?.UpdateUI(
834
- playerProfile.playerHeaderWidget,
835
- MakeMessage(mod.stringkeys.getObjectiveItem, this.carryingPlayer),
836
- true
837
- );
838
- playerProfile?.UpdateUI(
839
- playerProfile.playerSubHeaderWidget,
840
- MakeMessage(mod.stringkeys.subGetObjectiveItem),
841
- true
842
- );
843
- playerProfile?.playerHeaderWidget &&
844
- mod.SetUITextColor(playerProfile.playerHeaderWidget, battlefieldWhite);
845
- });
846
- }
847
-
848
- static ItemProximityCheck() {
849
- // this implementation will potentially mess up when multiple players enter the pickup range in quicker succession than the tick, should probably have a failsafe
850
- if (!this.isBeingCarried) {
851
- const player = mod.ClosestPlayerTo(this.currentWorldIconPos);
852
- let pos;
853
- if (
854
- mod.IsPlayerValid(player) &&
855
- !mod.GetSoldierState(player, mod.SoldierStateBool.IsAISoldier) &&
856
- mod.GetSoldierState(player, mod.SoldierStateBool.IsAlive)
857
- ) {
858
- pos = mod.GetSoldierState(player, mod.SoldierStateVector.GetPosition);
859
- const playerPos = pos;
860
- const distance = mod.DistanceBetween(
861
- this.currentWorldIconPos,
862
- playerPos
863
- );
864
-
865
- if (distance <= itemPickupDistance) {
866
- this.ItemPickedUp(player);
867
- }
868
- }
869
- }
870
- }
871
-
872
- static ItemPickedUp(player: mod.Player) {
873
- this.isBeingCarried = true;
874
- this.carryingPlayer = player;
875
- this.itemDroppedDebounce = true;
876
- this.itemCurrentlyDropped = false;
877
- this.dropTime = 0; // reset the drop time
878
-
879
- mod.SpotTarget(player, 10000000);
880
-
881
- // should maybe disable the world icon for the player holding the item,
882
- // though its position above the player's head should hide it enough.
883
- this.EnableCarryingWorldIcons(true);
884
-
885
- const playerProfile = PlayerProfile.Get(player);
886
-
887
- if (this.hasBeenPickedUpOnce) {
888
- mod.SetPlayerMovementSpeedMultiplier(player, itemCarrySpeedFactor);
889
- console.log("itemCarrySpeedFactor: ", itemCarrySpeedFactor);
890
- if (
891
- itemCarrySpeedFactor + itemCarrySpeedIncrement <
892
- itemCarrySpeedFactorCap + itemCarrySpeedIncrement
893
- )
894
- itemCarrySpeedFactor = itemCarrySpeedFactor + itemCarrySpeedIncrement;
895
-
896
- if (playerProfile?.maxHealth != undefined) {
897
- mod.SetPlayerMaxHealth(
898
- player,
899
- playerProfile?.maxHealth * itemCarryHealthFactor
900
- );
901
- console.log("itemCarryHealthFactor: ", itemCarryHealthFactor);
902
- if (
903
- itemCarryHealthFactor + itemCarryHealthIncrement <
904
- itemCarryHealthFactorCap + itemCarryHealthIncrement
905
- )
906
- itemCarryHealthFactor =
907
- itemCarryHealthFactor + itemCarryHealthIncrement;
908
- }
909
- }
910
-
911
- console.log("Item picked up, pre ShowCarryBuffUI");
912
-
913
- playerProfile?.ShowCarryBuffUI(true);
914
-
915
- mod.EnableInputRestriction(
916
- player,
917
- mod.RestrictedInputs.SelectPrimary,
918
- true
919
- );
920
- mod.ForceSwitchInventory(player, mod.InventorySlots.SecondaryWeapon);
921
-
922
- this.hasBeenPickedUpOnce = true;
923
-
924
- console.log("Item picked up has been run");
925
-
926
- PlayerProfile.playerInstances.forEach((element) => {
927
- console.log(
928
- "running carry UI update for player: " + mod.GetObjId(element)
929
- );
930
- const playerProfile = PlayerProfile.Get(element);
931
- if (
932
- mod.GetObjId(ObjectiveItemData.carryingPlayer) == mod.GetObjId(element)
933
- ) {
934
- playerProfile?.UpdateUI(
935
- playerProfile.playerHeaderWidget,
936
- MakeMessage(mod.stringkeys.youHoldTheItem),
937
- true
938
- );
939
- playerProfile?.UpdateUI(
940
- playerProfile.playerSubHeaderWidget,
941
- MakeMessage(mod.stringkeys.subYouHoldTheItem),
942
- true
943
- );
944
- playerProfile?.playerHeaderWidget &&
945
- mod.SetUITextColor(
946
- playerProfile.playerHeaderWidget,
947
- teamColors[GetTrueTeamIDNumberOfPlayer(this.carryingPlayer) - 1]
948
- );
949
- } else if (
950
- mod.GetObjId(mod.GetTeam(ObjectiveItemData.carryingPlayer)) ==
951
- mod.GetObjId(mod.GetTeam(element))
952
- ) {
953
- playerProfile?.UpdateUI(
954
- playerProfile.playerHeaderWidget,
955
- MakeMessage(mod.stringkeys.yourTeamHoldsTheItem),
956
- true
957
- );
958
- playerProfile?.UpdateUI(
959
- playerProfile.playerSubHeaderWidget,
960
- MakeMessage(mod.stringkeys.subYourTeamHoldsTheItem),
961
- true
962
- );
963
- playerProfile?.playerHeaderWidget &&
964
- mod.SetUITextColor(
965
- playerProfile.playerHeaderWidget,
966
- teamColors[GetTrueTeamIDNumberOfPlayer(this.carryingPlayer) - 1]
967
- );
968
- } else {
969
- playerProfile?.UpdateUI(
970
- playerProfile.playerHeaderWidget,
971
- MakeMessage(
972
- mod.stringkeys.playerHoldingObjectiveItem,
973
- GetAdjustedTeamNumber(this.carryingPlayer)
974
- ),
975
- true
976
- );
977
- playerProfile?.UpdateUI(
978
- playerProfile.playerSubHeaderWidget,
979
- MakeMessage(mod.stringkeys.subPlayerHoldingObjectiveItem),
980
- true
981
- );
982
- playerProfile?.playerHeaderWidget &&
983
- mod.SetUITextColor(
984
- playerProfile.playerHeaderWidget,
985
- teamColors[GetTrueTeamIDNumberOfPlayer(this.carryingPlayer) - 1]
986
- );
987
- }
988
- });
989
-
990
- console.log(
991
- "will now activate extraction point for team " +
992
- GetTrueTeamIDNumberOfPlayer(this.carryingPlayer)
993
- );
994
-
995
- ExtractionPoint.ActivateExtractionPoint(mod.GetTeam(player));
996
- }
997
-
998
- static ItemDropped(player?: mod.Player) {
999
- this.isBeingCarried = false;
1000
- this.currentWorldIconPos = mod.Add(
1001
- this.lastCarryingPlayerPos,
1002
- mod.CreateVector(0, 0.7, 0)
1003
- );
1004
- this.itemCurrentlyDropped = true;
1005
- this.dropTime = mod.GetMatchTimeElapsed();
1006
-
1007
- ExtractionPoint.DeactivateAllExtractionPoints();
1008
-
1009
- if (player) {
1010
- mod.SpotTarget(player, 0.1);
1011
- mod.SetPlayerMovementSpeedMultiplier(player, 1.0);
1012
- const playerProfile = PlayerProfile.Get(player);
1013
-
1014
- if (playerProfile?.maxHealth != undefined) {
1015
- mod.SetPlayerMaxHealth(player, playerProfile?.maxHealth);
1016
- }
1017
-
1018
- playerProfile?.ShowCarryBuffUI(false);
1019
-
1020
- mod.EnableInputRestriction(
1021
- player,
1022
- mod.RestrictedInputs.SelectPrimary,
1023
- false
1024
- );
1025
- }
1026
-
1027
- this.EnableCarryingWorldIcons(false);
1028
-
1029
- mod.SetWorldIconPosition(this.defaultWorldIcon, this.currentWorldIconPos);
1030
-
1031
- PlayerProfile.playerInstances.forEach((element, elementIndex) => {
1032
- const playerProfile = PlayerProfile.Get(element);
1033
- playerProfile?.UpdateUI(
1034
- playerProfile.playerHeaderWidget,
1035
- MakeMessage(mod.stringkeys.objectiveItemDropped, this.carryingPlayer),
1036
- true
1037
- );
1038
- playerProfile?.UpdateUI(
1039
- playerProfile.playerSubHeaderWidget,
1040
- MakeMessage(mod.stringkeys.subObjectiveItemDropped),
1041
- true
1042
- );
1043
- playerProfile?.playerHeaderWidget &&
1044
- mod.SetUITextColor(playerProfile.playerHeaderWidget, battlefieldWhite);
1045
- });
1046
- }
1047
-
1048
- static ItemHeld() {
1049
- if (
1050
- this.dropTime > 0 &&
1051
- mod.GetMatchTimeElapsed() - this.dropTime > itemReturnTime
1052
- ) {
1053
- console.log(
1054
- "item return time exceeded, returning item to original position"
1055
- );
1056
- this.ReturnItemToOriginalPosition();
1057
- //mod.DisplayNotificationMessage(MakeMessage(mod.stringkeys.packageReturned));
1058
- }
1059
-
1060
- if (!this.isBeingCarried) return;
1061
-
1062
- if (
1063
- mod.IsPlayerValid(this.carryingPlayer) &&
1064
- mod.GetSoldierState(this.carryingPlayer, mod.SoldierStateBool.IsAlive)
1065
- ) {
1066
- this.lastCarryingPlayerPos = mod.GetSoldierState(
1067
- this.carryingPlayer,
1068
- mod.SoldierStateVector.GetPosition
1069
- );
1070
- const playerPosWithOffset = mod.Add(
1071
- this.lastCarryingPlayerPos,
1072
- mod.CreateVector(0, 2.3, 0)
1073
- );
1074
- mod.SetWorldIconPosition(this.teamWorldIcon1, playerPosWithOffset);
1075
- mod.SetWorldIconPosition(this.teamWorldIcon2, playerPosWithOffset);
1076
- mod.SetWorldIconPosition(this.teamWorldIcon3, playerPosWithOffset);
1077
- mod.SetWorldIconPosition(this.teamWorldIcon4, playerPosWithOffset);
1078
- mod.MoveVFX(
1079
- this.vfxInstance,
1080
- mod.Add(this.lastCarryingPlayerPos, mod.CreateVector(0, 2.5, 0)),
1081
- mod.CreateVector(0, 0, 0)
1082
- );
1083
- this.currentWorldIconPos = playerPosWithOffset;
1084
- }
1085
- }
1086
- }
1087
-
1088
- function GetTrueTeamIDNumberOfPlayer(player: mod.Player) {
1089
- if (!mod.IsPlayerValid(player) || mod.GetObjId(player) < 0) {
1090
- console.log(
1091
- `GetTrueTeamIDNumberOfPlayer called with invalid player: ${mod.GetObjId(
1092
- player
1093
- )}`
1094
- );
1095
- return 1; // Default to team 1 instead of 0
1096
- }
1097
-
1098
- const teamId = mod.GetTeam(player);
1099
- let teamInt = 1;
1100
-
1101
- // Start from 1 since team 0 doesn't exist
1102
- for (let i = 1; i <= teamAmount; i++) {
1103
- try {
1104
- if (mod.GetObjId(teamId) == mod.GetObjId(mod.GetTeam(i))) {
1105
- teamInt = i;
1106
- break;
1107
- }
1108
- } catch (error) {
1109
- console.log(
1110
- `Error comparing team IDs for player ${mod.GetObjId(player)}: ${error}`
1111
- );
1112
- }
1113
- }
1114
-
1115
- // Validate the result
1116
- if (teamInt < 1 || teamInt > teamAmount) {
1117
- console.log(
1118
- `Invalid teamInt ${teamInt} for player ${mod.GetObjId(
1119
- player
1120
- )}, defaulting to team 1`
1121
- );
1122
- teamInt = 1;
1123
- }
1124
-
1125
- console.log(
1126
- `player ${mod.GetObjId(player)} teamInt is now set to ${teamInt}`
1127
- );
1128
- return teamInt;
1129
- }
1130
-
1131
- function GetTrueTeamIDNumberOfTeam(team: mod.Team): number {
1132
- const teamId = team;
1133
- let teamInt = 0;
1134
-
1135
- for (let i = 1; i <= teamAmount; i++) {
1136
- if (mod.GetObjId(teamId) == mod.GetObjId(mod.GetTeam(i))) {
1137
- teamInt = i;
1138
- break;
1139
- }
1140
- }
1141
-
1142
- return teamInt;
1143
- }
1144
-
1145
- // this is no longer adjusted
1146
- function GetAdjustedTeamNumber(
1147
- player?: mod.Player | undefined,
1148
- team?: mod.Team | undefined
1149
- ): number {
1150
- let teamId: mod.Team | undefined;
1151
- if (player) teamId = mod.GetTeam(player);
1152
- if (team) teamId = team;
1153
- let teamInt = 0;
1154
-
1155
- player && console.log("will get teamInt for player " + mod.GetObjId(player));
1156
-
1157
- if (teamId) {
1158
- for (let i = 1; i <= teamAmount; i++) {
1159
- if (mod.GetObjId(teamId) == mod.GetObjId(mod.GetTeam(i))) {
1160
- teamInt = i;
1161
- player &&
1162
- console.log(
1163
- "player " +
1164
- mod.GetObjId(player) +
1165
- " teamInt is now set to " +
1166
- teamInt
1167
- );
1168
- break;
1169
- }
1170
- }
1171
- }
1172
-
1173
- return teamInt;
1174
- }
1175
-
1176
- let gameStartDebounce: boolean = false;
1177
-
1178
- class PlayerProfile {
1179
- player: mod.Player;
1180
- playerTeamID: number = -1;
1181
- maxHealth: number = 100;
1182
- checkpointNb: number = 0;
1183
- currentTrack: number = 1;
1184
- playerTeamWidget: mod.UIWidget;
1185
- playerHeaderWidget: mod.UIWidget;
1186
- playerSubHeaderWidget: mod.UIWidget;
1187
- playerAmmoFeedbackWidget: mod.UIWidget[];
1188
- playerCarryBuffWidget: mod.UIWidget[];
1189
- playerLoadoutWarningWidget: mod.UIWidget;
1190
- versionWidget: mod.UIWidget;
1191
- static playerInstances: mod.Player[] = [];
1192
- static deployedPlayers: mod.Player[] = [];
1193
- static #allPlayerProfiles: { [key: number]: PlayerProfile } = {}; // probably remove playerprofile here as well when players leave
1194
-
1195
- constructor(player: mod.Player) {
1196
- this.player = player;
1197
- this.playerHeaderWidget = this.CreateHeaderUI();
1198
- this.playerSubHeaderWidget = this.CreateSubHeaderUI();
1199
- this.playerTeamWidget = this.CreatePlayerTeamUI();
1200
- this.playerAmmoFeedbackWidget = [
1201
- this.CreateAmmoFeedbackUI(),
1202
- this.CreateAmmoFadeLineUI(true),
1203
- this.CreateAmmoFadeLineUI(false),
1204
- ];
1205
- this.playerCarryBuffWidget = [
1206
- this.CreateCarryBuffUI(true),
1207
- this.CreateCarryBuffUI(false),
1208
- this.CreateCarryTextBlockUI(),
1209
- ];
1210
- this.playerLoadoutWarningWidget = this.CreateLoadoutWarningUI();
1211
- this.versionWidget = this.CreateVersionUI();
1212
- PlayerProfile.playerInstances.push(this.player);
1213
- PlayerProfile.HandleIfTheGameIsFull();
1214
- }
1215
-
1216
- static Get(player: mod.Player): PlayerProfile | undefined {
1217
- if (mod.GetObjId(player) > -1) {
1218
- let index = mod.GetObjId(player);
1219
- let playerProfile = this.#allPlayerProfiles[index];
1220
-
1221
- // if the player does not have a profile, create and initialize one
1222
- if (!playerProfile) {
1223
- playerProfile = new PlayerProfile(player);
1224
-
1225
- if (debugPlayer) console.log("Creating Player Profile");
1226
-
1227
- this.#allPlayerProfiles[index] = playerProfile;
1228
- }
1229
- return playerProfile;
1230
- }
1231
- }
1232
-
1233
- static removePlayerProfile(playerId: number): boolean {
1234
- if (this.#allPlayerProfiles[playerId]) {
1235
- delete this.#allPlayerProfiles[playerId];
1236
- return true; // successfully deleted
1237
- }
1238
- return false; // playerId not found
1239
- }
1240
-
1241
- static HandleIfTheGameIsFull() {
1242
- console.log("would have tried to handle if the game is full");
1243
- }
1244
-
1245
- static RemovePlayerFromDeployedPlayers(player: mod.Player) {
1246
- const index = this.deployedPlayers.findIndex(
1247
- (p) => mod.GetObjId(p) === mod.GetObjId(player)
1248
- );
1249
- if (index !== -1) {
1250
- this.deployedPlayers.splice(index, 1);
1251
- console.log(
1252
- "Removed player from deployedPlayers: ",
1253
- mod.GetObjId(player)
1254
- );
1255
- } else {
1256
- console.log(
1257
- "Player not found in deployedPlayers: ",
1258
- mod.GetObjId(player)
1259
- );
1260
- }
1261
- }
1262
-
1263
- static RemovePlayerFromPlayerInstances(player: mod.Player) {
1264
- const index = this.playerInstances.findIndex(
1265
- (p) => mod.GetObjId(p) === mod.GetObjId(player)
1266
- );
1267
- if (index !== -1) {
1268
- this.playerInstances.splice(index, 1);
1269
- console.log(
1270
- "Removed player from playerInstances: ",
1271
- mod.GetObjId(player)
1272
- );
1273
- } else {
1274
- console.log(
1275
- "Player not found in playerInstances: ",
1276
- mod.GetObjId(player)
1277
- );
1278
- }
1279
- }
1280
-
1281
- static whileLoopStarted: boolean = false;
1282
-
1283
- static async UpdateGameStartCountdown() {
1284
- if (gameStartDebounce || this.whileLoopStarted) return;
1285
-
1286
- this.deployedPlayers.forEach((element) => {
1287
- const playerProfile = this.Get(element);
1288
- playerProfile?.UpdateUI(
1289
- playerProfile.playerHeaderWidget,
1290
- MakeMessage(mod.stringkeys.waitingForPlayers),
1291
- true
1292
- );
1293
- playerProfile?.UpdateUI(
1294
- playerProfile.playerSubHeaderWidget,
1295
- MakeMessage(
1296
- mod.stringkeys.playersToWaitFor,
1297
- this.deployedPlayers.length,
1298
- requiredPlayersToStart
1299
- ),
1300
- true
1301
- );
1302
- });
1303
-
1304
- if (
1305
- this.deployedPlayers.length >= requiredPlayersToStart &&
1306
- !this.whileLoopStarted
1307
- ) {
1308
- //pls check for only deployed players yes
1309
- this.whileLoopStarted = true;
1310
- while (true) {
1311
- this.playerInstances.forEach((element) => {
1312
- const playerProfile = this.Get(element);
1313
- const formattedTime = FormatTime(gameStartCountdown);
1314
- playerProfile?.UpdateUI(
1315
- playerProfile.playerHeaderWidget,
1316
- MakeMessage(mod.stringkeys.gameStartingIn),
1317
- true
1318
- );
1319
- playerProfile?.UpdateUI(
1320
- playerProfile.playerSubHeaderWidget,
1321
- MakeMessage(
1322
- mod.stringkeys.timerCounterThing,
1323
- formattedTime[0],
1324
- formattedTime[1],
1325
- formattedTime[2]
1326
- ),
1327
- true
1328
- );
1329
- if (
1330
- gameStartCountdown <= 0 &&
1331
- mod.GetSoldierState(element, mod.SoldierStateBool.IsAlive)
1332
- ) {
1333
- mod.EnableAllInputRestrictions(element, false);
1334
- }
1335
- });
1336
-
1337
- if (this.deployedPlayers.length < requiredPlayersToStart) {
1338
- gameStartCountdown = baseGameStartCountdown; // reset the countdown if not enough players are deployed
1339
- this.playerInstances.forEach((element) => {
1340
- const playerProfile = this.Get(element);
1341
- playerProfile?.UpdateUI(
1342
- playerProfile.playerHeaderWidget,
1343
- MakeMessage(mod.stringkeys.waitingForPlayers),
1344
- true
1345
- );
1346
- playerProfile?.UpdateUI(
1347
- playerProfile.playerSubHeaderWidget,
1348
- MakeMessage(
1349
- mod.stringkeys.playersToWaitFor,
1350
- this.deployedPlayers.length,
1351
- requiredPlayersToStart
1352
- ),
1353
- true
1354
- );
1355
- });
1356
- this.whileLoopStarted = false;
1357
- break;
1358
- }
1359
-
1360
- if (gameStartCountdown <= 0 && !gameStartDebounce) {
1361
- gameStartDebounce = true;
1362
- this.playerInstances.forEach((element) => {
1363
- const playerProfile = this.Get(element);
1364
- playerProfile?.UpdateUI(
1365
- playerProfile.playerHeaderWidget,
1366
- MakeMessage(mod.stringkeys.getObjectiveItem),
1367
- true
1368
- );
1369
- playerProfile?.UpdateUI(
1370
- playerProfile.playerSubHeaderWidget,
1371
- MakeMessage(mod.stringkeys.subGetObjectiveItem),
1372
- true
1373
- );
1374
- });
1375
- SpawnEnemies();
1376
- break;
1377
- }
1378
-
1379
- await mod.Wait(1);
1380
- gameStartCountdown--;
1381
- }
1382
- } else {
1383
- gameStartCountdown = baseGameStartCountdown; // reset the countdown if not enough players are deployed
1384
- this.deployedPlayers.forEach((element) => {
1385
- const playerProfile = this.Get(element);
1386
- playerProfile?.UpdateUI(
1387
- playerProfile.playerHeaderWidget,
1388
- MakeMessage(mod.stringkeys.waitingForPlayers),
1389
- true
1390
- );
1391
- playerProfile?.UpdateUI(
1392
- playerProfile.playerSubHeaderWidget,
1393
- MakeMessage(
1394
- mod.stringkeys.playersToWaitFor,
1395
- this.deployedPlayers.length,
1396
- requiredPlayersToStart
1397
- ),
1398
- true
1399
- );
1400
- });
1401
- }
1402
- }
1403
-
1404
- CreateVersionUI(): mod.UIWidget {
1405
- const coolahhuiname: string = "name" + uniqueNameNumber++;
1406
- mod.AddUIText(
1407
- coolahhuiname,
1408
- mod.CreateVector(0, 0, 0),
1409
- mod.CreateVector(200, 25, 0),
1410
- mod.UIAnchor.BottomRight,
1411
- MakeMessage(
1412
- mod.stringkeys.modversion,
1413
- VERSION[0],
1414
- VERSION[1],
1415
- VERSION[2]
1416
- ),
1417
- this.player
1418
- );
1419
- let widget = mod.FindUIWidgetWithName(coolahhuiname) as mod.UIWidget;
1420
- mod.SetUITextSize(widget, 20);
1421
- mod.SetUITextAnchor(widget, mod.UIAnchor.Center);
1422
- mod.SetUIWidgetBgColor(widget, mod.CreateVector(1, 1, 1));
1423
- mod.SetUITextColor(widget, mod.CreateVector(1, 1, 1));
1424
- mod.SetUIWidgetBgFill(widget, mod.UIBgFill.Blur);
1425
- mod.SetUIWidgetBgAlpha(widget, 1);
1426
- mod.SetUIWidgetDepth(widget, mod.UIDepth.AboveGameUI);
1427
- mod.SetUIWidgetVisible(widget, true);
1428
-
1429
- return widget;
1430
- }
1431
-
1432
- ShowLoadoutWarningUI(show: boolean) {
1433
- mod.SetUIWidgetVisible(this.playerLoadoutWarningWidget, show);
1434
- mod.SetUITextLabel(
1435
- this.playerLoadoutWarningWidget,
1436
- MakeMessage(mod.stringkeys.loadoutWarning)
1437
- );
1438
- console.log("showing loadout warning");
1439
- }
1440
-
1441
- CreateLoadoutWarningUI(): mod.UIWidget {
1442
- const coolahhuiname: string = "name" + uniqueNameNumber++;
1443
- mod.AddUIText(
1444
- coolahhuiname,
1445
- mod.CreateVector(0, 80, 0),
1446
- mod.CreateVector(370, 35, 0),
1447
- mod.UIAnchor.Center,
1448
- MakeMessage(mod.stringkeys.loadoutWarning),
1449
- this.player
1450
- );
1451
- let widget = mod.FindUIWidgetWithName(coolahhuiname) as mod.UIWidget;
1452
- mod.SetUITextSize(widget, 20);
1453
- mod.SetUITextAnchor(widget, mod.UIAnchor.Center);
1454
- mod.SetUIWidgetBgColor(widget, mod.CreateVector(1, 0.8, 0.8));
1455
- mod.SetUITextColor(widget, mod.CreateVector(1, 1, 1));
1456
- mod.SetUIWidgetBgFill(widget, mod.UIBgFill.Blur);
1457
- mod.SetUIWidgetBgAlpha(widget, 1);
1458
- mod.SetUIWidgetDepth(widget, mod.UIDepth.AboveGameUI);
1459
- mod.SetUIWidgetVisible(widget, false);
1460
-
1461
- return widget;
1462
- }
1463
-
1464
- ShowCarryBuffUI(show: boolean) {
1465
- if (show) {
1466
- mod.SetUIWidgetVisible(this.playerCarryBuffWidget[0], true);
1467
- mod.SetUIWidgetVisible(this.playerCarryBuffWidget[1], true);
1468
- mod.SetUITextLabel(
1469
- this.playerCarryBuffWidget[0],
1470
- MakeMessage(mod.stringkeys.speedNumber, itemCarrySpeedFactor * 100)
1471
- );
1472
- mod.SetUITextLabel(
1473
- this.playerCarryBuffWidget[1],
1474
- MakeMessage(mod.stringkeys.healthNumber, itemCarryHealthFactor * 100)
1475
- );
1476
- mod.SetUIWidgetVisible(this.playerCarryBuffWidget[2], true);
1477
- } else {
1478
- mod.SetUIWidgetVisible(this.playerCarryBuffWidget[0], false);
1479
- mod.SetUIWidgetVisible(this.playerCarryBuffWidget[1], false);
1480
- mod.SetUITextLabel(
1481
- this.playerCarryBuffWidget[0],
1482
- MakeMessage(mod.stringkeys.speedNumber, itemCarrySpeedFactor * 100)
1483
- );
1484
- mod.SetUITextLabel(
1485
- this.playerCarryBuffWidget[1],
1486
- MakeMessage(mod.stringkeys.healthNumber, itemCarryHealthFactor * 100)
1487
- );
1488
- mod.SetUIWidgetVisible(this.playerCarryBuffWidget[2], false);
1489
- }
1490
- }
1491
-
1492
- CreateCarryTextBlockUI(): mod.UIWidget {
1493
- const coolahhuiname: string = "name" + uniqueNameNumber++;
1494
- mod.AddUIText(
1495
- coolahhuiname,
1496
- mod.CreateVector(0, 148, 0),
1497
- mod.CreateVector(170, 22, 0),
1498
- mod.UIAnchor.TopCenter,
1499
- MakeMessage(mod.stringkeys.xfirex),
1500
- this.player
1501
- );
1502
- let widget = mod.FindUIWidgetWithName(coolahhuiname) as mod.UIWidget;
1503
- mod.SetUITextSize(widget, 18);
1504
- mod.SetUITextAnchor(widget, mod.UIAnchor.Center);
1505
- mod.SetUIWidgetPadding(widget, 0);
1506
- mod.SetUIWidgetBgColor(widget, mod.CreateVector(1, 0.8, 0.8));
1507
- mod.SetUITextColor(widget, mod.CreateVector(1, 1, 1));
1508
- mod.SetUIWidgetBgFill(widget, mod.UIBgFill.Blur);
1509
- mod.SetUIWidgetBgAlpha(widget, 1);
1510
- mod.SetUIWidgetVisible(widget, false);
1511
-
1512
- return widget;
1513
- }
1514
-
1515
- CreateCarryBuffUI(isSpeed: boolean): mod.UIWidget {
1516
- const coolahhuiname: string = "name" + uniqueNameNumber++;
1517
- //console.log(coolahhteamuiname);
1518
- const message: mod.Message = isSpeed
1519
- ? MakeMessage(mod.stringkeys.speedNumber, itemCarrySpeedFactor * 100)
1520
- : MakeMessage(mod.stringkeys.healthNumber, itemCarryHealthFactor * 100);
1521
- mod.AddUIText(
1522
- coolahhuiname,
1523
- mod.CreateVector(isSpeed ? -140 : 140, 148, 0),
1524
- mod.CreateVector(110, 22, 0),
1525
- mod.UIAnchor.TopCenter,
1526
- message,
1527
- this.player
1528
- );
1529
- let widget = mod.FindUIWidgetWithName(coolahhuiname) as mod.UIWidget;
1530
- mod.SetUITextSize(widget, 18);
1531
- mod.SetUITextAnchor(widget, mod.UIAnchor.Center);
1532
- mod.SetUIWidgetBgColor(widget, battlefieldBlueBg);
1533
- mod.SetUITextColor(widget, battlefieldWhite);
1534
- mod.SetUIWidgetBgFill(widget, mod.UIBgFill.Blur);
1535
- mod.SetUIWidgetBgAlpha(widget, 1);
1536
- mod.SetUIWidgetVisible(widget, false);
1537
-
1538
- return widget;
1539
- }
1540
-
1541
- CreatePlayerTeamUI() {
1542
- const coolahhteamuiname = "name" + uniqueNameNumber++;
1543
- console.log(coolahhteamuiname);
1544
- mod.AddUIText(
1545
- coolahhteamuiname,
1546
- mod.CreateVector(56, 18, 0),
1547
- mod.CreateVector(75, 25, 0),
1548
- mod.UIAnchor.TopCenter,
1549
- MakeMessage(
1550
- mod.stringkeys.teamNumber,
1551
- GetAdjustedTeamNumber(this.player)
1552
- ),
1553
- this.player
1554
- );
1555
- let widget = mod.FindUIWidgetWithName(coolahhteamuiname);
1556
- mod.SetUITextSize(widget, 20);
1557
- mod.SetUITextAnchor(widget, mod.UIAnchor.Center);
1558
-
1559
- // Safe team color assignment
1560
- try {
1561
- if (mod.IsPlayerValid(this.player)) {
1562
- const teamInt = GetTrueTeamIDNumberOfPlayer(this.player);
1563
- const teamColorIndex = teamInt - 1;
1564
-
1565
- if (
1566
- teamColorIndex >= 0 &&
1567
- teamColorIndex < teamColors.length &&
1568
- teamColors[teamColorIndex]
1569
- ) {
1570
- mod.SetUIWidgetBgColor(widget, teamColors[teamColorIndex]);
1571
- } else {
1572
- console.log(
1573
- `Invalid team color for player ${mod.GetObjId(
1574
- this.player
1575
- )}, using fallback`
1576
- );
1577
- mod.SetUIWidgetBgColor(widget, teamColors[0]);
1578
- }
1579
- } else {
1580
- mod.SetUIWidgetBgColor(widget, teamColors[0]);
1581
- }
1582
- } catch (error) {
1583
- console.log(`Error setting team color: ${error}`);
1584
- mod.SetUIWidgetBgColor(widget, teamColors[0]);
1585
- }
1586
-
1587
- mod.SetUITextColor(widget, mod.CreateVector(0, 0, 0));
1588
- mod.SetUIWidgetBgFill(widget, mod.UIBgFill.Solid);
1589
- mod.SetUIWidgetBgAlpha(widget, 1);
1590
- this.CreatePlayerTeamBgUI();
1591
- return widget;
1592
- }
1593
-
1594
- CreatePlayerTeamBgUI(): void {
1595
- const coolahhteamuiname: string = "name" + uniqueNameNumber++;
1596
- mod.AddUIText(
1597
- coolahhteamuiname,
1598
- mod.CreateVector(0, 13, 0),
1599
- mod.CreateVector(214, 35, 0),
1600
- mod.UIAnchor.TopCenter,
1601
- MakeMessage(mod.stringkeys.youAreOnTeam),
1602
- this.player
1603
- );
1604
- let widget = mod.FindUIWidgetWithName(coolahhteamuiname) as mod.UIWidget;
1605
- mod.SetUITextSize(widget, 26);
1606
- mod.SetUITextAnchor(widget, mod.UIAnchor.CenterLeft);
1607
- mod.SetUITextColor(widget, battlefieldWhite);
1608
- mod.SetUIWidgetBgFill(widget, mod.UIBgFill.Blur);
1609
- mod.SetUIWidgetBgColor(widget, battlefieldBlueBg);
1610
- mod.SetUIWidgetBgAlpha(widget, 1);
1611
- }
1612
-
1613
- ShowPlayerTeamWidget(show: boolean) {
1614
- if (!mod.IsPlayerValid(this.player)) {
1615
- console.log("ShowPlayerTeamWidget: Invalid player, aborting");
1616
- return;
1617
- }
1618
-
1619
- if (show) {
1620
- const teamInt = GetTrueTeamIDNumberOfPlayer(this.player);
1621
- const teamColorIndex = teamInt - 1;
1622
-
1623
- // Validate team color exists
1624
- if (
1625
- teamColorIndex < 0 ||
1626
- teamColorIndex >= teamColors.length ||
1627
- !teamColors[teamColorIndex]
1628
- ) {
1629
- console.log(
1630
- `Invalid team color index ${teamColorIndex} for player ${mod.GetObjId(
1631
- this.player
1632
- )}, using default`
1633
- );
1634
- mod.SetUIWidgetBgColor(this.playerTeamWidget, teamColors[0]); // fallback to first color
1635
- } else {
1636
- mod.SetUIWidgetBgColor(
1637
- this.playerTeamWidget,
1638
- teamColors[teamColorIndex]
1639
- );
1640
- }
1641
-
1642
- mod.SetUIWidgetVisible(this.playerTeamWidget, true);
1643
- mod.SetUITextLabel(
1644
- this.playerTeamWidget,
1645
- MakeMessage(
1646
- mod.stringkeys.teamNumber,
1647
- GetAdjustedTeamNumber(this.player)
1648
- )
1649
- );
1650
- } else {
1651
- mod.SetUIWidgetVisible(this.playerTeamWidget, false);
1652
- }
1653
- }
1654
-
1655
- UpdateUI(
1656
- widget: mod.UIWidget | undefined,
1657
- message?: mod.Message,
1658
- show?: boolean
1659
- ) {
1660
- widget && message && mod.SetUITextLabel(widget, message);
1661
- widget && show && mod.SetUIWidgetVisible(widget, show);
1662
- }
1663
-
1664
- //currentLerpvalue: number = 0;
1665
-
1666
- async InterpAmmoFeedback() {
1667
- let currentLerpvalue: number = 0;
1668
- let lerpIncrement: number = 0;
1669
- while (currentLerpvalue < 1.0) {
1670
- if (!this.ammoFeedbackBeingShown) break;
1671
- lerpIncrement = lerpIncrement + 0.1;
1672
- currentLerpvalue = Lerp(currentLerpvalue, 1, lerpIncrement);
1673
- mod.SetUIWidgetBgAlpha(
1674
- this.playerAmmoFeedbackWidget[0],
1675
- 1 - currentLerpvalue
1676
- );
1677
- mod.SetUIWidgetBgAlpha(
1678
- this.playerAmmoFeedbackWidget[1],
1679
- 1 - currentLerpvalue
1680
- );
1681
- mod.SetUIWidgetBgAlpha(
1682
- this.playerAmmoFeedbackWidget[2],
1683
- 1 - currentLerpvalue
1684
- );
1685
- mod.SetUITextAlpha(
1686
- this.playerAmmoFeedbackWidget[0],
1687
- 1 - currentLerpvalue
1688
- );
1689
- await mod.Wait(0.0);
1690
- }
1691
- }
1692
-
1693
- ammoFeedbackBeingShown: boolean = false;
1694
- ammoFeedbackQueued: boolean = false;
1695
-
1696
- async ShowAmmoFeedback() {
1697
- if (this.ammoFeedbackBeingShown) {
1698
- this.ammoFeedbackQueued = true;
1699
- return;
1700
- }
1701
-
1702
- this.ammoFeedbackBeingShown = true;
1703
- mod.SetUIWidgetVisible(this.playerAmmoFeedbackWidget[0], true);
1704
- mod.SetUIWidgetVisible(this.playerAmmoFeedbackWidget[1], true);
1705
- mod.SetUIWidgetVisible(this.playerAmmoFeedbackWidget[2], true);
1706
- mod.SetUIWidgetBgAlpha(this.playerAmmoFeedbackWidget[0], 1);
1707
- mod.SetUIWidgetBgAlpha(this.playerAmmoFeedbackWidget[1], 1);
1708
- mod.SetUIWidgetBgAlpha(this.playerAmmoFeedbackWidget[2], 1);
1709
-
1710
- mod.SetUITextAlpha(this.playerAmmoFeedbackWidget[0], 1);
1711
-
1712
- await mod.Wait(0.9);
1713
- this.InterpAmmoFeedback();
1714
- await mod.Wait(0.5);
1715
-
1716
- if (this.ammoFeedbackQueued) {
1717
- this.ammoFeedbackBeingShown = false;
1718
- this.ammoFeedbackQueued = false;
1719
- mod.SetUIWidgetVisible(this.playerAmmoFeedbackWidget[0], false);
1720
- mod.SetUIWidgetVisible(this.playerAmmoFeedbackWidget[1], false);
1721
- mod.SetUIWidgetVisible(this.playerAmmoFeedbackWidget[2], false);
1722
- await mod.Wait(0.1);
1723
- this.ShowAmmoFeedback();
1724
- return;
1725
- }
1726
-
1727
- this.ammoFeedbackBeingShown = false;
1728
- mod.SetUIWidgetVisible(this.playerAmmoFeedbackWidget[0], false);
1729
- mod.SetUIWidgetVisible(this.playerAmmoFeedbackWidget[1], false);
1730
- mod.SetUIWidgetVisible(this.playerAmmoFeedbackWidget[2], false);
1731
- }
1732
-
1733
- CreateAmmoFeedbackUI(): mod.UIWidget {
1734
- const coolahhuiname: string = "name" + uniqueNameNumber++;
1735
- mod.AddUIText(
1736
- coolahhuiname,
1737
- mod.CreateVector(0, 185, 0),
1738
- mod.CreateVector(150, 25, 0),
1739
- mod.UIAnchor.TopCenter,
1740
- MakeMessage(mod.stringkeys.ammoUp),
1741
- this.player
1742
- );
1743
- let widget = mod.FindUIWidgetWithName(coolahhuiname) as mod.UIWidget;
1744
- mod.SetUITextColor(widget, mod.CreateVector(0, 0, 0));
1745
- mod.SetUITextSize(widget, 18);
1746
- mod.SetUITextAnchor(widget, mod.UIAnchor.Center);
1747
- mod.SetUIWidgetPadding(widget, -100);
1748
- mod.SetUIWidgetVisible(widget, true);
1749
- mod.SetUIWidgetBgFill(widget, mod.UIBgFill.Solid);
1750
- mod.SetUIWidgetBgColor(widget, battlefieldWhite);
1751
- mod.SetUIWidgetBgAlpha(widget, 0.9);
1752
- mod.SetUIWidgetVisible(widget, false);
1753
-
1754
- return widget;
1755
- }
1756
-
1757
- CreateAmmoFadeLineUI(right: boolean): mod.UIWidget {
1758
- const coolahhuiname: string = "name" + uniqueNameNumber++;
1759
- let horizontalOffset: number = right ? 150 : -150;
1760
- mod.AddUIContainer(
1761
- coolahhuiname,
1762
- mod.CreateVector(horizontalOffset, 185, 0),
1763
- mod.CreateVector(150, 25, 0),
1764
- mod.UIAnchor.TopCenter,
1765
- this.player
1766
- );
1767
- let widget = mod.FindUIWidgetWithName(coolahhuiname) as mod.UIWidget;
1768
- mod.SetUIWidgetPadding(widget, 1);
1769
- right
1770
- ? mod.SetUIWidgetBgFill(widget, mod.UIBgFill.GradientLeft)
1771
- : mod.SetUIWidgetBgFill(widget, mod.UIBgFill.GradientRight);
1772
- mod.SetUIWidgetBgColor(widget, battlefieldWhite);
1773
- mod.SetUIWidgetBgAlpha(widget, 0.9);
1774
- mod.SetUIWidgetVisible(widget, false);
1775
-
1776
- return widget;
1777
- }
1778
-
1779
- CreateHeaderUI(): mod.UIWidget {
1780
- const coolahhuiname: string = "name" + uniqueNameNumber++;
1781
- mod.AddUIText(
1782
- coolahhuiname,
1783
- mod.CreateVector(0, 60, 0),
1784
- mod.CreateVector(390, 82, 0),
1785
- mod.UIAnchor.TopCenter,
1786
- MakeMessage(mod.stringkeys.waitingForPlayers),
1787
- this.player
1788
- );
1789
- let widget = mod.FindUIWidgetWithName(coolahhuiname) as mod.UIWidget;
1790
- mod.SetUITextColor(widget, battlefieldWhite);
1791
- mod.SetUITextSize(widget, 38);
1792
- mod.SetUITextAnchor(widget, mod.UIAnchor.TopCenter);
1793
- mod.SetUIWidgetPadding(widget, 1);
1794
- mod.SetUIWidgetVisible(widget, true);
1795
- mod.SetUIWidgetBgFill(widget, mod.UIBgFill.Blur);
1796
- mod.SetUIWidgetBgColor(widget, battlefieldBlueBg);
1797
- mod.SetUIWidgetBgAlpha(widget, 1);
1798
-
1799
- this.CreateDividingLineUI(true);
1800
- this.CreateDividingLineUI(false);
1801
- this.CreateFrameLineUI(true);
1802
- this.CreateFrameLineUI(false);
1803
-
1804
- return widget;
1805
- }
1806
-
1807
- CreateDividingLineUI(right: boolean): mod.UIWidget {
1808
- const coolahhuiname: string = "name" + uniqueNameNumber++;
1809
- let horizontalOffset: number = right ? 85 : -85;
1810
- mod.AddUIContainer(
1811
- coolahhuiname,
1812
- mod.CreateVector(horizontalOffset, 106, 0),
1813
- mod.CreateVector(170, 1.0, 0),
1814
- mod.UIAnchor.TopCenter,
1815
- this.player
1816
- );
1817
- let widget = mod.FindUIWidgetWithName(coolahhuiname) as mod.UIWidget;
1818
- mod.SetUIWidgetVisible(widget, true);
1819
- mod.SetUIWidgetBgFill(widget, mod.UIBgFill.Solid);
1820
- mod.SetUIWidgetBgColor(widget, battlefieldWhite);
1821
- mod.SetUIWidgetBgAlpha(widget, 1);
1822
-
1823
- return widget;
1824
- }
1825
-
1826
- CreateFrameLineUI(right: boolean): mod.UIWidget {
1827
- const coolahhuiname: string = "name" + uniqueNameNumber++;
1828
- let horizontalOffset: number = right ? 195 : -195;
1829
- mod.AddUIContainer(
1830
- coolahhuiname,
1831
- mod.CreateVector(horizontalOffset, 60, 0),
1832
- mod.CreateVector(1.0, 82, 0),
1833
- mod.UIAnchor.TopCenter,
1834
- this.player
1835
- );
1836
- let widget = mod.FindUIWidgetWithName(coolahhuiname) as mod.UIWidget;
1837
- mod.SetUIWidgetVisible(widget, true);
1838
- mod.SetUIWidgetBgFill(widget, mod.UIBgFill.Solid);
1839
- mod.SetUIWidgetBgColor(widget, battlefieldWhite);
1840
- mod.SetUIWidgetBgAlpha(widget, 1);
1841
-
1842
- return widget;
1843
- }
1844
-
1845
- CreateSubHeaderUI(): mod.UIWidget {
1846
- const coolahhuiname: string = "name" + uniqueNameNumber++;
1847
- mod.AddUIText(
1848
- coolahhuiname,
1849
- mod.CreateVector(0, 60, 0),
1850
- mod.CreateVector(450, 82, 0),
1851
- mod.UIAnchor.TopCenter,
1852
- MakeMessage(mod.stringkeys.subGetObjectiveItem),
1853
- this.player
1854
- );
1855
- let widget = mod.FindUIWidgetWithName(coolahhuiname) as mod.UIWidget;
1856
- mod.SetUITextColor(widget, battlefieldWhite);
1857
- mod.SetUITextSize(widget, 24);
1858
- mod.SetUITextAnchor(widget, mod.UIAnchor.BottomCenter);
1859
- mod.SetUIWidgetPadding(widget, 5);
1860
- mod.SetUIWidgetVisible(widget, true);
1861
- mod.SetUIWidgetBgAlpha(widget, 0);
1862
- mod.SetUIWidgetBgFill(widget, mod.UIBgFill.Blur);
1863
-
1864
- return widget;
1865
- }
1866
- }
1867
-
1868
- type EnemyBehavior = {
1869
- onSpawn: (player: mod.Player, enemy: AIEnemy) => void | Promise<void>;
1870
- onDeath: (player: mod.Player, enemy: AIEnemy) => void | Promise<void>;
1871
- onHit: (player: mod.Player, enemy: AIEnemy) => void | Promise<void>;
1872
- };
1873
-
1874
- type EnemyOptions = {
1875
- moveSpeed?: mod.MoveSpeed;
1876
- speedMultiplier?: number;
1877
- explosionRadius?: number;
1878
- explosionDamage?: number;
1879
- health?: number;
1880
- stance?: mod.Stance;
1881
- spawnPointID?: number;
1882
- randomSpawn?: number[];
1883
- soldierClass?: mod.SoldierClass;
1884
- };
1885
-
1886
- class AIEnemy {
1887
- public moveSpeed: mod.MoveSpeed;
1888
- public speedMultiplier: number;
1889
- public explosionRadius: number;
1890
- public explosionDamage: number;
1891
- public health: number;
1892
- public stance: mod.Stance;
1893
- public spawnPointID: number;
1894
- public player?: mod.Player;
1895
- public randomSpawn?: number[];
1896
- public soldierClass: mod.SoldierClass;
1897
- public baseAmmo: number = 0;
1898
-
1899
- constructor(private behavior: EnemyBehavior, options: EnemyOptions = {}) {
1900
- this.moveSpeed = options.moveSpeed ?? mod.MoveSpeed.Sprint;
1901
- this.explosionRadius = options.explosionRadius ?? 10;
1902
- this.explosionDamage = options.explosionDamage ?? 10;
1903
- this.health = options.health ?? 100;
1904
- this.speedMultiplier = options.speedMultiplier ?? 1;
1905
- this.stance = options.stance ?? mod.Stance.Stand;
1906
- this.spawnPointID = options.spawnPointID ?? 1;
1907
-
1908
- if (options.randomSpawn && options.randomSpawn?.length > 0) {
1909
- this.spawnPointID =
1910
- options.randomSpawn[H.getRandomInt(options.randomSpawn.length)];
1911
- }
1912
-
1913
- // If no soldierclass given, Random select a class
1914
- if (options.soldierClass) {
1915
- this.soldierClass = options.soldierClass;
1916
- } else {
1917
- const classes = Object.values(mod.SoldierClass) as mod.SoldierClass[];
1918
- const randomClass = classes[Math.floor(Math.random() * classes.length)];
1919
- this.soldierClass = mod.SoldierClass.Assault; // hardcoded to assault for now
1920
- }
1921
- }
1922
-
1923
- async InitBehavior(player: mod.Player) {
1924
- this.player = player;
1925
- mod.AIEnableShooting(player, false);
1926
- mod.SetPlayerMaxHealth(player, this.health);
1927
- mod.AISetMoveSpeed(player, this.moveSpeed);
1928
- mod.AISetStance(player, this.stance);
1929
- mod.SetPlayerMovementSpeedMultiplier(player, this.speedMultiplier);
1930
- await this.behavior.onSpawn(player, this);
1931
- }
1932
-
1933
- async die(player: mod.Player) {
1934
- await this.behavior.onDeath(player, this);
1935
- }
1936
-
1937
- async onHit(player: mod.Player) {
1938
- await this.behavior.onHit(player, this);
1939
- }
1940
- }
1941
-
1942
- const meleeShooterBehavior: EnemyBehavior = {
1943
- onSpawn: async (player: mod.Player, enemy: AIEnemy) => {
1944
- // set up for Assault
1945
-
1946
- mod.RemoveEquipment(player, mod.InventorySlots.PrimaryWeapon);
1947
- mod.RemoveEquipment(player, mod.InventorySlots.SecondaryWeapon);
1948
- mod.RemoveEquipment(player, mod.InventorySlots.GadgetOne);
1949
- mod.RemoveEquipment(player, mod.InventorySlots.GadgetTwo);
1950
- mod.RemoveEquipment(player, mod.InventorySlots.Throwable);
1951
- mod.RemoveEquipment(player, mod.InventorySlots.ClassGadget);
1952
- mod.AddEquipment(player, mod.Weapons.SMG_SGX);
1953
- mod.AddEquipment(player, mod.Weapons.Sidearm_M45A1);
1954
- mod.AIEnableShooting(player, true);
1955
- mod.AIEnableTargeting(player, false);
1956
- mod.AIParachuteBehavior(player);
1957
- await mod.Wait(5);
1958
- mod.AIDefendPositionBehavior(
1959
- player,
1960
- mod.GetSoldierState(player, mod.SoldierStateVector.GetPosition),
1961
- 0,
1962
- aiLeashRange
1963
- );
1964
- MeleeShooterLogic(player, enemy);
1965
- },
1966
- onDeath: async (player: mod.Player, enemy: AIEnemy) => {
1967
- if (debugAIBehavior) console.log("Default enemy died behavior triggered");
1968
- RespawnEnemyAfterTime(enemy.spawnPointID);
1969
- },
1970
- onHit: async () => {
1971
- if (debugAIBehavior) console.log("Default enemy hit behavior triggered");
1972
- },
1973
- };
1974
-
1975
- async function MeleeShooterLogic(player: mod.Player, enemy: AIEnemy) {
1976
- await mod.Wait(2.0);
1977
- while (true) {
1978
- if (
1979
- mod.IsPlayerValid(player) &&
1980
- mod.GetSoldierState(player, mod.SoldierStateBool.IsAlive)
1981
- ) {
1982
- const aiPos = mod.GetSoldierState(
1983
- player,
1984
- mod.SoldierStateVector.GetPosition
1985
- );
1986
- let playerInRange: boolean = false;
1987
- PlayerProfile.playerInstances.forEach((element) => {
1988
- if (
1989
- element &&
1990
- mod.IsPlayerValid(element) &&
1991
- mod.GetSoldierState(element, mod.SoldierStateBool.IsAlive)
1992
- ) {
1993
- const tempPlayerPos = mod.GetSoldierState(
1994
- element,
1995
- mod.SoldierStateVector.GetPosition
1996
- );
1997
- if (mod.DistanceBetween(aiPos, tempPlayerPos) < aiEngageRange) {
1998
- playerInRange = true;
1999
- return;
2000
- }
2001
- }
2002
- });
2003
-
2004
- if (playerInRange) {
2005
- mod.AIEnableTargeting(player, true);
2006
- await mod.Wait(Math.random() + 3.0);
2007
- mod.AIEnableTargeting(player, false);
2008
- } else {
2009
- await mod.Wait(1.0);
2010
- }
2011
- } else {
2012
- await mod.Wait(1.0);
2013
- }
2014
- }
2015
- }
2016
-
2017
- class AISpawnHandler {
2018
- static aiSpawnTask = new Map<number, AIEnemy[]>();
2019
- static aiSpawnedPool = new Map<number, AIEnemy[]>();
2020
- static aiBehaviorsAssignedMap = new Map<number, AIEnemy>();
2021
- static activeSpawnLoops: Set<number> = new Set();
2022
- static SpawnAIEnemyWithBehavior(
2023
- enemyBehavior: EnemyBehavior,
2024
- amount: number = 1,
2025
- options?: any
2026
- ) {
2027
- for (let index = 0; index < amount; index++) {
2028
- const aiEnemy = new AIEnemy(enemyBehavior, options);
2029
- AISpawnHandler.addEnemyToPool(aiEnemy.spawnPointID, aiEnemy);
2030
- }
2031
- }
2032
-
2033
- static async addEnemyToPool(spawnPointID: number, enemy: AIEnemy) {
2034
- if (!mod.GetSpawner(spawnPointID)) {
2035
- return;
2036
- }
2037
-
2038
- if (!AISpawnHandler.aiSpawnTask.has(spawnPointID)) {
2039
- AISpawnHandler.aiSpawnTask.set(spawnPointID, []);
2040
- }
2041
-
2042
- AISpawnHandler.aiSpawnTask.get(spawnPointID)?.push(enemy);
2043
-
2044
- // Start the spawn loop only if it's not already running
2045
- if (!AISpawnHandler.activeSpawnLoops.has(spawnPointID)) {
2046
- AISpawnHandler.startSpawnLoop(spawnPointID);
2047
- }
2048
- }
2049
-
2050
- static async ClearAllSpawns() {
2051
- AISpawnHandler.aiSpawnedPool.clear();
2052
- await mod.Wait(1);
2053
- AISpawnHandler.aiBehaviorsAssignedMap.forEach((aiEnemy) => {
2054
- const player = aiEnemy.player;
2055
-
2056
- if (player) {
2057
- mod.Kill(player);
2058
- }
2059
- });
2060
- }
2061
-
2062
- static async startSpawnLoop(spawnPointID: number): Promise<void> {
2063
- AISpawnHandler.activeSpawnLoops.add(spawnPointID);
2064
- while (true) {
2065
- const pool = AISpawnHandler.aiSpawnTask.get(spawnPointID);
2066
-
2067
- if (!pool || pool.length === 0) {
2068
- break; // Stop the loop when the pool is empty
2069
- }
2070
-
2071
- const enemy = pool.shift(); // Remove the first enemy
2072
-
2073
- if (!enemy) break;
2074
-
2075
- mod.SpawnAIFromAISpawner(
2076
- mod.GetSpawner(spawnPointID),
2077
- enemy.soldierClass,
2078
- mod.GetTeam(5)
2079
- );
2080
-
2081
- if (!AISpawnHandler.aiSpawnedPool.has(spawnPointID)) {
2082
- AISpawnHandler.aiSpawnedPool.set(spawnPointID, []);
2083
- }
2084
-
2085
- AISpawnHandler.aiSpawnedPool.get(spawnPointID)?.push(enemy);
2086
- await mod.Wait(0.5);
2087
- }
2088
- AISpawnHandler.activeSpawnLoops.delete(spawnPointID);
2089
- }
2090
-
2091
- static async AiDied(player: mod.Player) {
2092
- const aiID = mod.GetObjId(player);
2093
- const aiPlayer = AISpawnHandler.aiBehaviorsAssignedMap.get(aiID);
2094
-
2095
- if (aiPlayer) {
2096
- aiPlayer.die(player);
2097
- AISpawnHandler.aiBehaviorsAssignedMap.delete(aiID);
2098
- } else {
2099
- if (debugAIEnemy) console.log("Error: Failed To find behavior class");
2100
- }
2101
- }
2102
-
2103
- static async assignAIBehavior(player: mod.Player) {
2104
- let closetsSpawnPointID: number | null = null;
2105
-
2106
- for (const key in spawnPointsMap) {
2107
- if (
2108
- mod.IsPlayerValid(player) &&
2109
- mod.GetSoldierState(player, mod.SoldierStateBool.IsAlive) &&
2110
- spawnPointsMap.hasOwnProperty(Number(key))
2111
- ) {
2112
- const convertedToBFVector = mod.CreateVector(
2113
- spawnPointsMap[Number(key)].x,
2114
- spawnPointsMap[Number(key)].y,
2115
- spawnPointsMap[Number(key)].z
2116
- );
2117
- const playerPos = mod.GetSoldierState(
2118
- player,
2119
- mod.SoldierStateVector.GetPosition
2120
- );
2121
- const dinstanceCheck = mod.DistanceBetween(
2122
- convertedToBFVector,
2123
- playerPos
2124
- );
2125
-
2126
- if (dinstanceCheck <= 5) {
2127
- closetsSpawnPointID = Number(key);
2128
- break;
2129
- }
2130
- }
2131
- }
2132
-
2133
- if (closetsSpawnPointID == null) {
2134
- mod.Kill(player);
2135
- return;
2136
- }
2137
-
2138
- const playerObjId = mod.GetObjId(player);
2139
- const enemyAtSpawnPoint = AISpawnHandler.aiSpawnedPool
2140
- .get(closetsSpawnPointID)
2141
- ?.pop();
2142
-
2143
- if (!enemyAtSpawnPoint) {
2144
- mod.Kill(player);
2145
- return;
2146
- }
2147
-
2148
- enemyAtSpawnPoint.InitBehavior(player);
2149
- AISpawnHandler.aiBehaviorsAssignedMap.set(playerObjId, enemyAtSpawnPoint);
2150
- }
2151
- }
2152
-
2153
- async function RespawnEnemyAfterTime(id: number) {
2154
- await mod.Wait(enemyRespawnTime);
2155
- AISpawnHandler.SpawnAIEnemyWithBehavior(meleeShooterBehavior, 1, {
2156
- spawnPointID: id,
2157
- health: 100,
2158
- speedMultiplier: 0.5,
2159
- });
2160
- }
2161
-
2162
- function ShuffleArray<T>(array: T[]): T[] {
2163
- const shuffled = [...array]; // Create a copy to avoid mutating the original
2164
- for (let i = shuffled.length - 1; i > 0; i--) {
2165
- const j = Math.floor(Math.random() * (i + 1));
2166
- [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
2167
- }
2168
- return shuffled;
2169
- }
2170
-
2171
- class ExtractionPoint {
2172
- worldIcon: mod.WorldIcon;
2173
- areaTrigger: mod.AreaTrigger;
2174
- team: mod.Team | undefined;
2175
- position: mod.Vector;
2176
- vfx: mod.VFX[] | undefined;
2177
-
2178
- static currentExtractionPoint: ExtractionPoint | undefined;
2179
- static availableExtractionPoints: ExtractionPoint[] = [];
2180
-
2181
- constructor(
2182
- worldIcon: mod.WorldIcon,
2183
- areaTriggerId: mod.AreaTrigger,
2184
- teamId: mod.Team,
2185
- position: mod.Vector
2186
- ) {
2187
- this.worldIcon = worldIcon;
2188
- this.areaTrigger = areaTriggerId;
2189
- this.team = teamId;
2190
- this.position = position;
2191
- }
2192
-
2193
- static Initialize() {
2194
- let randomNumbers = [1, 2, 3, 4];
2195
- randomNumbers = ShuffleArray(randomNumbers);
2196
-
2197
- this.availableExtractionPoints = [
2198
- new ExtractionPoint(
2199
- mod.GetWorldIcon(600),
2200
- mod.GetAreaTrigger(500),
2201
- mod.GetTeam(randomNumbers[0]),
2202
- mod.CreateVector(20.633, 75.84, -58.129)
2203
- ),
2204
- new ExtractionPoint(
2205
- mod.GetWorldIcon(601),
2206
- mod.GetAreaTrigger(501),
2207
- mod.GetTeam(randomNumbers[1]),
2208
- mod.CreateVector(23.193, 80.317, -22.82)
2209
- ),
2210
- new ExtractionPoint(
2211
- mod.GetWorldIcon(602),
2212
- mod.GetAreaTrigger(502),
2213
- mod.GetTeam(randomNumbers[2]),
2214
- mod.CreateVector(-16.15, 80.397, 20.617)
2215
- ),
2216
- new ExtractionPoint(
2217
- mod.GetWorldIcon(603),
2218
- mod.GetAreaTrigger(503),
2219
- mod.GetTeam(randomNumbers[3]),
2220
- mod.CreateVector(7.352, 78.621, -133.505)
2221
- ),
2222
- ];
2223
- }
2224
-
2225
- static ActivateExtractionPoint(team: mod.Team) {
2226
- this.availableExtractionPoints.forEach((element) => {
2227
- if (element?.team && mod.GetObjId(element.team) == mod.GetObjId(team)) {
2228
- this.currentExtractionPoint?.Activate(false);
2229
- this.currentExtractionPoint = element;
2230
- this.currentExtractionPoint?.Activate(true);
2231
- this.currentExtractionPoint.ExtractionPointVFXHandler();
2232
- return;
2233
- }
2234
- });
2235
- }
2236
-
2237
- static RespawnVFXForCurrentExtractionPoint() {
2238
- this.currentExtractionPoint?.RespawnExtractionVFX();
2239
- }
2240
-
2241
- async RespawnExtractionVFX() {
2242
- if (ObjectiveItemData.carryingPlayer && this.vfx && this.vfx[1]) {
2243
- mod.EnableVFX(this.vfx[1], false);
2244
- this.vfx[1] = H.SpawnVFX(
2245
- mod.RuntimeSpawn_Common.FX_Granite_Strike_Smoke_Marker_Yellow,
2246
- mod.Add(this.position, mod.CreateVector(0, 0, 0))
2247
- );
2248
- }
2249
- }
2250
-
2251
- async ExtractionPointVFXHandler() {
2252
- this.vfx?.push(
2253
- H.SpawnVFX(
2254
- mod.RuntimeSpawn_Common.FX_Impact_SupplyDrop_Brick,
2255
- mod.Add(this.position, mod.CreateVector(0, 0, 0))
2256
- )
2257
- );
2258
- this.vfx?.push(
2259
- H.SpawnVFX(
2260
- mod.RuntimeSpawn_Common.FX_Granite_Strike_Smoke_Marker_Yellow,
2261
- mod.Add(this.position, mod.CreateVector(0, 0, 0))
2262
- )
2263
- );
2264
- }
2265
-
2266
- static DeactivateAllExtractionPoints() {
2267
- this.availableExtractionPoints.forEach((element) => {
2268
- element.vfx?.forEach((vfxEntity) => mod.EnableVFX(vfxEntity, false));
2269
- element.vfx = [];
2270
- this.currentExtractionPoint?.Activate(false);
2271
- this.currentExtractionPoint = undefined;
2272
- });
2273
- }
2274
-
2275
- Activate(active: boolean) {
2276
- if (active) {
2277
- mod.EnableAreaTrigger(this.areaTrigger, true);
2278
- mod.EnableWorldIconImage(this.worldIcon, true);
2279
- mod.EnableWorldIconText(this.worldIcon, true);
2280
- mod.SetWorldIconText(
2281
- this.worldIcon,
2282
- MakeMessage(
2283
- mod.stringkeys.extractionPointWorldIcon,
2284
- GetAdjustedTeamNumber(undefined, this.team)
2285
- )
2286
- );
2287
- this.team &&
2288
- mod.SetWorldIconColor(
2289
- this.worldIcon,
2290
- teamColors[GetTrueTeamIDNumberOfTeam(this.team) - 1]
2291
- );
2292
- } else {
2293
- mod.EnableAreaTrigger(this.areaTrigger, false);
2294
- mod.EnableWorldIconImage(this.worldIcon, false);
2295
- mod.EnableWorldIconText(this.worldIcon, false);
2296
- }
2297
- }
2298
- }
2299
-
2300
- function FormatTime(sec: number): [number, number, number] {
2301
- const minutes = Math.floor(sec / 60);
2302
- const seconds = Math.floor(sec % 10);
2303
- const coolerSeconds = Math.floor((sec % 60) / 10);
2304
- return [minutes, coolerSeconds, seconds];
2305
- }
2306
-
2307
- export async function OnPlayerEnterAreaTrigger(
2308
- eventPlayer: mod.Player,
2309
- eventAreaTrigger: mod.AreaTrigger
2310
- ) {
2311
- if (
2312
- eventPlayer &&
2313
- mod.GetSoldierState(eventPlayer, mod.SoldierStateBool.IsAlive) &&
2314
- mod.GetSoldierState(eventPlayer, mod.SoldierStateBool.IsAISoldier) == true
2315
- ) {
2316
- return;
2317
- }
2318
-
2319
- if (debugPlayer) console.log("Enter Extraction Point 500");
2320
-
2321
- const objId = mod.GetObjId(eventAreaTrigger);
2322
-
2323
- if (
2324
- eventPlayer &&
2325
- ObjectiveItemData.carryingPlayer &&
2326
- mod.GetObjId(eventPlayer) == mod.GetObjId(ObjectiveItemData.carryingPlayer)
2327
- ) {
2328
- if (
2329
- ExtractionPoint.currentExtractionPoint &&
2330
- objId == mod.GetObjId(ExtractionPoint.currentExtractionPoint?.areaTrigger)
2331
- ) {
2332
- mod.DeleteAllUIWidgets();
2333
- mod.EndGameMode(mod.GetTeam(eventPlayer));
2334
- console.log("Ending Game");
2335
- }
2336
- }
2337
- }
2338
-
2339
- export async function OnPlayerExitAreaTrigger(
2340
- eventPlayer: mod.Player,
2341
- eventAreaTrigger: mod.AreaTrigger
2342
- ) {
2343
- if (
2344
- eventPlayer &&
2345
- mod.IsPlayerValid(eventPlayer) &&
2346
- mod.GetSoldierState(eventPlayer, mod.SoldierStateBool.IsAlive) &&
2347
- mod.GetSoldierState(eventPlayer, mod.SoldierStateBool.IsAISoldier) == true
2348
- ) {
2349
- return;
2350
- }
2351
-
2352
- const objId = mod.GetObjId(eventAreaTrigger);
2353
- }
2354
-
2355
-
2356
- // === src\HoH_Helpers.ts ===
2357
- class H {
2358
- static SpawnVFX(vfxId: any, targetpoint: mod.Vector, rotation: mod.Vector, scale: mod.Vector): mod.VFX;
2359
- static SpawnVFX(vfxType: any, position: mod.Vector): mod.VFX;
2360
-
2361
- static SpawnVFX(
2362
- vfxParam: any,
2363
- positionParam: mod.Vector,
2364
- rotationParam?: mod.Vector,
2365
- scaleParam?: mod.Vector
2366
- ): mod.VFX | null {
2367
- if (rotationParam !== undefined && scaleParam !== undefined) {
2368
- // Handle the 4-parameter case
2369
- const vfxObject = mod.SpawnObject(vfxParam, positionParam, rotationParam, scaleParam);
2370
- mod.EnableVFX(vfxObject, true);
2371
- const vfxInstance = mod.GetVFX(mod.GetObjId(vfxObject));
2372
- return vfxInstance;
2373
- } else {
2374
- // Handle the 2-parameter case
2375
- try {
2376
- const vfxObject = mod.SpawnObject(vfxParam, positionParam, mod.CreateVector(0, 0, 0), mod.CreateVector(1, 1, 1));
2377
- if (vfxObject) {
2378
- mod.EnableVFX(vfxObject, true);
2379
- const vfxInstance = mod.GetVFX(mod.GetObjId(vfxObject));
2380
- return vfxInstance;
2381
- }
2382
- } catch (error) {
2383
- console.log(`Error spawning VFX: ${error}`);
2384
- }
2385
- return null;
2386
- }
2387
- }
2388
-
2389
- static getRandomInt(max: number) {
2390
- return Math.floor(Math.random() * max);
2391
- }
2392
- }
2393
-