@bf6mods/cli 1.0.0 → 1.0.2

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 +72 -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,3421 +0,0 @@
1
- // === acePursuit.ts ===
2
- const VERSION = [1, 8, 239];
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
- // Version Format [ship, delivery, patch/compile]
14
- const debugPlayer = false;
15
-
16
- const catchupMechanicSprintDisable = true;
17
-
18
- const MinimumPlayerToStart = 1;
19
- const MapPlayers = 8;
20
-
21
- const CIRCLE_MAX = 70;
22
- const CIRCLE_MIN = 25;
23
-
24
- enum GameType {
25
- race = 0,
26
- timeSurvival = 1,
27
- }
28
-
29
- type Checkpoint = {
30
- id: number;
31
- position: Vector3;
32
- checkpointStart: Vector3;
33
- checkpointEnd: Vector3;
34
- flipdir?: boolean;
35
- };
36
-
37
- type RaceTrack = {
38
- trackId: string;
39
- name: string;
40
- laps: number;
41
- gametype: GameType;
42
- availableVehicles: mod.VehicleList[]
43
- checkPoints: Checkpoint[];
44
- };
45
-
46
- type Vector3 = { x: number; y: number, z: number };
47
-
48
- function getTrackById(id: string): RaceTrack | undefined {
49
- return tracks.find(track => track.trackId === id);
50
- }
51
-
52
- class TrackData {
53
-
54
- trackId: string;
55
- checkPoints: Checkpoint[];
56
- laps: number;
57
- playersInRace: PlayerProfile[] = [];
58
- raceTime: number = 0;
59
- winner: boolean = false;
60
- #maxReadyupCountdown: number = 350;
61
- readyupCountDown: number = 350;
62
- countdownToStart: number = 3;
63
- countdownToEnd: number = 45;
64
- winnerPlayer: PlayerProfile | undefined;
65
- availableVehicles: mod.VehicleList[] = [];
66
- trackState: TrackState = TrackState.none
67
- gametype: GameType = GameType.race;
68
- firstPlayerHasJoined: boolean = false
69
-
70
- constructor(track: RaceTrack) {
71
-
72
- console.log("Prepere Track " + track.name)
73
-
74
- this.checkPoints = track.checkPoints;
75
- this.laps = track.laps;
76
- this.availableVehicles = track.availableVehicles;
77
- this.trackId = track.trackId;
78
- this.trackState = TrackState.selected;
79
- this.gametype = track.gametype;
80
- }
81
-
82
- PlayerCompletedTrack(playerProfile: PlayerProfile) {
83
- playerProfile.playerRaceTime = mod.GetMatchTimeElapsed();
84
- playerProfile.completedTrack = true;
85
-
86
- this.playersInRace.forEach(playerProfile => {
87
- playerProfile.ScoreboardUI?.update()
88
- })
89
-
90
- if (this.winnerPlayer == undefined) {
91
- console.log("Winner Found")
92
- this.Winner(playerProfile)
93
-
94
- } else {
95
- this.CompletedTrackShowPlacement(playerProfile)
96
- }
97
- }
98
-
99
- CompletedTrackShowPlacement(playerProfile: PlayerProfile) {
100
- playerProfile.PlacementUI?.Open(mod.stringkeys.header_placement, currentRace.playersInRace.findIndex(pp => pp.player == playerProfile.player) + 1, 45)
101
- }
102
-
103
- async Winner(playerProfile: PlayerProfile) {
104
-
105
- this.winnerPlayer = playerProfile;
106
- playerProfile.PlacementUI?.Open(mod.stringkeys.victory, 0, 85)
107
- currentRace.trackState = TrackState.winnerFound;
108
-
109
- await mod.Wait(2)
110
-
111
- currentRace.playersInRace.forEach(playerProfile => {
112
- playerProfile.EndingCountDownUI?.Open(this.countdownToEnd)
113
- });
114
-
115
- while (this.countdownToEnd > 0 && this.hasActiveRacers()) {
116
- currentRace.playersInRace.forEach(playerProfile => {
117
- playerProfile.EndingCountDownUI?.update(this.countdownToEnd)
118
- });
119
- await mod.Wait(1)
120
- this.countdownToEnd--;
121
- }
122
-
123
- currentRace.playersInRace.forEach(playerProfile => {
124
- playerProfile.EndingCountDownUI?.Close()
125
- });
126
-
127
- currentRace.trackState = TrackState.over;
128
-
129
- console.log("Ending game")
130
- mod.EndGameMode(playerProfile.player)
131
- }
132
-
133
-
134
- hasActiveRacers() {
135
- return currentRace.playersInRace.some(player => player.completedTrack === false);
136
- }
137
-
138
- async AddPlayerToTrack(player: mod.Player) {
139
- const playerP = PlayerProfile.get(player);
140
-
141
- if (playerP) {
142
-
143
- if (this.playersInRace.includes(playerP)) {
144
- console.log("Player already in the race")
145
- return
146
- }
147
-
148
- playerP.readyUp = false;
149
- playerP.lap = 0;
150
- playerP.checkpoint = 0;
151
- playerP.nextCheckpoint = 0;
152
- playerP.playerRaceTime = null;
153
- playerP.completedTrack = false;
154
- playerP.currentTrackID = currentRace.trackId;
155
- playerP.checkPointPosition = ConverVector3ToModVector(currentRace.checkPoints[0].position)
156
- this.playersInRace.push(playerP)
157
- currentRace.AssignPlayerNumber(playerP)
158
-
159
- if (currentRace.trackState == TrackState.selected) {
160
- playerP.VehicleShopUI?.cameraTeleport()
161
- playerP.OpenVehicleOptionsUI()
162
- playerP.ScoreboardUI?.open()
163
-
164
- currentRace.playersInRace.forEach(PlayerProfile => {
165
- PlayerProfile.VehicleShopUI?.UIUpdatePlayersReady()
166
- PlayerProfile.ScoreboardUI?.update()
167
- });
168
- }
169
-
170
- console.log("player pushed to race array")
171
- } else {
172
- console.log("could not find player to put into race")
173
- }
174
-
175
- }
176
-
177
- PlayerLeftGame() {
178
- // Remove invalid players and clean them up
179
- currentRace.playersInRace = currentRace.playersInRace.filter(playerProfile => {
180
- if (!this.isValidPlayer(playerProfile.player)) {
181
- playerProfile.CloseAllUI()
182
- playerProfile.DeletePlayerWidgets()
183
- playerProfile.DestroyVehicle();
184
- playerProfile.RemoveWorldIcons();
185
-
186
- return false; // remove from list
187
- }
188
- return true; // keep
189
- });
190
-
191
- // Update UI and possibly start countdown
192
- if (currentRace.trackState === TrackState.selected) {
193
- currentRace.playersInRace.forEach(player => {
194
- player.VehicleShopUI?.UIUpdatePlayersReady();
195
- player.ScoreboardUI?.update();
196
- });
197
- // Updated scoreboard
198
- } else if (currentRace.trackState === TrackState.running || currentRace.trackState === TrackState.winnerFound) {
199
- currentRace.playersInRace.forEach(player => {
200
- player.ScoreboardUI?.update();
201
- });
202
- this.UpdateOrder()
203
- }
204
- }
205
-
206
-
207
- isValidPlayer(player: mod.Player | null | undefined): boolean {
208
- return player != null && mod.IsPlayerValid(player);
209
- }
210
-
211
- AssignPlayerNumber(playerProfile: PlayerProfile) {
212
-
213
- const usedIds = currentRace.playersInRace.map(p => p.playerRacerNumber);
214
-
215
- // Find the first free ID.
216
- let freeId = -1;
217
- for (let i = 0; i < MapPlayers; i++) {
218
- if (!usedIds.includes(i)) {
219
- freeId = i;
220
- break;
221
- }
222
- }
223
-
224
- if (freeId === -1) {
225
- console.log("ERROR: No available slots for new players!");
226
- }
227
-
228
- // Assign the ID to the joining player
229
- playerProfile.playerRacerNumber = freeId;
230
- console.log("Player joined race, Assign race number: " + freeId)
231
- }
232
-
233
- async RaceStartCountdown() {
234
- currentRace.playersInRace.forEach(playerProfile => {
235
- playerProfile.StartCountDownUI?.Open(mod.stringkeys.scoreboard_1_name, this.countdownToStart)
236
- });
237
-
238
- await mod.Wait(1)
239
- while (this.countdownToStart > 1) {
240
- this.countdownToStart--;
241
-
242
- currentRace.playersInRace.forEach(playerProfile => {
243
- playerProfile.StartCountDownUI?.update(mod.stringkeys.scoreboard_1_name, this.countdownToStart)
244
- });
245
-
246
- await mod.Wait(1)
247
- }
248
-
249
- currentRace.playersInRace.forEach(playerProfile => {
250
- playerProfile.StartCountDownUI?.update(mod.stringkeys.gamestart, this.countdownToStart)
251
- });
252
-
253
- currentRace.playersInRace.forEach(playerProfile => {
254
- playerProfile.StartCountDownUI?.Close(3)
255
- });
256
- }
257
-
258
- countdownInProgress: boolean = false;
259
-
260
- async StartCountdown() {
261
-
262
- if (this.countdownInProgress === true) {
263
- console.log("Countdown already running");
264
- return;
265
- }
266
-
267
- if (!this.HasMinimumPlayers()) {
268
- console.log("Countdown cancelled: not enough players in game");
269
- return
270
- }
271
-
272
- this.countdownInProgress = true;
273
- this.readyupCountDown = this.#maxReadyupCountdown;
274
-
275
- while (this.readyupCountDown > 0) {
276
- this.readyupCountDown--;
277
-
278
- this.playersInRace.forEach(player => {
279
- player.VehicleShopUI?.UIUpdatePlayersReady()
280
- });
281
-
282
- await mod.Wait(1)
283
-
284
- const playerReady = this.GetPlayersReady();
285
-
286
- if (playerReady.total == 0) {
287
- console.log("Countdown cancelled: No players in lobby");
288
- this.countdownInProgress = false;
289
- return
290
- } else if (playerReady.ready == playerReady.total) {
291
- this.readyupCountDown = 0;
292
- }
293
- }
294
-
295
- console.log("Starting game...");
296
-
297
- await this.StartGame()
298
- this.countdownInProgress = false;
299
- }
300
- HasMinimumPlayers() {
301
- return this.playersInRace.length >= MinimumPlayerToStart
302
- }
303
-
304
- IsPlayersReady() {
305
- return this.playersInRace.every(player => player.readyUp === true);
306
- }
307
-
308
- IndexExists<T>(array: T[], index: number): boolean {
309
- return index >= 0 && index < array.length;
310
- }
311
-
312
- GetPlayersReady() {
313
- const readyCount = this.playersInRace.filter(p => p.readyUp).length;
314
- return { ready: readyCount, total: this.playersInRace.length };
315
- }
316
-
317
- IsPlayerInRace(player: mod.Player) {
318
-
319
- const playerPro = PlayerProfile.get(player)
320
-
321
- if (!playerPro) {
322
- return false;
323
- }
324
-
325
- return currentRace?.playersInRace?.some(
326
- item => mod.GetObjId(item.player) == mod.GetObjId(playerPro.player)
327
- ) ?? false;
328
- }
329
-
330
- async StartGame() {
331
- mod.DisablePlayerJoin()
332
-
333
- currentRace.trackState = TrackState.starting
334
-
335
- this.playersInRace.forEach(playerProfile => {
336
- playerProfile.VehicleShopUI?.close();
337
- if (mod.IsPlayerValid(playerProfile.player) && mod.GetSoldierState(playerProfile.player, mod.SoldierStateBool.IsAlive)) {
338
- mod.EnableAllInputRestrictions(playerProfile.player, true)
339
- }
340
- playerProfile.FadeInScreenUI?.FadeIn()
341
- });
342
-
343
- await mod.Wait(1)
344
-
345
- this.playersInRace.forEach(playerProfile => {
346
- playerProfile.InitRacer();
347
- });
348
-
349
- await mod.Wait(5)
350
-
351
-
352
- this.playersInRace.forEach(playerProfile => {
353
- playerProfile.FadeInScreenUI?.FadeOut()
354
- });
355
-
356
- await mod.Wait(2)
357
-
358
-
359
- await this.RaceStartCountdown()
360
-
361
- this.playersInRace.forEach(playerProfile => {
362
- playerProfile.UpdateWorldIconPosition();
363
- });
364
-
365
- currentRace.trackState = TrackState.running
366
-
367
- currentRace.raceTime = mod.GetMatchTimeElapsed();
368
-
369
- this.playersInRace.forEach(playerProfile => {
370
- if (mod.IsPlayerValid(playerProfile.player) && mod.GetSoldierState(playerProfile.player, mod.SoldierStateBool.IsAlive)) {
371
- mod.EnableAllInputRestrictions(playerProfile.player, false)
372
- }
373
-
374
- });
375
-
376
- this.playersInRace.forEach(playerProfile => {
377
- playerProfile.ScoreboardUI?.update()
378
- })
379
-
380
- this.DistanceCheckToCheckpoint();
381
- this.SpawnAiEnemyVehicle();
382
- this.UpdateScoreboardLoop();
383
- this.StartFireworks();
384
-
385
-
386
- }
387
- async DebugLoop() {
388
-
389
- while (true) {
390
-
391
- currentRace.playersInRace.forEach(element => {
392
-
393
- element.boosterDisabled = true
394
- element.BoosterDisableUI?.Trigger()
395
-
396
- });
397
-
398
- await mod.Wait(5)
399
- currentRace.playersInRace.forEach(element => {
400
- element.boosterDisabled = false
401
- element.BoosterDisableUI?.Trigger()
402
-
403
- });
404
- await mod.Wait(5)
405
- }
406
-
407
-
408
- }
409
-
410
-
411
- async DistanceCheckToCheckpoint() {
412
-
413
- while (this.trackState == TrackState.running || this.trackState == TrackState.winnerFound) {
414
- this.playersInRace.forEach(playerProfile => {
415
-
416
- if (playerProfile.completedTrack == true) {
417
- console.log("Player have already completed track")
418
- return;
419
- }
420
-
421
-
422
- if (!playerProfile.player) {
423
- return;
424
- }
425
-
426
-
427
- if (!mod.GetSoldierState(playerProfile.player, mod.SoldierStateBool.IsAlive)) {
428
- return
429
- }
430
-
431
- const playerPosition = mod.GetSoldierState(playerProfile.player, mod.SoldierStateVector.GetPosition)
432
-
433
- if (!playerPosition) {
434
- return
435
- }
436
-
437
- const targetCheckpoint = ConverVector3ToModVector(this.checkPoints[playerProfile.nextCheckpoint].position)
438
-
439
- const distance = mod.DistanceBetween(playerPosition, targetCheckpoint)
440
-
441
-
442
- if (distance <= playerProfile.checkpointCircleSize) {
443
-
444
- playerProfile.checkpoint++;
445
-
446
- const positionInRace = this.playersInRace.indexOf(playerProfile)
447
- playerProfile.checkpointCircleSize = getCheckpointSize(positionInRace, currentRace.playersInRace.length);
448
-
449
- //update checkpoint position
450
- playerProfile.nextCheckpoint = (playerProfile.checkpoint) % this.checkPoints.length
451
- playerProfile.checkPointPosition = ConverVector3ToModVector(this.checkPoints[playerProfile.nextCheckpoint].position)
452
-
453
- const lapsCompl = Math.floor((playerProfile.checkpoint / this.checkPoints.length))
454
-
455
- if (lapsCompl != playerProfile.lap) {
456
- playerProfile.lap = lapsCompl;
457
- console.log("lap" + playerProfile.lap)
458
- }
459
-
460
- if (playerProfile.lap >= this.laps && ((playerProfile.checkpoint % this.checkPoints.length) >= 1) && !playerProfile.completedTrack) {
461
- this.PlayerCompletedTrack(playerProfile)
462
- console.log("player win " + playerProfile.playerRaceTime)
463
- }
464
-
465
- playerProfile.UpdateWorldIconPosition();
466
- this.UpdateOrder()
467
- }
468
-
469
- });
470
- await mod.Wait(0.1)
471
- }
472
- }
473
-
474
- StartFireworks() {
475
- const fireworkArray = generateSpawnLine({ x: 121.062789916992, y: 177.110992431641, z: 163.706634521484 }, { x: 277.184600830078, y: 177.110992431641, z: 13.0980796813965 }, 6)
476
-
477
- fireworkArray.forEach(firework => {
478
- SpawnVFXAtPosition(ConverVector3ToModVector(firework.position), mod.RuntimeSpawn_Common.FX_Sparks)
479
- });
480
- }
481
-
482
- async SpawnAiEnemyVehicle() {
483
- console.log("start SpawnAi EnemyVehicle")
484
-
485
- const vehicArray = [
486
- mod.GetVehicleSpawner(1),
487
- mod.GetVehicleSpawner(2),
488
- mod.GetVehicleSpawner(3),
489
- mod.GetVehicleSpawner(4),
490
- mod.GetVehicleSpawner(5),
491
- mod.GetVehicleSpawner(6),
492
- mod.GetVehicleSpawner(7),
493
- mod.GetVehicleSpawner(8),
494
- mod.GetVehicleSpawner(9),
495
- mod.GetVehicleSpawner(10),
496
- mod.GetVehicleSpawner(11),
497
- mod.GetVehicleSpawner(12),
498
- mod.GetVehicleSpawner(13),
499
- mod.GetVehicleSpawner(14),
500
- ]
501
-
502
-
503
- for (let index = 0; index < vehicArray.length; index++) {
504
- mod.ForceVehicleSpawnerSpawn(vehicArray[index])
505
- await mod.Wait(0.1)
506
- }
507
-
508
- const aiArray = [
509
- mod.GetSpawner(1),
510
- mod.GetSpawner(2),
511
- mod.GetSpawner(3),
512
- mod.GetSpawner(4),
513
- mod.GetSpawner(5),
514
- mod.GetSpawner(6),
515
- mod.GetSpawner(7),
516
- mod.GetSpawner(8),
517
- mod.GetSpawner(9),
518
- mod.GetSpawner(10),
519
- mod.GetSpawner(11),
520
- mod.GetSpawner(12),
521
- mod.GetSpawner(13),
522
- mod.GetSpawner(14),
523
- ]
524
-
525
- for (let index = 0; index < aiArray.length; index++) {
526
- mod.SpawnAIFromAISpawner(aiArray[index], mod.SoldierClass.Assault, mod.GetTeam(9))
527
- await mod.Wait(0.1)
528
- }
529
-
530
- console.log("completed SpawnAiEnemyVehicle")
531
- }
532
-
533
- async TimeLoop() {
534
- console.log("Starting: TimeLoop")
535
-
536
- while (currentRace.trackState == TrackState.running || currentRace.trackState == TrackState.winnerFound) {
537
- let foundPlayerInRace = false;
538
-
539
- for (let index = 0; index < this.playersInRace.length; index++) {
540
- const pp = this.playersInRace[index];
541
-
542
- if (pp) {
543
- // pp.UITest.open();
544
- }
545
-
546
- if (pp.completedTrack) {
547
- continue
548
- }
549
-
550
-
551
-
552
-
553
- let timeleft = pp.timeLeft - 0.1
554
-
555
- if (timeleft < 0) {
556
- pp.timeLeft = 0;
557
- } else {
558
- pp.timeLeft = timeleft;
559
- }
560
-
561
- if (pp.timeLeft == 0) {
562
- continue;
563
- }
564
-
565
-
566
- if (pp.timeLeft > 0) {
567
- foundPlayerInRace = true;
568
- }
569
- }
570
-
571
-
572
- if (foundPlayerInRace == false) {
573
- return
574
- }
575
-
576
- await mod.Wait(0.1)
577
- }
578
- }
579
-
580
- async UpdateScoreboardLoop() {
581
- console.log("Start UpdateScoreboard loop")
582
- while (this.trackState == TrackState.running || this.trackState == TrackState.winnerFound) {
583
- await mod.Wait(1.0)
584
- this.UpdateOrder();
585
- }
586
- }
587
-
588
-
589
- UpdateScoreboard() {
590
- currentRace.playersInRace.forEach(playerProfile => {
591
- playerProfile.ScoreboardUI?.update()
592
- })
593
-
594
- }
595
-
596
-
597
- UpdateOrder() {
598
-
599
- const oldarray = JSON.parse(JSON.stringify(this.playersInRace));
600
-
601
- const updatedArray = sortRaceStanding(this.playersInRace);
602
-
603
- let overtakingPlayers = detectOvertakes(oldarray, updatedArray);
604
- for (let playerProfile of overtakingPlayers) {
605
- playerProfile.OvertookPlayer();
606
- }
607
-
608
- if (hasOrderChangedByKey(oldarray, updatedArray)) {
609
- console.log("Race Order Changed")
610
- this.playersInRace = updatedArray
611
-
612
- currentRace.playersInRace.forEach(playerProfile => {
613
- playerProfile.ScoreboardUI?.update()
614
- })
615
-
616
- if (currentRace.playersInRace.length >= 2 && catchupMechanicSprintDisable) {
617
- const players = currentRace.playersInRace;
618
-
619
- // Calculate how many players should have sprint disabled (round up to at least 1)
620
- const disableCount = Math.max(1, Math.ceil(players.length * 0.3));
621
-
622
- for (let i = 0; i < players.length; i++) {
623
- const disableSprint = i < disableCount; // First X players have sprint disabled
624
- mod.EnableInputRestriction(players[i].player, mod.RestrictedInputs.Sprint, disableSprint);
625
- players[i].boosterDisabled = disableSprint;
626
- players[i].BoosterDisableUI?.Trigger()
627
- }
628
- } else if (currentRace.playersInRace.length <= 1 && catchupMechanicSprintDisable) {
629
- // If a player leaves the game, and only one player is left. reactivate sprint.
630
- const playerProf = currentRace.playersInRace[0];
631
- if (playerProf && playerProf.boosterDisabled) {
632
- mod.EnableInputRestriction(playerProf.player, mod.RestrictedInputs.Sprint, false);
633
- playerProf.boosterDisabled = false;
634
- playerProf.BoosterDisableUI?.Trigger()
635
- }
636
- }
637
-
638
-
639
- }
640
- }
641
-
642
- }
643
-
644
- function detectOvertakes(oldOrder: PlayerProfile[], newOrder: PlayerProfile[]) {
645
- let overtakes: PlayerProfile[] = [];
646
-
647
- for (let player of newOrder) {
648
- const id = player.playerProfileId;
649
- const oldPos = oldOrder.findIndex(p => p.playerProfileId === id);
650
- const newPos = newOrder.findIndex(p => p.playerProfileId === id);
651
-
652
- if (newPos < oldPos) {
653
- overtakes.push(player);
654
- }
655
- }
656
- return overtakes;
657
- }
658
-
659
- function hasOrderChangedByKey(prev: PlayerProfile[], current: PlayerProfile[]): boolean {
660
- if (prev.length !== current.length) return true;
661
- return prev.some((p, i) =>
662
- p.playerProfileId !== current[i].playerProfileId
663
- );
664
- }
665
-
666
- function compareRacers(a: PlayerProfile, b: PlayerProfile): number {
667
-
668
-
669
- if (a.completedTrack && b.completedTrack) return a.playerRaceTime! - b.playerRaceTime!;
670
- if (a.completedTrack) return -1;
671
- if (b.completedTrack) return 1;
672
-
673
-
674
- if (a.lap !== b.lap) return b.lap - a.lap;
675
- if (a.checkpoint !== b.checkpoint) return b.checkpoint - a.checkpoint;
676
-
677
-
678
- const aDistance = mod.DistanceBetween(mod.GetSoldierState(a.player, mod.SoldierStateVector.GetPosition), a.checkPointPosition)
679
- const bDistance = mod.DistanceBetween(mod.GetSoldierState(b.player, mod.SoldierStateVector.GetPosition), b.checkPointPosition)
680
-
681
- if (aDistance !== bDistance) return aDistance - bDistance;
682
-
683
- return 0;
684
- }
685
-
686
-
687
- function sortRaceStanding(racers: PlayerProfile[]): PlayerProfile[] {
688
- return [...racers].sort(compareRacers);
689
- }
690
-
691
- let currentRace: TrackData;
692
-
693
- function PrepareRace(trackId: string) {
694
- const track = getTrackById(trackId);
695
- if (track) {
696
- currentRace = new TrackData(track);
697
- } else {
698
- console.log("Could not find trackid")
699
- }
700
- }
701
-
702
- export async function OnGameModeStarted() {
703
-
704
- console.log("HoH Test Game Mode Started");
705
-
706
- PrepareRace("track_02")
707
-
708
- mod.SetAIToHumanDamageModifier(0.5)
709
- mod.SetSpawnMode(mod.SpawnModes.AutoSpawn)
710
- }
711
-
712
- function MakeMessage(message: string, ...args: any[]) {
713
- switch (args.length) {
714
- case 0:
715
- return mod.Message(message);
716
- case 1:
717
- return mod.Message(message, args[0]);
718
- case 2:
719
- return mod.Message(message, args[0], args[1]);
720
- case 3:
721
- return mod.Message(message, args[0], args[1], args[2]);
722
- default:
723
- throw new Error("Invalid number of arguments");
724
- }
725
- }
726
-
727
- enum TrackState {
728
- none = 0,
729
- selected = 1,
730
- starting = 2,
731
- running = 3,
732
- winnerFound = 4,
733
- over = 5
734
- }
735
-
736
- let uniqueID: number = 0;
737
-
738
- class PlayerProfile {
739
-
740
- timeLeft: number = 30;
741
- player: mod.Player;
742
- checkpoint: number = 0;
743
- nextCheckpoint: number = 1;
744
- lap: number = 0;
745
- currentTrackID: string = "";
746
- playerRaceTime: number | null = null;
747
- completedTrack: boolean = false;
748
- checkPointPosition: mod.Vector = mod.CreateVector(0, 0, 0);
749
- checkPointPositionLookDirection2: Vector3 = { x: 0, y: 0, z: 0 }
750
- checkPointPosition2: Vector3 = { x: 0, y: 0, z: 0 }
751
- selectedVehicle: mod.VehicleList = mod.VehicleList.F22;
752
- playerProfileId: number = -1;
753
- playerRacerNumber: number = -1;
754
- readyUp: boolean = false;
755
- checkpointCircleSize: number = 20;
756
- boosterDisabled: boolean = false;
757
-
758
- checkpointWorldIcons: mod.WorldIcon[] = [];
759
- checkpointDirectionWorldIcons: mod.WorldIcon[] = [];
760
-
761
- checkpointWorldIconsTwo: mod.WorldIcon[] = [];
762
- checkpointDirectionWorldIconsTwo: mod.WorldIcon[] = [];
763
-
764
- checkpointWorldIconsHolder: HoH_CheckpointWorldIconsHolder | undefined;
765
- nextcheckpointWorldIconsHolder: HoH_CheckpointWorldIconsHolder | undefined;
766
-
767
-
768
-
769
- VehicleShopUI: HoH_UIVehicleSelect | undefined;
770
- FadeInScreenUI: HoH_UIBlackScreen | undefined;
771
- StartCountDownUI: HoH_UIStartCountdown | undefined;
772
- PlacementUI: HoH_UIPlacementHeader | undefined;
773
- EndingCountDownUI: HoH_UIEndingGameCountdown | undefined;
774
- OvertakeUI: HoH_BenjiOvertakeUI | undefined;
775
- VersionNumberUI: HoH_Version | undefined;
776
- BoosterDisableUI: HoH_BoosterDisabledUI | undefined;
777
- ScoreboardUI: HoH_ScoreboardUI | undefined;
778
-
779
- playerSpawnedVeh: mod.Vehicle | undefined;
780
- playerSpawnedVehSpawner: mod.VehicleSpawner | undefined;
781
-
782
- static playerInstances: mod.Player[] = [];
783
-
784
- static #allHoHPlayers: { [key: number]: PlayerProfile } = {};
785
-
786
-
787
- constructor(player: mod.Player) {
788
- this.player = player;
789
- this.playerProfileId = uniqueID++;
790
-
791
- this.FadeInScreenUI = new HoH_UIBlackScreen(this);
792
- this.StartCountDownUI = new HoH_UIStartCountdown(this);
793
- this.PlacementUI = new HoH_UIPlacementHeader(this);
794
- this.EndingCountDownUI = new HoH_UIEndingGameCountdown(this);
795
- this.OvertakeUI = new HoH_BenjiOvertakeUI(this);
796
- this.VersionNumberUI = new HoH_Version(this)
797
- this.BoosterDisableUI = new HoH_BoosterDisabledUI(this)
798
- this.ScoreboardUI = new HoH_ScoreboardUI(this)
799
- }
800
-
801
- CloseAllUI() {
802
- this.FadeInScreenUI?.Close()
803
- this.StartCountDownUI?.Close()
804
- this.PlacementUI?.Close()
805
- this.EndingCountDownUI?.Close()
806
- this.OvertakeUI?.Close()
807
- this.VersionNumberUI?.Close()
808
- this.BoosterDisableUI?.Close()
809
- this.ScoreboardUI?.Close()
810
- this.VehicleShopUI?.close()
811
- }
812
-
813
-
814
- static get(player: mod.Player) {
815
- if (mod.GetObjId(player) > -1) {
816
- let index = mod.GetObjId(player);
817
-
818
- let hohPlayer = this.#allHoHPlayers[index];
819
- if (!hohPlayer) {
820
- hohPlayer = new PlayerProfile(player);
821
- if (debugPlayer) console.log("Creating Player Profile");
822
- this.#allHoHPlayers[index] = hohPlayer;
823
- this.playerInstances.push(player)
824
- }
825
- return hohPlayer;
826
- }
827
- if (debugPlayer) console.log("Error: could not finds an valid player object ID.");
828
- return undefined;
829
- }
830
-
831
- async DeletePlayerWidgets() {
832
-
833
- this.FadeInScreenUI?.Delete()
834
- this.StartCountDownUI?.Delete()
835
- this.PlacementUI?.Delete()
836
- this.EndingCountDownUI?.Delete()
837
- this.OvertakeUI?.Delete()
838
- this.VersionNumberUI?.Delete()
839
- this.BoosterDisableUI?.Delete()
840
- this.ScoreboardUI?.Delete()
841
-
842
-
843
- }
844
-
845
- DestroyVehicle() {
846
-
847
- if (this.playerSpawnedVeh) {
848
- mod.DealDamage(this.playerSpawnedVeh, 9999)
849
- }
850
- if (this.playerSpawnedVehSpawner) {
851
- mod.UnspawnObject(this.playerSpawnedVehSpawner)
852
- this.playerSpawnedVehSpawner = undefined;
853
- }
854
- }
855
-
856
- SetVehicle(vehicle: mod.VehicleList) {
857
- this.selectedVehicle = vehicle
858
- }
859
-
860
- InitRacer() {
861
-
862
- this.checkPointPosition = ConverVector3ToModVector(currentRace.checkPoints[0].position);
863
- this.checkPointPosition2 = currentRace.checkPoints[0].position;
864
-
865
- this.checkpointWorldIconsHolder = new HoH_CheckpointWorldIconsHolder(this, mod.CreateVector(0, 1, 0))
866
- this.nextcheckpointWorldIconsHolder = new HoH_CheckpointWorldIconsHolder(this, mod.CreateVector(1, 0, 0))
867
-
868
- VehicleHandler.RequestVehicle(this)
869
- }
870
-
871
- OpenVehicleOptionsUI() {
872
-
873
- if (this.VehicleShopUI == undefined) {
874
- this.VehicleShopUI = new HoH_UIVehicleSelect(this)
875
- }
876
- this.VehicleShopUI.open();
877
- }
878
-
879
-
880
- RefreshWorldIcons() {
881
- this.checkpointWorldIconsHolder?.Refresh()
882
- if ((this.checkpoint) < currentRace.laps * currentRace.checkPoints.length) {
883
- this.nextcheckpointWorldIconsHolder?.Refresh()
884
- }
885
- }
886
-
887
-
888
- RemoveWorldIcons() {
889
-
890
- if (this.checkpointWorldIconsHolder) {
891
- this.checkpointWorldIconsHolder.checkpointWorldIcons.forEach(element => {
892
- mod.UnspawnObject(element)
893
- });
894
- }
895
-
896
- if (this.nextcheckpointWorldIconsHolder) {
897
- this.nextcheckpointWorldIconsHolder.checkpointWorldIcons.forEach(element => {
898
- mod.UnspawnObject(element)
899
- });
900
- }
901
-
902
- }
903
-
904
- UpdateWorldIconPosition() {
905
- if (this.completedTrack) {
906
- this.checkpointWorldIconsHolder?.Hide()
907
- this.nextcheckpointWorldIconsHolder?.Hide()
908
- console.log("Hide ui since player completed track")
909
- return;
910
- }
911
-
912
- this.checkPointPosition2 = currentRace.checkPoints[this.nextCheckpoint].position
913
-
914
-
915
- this.checkPointPositionLookDirection2 = currentRace.checkPoints[(this.checkpoint + 1) % currentRace.checkPoints.length].position
916
-
917
-
918
- if (!this.checkpointWorldIconsHolder) {
919
- console.log("checkpointWorldIconsHolder not found")
920
- }
921
-
922
- this.checkpointWorldIconsHolder?.Update(this.checkPointPosition2, this.checkPointPositionLookDirection2, this.checkpointCircleSize)
923
-
924
-
925
- //upcoming checkpoint after target checkpoint
926
- const upcomingCheckpoint = (this.checkpoint + 1) % currentRace.checkPoints.length
927
- const upcomingcheckpointPosition2 = currentRace.checkPoints[upcomingCheckpoint].position
928
-
929
-
930
- this.nextcheckpointWorldIconsHolder?.Update(upcomingcheckpointPosition2, currentRace.checkPoints[(this.checkpoint + 2) % currentRace.checkPoints.length].position, this.checkpointCircleSize)
931
-
932
- if (!this.nextcheckpointWorldIconsHolder) {
933
- console.log("nextcheckpointWorldIconsHolder not found")
934
- }
935
-
936
- // Make the final checkpoint not have a next checkpoint.
937
- if ((this.checkpoint) >= currentRace.laps * currentRace.checkPoints.length) {
938
- this.nextcheckpointWorldIconsHolder?.Hide()
939
- console.log("hide last checkpoint")
940
- }
941
-
942
- }
943
-
944
-
945
- static removePlayer(player: mod.Player) {
946
- let index = mod.GetObjId(player);
947
-
948
- let hohPlayer = this.#allHoHPlayers[index];
949
- if (hohPlayer) {
950
- this.playerInstances.filter(item => item !== player);
951
- delete this.#allHoHPlayers[index];
952
- } else {
953
- if (debugPlayer) console.log("Error: could not find player with profile to remove");
954
- }
955
- }
956
-
957
-
958
- static removeInvalidPlayers() {
959
- // Remove invalid from array
960
- PlayerProfile.playerInstances = PlayerProfile.playerInstances.filter(player =>
961
- this.isValidPlayer(player)
962
- );
963
-
964
- // Remove invalid from object
965
- for (const id in PlayerProfile.#allHoHPlayers) {
966
- const { player } = PlayerProfile.#allHoHPlayers[id];
967
- if (!this.isValidPlayer(player)) {
968
- delete PlayerProfile.#allHoHPlayers[id];
969
- }
970
- }
971
- }
972
-
973
- static isValidPlayer(player: mod.Player | null | undefined): boolean {
974
- // Check for null/undefined before calling mod function
975
- return player != null && mod.IsPlayerValid(player);
976
- }
977
-
978
-
979
-
980
- OvertookPlayer() {
981
- this.OvertakeUI?.Trigger()
982
- }
983
-
984
- }
985
-
986
- function getCheckpointSize(index: number, totalPlayers: number) {
987
-
988
-
989
- if (index < 0 || index >= totalPlayers) {
990
- return CIRCLE_MIN;
991
- }
992
-
993
-
994
- if (totalPlayers === 1) {
995
- return CIRCLE_MIN
996
- }
997
-
998
-
999
- const normalized = index / (totalPlayers - 1);
1000
-
1001
-
1002
- return CIRCLE_MIN + normalized * (CIRCLE_MAX - CIRCLE_MIN);
1003
- }
1004
-
1005
- class HoH_CheckpointWorldIconsHolder {
1006
-
1007
- #playerprofile: PlayerProfile;
1008
-
1009
- color: mod.Vector;
1010
- circleSize: number = 40;
1011
- directionForwardOffset: number = 35
1012
- amountoficons: number = 8;
1013
- checkpointWorldIcons: mod.WorldIcon[] = [];
1014
-
1015
-
1016
-
1017
- constructor(playerprofile: PlayerProfile, color: mod.Vector) {
1018
- this.#playerprofile = playerprofile;
1019
- this.color = color;
1020
-
1021
- const checkpointWidgets = generatePointsInACircle(this.#playerprofile.checkPointPosition2, this.#playerprofile.checkPointPositionLookDirection2, this.circleSize, this.amountoficons)
1022
-
1023
-
1024
-
1025
- //Circle widgets
1026
- checkpointWidgets.forEach(element => {
1027
- const worldicon = mod.SpawnObject(mod.RuntimeSpawn_Common.WorldIcon, mod.CreateVector(element.x, element.y, element.z), mod.CreateVector(0, 0, 0))
1028
- mod.SetWorldIconPosition(worldicon, mod.CreateVector(element.x, element.y, element.z))
1029
- mod.SetWorldIconColor(worldicon, color)
1030
- mod.SetWorldIconImage(worldicon, mod.WorldIconImages.Triangle)
1031
- mod.EnableWorldIconImage(worldicon, false)
1032
- mod.SetWorldIconOwner(worldicon, mod.GetTeam(this.#playerprofile.player))
1033
- this.checkpointWorldIcons.push(worldicon)
1034
- });
1035
- }
1036
-
1037
-
1038
- Hide() {
1039
- this.checkpointWorldIcons.forEach(worldicon => {
1040
- mod.EnableWorldIconImage(worldicon, false)
1041
- });
1042
- }
1043
-
1044
- async Refresh() {
1045
- if (!this.#playerprofile.completedTrack) {
1046
- this.Hide()
1047
-
1048
- await mod.Wait(1)
1049
-
1050
- this.checkpointWorldIcons.forEach(worldicon => {
1051
- mod.EnableWorldIconImage(worldicon, true)
1052
- mod.GetObjectPosition(worldicon)
1053
- });
1054
- }
1055
- }
1056
-
1057
- Update(checkpointposition: Vector3, nextcheckpointPosition: Vector3, circleSize: number = this.circleSize) {
1058
- console.log("Update world icon positions")
1059
-
1060
- const checkpointWidgets = generatePointsInACircle(checkpointposition, nextcheckpointPosition, circleSize, this.amountoficons)
1061
-
1062
- for (let index = 0; index < this.checkpointWorldIcons.length; index++) {
1063
-
1064
- const position = checkpointWidgets[index]
1065
- const widget = this.checkpointWorldIcons[index]
1066
-
1067
- mod.SetWorldIconPosition(widget, mod.CreateVector(position.x, position.y, position.z))
1068
- mod.EnableWorldIconImage(widget, true)
1069
- }
1070
-
1071
- }
1072
- }
1073
-
1074
- function getLookAtRotation(from: Vector3, to: Vector3): Vector3 {
1075
- const dx = to.x - from.x;
1076
- const dy = to.y - from.y;
1077
- const dz = to.z - from.z;
1078
-
1079
- const distanceXZ = Math.sqrt(dx * dx + dz * dz);
1080
-
1081
- const pitch = Math.atan2(dy, distanceXZ);
1082
- const yaw = Math.atan2(dx, dz);
1083
- const roll = 0;
1084
-
1085
- return { x: pitch, y: yaw, z: roll };
1086
- }
1087
-
1088
- async function SpawnVFXAtPosition(targetpoint: mod.Vector, vfx: any, rotation?: mod.Vector, scale?: mod.Vector) {
1089
-
1090
-
1091
- const flareVFX = mod.SpawnObject(vfx, targetpoint, mod.CreateVector(0, 0, 0), mod.CreateVector(1, 1, 1));
1092
-
1093
- mod.EnableVFX(flareVFX, true)
1094
- }
1095
-
1096
- export async function OnVehicleSpawned(eventVehicle: mod.Vehicle) {
1097
- VehicleHandler.OnVehicleSpawned(eventVehicle)
1098
- }
1099
-
1100
- type VehicleAssignment = {
1101
- player: mod.Player;
1102
- position: mod.Vector;
1103
- vehicleSpawner: mod.VehicleSpawner;
1104
- vehicle?: mod.Vehicle;
1105
- };
1106
-
1107
- class VehicleHandler {
1108
-
1109
- static playerNeedingVehicle: VehicleAssignment[] = [];
1110
-
1111
-
1112
- static RequestVehicle(playerProfile: PlayerProfile) {
1113
- if (currentRace?.trackState == TrackState.starting || currentRace?.trackState == TrackState.running || currentRace?.trackState == TrackState.winnerFound || currentRace?.trackState == TrackState.over) {
1114
-
1115
- const currentCheckpoint = (playerProfile.checkpoint) % currentRace.checkPoints.length
1116
- const checkPoint = currentRace.checkPoints[currentCheckpoint];
1117
- if (!checkPoint) {
1118
- return;
1119
- }
1120
-
1121
- const spawnPosition = generateSpawnLine(checkPoint.checkpointStart, checkPoint.checkpointEnd, MapPlayers, checkPoint.flipdir ? "right" : "left")
1122
- const targetSpawnPoint = spawnPosition[playerProfile.playerRacerNumber]
1123
-
1124
-
1125
- const vehSpawner = mod.SpawnObject(mod.RuntimeSpawn_Common.VehicleSpawner, ConverVector3ToModVector(targetSpawnPoint.position), ConverVector3ToModVector(getLookAtRotation(targetSpawnPoint.position, targetSpawnPoint.forwardPosition)))
1126
-
1127
-
1128
- console.log("Target Spawn point " + targetSpawnPoint.position.x + " " + targetSpawnPoint.position.y + " " + targetSpawnPoint.position.z)
1129
-
1130
- VehicleHandler.playerNeedingVehicle.push({ player: playerProfile.player, position: ConverVector3ToModVector(targetSpawnPoint.position), vehicleSpawner: vehSpawner })
1131
-
1132
-
1133
- playerProfile.playerSpawnedVehSpawner = vehSpawner;
1134
-
1135
- mod.SetVehicleSpawnerVehicleType(vehSpawner, playerProfile.selectedVehicle)
1136
- mod.ForceVehicleSpawnerSpawn(vehSpawner)
1137
- }
1138
-
1139
- }
1140
-
1141
- static async OnVehicleSpawned(eventVehicle: mod.Vehicle) {
1142
-
1143
- console.log("OnVehicleSpawned")
1144
-
1145
- if (VehicleHandler.playerNeedingVehicle.length == 0) {
1146
- return;
1147
- }
1148
-
1149
- const vehiclePos = mod.GetVehicleState(eventVehicle, mod.VehicleStateVector.VehiclePosition)
1150
- let closestDistance: number | null = null;
1151
- let targetVehicleSpawner: VehicleAssignment | undefined;
1152
-
1153
- for (const veh of VehicleHandler.playerNeedingVehicle) {
1154
- const distance = mod.DistanceBetween(vehiclePos, veh.position);
1155
- console.log("Distance between vehicle and point: " + distance)
1156
- if (distance <= 25 && (closestDistance === null || distance < closestDistance)) {
1157
- closestDistance = distance;
1158
- targetVehicleSpawner = veh;
1159
- }
1160
- }
1161
-
1162
- if (targetVehicleSpawner == undefined) {
1163
- console.log("Could not find a vehicle close enough to the vehicle spawnpoint")
1164
- return
1165
- }
1166
-
1167
- const index = VehicleHandler.playerNeedingVehicle.indexOf(targetVehicleSpawner);
1168
- if (index !== -1) {
1169
- VehicleHandler.playerNeedingVehicle.splice(index, 1);
1170
- }
1171
-
1172
-
1173
- while (currentRace.IsPlayerInRace(targetVehicleSpawner.player) && !mod.GetSoldierState(targetVehicleSpawner.player, mod.SoldierStateBool.IsAlive)) {
1174
- await mod.Wait(0.1)
1175
- }
1176
-
1177
-
1178
- const pprofile = PlayerProfile.get(targetVehicleSpawner.player)
1179
- if (!pprofile) {
1180
- return
1181
- }
1182
-
1183
-
1184
- pprofile.playerSpawnedVeh = eventVehicle;
1185
-
1186
- // If player disconected remove their vehicle we just spawned.
1187
- if (!currentRace.IsPlayerInRace(targetVehicleSpawner.player)) {
1188
- pprofile.DestroyVehicle()
1189
- return
1190
- }
1191
-
1192
- const spawnOffset = mod.Add(vehiclePos, mod.CreateVector(0, 10, 0))
1193
-
1194
- mod.Teleport(targetVehicleSpawner.player, spawnOffset, 0)
1195
-
1196
- await mod.Wait(0.5)
1197
- mod.ForcePlayerToSeat(targetVehicleSpawner.player, eventVehicle, 0)
1198
-
1199
-
1200
- console.log("Vehicle ready: Seating player")
1201
- }
1202
- }
1203
-
1204
- export function ConverVector3ToModVector(vector3: Vector3): mod.Vector {
1205
- return mod.CreateVector(vector3.x, vector3.y, vector3.z)
1206
- }
1207
-
1208
- interface SpawnPoint {
1209
- position: Vector3; // point on the line
1210
- forwardPosition: Vector3; // 10 units to the left
1211
- }
1212
-
1213
- function generateSpawnLine(
1214
- start: Vector3,
1215
- end: Vector3,
1216
- count: number,
1217
- direction: "left" | "right" = "left",
1218
- distance: number = 10,
1219
- up: Vector3 = { x: 0, y: 1, z: 0 }
1220
- ): SpawnPoint[] {
1221
- if (count < 2) {
1222
- throw new Error("Count must be at least 2 to generate a line.");
1223
- }
1224
-
1225
- const spawnPoints: SpawnPoint[] = [];
1226
-
1227
- // Forward vector along line
1228
- const dx = end.x - start.x;
1229
- const dy = end.y - start.y;
1230
- const dz = end.z - start.z;
1231
- const len = Math.sqrt(dx * dx + dy * dy + dz * dz);
1232
- const forward = { x: dx / len, y: dy / len, z: dz / len };
1233
-
1234
- // Compute left = up × forward (always "left", never flipped)
1235
- const left = {
1236
- x: up.y * forward.z - up.z * forward.y,
1237
- y: up.z * forward.x - up.x * forward.z,
1238
- z: up.x * forward.y - up.y * forward.x,
1239
- };
1240
-
1241
- // Scale left vector to desired distance
1242
- const sideScaled = { x: left.x * distance, y: left.y * distance, z: left.z * distance };
1243
-
1244
- // Step size
1245
- const stepX = dx / (count - 1);
1246
- const stepY = dy / (count - 1);
1247
- const stepZ = dz / (count - 1);
1248
-
1249
- for (let i = 0; i < count; i++) {
1250
- const position = {
1251
- x: start.x + stepX * i,
1252
- y: start.y + stepY * i,
1253
- z: start.z + stepZ * i,
1254
- };
1255
-
1256
- const forwardPosition = {
1257
- x: position.x + sideScaled.x,
1258
- y: position.y + sideScaled.y,
1259
- z: position.z + sideScaled.z,
1260
- };
1261
-
1262
- spawnPoints.push({ position, forwardPosition });
1263
- }
1264
-
1265
- // Reverse array order if "right"
1266
- if (direction === "right") {
1267
- return spawnPoints.reverse();
1268
- }
1269
-
1270
- return spawnPoints;
1271
- }
1272
-
1273
- export async function OnPlayerLeaveGame(eventNumber: number) {
1274
- console.log("Player left the game. Removing invalid players")
1275
- currentRace?.PlayerLeftGame()
1276
- PlayerProfile.removeInvalidPlayers()
1277
- }
1278
-
1279
-
1280
- export async function OnPlayerDeployed(player: mod.Player) {
1281
-
1282
- try {
1283
-
1284
- //Add remove weapons code
1285
- mod.RemoveEquipment(player, mod.InventorySlots.PrimaryWeapon)
1286
- mod.RemoveEquipment(player, mod.InventorySlots.SecondaryWeapon)
1287
- mod.RemoveEquipment(player, mod.InventorySlots.GadgetOne)
1288
- mod.RemoveEquipment(player, mod.InventorySlots.GadgetTwo)
1289
- mod.RemoveEquipment(player, mod.InventorySlots.ClassGadget)
1290
-
1291
- } catch (error) {
1292
-
1293
- }
1294
-
1295
- if (mod.GetSoldierState(player, mod.SoldierStateBool.IsAISoldier) == false) {
1296
-
1297
- if (currentRace?.trackState == TrackState.selected) {
1298
- currentRace.AddPlayerToTrack(player)
1299
- currentRace.StartCountdown();
1300
-
1301
- } else if (currentRace?.trackState == TrackState.running ||
1302
- currentRace?.trackState == TrackState.winnerFound ||
1303
- currentRace?.trackState == TrackState.over) {
1304
-
1305
- const playerprofile = PlayerProfile.get(player)
1306
-
1307
- if (!currentRace.IsPlayerInRace(player)) {
1308
- currentRace.AddPlayerToTrack(player)
1309
- playerprofile?.ScoreboardUI?.open()
1310
- playerprofile?.InitRacer();
1311
- playerprofile?.UpdateWorldIconPosition();
1312
- playerprofile?.BoosterDisableUI?.Trigger()
1313
- playerprofile?.RefreshWorldIcons()
1314
-
1315
- currentRace.playersInRace.forEach(playerProfile => {
1316
- playerProfile.ScoreboardUI?.update()
1317
- })
1318
- return
1319
- }
1320
-
1321
- if (playerprofile) {
1322
- VehicleHandler.RequestVehicle(playerprofile)
1323
- playerprofile.BoosterDisableUI?.Trigger()
1324
- playerprofile.RefreshWorldIcons()
1325
- }
1326
-
1327
- }
1328
-
1329
- } else {
1330
-
1331
- if (currentRace?.trackState == TrackState.running || currentRace?.trackState == TrackState.winnerFound) {
1332
-
1333
- const position = mod.GetSoldierState(player, mod.SoldierStateVector.GetPosition)
1334
- const closesVeh = GetUnoccupiedVehicleInRange(position)
1335
-
1336
- if (closesVeh) {
1337
- mod.ForcePlayerToSeat(player, closesVeh, 0)
1338
- TargetFirstPlayer(player)
1339
- } else {
1340
- //AiStingerAmmo(player)
1341
- }
1342
-
1343
-
1344
- } else {
1345
- console.log("Debug Ai Spawned")
1346
-
1347
- mod.AIEnableShooting(player, false)
1348
- mod.AIEnableTargeting(player, false)
1349
- currentRace.AddPlayerToTrack(player)
1350
- const playerprofile = PlayerProfile.get(player)
1351
- if (playerprofile) {
1352
- playerprofile.readyUp = true;
1353
- }
1354
-
1355
- }
1356
- }
1357
-
1358
-
1359
-
1360
- }
1361
-
1362
-
1363
- async function TargetFirstPlayer(player: mod.Player) {
1364
- while (mod.IsPlayerValid(player) && currentRace.trackState == TrackState.running) {
1365
-
1366
- mod.AISetTarget(player, currentRace.playersInRace[0].player)
1367
-
1368
- await mod.Wait(0.1);
1369
- const inputduration = 5; //getRandomFloatInRange(0.1,2);
1370
- mod.AIForceFire(player, inputduration);
1371
-
1372
- //mod.AIForceFire(player,10)
1373
-
1374
- await mod.Wait(5)
1375
- }
1376
-
1377
- }
1378
-
1379
- function GetUnoccupiedVehicleInRange(pos: mod.Vector): mod.Vehicle | undefined {
1380
-
1381
- const allVeh = mod.AllVehicles();
1382
-
1383
- for (let index = 0; index < mod.CountOf(allVeh); index++) {
1384
- const veh = mod.ValueInArray(allVeh, index)
1385
- if (!mod.IsVehicleOccupied(veh)) {
1386
- const vehPos = mod.GetVehicleState(veh, mod.VehicleStateVector.VehiclePosition);
1387
- if (mod.DistanceBetween(pos, vehPos) <= 15) {
1388
- return veh;
1389
- }
1390
- }
1391
- }
1392
- console.log("Could not find vehicle close enough.")
1393
- return undefined
1394
- }
1395
-
1396
- export async function OnPlayerDied(player: mod.Player) {
1397
-
1398
- if (mod.GetSoldierState(player, mod.SoldierStateBool.IsAISoldier) == false) {
1399
-
1400
- const playerProf = PlayerProfile.get(player);
1401
-
1402
- if (playerProf) {
1403
- playerProf.DestroyVehicle()
1404
- playerProf.BoosterDisableUI?.Trigger()
1405
- }
1406
-
1407
- }
1408
- }
1409
-
1410
- function generatePointsInACircle(
1411
- center: Vector3,
1412
- lookAt: Vector3,
1413
- radius: number,
1414
- segments: number
1415
- ): Vector3[] {
1416
- const positions: Vector3[] = [];
1417
-
1418
- // Compute forward direction vector
1419
- const forward = normalizeVector(subtractVectors(lookAt, center));
1420
-
1421
- // Choose arbitrary up vector
1422
- const worldUp = { x: 0, y: 1, z: 0 };
1423
-
1424
- // Compute right vector
1425
- let right = crossProduct(worldUp, forward);
1426
- if (length(right) < 0.0001) {
1427
- // If forward is parallel to worldUp, use another up
1428
- right = crossProduct({ x: 1, y: 0, z: 0 }, forward);
1429
- }
1430
- right = normalizeVector(right);
1431
-
1432
- // Compute actual up vector perpendicular to forward and right
1433
- const up = normalizeVector(crossProduct(forward, right));
1434
-
1435
- for (let i = 0; i < segments; i++) {
1436
- const angle = (i / segments) * Math.PI * 2;
1437
- const x = Math.cos(angle) * radius;
1438
- const y = Math.sin(angle) * radius;
1439
-
1440
- const point = {
1441
- x: center.x + right.x * x + up.x * y,
1442
- y: center.y + right.y * x + up.y * y,
1443
- z: center.z + right.z * x + up.z * y,
1444
- };
1445
-
1446
- positions.push(point);
1447
- }
1448
-
1449
- return positions;
1450
- }
1451
-
1452
- function subtractVectors(a: Vector3, b: Vector3): Vector3 {
1453
- return { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z };
1454
- }
1455
-
1456
- function normalizeVector(v: Vector3): Vector3 {
1457
- const len = length(v);
1458
- return len === 0 ? { x: 0, y: 0, z: 0 } : { x: v.x / len, y: v.y / len, z: v.z / len };
1459
- }
1460
-
1461
- function crossProduct(a: Vector3, b: Vector3): Vector3 {
1462
- return {
1463
- x: a.y * b.z - a.z * b.y,
1464
- y: a.z * b.x - a.x * b.z,
1465
- z: a.x * b.y - a.y * b.x,
1466
- };
1467
- }
1468
-
1469
- function length(v: Vector3): number {
1470
- return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
1471
- }
1472
-
1473
-
1474
- export async function OnPlayerUIButtonEvent(eventPlayer: mod.Player, eventUIWidget: mod.UIWidget, eventUIButtonEvent: mod.UIButtonEvent) {
1475
-
1476
- const playerProfile = PlayerProfile.get(eventPlayer)
1477
-
1478
- if (!playerProfile) {
1479
- return
1480
- }
1481
-
1482
- playerProfile.VehicleShopUI?.OnButtonPressed(eventPlayer, eventUIWidget, eventUIButtonEvent)
1483
- }
1484
-
1485
-
1486
-
1487
- function Lerp(a: number, b: number, t: number): number {
1488
- return a + (b - a) * t;
1489
- }
1490
-
1491
-
1492
-
1493
-
1494
-
1495
- // === acePursuitRawData.ts ===
1496
-
1497
-
1498
-
1499
- const tracks: RaceTrack[] = [
1500
- {
1501
- trackId: "track_01",
1502
- name: "Quad_Chaos",
1503
- laps: 3,
1504
- availableVehicles: [mod.VehicleList.Quadbike],
1505
- gametype: GameType.race,
1506
- checkPoints: [
1507
-
1508
- ]
1509
- },
1510
- {
1511
- trackId: "track_02",
1512
- name: "Air_Lap",
1513
- laps: 1,
1514
- availableVehicles: [mod.VehicleList.F22, mod.VehicleList.F16, mod.VehicleList.JAS39],
1515
- gametype: GameType.race,
1516
- checkPoints: [
1517
- { id: 106, checkpointStart: { x: 224.177551269531, y: 185.776763916016, z: -25.1318969726563 }, checkpointEnd: { x: 88.1495590209961, y: 185.776763916016, z: 105.332855224609 }, position: { x: 547.106201171875, y: 183.570999145508, z: 453.183319091797 } },
1518
- { id: 107, checkpointStart: { x: 224.177551269531, y: 185.776763916016, z: -25.1318969726563 }, checkpointEnd: { x: 88.1495590209961, y: 185.776763916016, z: 105.332855224609 }, position: { x: 883.77880859375, y: 201.873992919922, z: 898.134033203125 } },
1519
-
1520
- { id: 108, checkpointStart: { x: 1174.2579345, y: 187.2900, z: 1043.66088 }, checkpointEnd: { x: 1047.197265625, y: 186.30224609375, z: 1181.48742675781 }, position: { x: 1552.362, y: 201.8742, z: 1429.677 } },
1521
- { id: 109, checkpointStart: { x: 1174.2579345, y: 187.2900, z: 1043.66088 }, checkpointEnd: { x: 1047.197265625, y: 186.30224609375, z: 1181.48742675781 }, position: { x: 2048.393, y: 208.4673, z: 1706.873 } },
1522
-
1523
- { id: 110, checkpointStart: { x: 2296.06323242188, y: 188.086486816406, z: 1665.53356933594 }, checkpointEnd: { x: 2205.1943359375, y: 187.098724365234, z: 1829.49523925781 }, position: { x: 2676.97, y: 208.4673, z: 1946.0 } },
1524
- { id: 111, checkpointStart: { x: 2296.06323242188, y: 188.086486816406, z: 1665.53356933594 }, checkpointEnd: { x: 2205.1943359375, y: 187.098724365234, z: 1829.49523925781 }, position: { x: 3299.96630859375, y: 261.307495117188, z: 2330.958984375 } },
1525
-
1526
- { id: 112, checkpointStart: { x: 3409.69604492188, y: 187.067138671875, z: 2247.3193359375 }, checkpointEnd: { x: 3268.25463867188, y: 186.079376220703, z: 2370.34326171875 }, position: { x: 3939.844, y: 263.038, z: 2924.436 } },
1527
- { id: 113, checkpointStart: { x: 3409.69604492188, y: 187.067138671875, z: 2247.3193359375 }, checkpointEnd: { x: 3268.25463867188, y: 186.079376220703, z: 2370.34326171875 }, position: { x: 4617.52392578125, y: 271.122009277344, z: 3677.669921875 } },
1528
-
1529
- { id: 114, checkpointStart: { x: 4671.20703125, y: 310.601776123047, z: 4259.2900390625 }, checkpointEnd: { x: 4805.0439453125, y: 310.499969482422, z: 4372.10498046875 }, position: { x: 5288.721, y: 355.434, z: 3896.095 }, },
1530
- { id: 115, checkpointStart: { x: 4671.20703125, y: 310.601776123047, z: 4259.2900390625 }, checkpointEnd: { x: 4805.0439453125, y: 310.499969482422, z: 4372.10498046875 }, position: { x: 5466.977, y: 423.387, z: 3535.378 }, },
1531
-
1532
- { id: 116, checkpointStart: { x: 5552.3984375, y: 530.694274902344, z: 3811.77294921875 }, checkpointEnd: { x: 5708.0478515625, y: 529.706481933594, z: 3722.24780273438 }, position: { x: 5326.602, y: 557.992, z: 3181.616 } },
1533
- { id: 117, checkpointStart: { x: 5552.3984375, y: 530.694274902344, z: 3811.77294921875 }, checkpointEnd: { x: 5708.0478515625, y: 529.706481933594, z: 3722.24780273438 }, position: { x: 4515.22607421875, y: 441.529144287109, z: 2739.50341796875 } },
1534
-
1535
- { id: 118, checkpointStart: { x: 4541.82080078125, y: 328.444671630859, z: 2850.97265625 }, checkpointEnd: { x: 4629.31396484375, y: 327.456909179688, z: 2685.18530273438 }, position: { x: 3970.04, y: 334.594, z: 2572.894 } },
1536
- { id: 119, checkpointStart: { x: 4541.82080078125, y: 328.444671630859, z: 2850.97265625 }, checkpointEnd: { x: 4629.31396484375, y: 327.456909179688, z: 2685.18530273438 }, position: { x: 3342.115, y: 260.9633, z: 2219.49 } },
1537
-
1538
- { id: 120, checkpointStart: { x: 3309.59326171875, y: 187.919281005859, z: 2412.44750976563 }, checkpointEnd: { x: 3450.93359375, y: 186.931518554688, z: 2289.3076171875 }, position: { x: 2624.016, y: 293.6768, z: 2070.868 }, flipdir: true },
1539
- { id: 121, checkpointStart: { x: 3309.59326171875, y: 187.919281005859, z: 2412.44750976563 }, checkpointEnd: { x: 3450.93359375, y: 186.931518554688, z: 2289.3076171875 }, position: { x: 2050.632, y: 311.7585, z: 1620.939 }, flipdir: true },
1540
-
1541
- { id: 1210, checkpointStart: { x: 2259.86279296875, y: 187.481216430664, z: 1861.27551269531 }, checkpointEnd: { x: 2349.51904296875, y: 186.493453979492, z: 1696.64758300781 }, position: { x: 1518.23, y: 323.8511, z: 1482.588 }, flipdir: true },
1542
- { id: 122, checkpointStart: { x: 2259.86279296875, y: 187.481216430664, z: 1861.27551269531 }, checkpointEnd: { x: 2349.51904296875, y: 186.493453979492, z: 1696.64758300781 }, position: { x: 1042.26672363281, y: 292.134704589844, z: 854.870483398438 }, flipdir: true },
1543
-
1544
- { id: 123, checkpointStart: { x: 1088.71118164063, y: 186.349456787109, z: 1222.66943359375 }, checkpointEnd: { x: 1216.44152832031, y: 185.361694335938, z: 1085.46325683594 }, position: { x: 393.625457763672, y: 350.244506835938, z: 96.0521240234375 }, flipdir: true },
1545
-
1546
- { id: 1230, checkpointStart: { x: 127.68977355957, y: 185.05647277832, z: 148.481643676758 }, checkpointEnd: { x: 262.190673828125, y: 183.409637451172, z: 17.2779006958008 }, position: { x: -78.9294662475586, y: 213.880004882813, z: -173.546005249023 }, flipdir: true },
1547
- { id: 124, checkpointStart: { x: 127.68977355957, y: 185.05647277832, z: 148.481643676758 }, checkpointEnd: { x: 262.190673828125, y: 183.409637451172, z: 17.2779006958008 }, position: { x: -530.65, y: 301.9926, z: -101.325 }, flipdir: true },
1548
- { id: 125, checkpointStart: { x: 127.68977355957, y: 185.05647277832, z: 148.481643676758 }, checkpointEnd: { x: 262.190673828125, y: 183.409637451172, z: 17.2779006958008 }, position: { x: -1235.055, y: 251.483, z: -262.1271 }, flipdir: true },
1549
-
1550
- { id: 126, checkpointStart: { x: -2109.8779296875, y: 483.681701660156, z: -280.909484863281 }, checkpointEnd: { x: -2105.28930664063, y: 482.693939208984, z: -468.311492919922 }, position: { x: -2510.07, y: 675.4128, z: -367.911 } },
1551
- { id: 127, checkpointStart: { x: -2109.8779296875, y: 483.681701660156, z: -280.909484863281 }, checkpointEnd: { x: -2105.28930664063, y: 482.693939208984, z: -468.311492919922 }, position: { x: -3051.823, y: 992.7201, z: -134.6379 } },
1552
- { id: 1280, checkpointStart: { x: -2109.8779296875, y: 483.681701660156, z: -280.909484863281 }, checkpointEnd: { x: -2105.28930664063, y: 482.693939208984, z: -468.311492919922 }, position: { x: -3324.713, y: 924.931, z: 221.4012 } },
1553
-
1554
- { id: 128, checkpointStart: { x: -2947.99340820313, y: 739.220336914063, z: 93.411865234375 }, checkpointEnd: { x: -3132.34106445313, y: 738.232543945313, z: 59.4026794433594 }, position: { x: -3465.781, y: 875.6663, z: 683.3296 } },
1555
- { id: 129, checkpointStart: { x: -2947.99340820313, y: 739.220336914063, z: 93.411865234375 }, checkpointEnd: { x: -3132.34106445313, y: 738.232543945313, z: 59.4026794433594 }, position: { x: -3273.344, y: 829.738, z: 973.0317 } },
1556
- { id: 130, checkpointStart: { x: -2947.99340820313, y: 739.220336914063, z: 93.411865234375 }, checkpointEnd: { x: -3132.34106445313, y: 738.232543945313, z: 59.4026794433594 }, position: { x: -2918.56, y: 751.904, z: 941.331 } },
1557
-
1558
- { id: 1300, checkpointStart: { x: -2819.57739257813, y: 607.91748046875, z: 672.408569335938 }, checkpointEnd: { x: -2648.84423828125, y: 606.9296875, z: 749.808410644531 }, position: { x: -2617.48413085938, y: 633.155151367188, z: 378.069183349609 } },
1559
- { id: 131, checkpointStart: { x: -2819.57739257813, y: 607.91748046875, z: 672.408569335938 }, checkpointEnd: { x: -2648.84423828125, y: 606.9296875, z: 749.808410644531 }, position: { x: -2477.86, y: 537.821, z: 174.285 } },
1560
-
1561
- { id: 132, checkpointStart: { x: -2157.56713867188, y: 482.034240722656, z: -155.647933959961 }, checkpointEnd: { x: -2166.33764648438, y: 481.046478271484, z: 31.6049041748047 }, position: { x: -1207.372, y: 354.4803, z: -96.10004 } },
1562
- { id: 133, checkpointStart: { x: -2157.56713867188, y: 482.034240722656, z: -155.647933959961 }, checkpointEnd: { x: -2166.33764648438, y: 481.046478271484, z: 31.6049041748047 }, position: { x: -80.90897, y: 260.4618, z: 68.27824 } },
1563
-
1564
- ]
1565
- }
1566
- ];
1567
-
1568
-
1569
- // === UI_BenjiOvertake.ts ===
1570
-
1571
-
1572
- class HoH_BenjiOvertakeUI {
1573
-
1574
- #playerprofile: PlayerProfile;
1575
-
1576
- rootwidgets: mod.UIWidget[] = [];
1577
-
1578
- constructor(playerProfile: PlayerProfile) {
1579
- this.#playerprofile = playerProfile;
1580
- this.#Create();
1581
- }
1582
-
1583
- Delete() {
1584
-
1585
- for (let index = 0; index < this.rootwidgets.length; index++) {
1586
- const element = this.rootwidgets[index];
1587
- mod.DeleteUIWidget(element)
1588
- }
1589
-
1590
- }
1591
-
1592
- Close(){
1593
- this.rootwidgets.forEach(rootwidget => {
1594
- mod.SetUIWidgetVisible(rootwidget, false)
1595
- });
1596
- }
1597
-
1598
- #Create() {
1599
- const coolahhuiname: string = "overtake_message_" + this.#playerprofile.playerProfileId;
1600
- mod.AddUIText(coolahhuiname, mod.CreateVector(0, 100, 0), mod.CreateVector(200, 40, 0), mod.UIAnchor.TopCenter, MakeMessage(mod.stringkeys.overtakenmessage), this.#playerprofile.player);
1601
- const widget = mod.FindUIWidgetWithName(coolahhuiname);
1602
- mod.SetUITextColor(widget, mod.CreateVector(0, 0, 0));
1603
- mod.SetUITextSize(widget, 40);
1604
- mod.SetUITextAnchor(widget, mod.UIAnchor.Center);
1605
- mod.SetUIWidgetPadding(widget, -100);
1606
- mod.SetUIWidgetVisible(widget, true);
1607
- mod.SetUIWidgetBgFill(widget, mod.UIBgFill.Solid);
1608
- mod.SetUIWidgetBgColor(widget, mod.CreateVector(0.678, 0.753, 0.800));
1609
- mod.SetUIWidgetBgAlpha(widget, 0.9);
1610
- mod.SetUIWidgetVisible(widget, false);
1611
- this.rootwidgets.push(widget)
1612
-
1613
- this.rootwidgets.push(this.CreateFadeLineUI(true))
1614
- this.rootwidgets.push(this.CreateFadeLineUI(false))
1615
- }
1616
-
1617
-
1618
- CreateFadeLineUI(right: boolean): mod.UIWidget {
1619
- const coolahhuiname: string = "overtake_message_line_" + right + "_" + this.#playerprofile.playerProfileId;
1620
- let horizontalOffset: number = right ? 175 : -175;
1621
- mod.AddUIContainer(coolahhuiname, mod.CreateVector(horizontalOffset, 100, 0), mod.CreateVector(150, 40, 0), mod.UIAnchor.TopCenter, this.#playerprofile.player);
1622
- let widget = mod.FindUIWidgetWithName(coolahhuiname);
1623
- mod.SetUIWidgetPadding(widget, 1);
1624
- right ? mod.SetUIWidgetBgFill(widget, mod.UIBgFill.GradientLeft) : mod.SetUIWidgetBgFill(widget, mod.UIBgFill.GradientRight);
1625
- mod.SetUIWidgetBgColor(widget, mod.CreateVector(0.678, 0.753, 0.800));
1626
- mod.SetUIWidgetBgAlpha(widget, 0.9);
1627
- mod.SetUIWidgetVisible(widget, false);
1628
-
1629
- return widget;
1630
- }
1631
-
1632
-
1633
- async Trigger() {
1634
-
1635
- if (this.FeedbackBeingShown) {
1636
- return;
1637
- }
1638
- this.FeedbackBeingShown = true;
1639
-
1640
-
1641
- mod.SetUIWidgetVisible(this.rootwidgets[0], true);
1642
- mod.SetUIWidgetBgAlpha(this.rootwidgets[0], 1);
1643
- mod.SetUITextAlpha(this.rootwidgets[0], 1);
1644
-
1645
- mod.SetUIWidgetVisible(this.rootwidgets[1], true);
1646
- mod.SetUIWidgetVisible(this.rootwidgets[2], true);
1647
- mod.SetUIWidgetBgAlpha(this.rootwidgets[1], 1);
1648
- mod.SetUIWidgetBgAlpha(this.rootwidgets[2], 1);
1649
-
1650
- await mod.Wait(2.0);
1651
- this.InterpFeedback();
1652
- await mod.Wait(5.0);
1653
-
1654
- this.FeedbackBeingShown = false;
1655
- mod.SetUIWidgetVisible(this.rootwidgets[0], false);
1656
- mod.SetUIWidgetVisible(this.rootwidgets[1], false);
1657
- mod.SetUIWidgetVisible(this.rootwidgets[2], false);
1658
- }
1659
- FeedbackBeingShown: boolean = false;
1660
- FeedbackQueued: boolean = false;
1661
-
1662
- async InterpFeedback() {
1663
-
1664
-
1665
- let currentLerpvalue: number = 0;
1666
- let lerpIncrement: number = 0;
1667
- while (currentLerpvalue < 1.0) {
1668
- if (!this.FeedbackBeingShown) break;
1669
- lerpIncrement = lerpIncrement + 0.1;
1670
- currentLerpvalue = Lerp(currentLerpvalue, 1, lerpIncrement);
1671
- mod.SetUIWidgetBgAlpha(this.rootwidgets[0], 1 - currentLerpvalue);
1672
- mod.SetUITextAlpha(this.rootwidgets[0], 1 - currentLerpvalue);
1673
- mod.SetUIWidgetBgAlpha(this.rootwidgets[1], 1 - currentLerpvalue);
1674
- mod.SetUIWidgetBgAlpha(this.rootwidgets[2], 1 - currentLerpvalue);
1675
- await mod.Wait(0.1);
1676
- }
1677
-
1678
- }
1679
-
1680
- }
1681
-
1682
- // === UI_BoosterDisabled.ts ===
1683
-
1684
-
1685
- class HoH_BoosterDisabledUI {
1686
- private currentRunId = 0;
1687
- #playerprofile: PlayerProfile;
1688
- private WidgetON = false;
1689
- rootwidgets: mod.UIWidget[] = [];
1690
- constructor(playerProfile: PlayerProfile) {
1691
- this.#playerprofile = playerProfile;
1692
- this.#Create();
1693
- }
1694
- Delete() {
1695
-
1696
- for (let index = 0; index < this.rootwidgets.length; index++) {
1697
- const element = this.rootwidgets[index];
1698
- mod.DeleteUIWidget(element)
1699
- }
1700
-
1701
- }
1702
-
1703
- Close() {
1704
- this.rootwidgets.forEach(rootwidget => {
1705
- mod.SetUIWidgetVisible(rootwidget, false)
1706
- });
1707
- }
1708
-
1709
- widgetHeightPos = 120;
1710
- widgetHorisontalPos = -170;
1711
-
1712
- #Create() {
1713
- const coolahhuiname: string = "booster_disable_message_" + this.#playerprofile.playerProfileId;
1714
- mod.AddUIText(coolahhuiname, mod.CreateVector(this.widgetHorisontalPos, this.widgetHeightPos, 0), mod.CreateVector(205, 36, 0), mod.UIAnchor.BottomCenter, MakeMessage(mod.stringkeys.boosterdisabled), this.#playerprofile.player);
1715
- const widget = mod.FindUIWidgetWithName(coolahhuiname);
1716
- mod.SetUITextColor(widget, mod.CreateVector(1, 1, 1));
1717
- mod.SetUITextSize(widget, 14);
1718
- mod.SetUITextAnchor(widget, mod.UIAnchor.Center);
1719
- mod.SetUIWidgetPadding(widget, -100);
1720
- mod.SetUIWidgetVisible(widget, true);
1721
- mod.SetUIWidgetBgFill(widget, mod.UIBgFill.Solid);
1722
- mod.SetUIWidgetBgColor(widget, mod.CreateVector(0.68, 0, 0));
1723
- mod.SetUIWidgetBgAlpha(widget, 1.0);
1724
- mod.SetUIWidgetDepth(widget, mod.UIDepth.AboveGameUI)
1725
- mod.SetUIWidgetVisible(widget, false);
1726
- this.rootwidgets.push(widget)
1727
-
1728
- }
1729
-
1730
-
1731
- async Trigger() {
1732
-
1733
- if (!mod.IsPlayerValid(this.#playerprofile.player)) return;
1734
-
1735
- const isAlive = mod.GetSoldierState(
1736
- this.#playerprofile.player,
1737
- mod.SoldierStateBool.IsAlive
1738
- );
1739
- if (!isAlive) {
1740
- mod.SetUIWidgetVisible(this.rootwidgets[0], false);
1741
- return;
1742
- }
1743
-
1744
- if (this.#playerprofile.boosterDisabled) {
1745
- mod.SetUIWidgetVisible(this.rootwidgets[0], true);
1746
- } else {
1747
- mod.SetUIWidgetVisible(this.rootwidgets[0], false);
1748
- }
1749
-
1750
- }
1751
-
1752
- }
1753
-
1754
- // === UI_EndingGameCountdown.ts ===
1755
-
1756
-
1757
-
1758
- class HoH_UIEndingGameCountdown {
1759
- #Player: PlayerProfile
1760
-
1761
- headerWidget: mod.UIWidget | undefined
1762
- textWidget: mod.UIWidget | undefined
1763
-
1764
- constructor(playerProf: PlayerProfile) {
1765
- this.#Player = playerProf;
1766
-
1767
- const bfBlueColor = [0.678, 0.753, 0.800]
1768
- const height = 35;
1769
- const width = 240;
1770
- this.headerWidget = ParseUI(
1771
- {
1772
- type: "Container",
1773
- size: [width, height],
1774
- position: [0, 155],
1775
- name: "ending_countdown_" + this.#Player.playerProfileId,
1776
- anchor: mod.UIAnchor.TopCenter,
1777
- bgFill: mod.UIBgFill.Blur,
1778
- bgColor: [0.2, 0.2, 0.3],
1779
- bgAlpha: 0.8,
1780
- playerId: playerProf.player,
1781
- visible: false,
1782
- children: [
1783
- {
1784
- type: "Text",
1785
- name: "ending_countdown_text_" + this.#Player.playerProfileId,
1786
- size: [width, height],
1787
- position: [0, 0],
1788
- anchor: mod.UIAnchor.Center,
1789
- bgFill: mod.UIBgFill.None,
1790
- textColor: bfBlueColor,
1791
- textAnchor: mod.UIAnchor.Center,
1792
- textLabel: MakeMessage(mod.stringkeys.gameending, 12),
1793
- textSize: 25
1794
- },
1795
- ]
1796
- }
1797
- )
1798
- this.textWidget = mod.FindUIWidgetWithName("ending_countdown_text_" + this.#Player.playerProfileId)
1799
- }
1800
-
1801
-
1802
- Delete() {
1803
- this.headerWidget && mod.DeleteUIWidget(this.headerWidget)
1804
- // this.textWidget && mod.DeleteUIWidget(this.textWidget)
1805
- }
1806
-
1807
-
1808
- Open(timeleft: number) {
1809
- this.headerWidget && mod.SetUIWidgetVisible(this.headerWidget, true)
1810
- this.textWidget && mod.SetUITextLabel(this.textWidget, MakeMessage(mod.stringkeys.gameending, timeleft))
1811
- }
1812
-
1813
-
1814
- update(timeleft: number) {
1815
- this.textWidget && mod.SetUITextLabel(this.textWidget, MakeMessage(mod.stringkeys.gameending, timeleft))
1816
- }
1817
-
1818
- async Close(delayclose: number = 0) {
1819
- await mod.Wait(delayclose)
1820
- this.headerWidget && mod.SetUIWidgetVisible(this.headerWidget, false)
1821
- }
1822
- }
1823
-
1824
-
1825
- // === UI_FadeInBlackScreen.ts ===
1826
-
1827
-
1828
-
1829
- class HoH_UIBlackScreen {
1830
- #Player: PlayerProfile
1831
-
1832
- #black_screen_widget: mod.UIWidget | undefined;
1833
-
1834
- fadeinTime: number = 1;
1835
- fadeOutTime: number = 1;
1836
-
1837
- constructor(playerProf: PlayerProfile) {
1838
- this.#Player = playerProf
1839
-
1840
- this.#black_screen_widget = ParseUI(
1841
- {
1842
- type: "Container",
1843
- size: [2500, 2500],
1844
- position: [0, 0],
1845
- name: "fadeScreen_" + this.#Player.playerProfileId,
1846
- anchor: mod.UIAnchor.Center,
1847
- bgFill: mod.UIBgFill.Solid,
1848
- bgColor: [0, 0, 0],
1849
- bgAlpha: 0.0,
1850
- playerId: playerProf.player
1851
- }
1852
- )
1853
- }
1854
-
1855
- Close() {
1856
- this.#black_screen_widget && mod.SetUIWidgetVisible(this.#black_screen_widget, false)
1857
- }
1858
-
1859
- Delete() {
1860
- this.#black_screen_widget && mod.DeleteUIWidget(this.#black_screen_widget)
1861
- }
1862
-
1863
- async FadeIn() {
1864
-
1865
- if (this.#black_screen_widget) {
1866
-
1867
- this.#black_screen_widget && mod.SetUIWidgetVisible(this.#black_screen_widget, true)
1868
- mod.SetUIWidgetBgAlpha(this.#black_screen_widget, 0);
1869
-
1870
-
1871
- let time = 0;
1872
-
1873
- while (time < 1) {
1874
-
1875
- time += 0.1
1876
-
1877
-
1878
- if (time > 1) {
1879
- time = 1;
1880
- }
1881
-
1882
- mod.SetUIWidgetBgAlpha(this.#black_screen_widget, time)
1883
- await mod.Wait(0.1)
1884
-
1885
- }
1886
-
1887
- mod.SetUIWidgetBgAlpha(this.#black_screen_widget, 1)
1888
-
1889
- }
1890
- }
1891
-
1892
- async FadeOut() {
1893
-
1894
- if (this.#black_screen_widget) {
1895
-
1896
- mod.SetUIWidgetBgAlpha(this.#black_screen_widget, 1);
1897
-
1898
- let time = 1;
1899
-
1900
- while (time > 0) {
1901
-
1902
- time -= 0.1
1903
-
1904
- if (time < 0) {
1905
- time = 0;
1906
- }
1907
-
1908
- mod.SetUIWidgetBgAlpha(this.#black_screen_widget, time)
1909
- await mod.Wait(0.1)
1910
-
1911
- }
1912
-
1913
- mod.SetUIWidgetBgAlpha(this.#black_screen_widget, 0);
1914
- this.#black_screen_widget && mod.SetUIWidgetVisible(this.#black_screen_widget, false)
1915
- }
1916
- }
1917
- }
1918
-
1919
- // === UI_GlobalHelpers.ts ===
1920
-
1921
-
1922
-
1923
- type UIVector = mod.Vector | number[];
1924
-
1925
- interface UIParams {
1926
- name: string;
1927
- type: string;
1928
- position: any;
1929
- size: any;
1930
- anchor: mod.UIAnchor;
1931
- parent: mod.UIWidget;
1932
- visible: boolean;
1933
- textLabel: string;
1934
- textColor: UIVector;
1935
- textAlpha: number;
1936
- textSize: number;
1937
- textAnchor: mod.UIAnchor;
1938
- padding: number;
1939
- bgColor: UIVector;
1940
- bgAlpha: number;
1941
- bgFill: mod.UIBgFill;
1942
- imageType: mod.UIImageType;
1943
- imageColor: UIVector;
1944
- imageAlpha: number;
1945
- teamId?: mod.Team;
1946
- playerId?: mod.Player;
1947
- children?: any[];
1948
- buttonEnabled: boolean;
1949
- buttonColorBase: UIVector;
1950
- buttonAlphaBase: number;
1951
- buttonColorDisabled: UIVector;
1952
- buttonAlphaDisabled: number;
1953
- buttonColorPressed: UIVector;
1954
- buttonAlphaPressed: number;
1955
- buttonColorHover: UIVector;
1956
- buttonAlphaHover: number;
1957
- buttonColorFocused: UIVector;
1958
- buttonAlphaFocused: number;
1959
- }
1960
-
1961
- function __asModVector(param: number[] | mod.Vector) {
1962
- if (Array.isArray(param))
1963
- return mod.CreateVector(param[0], param[1], param.length == 2 ? 0 : param[2]);
1964
- else
1965
- return param;
1966
- }
1967
-
1968
- function __asModMessage(param: string | mod.Message) {
1969
- if (typeof (param) === "string")
1970
- return mod.Message(param);
1971
- return param;
1972
- }
1973
-
1974
- function __fillInDefaultArgs(params: UIParams) {
1975
- if (!params.hasOwnProperty('name'))
1976
- params.name = "";
1977
- if (!params.hasOwnProperty('position'))
1978
- params.position = mod.CreateVector(0, 0, 0);
1979
- if (!params.hasOwnProperty('size'))
1980
- params.size = mod.CreateVector(100, 100, 0);
1981
- if (!params.hasOwnProperty('anchor'))
1982
- params.anchor = mod.UIAnchor.TopLeft;
1983
- if (!params.hasOwnProperty('parent'))
1984
- params.parent = mod.GetUIRoot();
1985
- if (!params.hasOwnProperty('visible'))
1986
- params.visible = true;
1987
- if (!params.hasOwnProperty('padding'))
1988
- params.padding = (params.type == "Container") ? 0 : 8;
1989
- if (!params.hasOwnProperty('bgColor'))
1990
- params.bgColor = mod.CreateVector(0.25, 0.25, 0.25);
1991
- if (!params.hasOwnProperty('bgAlpha'))
1992
- params.bgAlpha = 0.5;
1993
- if (!params.hasOwnProperty('bgFill'))
1994
- params.bgFill = mod.UIBgFill.Solid;
1995
- }
1996
-
1997
- function __setNameAndGetWidget(uniqueName: any, params: any) {
1998
- let widget = mod.FindUIWidgetWithName(uniqueName) as mod.UIWidget;
1999
- mod.SetUIWidgetName(widget, params.name);
2000
- return widget;
2001
- }
2002
-
2003
- const __cUniqueName = "----uniquename----";
2004
-
2005
- function __addUIContainer(params: UIParams) {
2006
- __fillInDefaultArgs(params);
2007
- let restrict = params.teamId ?? params.playerId;
2008
- if (restrict) {
2009
- mod.AddUIContainer(__cUniqueName,
2010
- __asModVector(params.position),
2011
- __asModVector(params.size),
2012
- params.anchor,
2013
- params.parent,
2014
- params.visible,
2015
- params.padding,
2016
- __asModVector(params.bgColor),
2017
- params.bgAlpha,
2018
- params.bgFill,
2019
- restrict);
2020
- } else {
2021
- mod.AddUIContainer(__cUniqueName,
2022
- __asModVector(params.position),
2023
- __asModVector(params.size),
2024
- params.anchor,
2025
- params.parent,
2026
- params.visible,
2027
- params.padding,
2028
- __asModVector(params.bgColor),
2029
- params.bgAlpha,
2030
- params.bgFill);
2031
- }
2032
- let widget = __setNameAndGetWidget(__cUniqueName, params);
2033
- if (params.children) {
2034
- params.children.forEach((childParams: any) => {
2035
- childParams.parent = widget;
2036
- __addUIWidget(childParams);
2037
- });
2038
- }
2039
- return widget;
2040
- }
2041
-
2042
- function __fillInDefaultTextArgs(params: UIParams) {
2043
- if (!params.hasOwnProperty('textLabel'))
2044
- params.textLabel = "";
2045
- if (!params.hasOwnProperty('textSize'))
2046
- params.textSize = 0;
2047
- if (!params.hasOwnProperty('textColor'))
2048
- params.textColor = mod.CreateVector(1, 1, 1);
2049
- if (!params.hasOwnProperty('textAlpha'))
2050
- params.textAlpha = 1;
2051
- if (!params.hasOwnProperty('textAnchor'))
2052
- params.textAnchor = mod.UIAnchor.CenterLeft;
2053
- }
2054
-
2055
- function __addUIText(params: UIParams) {
2056
- __fillInDefaultArgs(params);
2057
- __fillInDefaultTextArgs(params);
2058
- let restrict = params.teamId ?? params.playerId;
2059
- if (restrict) {
2060
- mod.AddUIText(__cUniqueName,
2061
- __asModVector(params.position),
2062
- __asModVector(params.size),
2063
- params.anchor,
2064
- params.parent,
2065
- params.visible,
2066
- params.padding,
2067
- __asModVector(params.bgColor),
2068
- params.bgAlpha,
2069
- params.bgFill,
2070
- __asModMessage(params.textLabel),
2071
- params.textSize,
2072
- __asModVector(params.textColor),
2073
- params.textAlpha,
2074
- params.textAnchor,
2075
- restrict);
2076
- } else {
2077
- mod.AddUIText(__cUniqueName,
2078
- __asModVector(params.position),
2079
- __asModVector(params.size),
2080
- params.anchor,
2081
- params.parent,
2082
- params.visible,
2083
- params.padding,
2084
- __asModVector(params.bgColor),
2085
- params.bgAlpha,
2086
- params.bgFill,
2087
- __asModMessage(params.textLabel),
2088
- params.textSize,
2089
- __asModVector(params.textColor),
2090
- params.textAlpha,
2091
- params.textAnchor);
2092
- }
2093
- return __setNameAndGetWidget(__cUniqueName, params);
2094
- }
2095
-
2096
- function __fillInDefaultImageArgs(params: any) {
2097
- if (!params.hasOwnProperty('imageType'))
2098
- params.imageType = mod.UIImageType.None;
2099
- if (!params.hasOwnProperty('imageColor'))
2100
- params.imageColor = mod.CreateVector(1, 1, 1);
2101
- if (!params.hasOwnProperty('imageAlpha'))
2102
- params.imageAlpha = 1;
2103
- }
2104
-
2105
- function __addUIImage(params: UIParams) {
2106
- __fillInDefaultArgs(params);
2107
- __fillInDefaultImageArgs(params);
2108
- let restrict = params.teamId ?? params.playerId;
2109
- if (restrict) {
2110
- mod.AddUIImage(__cUniqueName,
2111
- __asModVector(params.position),
2112
- __asModVector(params.size),
2113
- params.anchor,
2114
- params.parent,
2115
- params.visible,
2116
- params.padding,
2117
- __asModVector(params.bgColor),
2118
- params.bgAlpha,
2119
- params.bgFill,
2120
- params.imageType,
2121
- __asModVector(params.imageColor),
2122
- params.imageAlpha,
2123
- restrict);
2124
- } else {
2125
- mod.AddUIImage(__cUniqueName,
2126
- __asModVector(params.position),
2127
- __asModVector(params.size),
2128
- params.anchor,
2129
- params.parent,
2130
- params.visible,
2131
- params.padding,
2132
- __asModVector(params.bgColor),
2133
- params.bgAlpha,
2134
- params.bgFill,
2135
- params.imageType,
2136
- __asModVector(params.imageColor),
2137
- params.imageAlpha);
2138
- }
2139
- return __setNameAndGetWidget(__cUniqueName, params);
2140
- }
2141
-
2142
- function __fillInDefaultArg(params: any, argName: any, defaultValue: any) {
2143
- if (!params.hasOwnProperty(argName))
2144
- params[argName] = defaultValue;
2145
- }
2146
-
2147
- function __fillInDefaultButtonArgs(params: any) {
2148
- if (!params.hasOwnProperty('buttonEnabled'))
2149
- params.buttonEnabled = true;
2150
- if (!params.hasOwnProperty('buttonColorBase'))
2151
- params.buttonColorBase = mod.CreateVector(0.7, 0.7, 0.7);
2152
- if (!params.hasOwnProperty('buttonAlphaBase'))
2153
- params.buttonAlphaBase = 1;
2154
- if (!params.hasOwnProperty('buttonColorDisabled'))
2155
- params.buttonColorDisabled = mod.CreateVector(0.2, 0.2, 0.2);
2156
- if (!params.hasOwnProperty('buttonAlphaDisabled'))
2157
- params.buttonAlphaDisabled = 0.5;
2158
- if (!params.hasOwnProperty('buttonColorPressed'))
2159
- params.buttonColorPressed = mod.CreateVector(0.25, 0.25, 0.25);
2160
- if (!params.hasOwnProperty('buttonAlphaPressed'))
2161
- params.buttonAlphaPressed = 1;
2162
- if (!params.hasOwnProperty('buttonColorHover'))
2163
- params.buttonColorHover = mod.CreateVector(1, 1, 1);
2164
- if (!params.hasOwnProperty('buttonAlphaHover'))
2165
- params.buttonAlphaHover = 1;
2166
- if (!params.hasOwnProperty('buttonColorFocused'))
2167
- params.buttonColorFocused = mod.CreateVector(1, 1, 1);
2168
- if (!params.hasOwnProperty('buttonAlphaFocused'))
2169
- params.buttonAlphaFocused = 1;
2170
- }
2171
-
2172
- function __addUIButton(params: UIParams) {
2173
- __fillInDefaultArgs(params);
2174
- __fillInDefaultButtonArgs(params);
2175
- let restrict = params.teamId ?? params.playerId;
2176
- if (restrict) {
2177
- mod.AddUIButton(__cUniqueName,
2178
- __asModVector(params.position),
2179
- __asModVector(params.size),
2180
- params.anchor,
2181
- params.parent,
2182
- params.visible,
2183
- params.padding,
2184
- __asModVector(params.bgColor),
2185
- params.bgAlpha,
2186
- params.bgFill,
2187
- params.buttonEnabled,
2188
- __asModVector(params.buttonColorBase), params.buttonAlphaBase,
2189
- __asModVector(params.buttonColorDisabled), params.buttonAlphaDisabled,
2190
- __asModVector(params.buttonColorPressed), params.buttonAlphaPressed,
2191
- __asModVector(params.buttonColorHover), params.buttonAlphaHover,
2192
- __asModVector(params.buttonColorFocused), params.buttonAlphaFocused,
2193
- restrict);
2194
- } else {
2195
- mod.AddUIButton(__cUniqueName,
2196
- __asModVector(params.position),
2197
- __asModVector(params.size),
2198
- params.anchor,
2199
- params.parent,
2200
- params.visible,
2201
- params.padding,
2202
- __asModVector(params.bgColor),
2203
- params.bgAlpha,
2204
- params.bgFill,
2205
- params.buttonEnabled,
2206
- __asModVector(params.buttonColorBase), params.buttonAlphaBase,
2207
- __asModVector(params.buttonColorDisabled), params.buttonAlphaDisabled,
2208
- __asModVector(params.buttonColorPressed), params.buttonAlphaPressed,
2209
- __asModVector(params.buttonColorHover), params.buttonAlphaHover,
2210
- __asModVector(params.buttonColorFocused), params.buttonAlphaFocused);
2211
- }
2212
- return __setNameAndGetWidget(__cUniqueName, params);
2213
- }
2214
-
2215
- function __addUIWidget(params: UIParams) {
2216
- if (params == null)
2217
- return undefined;
2218
- if (params.type == "Container")
2219
- return __addUIContainer(params);
2220
- else if (params.type == "Text")
2221
- return __addUIText(params);
2222
- else if (params.type == "Image")
2223
- return __addUIImage(params);
2224
- else if (params.type == "Button")
2225
- return __addUIButton(params);
2226
- return undefined;
2227
- }
2228
-
2229
- function ParseUI(...params: any[]) {
2230
- let widget: mod.UIWidget | undefined;
2231
- for (let a = 0; a < params.length; a++) {
2232
- widget = __addUIWidget(params[a] as UIParams);
2233
- }
2234
- return widget;
2235
- }
2236
-
2237
- // === UI_PlacementHeader.ts ===
2238
-
2239
-
2240
-
2241
- class HoH_UIPlacementHeader {
2242
- #Player: PlayerProfile
2243
-
2244
- headerWidget: mod.UIWidget | undefined
2245
- textWidget: mod.UIWidget | undefined
2246
-
2247
- constructor(playerProf: PlayerProfile) {
2248
- this.#Player = playerProf;
2249
-
2250
- const bfBlueColor = [0.678, 0.753, 0.800]
2251
- const height = 100;
2252
- const width = 500;
2253
- this.headerWidget = ParseUI(
2254
- {
2255
- type: "Container",
2256
- size: [width, height],
2257
- position: [0, 50],
2258
- name: "placement_" + this.#Player.playerProfileId,
2259
- anchor: mod.UIAnchor.TopCenter,
2260
- bgFill: mod.UIBgFill.Blur,
2261
- bgColor: [0.2, 0.2, 0.3],
2262
- bgAlpha: 0.9,
2263
- playerId: playerProf.player,
2264
- visible: false,
2265
- children: [
2266
- {
2267
- type: "Container",
2268
- name: "placement_line_right_" + this.#Player.playerProfileId,
2269
- size: [2, height],
2270
- position: [width / 2, 0],
2271
- anchor: mod.UIAnchor.Center,
2272
- bgFill: mod.UIBgFill.Solid,
2273
- bgColor: bfBlueColor,
2274
- bgAlpha: 1
2275
- },
2276
- {
2277
- type: "Container",
2278
- name: "placement_line_left_" + this.#Player.playerProfileId,
2279
- size: [2, height],
2280
- position: [-width / 2, 0],
2281
- anchor: mod.UIAnchor.Center,
2282
- bgFill: mod.UIBgFill.Solid,
2283
- bgColor: bfBlueColor,
2284
- bgAlpha: 1
2285
- },
2286
- {
2287
- type: "Text",
2288
- name: "placement_text" + this.#Player.playerProfileId,
2289
- size: [width, height],
2290
- position: [0, 0],
2291
- anchor: mod.UIAnchor.Center,
2292
- bgFill: mod.UIBgFill.None,
2293
- textColor: bfBlueColor,
2294
- textAnchor: mod.UIAnchor.Center,
2295
- textLabel: MakeMessage(mod.stringkeys.header_placement, 0),
2296
- textSize: 45
2297
- },
2298
- ]
2299
- }
2300
- )
2301
- this.textWidget = mod.FindUIWidgetWithName("placement_text" + this.#Player.playerProfileId)
2302
- }
2303
-
2304
-
2305
- Delete() {
2306
- this.headerWidget && mod.DeleteUIWidget(this.headerWidget)
2307
- //this.textWidget && mod.DeleteUIWidget(this.textWidget)
2308
- }
2309
-
2310
- Open(text: string, placement: number, scale: number) {
2311
- this.headerWidget && mod.SetUIWidgetVisible(this.headerWidget, true)
2312
- this.textWidget && mod.SetUITextLabel(this.textWidget, MakeMessage(text, placement))
2313
- this.textWidget && mod.SetUITextSize(this.textWidget, scale)
2314
- }
2315
-
2316
- update() {
2317
- }
2318
-
2319
- async Close(delayclose: number = 0) {
2320
- await mod.Wait(delayclose)
2321
- this.headerWidget && mod.SetUIWidgetVisible(this.headerWidget, false)
2322
- }
2323
-
2324
- }
2325
-
2326
- // === UI_Scoreboard.ts ===
2327
-
2328
-
2329
-
2330
- class HoH_ScoreboardUI {
2331
-
2332
- #playerProfile: PlayerProfile;
2333
- #CoreWidget: mod.UIWidget | undefined;
2334
-
2335
- #scoreboardPlacement_text: mod.UIWidget | undefined
2336
-
2337
- #ScoreboardplayerName: mod.UIWidget[] = []
2338
- #ScoreboardPlacement: mod.UIWidget[] = []
2339
- #ScoreboardTimeOne: mod.UIWidget[] = []
2340
- #ScoreboardTimeTwo: mod.UIWidget[] = []
2341
-
2342
- constructor(playerprofile: PlayerProfile) {
2343
- this.#playerProfile = playerprofile
2344
- this.Create()
2345
- }
2346
-
2347
-
2348
- Delete() {
2349
- this.#CoreWidget && mod.DeleteUIWidget(this.#CoreWidget)
2350
- }
2351
-
2352
-
2353
- update() {
2354
- console.log("Update Scoreboard positions")
2355
-
2356
- this.#CoreWidget && mod.SetUIWidgetVisible(this.#CoreWidget, true)
2357
-
2358
- const playerPositionInRace = currentRace.playersInRace.indexOf(this.#playerProfile)
2359
-
2360
- this.#scoreboardPlacement_text && mod.SetUITextLabel(this.#scoreboardPlacement_text, MakeMessage(mod.stringkeys.position_in_race, playerPositionInRace + 1, currentRace.playersInRace.length))
2361
-
2362
- for (let index = 0; index < this.#ScoreboardplayerName.length; index++) {
2363
- const playerInPos = this.indexExists(currentRace.playersInRace, index)
2364
-
2365
-
2366
- if (playerInPos) {
2367
-
2368
- const playerProf = currentRace.playersInRace[index];
2369
- const playerTime = playerProf.playerRaceTime;
2370
-
2371
- if (playerTime) {
2372
- const formatTime = this.FormatTime(playerTime - currentRace.raceTime)
2373
-
2374
- mod.SetUITextLabel(this.#ScoreboardTimeOne[index], MakeMessage(mod.stringkeys.scoreboard_1_time_1, formatTime[0], formatTime[1]))
2375
- mod.SetUITextLabel(this.#ScoreboardTimeTwo[index], MakeMessage(mod.stringkeys.scoreboard_1_time_2, formatTime[2], formatTime[3], formatTime[4]))
2376
-
2377
- mod.SetUIWidgetVisible(this.#ScoreboardTimeOne[index], true)
2378
- mod.SetUIWidgetVisible(this.#ScoreboardTimeTwo[index], true)
2379
- } else {
2380
- mod.SetUIWidgetVisible(this.#ScoreboardTimeOne[index], false)
2381
- mod.SetUIWidgetVisible(this.#ScoreboardTimeTwo[index], false)
2382
- }
2383
-
2384
- mod.SetUIWidgetVisible(this.#ScoreboardplayerName[index], true)
2385
- mod.SetUIWidgetVisible(this.#ScoreboardPlacement[index], true)
2386
-
2387
-
2388
- mod.SetUITextLabel(this.#ScoreboardplayerName[index], MakeMessage(mod.stringkeys.scoreboard_1_name, currentRace.playersInRace[index].player))
2389
-
2390
-
2391
- if (currentRace.trackState == TrackState.selected) {
2392
- //Makes the players name green when ready
2393
- if (playerProf.readyUp) {
2394
- mod.SetUITextColor(this.#ScoreboardplayerName[index], mod.CreateVector(0.4196, 0.9098, 0.0745))
2395
- mod.SetUITextColor(this.#ScoreboardPlacement[index], mod.CreateVector(0.4196, 0.9098, 0.0745))
2396
- mod.SetUITextColor(this.#ScoreboardTimeOne[index], mod.CreateVector(0.4196, 0.9098, 0.0745))
2397
- mod.SetUITextColor(this.#ScoreboardTimeTwo[index], mod.CreateVector(0.4196, 0.9098, 0.0745))
2398
- } else {
2399
- mod.SetUITextColor(this.#ScoreboardplayerName[index], mod.CreateVector(0.678, 0.753, 0.800))
2400
- mod.SetUITextColor(this.#ScoreboardPlacement[index], mod.CreateVector(0.678, 0.753, 0.800))
2401
- mod.SetUITextColor(this.#ScoreboardTimeOne[index], mod.CreateVector(0.678, 0.753, 0.800))
2402
- mod.SetUITextColor(this.#ScoreboardTimeTwo[index], mod.CreateVector(0.678, 0.753, 0.800))
2403
- }
2404
-
2405
- } else if (index == playerPositionInRace) {
2406
- mod.SetUITextColor(this.#ScoreboardplayerName[index], mod.CreateVector(1, 1, 0))
2407
- mod.SetUITextColor(this.#ScoreboardPlacement[index], mod.CreateVector(1, 1, 0))
2408
- mod.SetUITextColor(this.#ScoreboardTimeOne[index], mod.CreateVector(1, 1, 0))
2409
- mod.SetUITextColor(this.#ScoreboardTimeTwo[index], mod.CreateVector(1, 1, 0))
2410
- } else {
2411
- mod.SetUITextColor(this.#ScoreboardplayerName[index], mod.CreateVector(0.678, 0.753, 0.800))
2412
- mod.SetUITextColor(this.#ScoreboardPlacement[index], mod.CreateVector(0.678, 0.753, 0.800))
2413
- mod.SetUITextColor(this.#ScoreboardTimeOne[index], mod.CreateVector(0.678, 0.753, 0.800))
2414
- mod.SetUITextColor(this.#ScoreboardTimeTwo[index], mod.CreateVector(0.678, 0.753, 0.800))
2415
- }
2416
-
2417
- } else {
2418
-
2419
- mod.SetUIWidgetVisible(this.#ScoreboardplayerName[index], false)
2420
- mod.SetUIWidgetVisible(this.#ScoreboardPlacement[index], false)
2421
- mod.SetUIWidgetVisible(this.#ScoreboardTimeOne[index], false)
2422
- mod.SetUIWidgetVisible(this.#ScoreboardTimeTwo[index], false)
2423
- }
2424
-
2425
- }
2426
- }
2427
-
2428
- indexExists<T>(array: T[], index: number): boolean {
2429
- return index >= 0 && index < array.length;
2430
- }
2431
-
2432
- FormatTime(time: number,): number[] {
2433
-
2434
-
2435
- const minutes = Math.floor(time / 60);
2436
- const seconds = Math.floor(time % 60);
2437
- const tenths = Math.floor((time % 1) * 10);
2438
-
2439
- const result: number[] = [];
2440
-
2441
- // Ensure minutes are always 2 digits
2442
- result.push(Math.floor(minutes / 10));
2443
- result.push(minutes % 10);
2444
-
2445
- // Ensure seconds are always 2 digits
2446
- result.push(Math.floor(seconds / 10));
2447
- result.push(seconds % 10);
2448
-
2449
- // Tenths is always 1 digit
2450
- result.push(tenths);
2451
-
2452
- return result;
2453
- }
2454
-
2455
- Create() {
2456
-
2457
- console.log("Creating Scoreboard UI")
2458
- let children = []
2459
-
2460
- const ScoreboardplayerPlacement = `Scoreboard2Placement_text_${this.#playerProfile.playerProfileId}`
2461
-
2462
- const Scoreboardlaps = `Scoreboard2laps_text_${this.#playerProfile.playerProfileId}`
2463
-
2464
- children.push(
2465
- {
2466
- type: "Text",
2467
- name: ScoreboardplayerPlacement,
2468
- textLabel: MakeMessage(mod.stringkeys.position_in_race, 1, MapPlayers),
2469
- position: [0, -180, 1],
2470
- size: [170, 140, 0],
2471
- textSize: 110,
2472
- bgFill: mod.UIBgFill.Blur,
2473
- textColor: [0.678, 0.753, 0.800],
2474
- textAnchor: mod.UIAnchor.Center,
2475
- anchor: mod.UIAnchor.TopLeft,
2476
- visible: true
2477
- }
2478
- )
2479
-
2480
- for (let index = 0; index < MapPlayers; index++) {
2481
-
2482
- const ScoreboardplayerName = `Scoreboard2playerName${index}text_${this.#playerProfile.playerProfileId}`
2483
- const ScoreboardPlacement = `Scoreboard2Placement${index}text_${this.#playerProfile.playerProfileId}`
2484
- const ScoreboardTimeOne = `Scoreboard2TimeOne${index}text_${this.#playerProfile.playerProfileId}`
2485
- const ScoreboardTimeTwo = `Scoreboard2TimeTwo${index}text_${this.#playerProfile.playerProfileId}`
2486
-
2487
- const rowPadding = 30;
2488
- const startY = -125
2489
- const y = startY + index * rowPadding;
2490
-
2491
- const textBoxHeight = 30;
2492
-
2493
- const textSize = 20;
2494
- const textNameSize = 15;
2495
- const timeSize = 15;
2496
-
2497
- children.push(
2498
- {
2499
- type: "Text",
2500
- name: ScoreboardPlacement,
2501
- textLabel: MakeMessage(mod.stringkeys.scoreboard_1_name, index + 1),
2502
- position: [-15, y, 1],
2503
- size: [30, textBoxHeight, 0],
2504
- textSize: textSize,
2505
- bgFill: mod.UIBgFill.Blur,
2506
- textColor: [0.678, 0.753, 0.800],
2507
- textAnchor: mod.UIAnchor.CenterLeft,
2508
- anchor: mod.UIAnchor.CenterLeft,
2509
- visible: true
2510
- },
2511
- {
2512
- type: "Text",
2513
- name: ScoreboardplayerName,
2514
- textLabel: MakeMessage(mod.stringkeys.X),
2515
- position: [20, y, 1],
2516
- size: [200, textBoxHeight, 0],
2517
- textSize: textNameSize,
2518
- bgFill: mod.UIBgFill.Blur,
2519
- textColor: [0.678, 0.753, 0.800],
2520
- textAnchor: mod.UIAnchor.CenterLeft,
2521
- anchor: mod.UIAnchor.CenterLeft,
2522
- visible: true
2523
- },
2524
- {
2525
- type: "Text",
2526
- name: ScoreboardTimeOne,
2527
- textLabel: MakeMessage(mod.stringkeys.X),
2528
- position: [160, y, 1],
2529
- size: [250, textBoxHeight, 0],
2530
- textSize: timeSize,
2531
- bgFill: mod.UIBgFill.None,
2532
- textColor: [0.678, 0.753, 0.800],
2533
- textAnchor: mod.UIAnchor.CenterLeft,
2534
- anchor: mod.UIAnchor.CenterLeft,
2535
- visible: true
2536
-
2537
- },
2538
- {
2539
- type: "Text",
2540
- name: ScoreboardTimeTwo,
2541
- textLabel: MakeMessage(mod.stringkeys.X),
2542
- position: [180, y, 1],
2543
- size: [250, textBoxHeight, 0],
2544
- textSize: timeSize,
2545
- bgFill: mod.UIBgFill.None,
2546
- textColor: [0.678, 0.753, 0.800],
2547
- textAnchor: mod.UIAnchor.CenterLeft,
2548
- anchor: mod.UIAnchor.CenterLeft,
2549
- visible: true
2550
-
2551
- }
2552
- )
2553
-
2554
- }
2555
-
2556
- const scoreboardContainerWidget = ParseUI({
2557
- type: "Container",
2558
- name: `scoreboard_Container_${this.#playerProfile.playerProfileId}`,
2559
- position: [0, -200, 0],
2560
- size: [250, 300, 0],
2561
- anchor: mod.UIAnchor.CenterLeft,
2562
- bgColor: [1, 1, 1],
2563
- bgFill: mod.UIBgFill.None,
2564
- bgAlpha: 1,
2565
- padding: 20,
2566
- children: children,
2567
- playerId: this.#playerProfile.player,
2568
- visible: false
2569
- })
2570
-
2571
-
2572
- this.#CoreWidget = scoreboardContainerWidget;
2573
- this.#scoreboardPlacement_text = mod.FindUIWidgetWithName(ScoreboardplayerPlacement)
2574
-
2575
- for (let index = 0; index < MapPlayers; index++) {
2576
-
2577
- const ScoreboardPlacement = `Scoreboard2Placement${index}text_${this.#playerProfile.playerProfileId}`
2578
- const ScoreboardplayerName = `Scoreboard2playerName${index}text_${this.#playerProfile.playerProfileId}`
2579
- const ScoreboardTimeOne = `Scoreboard2TimeOne${index}text_${this.#playerProfile.playerProfileId}`
2580
- const ScoreboardTimeTwo = `Scoreboard2TimeTwo${index}text_${this.#playerProfile.playerProfileId}`
2581
-
2582
- this.#ScoreboardPlacement.push(mod.FindUIWidgetWithName(ScoreboardPlacement))
2583
- this.#ScoreboardplayerName.push(mod.FindUIWidgetWithName(ScoreboardplayerName))
2584
- this.#ScoreboardTimeOne.push(mod.FindUIWidgetWithName(ScoreboardTimeOne))
2585
- this.#ScoreboardTimeTwo.push(mod.FindUIWidgetWithName(ScoreboardTimeTwo))
2586
- }
2587
-
2588
-
2589
- //Extra settings
2590
- this.#CoreWidget && mod.SetUIWidgetDepth(this.#CoreWidget, mod.UIDepth.BelowGameUI)
2591
- }
2592
-
2593
- open() {
2594
- if (this.#CoreWidget == undefined) {
2595
- this.Create()
2596
- }
2597
-
2598
- this.update()
2599
-
2600
- this.#CoreWidget && mod.SetUIWidgetVisible(this.#CoreWidget, true)
2601
- }
2602
-
2603
-
2604
- Close() {
2605
- this.#CoreWidget && mod.SetUIWidgetVisible(this.#CoreWidget, false)
2606
- }
2607
-
2608
- }
2609
-
2610
- // === UI_StartCountdown.ts ===
2611
-
2612
-
2613
-
2614
- class HoH_UIStartCountdown {
2615
- #Player: PlayerProfile
2616
-
2617
- headerWidget: mod.UIWidget | undefined
2618
- textWidget: mod.UIWidget | undefined
2619
-
2620
- constructor(playerProf: PlayerProfile) {
2621
- this.#Player = playerProf;
2622
-
2623
- const bfBlueColor = [0.678, 0.753, 0.800]
2624
- const height = 125;
2625
- this.headerWidget = ParseUI(
2626
- {
2627
- type: "Container",
2628
- size: [150, height],
2629
- position: [0, 50],
2630
- name: "start_countdown_" + this.#Player.playerProfileId,
2631
- anchor: mod.UIAnchor.TopCenter,
2632
- bgFill: mod.UIBgFill.Blur,
2633
- bgColor: [0.2, 0.2, 0.3],
2634
- bgAlpha: 0.9,
2635
- playerId: playerProf.player,
2636
- visible: false,
2637
- children: [
2638
- {
2639
- type: "Container",
2640
- name: "start_countdown_line_right_" + this.#Player.playerProfileId,
2641
- size: [2, height],
2642
- position: [75, 0],
2643
- anchor: mod.UIAnchor.Center,
2644
- bgFill: mod.UIBgFill.Solid,
2645
- bgColor: bfBlueColor,
2646
- bgAlpha: 1
2647
- },
2648
- {
2649
- type: "Container",
2650
- name: "start_countdown_line_left_" + this.#Player.playerProfileId,
2651
- size: [2, height],
2652
- position: [-75, 0],
2653
- anchor: mod.UIAnchor.Center,
2654
- bgFill: mod.UIBgFill.Solid,
2655
- bgColor: bfBlueColor,
2656
- bgAlpha: 1
2657
- },
2658
- {
2659
- type: "Text",
2660
- name: "start_countdown_text" + this.#Player.playerProfileId,
2661
- size: [100, height],
2662
- position: [0, 0],
2663
- anchor: mod.UIAnchor.Center,
2664
- bgFill: mod.UIBgFill.None,
2665
- textColor: bfBlueColor,
2666
- textAnchor: mod.UIAnchor.Center,
2667
- textLabel: MakeMessage(mod.stringkeys.scoreboard_1_name),
2668
- textSize: 85
2669
- }
2670
- ]
2671
- }
2672
- )
2673
- this.textWidget = mod.FindUIWidgetWithName("start_countdown_text" + this.#Player.playerProfileId)
2674
- }
2675
-
2676
-
2677
- Delete() {
2678
- this.headerWidget && mod.DeleteUIWidget(this.headerWidget)
2679
- //this.textWidget && mod.DeleteUIWidget(this.textWidget)
2680
- }
2681
-
2682
- Open(text: string, countdowntime: number) {
2683
- this.headerWidget && mod.SetUIWidgetVisible(this.headerWidget, true)
2684
- this.textWidget && mod.SetUITextLabel(this.textWidget, MakeMessage(text, countdowntime))
2685
- }
2686
-
2687
-
2688
- update(text: string, countdowntime: number) {
2689
- this.textWidget && mod.SetUITextLabel(this.textWidget, MakeMessage(text, countdowntime))
2690
- }
2691
-
2692
- async Close(delayclose: number = 0) {
2693
- await mod.Wait(delayclose)
2694
- this.headerWidget && mod.SetUIWidgetVisible(this.headerWidget, false)
2695
- }
2696
-
2697
- }
2698
-
2699
- // === UI_VehicleSelect.ts ===
2700
-
2701
-
2702
-
2703
- type HoH_ClickFunction = () => void;
2704
- type HoH_FocusFunction = (focusIn: boolean) => void;
2705
-
2706
-
2707
- const VehiclePositions = [
2708
- { x: 217.841003417969, y: 227.279006958008, z: 558.077026367188 },
2709
- { x: 242.748123168945, y: 228.753005981445, z: 563.011169433594 },
2710
- { x: 268.551696777344, y: 228.162994384766, z: 568.041442871094 }
2711
- ]
2712
-
2713
- const playerVehicleSelectPositions = [
2714
- [
2715
- { x: 214.76530456543, y: 227.879440307617, z: 571.411010742188 },
2716
- { x: 228.050430297852, y: 227.879440307617, z: 573.903076171875 }
2717
- ],
2718
- [
2719
- { x: 241.145736694336, y: 227.879440307617, z: 577.202758789063 },
2720
- { x: 254.34407043457, y: 227.879440307617, z: 580.119812011719 }
2721
- ],
2722
- [
2723
- { x: 265.234405517578, y: 227.879440307617, z: 581.415283203125 },
2724
- { x: 278.574584960938, y: 227.879440307617, z: 583.592895507813 }
2725
- ]
2726
-
2727
- ]
2728
-
2729
- class HoH_UIButtonHolder {
2730
-
2731
- playerProfile: PlayerProfile;
2732
-
2733
- button_id: string
2734
- button_widget: mod.UIWidget
2735
-
2736
- button_text_id: string
2737
- button_text_widget: mod.UIWidget
2738
-
2739
- select_text_id: string | undefined
2740
- select_widget: mod.UIWidget | undefined
2741
-
2742
- click: HoH_ClickFunction;
2743
- focus: HoH_FocusFunction;
2744
-
2745
- constructor(playerProfile: PlayerProfile, uniqueButtonName: string, uniqueTextName: string, uniqueSelectName?: string, clickFunction?: HoH_ClickFunction, focusFunction?: HoH_FocusFunction) {
2746
- this.button_id = uniqueButtonName;
2747
- this.button_widget = mod.FindUIWidgetWithName(uniqueButtonName);
2748
- this.button_text_id = uniqueTextName;
2749
- this.button_text_widget = mod.FindUIWidgetWithName(uniqueTextName);
2750
- this.playerProfile = playerProfile;
2751
-
2752
- if (uniqueSelectName) {
2753
- this.select_text_id = uniqueSelectName;
2754
- this.select_widget = mod.FindUIWidgetWithName(uniqueSelectName)
2755
- }
2756
-
2757
- if (focusFunction) {
2758
- mod.EnableUIButtonEvent(this.button_widget, mod.UIButtonEvent.FocusIn, true)
2759
- mod.EnableUIButtonEvent(this.button_widget, mod.UIButtonEvent.FocusOut, true)
2760
- }
2761
-
2762
- this.focus = focusFunction?.bind(this) ?? this.defaultFocus;
2763
- this.click = clickFunction?.bind(this) ?? this.defaultClick;
2764
- }
2765
-
2766
- defaultClick() { console.log("default Click") }
2767
- defaultFocus() { console.log("default focus") }
2768
-
2769
- }
2770
-
2771
- class HoH_UIVehicleSelect {
2772
-
2773
- #Left_Button_Holder: HoH_UIButtonHolder | undefined = undefined;
2774
- #Right_Button_Holder: HoH_UIButtonHolder | undefined = undefined;
2775
-
2776
- #Readyup_Button_Holder: HoH_UIButtonHolder | undefined = undefined;
2777
-
2778
- #LEFT_BUTTON: string
2779
- #LEFT_BUTTON_TEXT: string
2780
- #LEFT_BUTTON_SELECTED: string
2781
-
2782
- #RIGHT_BUTTON: string
2783
- #RIGHT_BUTTON_TEXT: string
2784
- #RIGHT_BUTTON_SELECTED: string
2785
-
2786
- #RootWidgets: mod.UIWidget[] = []
2787
-
2788
- #PLAYERS_WAITING_TEXT: string;
2789
- #players_ready_text_widget: mod.UIWidget | undefined;
2790
-
2791
- #PLAYERS_READY_COUNT_TEXT: string
2792
- #players_ready_count_widget: mod.UIWidget | undefined;
2793
-
2794
- #CURRENT_SELECT_VEH_TEXT: string;
2795
- #current_select_veh_Widget: mod.UIWidget | undefined;
2796
-
2797
- #READYUP_BUTTON: string
2798
- #READYUP_BUTTON_TEXT: string
2799
- #READYUP_BUTTON_SELECT: string
2800
-
2801
- #readyup_button_widget: mod.UIWidget | undefined;
2802
-
2803
- #playerProfile: PlayerProfile;
2804
-
2805
- UIOpen: boolean = false;
2806
-
2807
- selectVehNb: number = 0
2808
-
2809
-
2810
- constructor(player: PlayerProfile) {
2811
- this.#playerProfile = player;
2812
-
2813
- this.#LEFT_BUTTON = `left_veh_button_${this.#playerProfile.playerProfileId}`
2814
- this.#LEFT_BUTTON_TEXT = `left_veh_button_text_${this.#playerProfile.playerProfileId}`
2815
- this.#LEFT_BUTTON_SELECTED = `left_veh_button_selected_${this.#playerProfile.playerProfileId}`
2816
-
2817
- this.#RIGHT_BUTTON = `right_veh_button_${this.#playerProfile.playerProfileId}`
2818
- this.#RIGHT_BUTTON_TEXT = `right_veh_button_text_${this.#playerProfile.playerProfileId}`
2819
- this.#RIGHT_BUTTON_SELECTED = `right_veh_button_select_${this.#playerProfile.playerProfileId}`
2820
-
2821
- this.#READYUP_BUTTON = `readyup_veh_button_${this.#playerProfile.playerProfileId}`
2822
- this.#READYUP_BUTTON_TEXT = `readyup_veh_button_text_${this.#playerProfile.playerProfileId}`
2823
- this.#READYUP_BUTTON_SELECT = `readyup_veh_button_select_text_${this.#playerProfile.playerProfileId}`
2824
-
2825
- this.#PLAYERS_READY_COUNT_TEXT = `players_ready_count_text_${this.#playerProfile.playerProfileId}`
2826
- this.#CURRENT_SELECT_VEH_TEXT = `current_select_veh_text_${this.#playerProfile.playerProfileId}`
2827
- this.#PLAYERS_WAITING_TEXT = `players_waiting_text_${this.#playerProfile.playerProfileId}`
2828
-
2829
- this.selectVehNb = currentRace.availableVehicles.indexOf(this.#playerProfile.selectedVehicle)
2830
- }
2831
-
2832
- UIUpdatePlayersReady() {
2833
- const { ready, total } = currentRace.GetPlayersReady();
2834
- this.#players_ready_count_widget && mod.SetUITextLabel(this.#players_ready_count_widget, MakeMessage(mod.stringkeys.readyplayers, ready, total))
2835
-
2836
- if (total < MinimumPlayerToStart) {
2837
- this.#players_ready_text_widget && mod.SetUITextLabel(this.#players_ready_text_widget, MakeMessage(mod.stringkeys.waitingforplayersX, total, MapPlayers, MinimumPlayerToStart))
2838
-
2839
- }
2840
-
2841
- this.#players_ready_text_widget && mod.SetUITextLabel(this.#players_ready_text_widget, MakeMessage(mod.stringkeys.startsin, currentRace.readyupCountDown))
2842
-
2843
-
2844
- currentRace.UpdateScoreboard()
2845
- }
2846
-
2847
- EnableSwitchButtons(enabled: boolean) {
2848
- this.#Left_Button_Holder && mod.SetUIButtonEnabled(this.#Left_Button_Holder.button_widget, enabled)
2849
- this.#Right_Button_Holder && mod.SetUIButtonEnabled(this.#Right_Button_Holder.button_widget, enabled)
2850
-
2851
- if (enabled) {
2852
- this.#Readyup_Button_Holder && mod.SetUIWidgetBgColor(this.#Readyup_Button_Holder.button_widget, mod.CreateVector(1, 1, 1))
2853
- this.#Left_Button_Holder && mod.SetUIWidgetVisible(this.#Left_Button_Holder.button_widget, true)
2854
- this.#Right_Button_Holder && mod.SetUIWidgetVisible(this.#Right_Button_Holder.button_widget, true)
2855
- } else {
2856
- this.#Readyup_Button_Holder && mod.SetUIWidgetBgColor(this.#Readyup_Button_Holder.button_widget, mod.CreateVector(0.4196, 0.9098, 0.0745))
2857
- this.#Left_Button_Holder && mod.SetUIWidgetVisible(this.#Left_Button_Holder.button_widget, false)
2858
- this.#Right_Button_Holder && mod.SetUIWidgetVisible(this.#Right_Button_Holder.button_widget, false)
2859
- }
2860
- }
2861
-
2862
- VehicleSelectIncrease() {
2863
- if (this.selectVehNb > 0) {
2864
-
2865
- this.selectVehNb--;
2866
- this.cameraTeleport();
2867
- this.refresh();
2868
- }
2869
- }
2870
-
2871
- VehicleSelectDecrease() {
2872
- if (this.selectVehNb < currentRace.availableVehicles.length - 1) {
2873
-
2874
- this.selectVehNb++;
2875
- this.cameraTeleport()
2876
- this.refresh();
2877
- }
2878
- }
2879
-
2880
- #create() {
2881
-
2882
- const { ready, total } = currentRace.GetPlayersReady();
2883
-
2884
- const bfBlueColor = [0.678, 0.753, 0.800]
2885
- const buttonBgColor = [1, 1, 1]
2886
-
2887
- this.#RootWidgets.push(ParseUI({
2888
- type: "Container",
2889
- size: [500, 110],
2890
- position: [0, 75],
2891
- anchor: mod.UIAnchor.TopCenter,
2892
- bgFill: mod.UIBgFill.Blur,
2893
- bgColor: [0.2, 0.2, 0.3],
2894
- bgAlpha: 0.9,
2895
- playerId: this.#playerProfile.player,
2896
- children: [{
2897
- type: "Text",
2898
- name: this.#PLAYERS_WAITING_TEXT,
2899
- size: [500, 110],
2900
- position: [0, -28],
2901
- anchor: mod.UIAnchor.Center,
2902
- bgFill: mod.UIBgFill.None,
2903
- textColor: bfBlueColor,
2904
- textAnchor: mod.UIAnchor.Center,
2905
- textLabel: MakeMessage(mod.stringkeys.startsin, currentRace.readyupCountDown),
2906
- textSize: 38
2907
- },
2908
- {
2909
- type: "Text",
2910
- name: this.#PLAYERS_READY_COUNT_TEXT,
2911
- size: [250, 110],
2912
- position: [0, 25],
2913
- anchor: mod.UIAnchor.Center,
2914
- textColor: bfBlueColor,
2915
- bgFill: mod.UIBgFill.None,
2916
- textAnchor: mod.UIAnchor.Center,
2917
- textLabel: MakeMessage(mod.stringkeys.readyplayers, ready, total),
2918
- textSize: 24
2919
- },
2920
- {
2921
- type: "Container",
2922
- name: this.#PLAYERS_READY_COUNT_TEXT + "_left_side_line",
2923
- size: [1, 110],
2924
- position: [-252, 0],
2925
- anchor: mod.UIAnchor.Center,
2926
- bgFill: mod.UIBgFill.Solid,
2927
- bgColor: bfBlueColor,
2928
- bgAlpha: 1
2929
- }, {
2930
- type: "Container",
2931
- name: this.#PLAYERS_READY_COUNT_TEXT + "_right_side_line",
2932
- size: [1, 110],
2933
- position: [251, 0],
2934
- anchor: mod.UIAnchor.Center,
2935
- bgFill: mod.UIBgFill.Solid,
2936
- bgColor: bfBlueColor,
2937
- bgAlpha: 1
2938
- },
2939
- {
2940
- type: "Container",
2941
- name: this.#PLAYERS_READY_COUNT_TEXT + "_middle_line",
2942
- size: [425, 3],
2943
- position: [0, 0],
2944
- anchor: mod.UIAnchor.Center,
2945
- bgFill: mod.UIBgFill.Solid,
2946
- bgColor: bfBlueColor,
2947
- bgAlpha: 1
2948
- },
2949
- ]
2950
- }) as mod.UIWidget)
2951
-
2952
-
2953
- this.#players_ready_text_widget = mod.FindUIWidgetWithName(this.#PLAYERS_WAITING_TEXT)
2954
- this.#players_ready_count_widget = mod.FindUIWidgetWithName(this.#PLAYERS_READY_COUNT_TEXT)
2955
-
2956
-
2957
-
2958
- this.#RootWidgets.push(ParseUI({
2959
- type: "Container",
2960
- size: [500, 100],
2961
- position: [0, 75],
2962
- anchor: mod.UIAnchor.BottomCenter,
2963
- bgFill: mod.UIBgFill.None,
2964
- bgColor: mod.CreateVector(1, 1, 1),
2965
- bgAlpha: 0.0,
2966
- playerId: this.#playerProfile.player,
2967
- children: [
2968
- {
2969
- type: "Container",
2970
- name: this.#LEFT_BUTTON_SELECTED,
2971
- size: [60, 60],
2972
- position: [-150, 0],
2973
- anchor: mod.UIAnchor.Center,
2974
- bgFill: mod.UIBgFill.OutlineThin,
2975
- bgColor: bfBlueColor,
2976
- bgAlpha: 0.8,
2977
- visible: false
2978
- },
2979
- {
2980
- type: "Button",
2981
- name: this.#LEFT_BUTTON,
2982
- size: [50, 50],
2983
- position: [-150, 0],
2984
- anchor: mod.UIAnchor.Center,
2985
- bgFill: mod.UIBgFill.Blur,
2986
- buttonColorHover: [1, 1, 1],
2987
- bgColor: [1, 1, 1],
2988
- bgAlpha: 1.0,
2989
- }, {
2990
- type: "Text",
2991
- parent: this.#LEFT_BUTTON,
2992
- name: this.#LEFT_BUTTON_TEXT,
2993
- size: [50, 50],
2994
- position: [-150, 0],
2995
- anchor: mod.UIAnchor.Center,
2996
- bgFill: mod.UIBgFill.None,
2997
- textColor: bfBlueColor,
2998
- textAnchor: mod.UIAnchor.Center,
2999
- textLabel: MakeMessage(mod.stringkeys.leftArrow),
3000
- textSize: 35,
3001
-
3002
- },
3003
-
3004
-
3005
- {
3006
- type: "Container",
3007
- name: this.#READYUP_BUTTON_SELECT,
3008
- size: [240, 60],
3009
- position: [0, 0],
3010
- anchor: mod.UIAnchor.Center,
3011
- bgFill: mod.UIBgFill.OutlineThin,
3012
- bgColor: bfBlueColor,
3013
- bgAlpha: 0.8,
3014
- visible: false
3015
- },
3016
- {
3017
- type: "Button",
3018
- name: this.#READYUP_BUTTON,
3019
- size: [230, 50],
3020
- position: [0, 0],
3021
- anchor: mod.UIAnchor.Center,
3022
- bgFill: mod.UIBgFill.Blur,
3023
- buttonColorHover: [1, 1, 1],
3024
- bgColor: [1, 1, 1],
3025
- bgAlpha: 1.0
3026
- },
3027
- {
3028
- type: "Text",
3029
- parent: this.#READYUP_BUTTON,
3030
- name: this.#READYUP_BUTTON_TEXT,
3031
- size: [230, 50],
3032
- position: [0, 0],
3033
- anchor: mod.UIAnchor.Center,
3034
- bgFill: mod.UIBgFill.None,
3035
- textColor: bfBlueColor,
3036
- textAnchor: mod.UIAnchor.Center,
3037
- textLabel: MakeMessage(mod.stringkeys.ready),
3038
- textSize: 25
3039
- },
3040
-
3041
- {
3042
- type: "Container",
3043
- name: this.#RIGHT_BUTTON_SELECTED,
3044
- size: [60, 60],
3045
- position: [150, 0],
3046
- anchor: mod.UIAnchor.Center,
3047
- bgFill: mod.UIBgFill.OutlineThin,
3048
- bgColor: bfBlueColor,
3049
- bgAlpha: 0.8,
3050
- visible: false
3051
- },
3052
- {
3053
- type: "Button",
3054
- name: this.#RIGHT_BUTTON,
3055
- size: [50, 50],
3056
- position: [150, 0],
3057
- anchor: mod.UIAnchor.Center,
3058
- bgFill: mod.UIBgFill.Blur,
3059
- buttonColorHover: [1, 1, 1],
3060
- bgColor: [1, 1, 1],
3061
- bgAlpha: 1.0
3062
- }, {
3063
-
3064
- type: "Text",
3065
- parent: this.#RIGHT_BUTTON,
3066
- name: this.#RIGHT_BUTTON_TEXT,
3067
- size: [50, 50],
3068
- position: [150, 0],
3069
- anchor: mod.UIAnchor.Center,
3070
- bgFill: mod.UIBgFill.None,
3071
- textColor: bfBlueColor,
3072
- textAnchor: mod.UIAnchor.Center,
3073
- textLabel: MakeMessage(mod.stringkeys.rightArrow),
3074
- textSize: 35
3075
- },
3076
-
3077
- {
3078
- type: "Container",
3079
- name: this.#CURRENT_SELECT_VEH_TEXT + "_line",
3080
- size: [300, 3],
3081
- position: [0, -35],
3082
- anchor: mod.UIAnchor.Center,
3083
- bgFill: mod.UIBgFill.Solid,
3084
- bgColor: bfBlueColor,
3085
- bgAlpha: 0.5
3086
- },
3087
- {
3088
- type: "Text",
3089
- name: this.#CURRENT_SELECT_VEH_TEXT,
3090
- size: [350, 80],
3091
- position: [0, -70],
3092
- anchor: mod.UIAnchor.Center,
3093
- bgFill: mod.UIBgFill.None,
3094
- textColor: bfBlueColor,
3095
- textAnchor: mod.UIAnchor.Center,
3096
- textLabel: MakeMessage(mod.stringkeys.selectVeh),
3097
- textSize: 60
3098
- },
3099
- {
3100
- type: "Text",
3101
- name: this.#CURRENT_SELECT_VEH_TEXT + "_chosen_veh",
3102
- size: [300, 50],
3103
- position: [0, -105],
3104
- anchor: mod.UIAnchor.Center,
3105
- bgFill: mod.UIBgFill.None,
3106
- textColor: bfBlueColor,
3107
- textAnchor: mod.UIAnchor.Center,
3108
- textLabel: MakeMessage(mod.stringkeys.chosenvehicle),
3109
- textSize: 20
3110
- }
3111
- ]
3112
- }) as mod.UIWidget)
3113
-
3114
- this.#Left_Button_Holder = new HoH_UIButtonHolder(
3115
- this.#playerProfile,
3116
- this.#LEFT_BUTTON,
3117
- this.#LEFT_BUTTON_TEXT,
3118
- this.#LEFT_BUTTON_SELECTED,
3119
- function (this: HoH_UIButtonHolder) {
3120
- this.playerProfile.VehicleShopUI?.VehicleSelectIncrease();
3121
- },
3122
- function (this: HoH_UIButtonHolder, focusIn: boolean) {
3123
- if (focusIn) {
3124
- mod.SetUIWidgetBgFill(this.button_widget, mod.UIBgFill.Solid)
3125
- mod.SetUITextColor(this.button_text_widget, mod.CreateVector(0.2, 0.2, 0.2))
3126
- mod.SetUIWidgetBgColor(this.button_widget, mod.CreateVector(0.678, 0.753, 0.800))
3127
- this.select_widget && mod.SetUIWidgetVisible(this.select_widget, true)
3128
- } else {
3129
- mod.SetUIWidgetBgFill(this.button_widget, mod.UIBgFill.Blur)
3130
- mod.SetUITextColor(this.button_text_widget, mod.CreateVector(0.678, 0.753, 0.800))
3131
- mod.SetUIWidgetBgColor(this.button_widget, mod.CreateVector(1, 1, 1))
3132
- this.select_widget && mod.SetUIWidgetVisible(this.select_widget, false)
3133
- }
3134
- }
3135
- );
3136
-
3137
- this.#Right_Button_Holder = new HoH_UIButtonHolder(
3138
- this.#playerProfile,
3139
- this.#RIGHT_BUTTON,
3140
- this.#RIGHT_BUTTON_TEXT,
3141
- this.#RIGHT_BUTTON_SELECTED,
3142
- function (this: HoH_UIButtonHolder) {
3143
- this.playerProfile.VehicleShopUI?.VehicleSelectDecrease()
3144
-
3145
- },
3146
- function (this: HoH_UIButtonHolder, focusIn: boolean) {
3147
- if (focusIn) {
3148
- mod.SetUIWidgetBgFill(this.button_widget, mod.UIBgFill.Solid)
3149
- mod.SetUITextColor(this.button_text_widget, mod.CreateVector(0.2, 0.2, 0.2))
3150
- mod.SetUIWidgetBgColor(this.button_widget, mod.CreateVector(0.678, 0.753, 0.800))
3151
- this.select_widget && mod.SetUIWidgetVisible(this.select_widget, true)
3152
- } else {
3153
- mod.SetUIWidgetBgFill(this.button_widget, mod.UIBgFill.Blur)
3154
- mod.SetUITextColor(this.button_text_widget, mod.CreateVector(0.678, 0.753, 0.800))
3155
- mod.SetUIWidgetBgColor(this.button_widget, mod.CreateVector(1, 1, 1))
3156
- this.select_widget && mod.SetUIWidgetVisible(this.select_widget, false)
3157
- }
3158
- }
3159
- )
3160
-
3161
- this.#Readyup_Button_Holder = new HoH_UIButtonHolder(
3162
- this.#playerProfile,
3163
- this.#READYUP_BUTTON,
3164
- this.#READYUP_BUTTON_TEXT,
3165
- this.#READYUP_BUTTON_SELECT,
3166
- function (this: HoH_UIButtonHolder) {
3167
- if (this.playerProfile.readyUp) {
3168
- this.playerProfile.VehicleShopUI?.EnableSwitchButtons(false)
3169
-
3170
- } else {
3171
- this.playerProfile.VehicleShopUI?.EnableSwitchButtons(true)
3172
-
3173
- }
3174
- },
3175
- function (this: HoH_UIButtonHolder, focusIn: boolean) {
3176
-
3177
-
3178
- if (focusIn) {
3179
- mod.SetUIWidgetBgFill(this.button_widget, mod.UIBgFill.Solid)
3180
- mod.SetUITextColor(this.button_text_widget, mod.CreateVector(0.2, 0.2, 0.2))
3181
- mod.SetUIWidgetBgColor(this.button_widget, mod.CreateVector(0.678, 0.753, 0.800))
3182
- this.select_widget && mod.SetUIWidgetVisible(this.select_widget, true)
3183
- } else {
3184
- mod.SetUIWidgetBgFill(this.button_widget, mod.UIBgFill.Blur)
3185
- mod.SetUITextColor(this.button_text_widget, mod.CreateVector(0.678, 0.753, 0.800))
3186
- mod.SetUIWidgetBgColor(this.button_widget, mod.CreateVector(1, 1, 1))
3187
- this.select_widget && mod.SetUIWidgetVisible(this.select_widget, false)
3188
- }
3189
- }
3190
- )
3191
-
3192
- this.#current_select_veh_Widget = mod.FindUIWidgetWithName(this.#CURRENT_SELECT_VEH_TEXT)
3193
-
3194
-
3195
-
3196
- // CatchupMechanic Information
3197
-
3198
-
3199
-
3200
- const PLAYER_CATCHUP_MECHANIC_TITLE = `players_catchup_mechanic_title_${this.#playerProfile.playerProfileId}`
3201
- const PLAYER_CATCHUP_MECHANIC_DESC = `players_catchup_mechanic_desc_${this.#playerProfile.playerProfileId}`
3202
-
3203
- this.#RootWidgets.push(ParseUI({
3204
- type: "Container",
3205
- size: [500, 200],
3206
- position: [50, 350],
3207
- anchor: mod.UIAnchor.TopRight,
3208
- bgFill: mod.UIBgFill.Blur,
3209
- bgColor: [0.2, 0.2, 0.3],
3210
- bgAlpha: 0.6,
3211
- playerId: this.#playerProfile.player,
3212
- children: [{
3213
- type: "Text",
3214
- name: PLAYER_CATCHUP_MECHANIC_TITLE,
3215
- size: [500, 200],
3216
- position: [0, 0],
3217
- anchor: mod.UIAnchor.Center,
3218
- bgFill: mod.UIBgFill.None,
3219
- textColor: bfBlueColor,
3220
- textAnchor: mod.UIAnchor.TopLeft,
3221
- textLabel: MakeMessage(mod.stringkeys.afterburnerExplainedTitle),
3222
- textSize: 40
3223
- },
3224
- {
3225
- type: "Text",
3226
- name: PLAYER_CATCHUP_MECHANIC_DESC,
3227
- size: [500, 200],
3228
- position: [0, 20],
3229
- anchor: mod.UIAnchor.Center,
3230
- bgFill: mod.UIBgFill.None,
3231
- textColor: bfBlueColor,
3232
- textAnchor: mod.UIAnchor.CenterLeft,
3233
- textLabel: MakeMessage(mod.stringkeys.afterburnerExplained),
3234
- textSize: 30
3235
- },
3236
- ]
3237
- }) as mod.UIWidget)
3238
-
3239
- }
3240
-
3241
- cameraTeleport() {
3242
-
3243
- let startPos = playerVehicleSelectPositions[this.selectVehNb][0]
3244
- let endPod = playerVehicleSelectPositions[this.selectVehNb][1]
3245
-
3246
- const spawnPositions = generateSpawnLine(startPos, endPod, MapPlayers, "right")
3247
- const spawnposition = spawnPositions[this.#playerProfile.playerRacerNumber].position
3248
-
3249
- const lookrotation = this.lookAtYaw(spawnposition, VehiclePositions[this.selectVehNb])
3250
- mod.Teleport(this.#playerProfile.player, mod.CreateVector(spawnposition.x, spawnposition.y, spawnposition.z), lookrotation)
3251
-
3252
- }
3253
-
3254
- lookAtYaw(from: Vector3, to: Vector3): number {
3255
- const dx = to.x - from.x;
3256
- const dz = to.z - from.z;
3257
- return Math.atan2(dx, dz); // radians
3258
- }
3259
-
3260
-
3261
- refresh() {
3262
-
3263
- this.#playerProfile.SetVehicle(currentRace.availableVehicles[this.selectVehNb])
3264
- const vehicleEnumValue = currentRace.availableVehicles[this.selectVehNb];
3265
-
3266
- this.#current_select_veh_Widget && mod.SetUITextLabel(this.#current_select_veh_Widget, MakeMessage(this.getVehName(vehicleEnumValue)))
3267
- }
3268
-
3269
- getVehName(veh: mod.VehicleList) {
3270
- if (veh == mod.VehicleList.F22) {
3271
- return mod.stringkeys.vehicle_1
3272
- } else if (veh == mod.VehicleList.F16) {
3273
- return mod.stringkeys.vehicle_2
3274
- } else if (veh == mod.VehicleList.JAS39) {
3275
- return mod.stringkeys.vehicle_3
3276
- }
3277
- return ""
3278
- }
3279
-
3280
- async open() {
3281
- if (!this.#players_ready_count_widget)
3282
- this.#create();
3283
-
3284
- if (this.UIOpen == true) {
3285
- return
3286
- }
3287
-
3288
- this.UIOpen = true;
3289
-
3290
- this.#RootWidgets.forEach(Rootwidget => {
3291
- mod.SetUIWidgetVisible(Rootwidget, true)
3292
- });
3293
-
3294
-
3295
- mod.EnableUIInputMode(true, this.#playerProfile.player)
3296
-
3297
- this.refresh()
3298
- this.UIUpdatePlayersReady();
3299
- this.cameraTeleport();
3300
- await mod.Wait(1)
3301
- this.cameraTeleport();
3302
- }
3303
-
3304
- close() {
3305
- if (this.UIOpen == false) {
3306
- return
3307
- }
3308
-
3309
- this.UIOpen = false;
3310
- this.#RootWidgets.forEach(Rootwidget => {
3311
- mod.SetUIWidgetVisible(Rootwidget, false)
3312
- });
3313
-
3314
- mod.EnableUIInputMode(false, this.#playerProfile.player)
3315
- }
3316
-
3317
- OnButtonPressed(eventPlayer: mod.Player, eventUIWidget: mod.UIWidget, eventUIButtonEvent: mod.UIButtonEvent) {
3318
- if (mod.Equals(eventUIButtonEvent, mod.UIButtonEvent.FocusIn)) {
3319
- //console.log("FocusIn")
3320
- this.buttonFocused(mod.GetUIWidgetName(eventUIWidget), true)
3321
- } else if (mod.Equals(eventUIButtonEvent, mod.UIButtonEvent.FocusOut)) {
3322
- //console.log("FocusOut ")
3323
- this.buttonFocused(mod.GetUIWidgetName(eventUIWidget), false)
3324
- } else if (mod.Equals(eventUIButtonEvent, mod.UIButtonEvent.ButtonDown)) {
3325
- // console.log("ButtonDown")
3326
- this.buttonPressed(mod.GetUIWidgetName(eventUIWidget))
3327
- } else if (mod.Equals(eventUIButtonEvent, mod.UIButtonEvent.ButtonUp)) {
3328
- // console.log("ButtonUp")
3329
- } else if (mod.Equals(eventUIButtonEvent, mod.UIButtonEvent.HoverIn)) {
3330
- // console.log("HoverIn")
3331
- } else if (mod.Equals(eventUIButtonEvent, mod.UIButtonEvent.HoverOut)) {
3332
- //console.log("HoverOut")
3333
- }
3334
-
3335
- }
3336
-
3337
- buttonFocused(widgetName: string, focusIn: boolean = false) {
3338
- if (widgetName == this.#LEFT_BUTTON && this.#Left_Button_Holder) {
3339
- this.#Left_Button_Holder.focus(focusIn);
3340
- } else if (widgetName == this.#RIGHT_BUTTON && this.#Right_Button_Holder) {
3341
- this.#Right_Button_Holder.focus(focusIn);
3342
- } else if (widgetName == this.#READYUP_BUTTON && this.#Readyup_Button_Holder) {
3343
- this.#Readyup_Button_Holder.focus(focusIn);
3344
- }
3345
- }
3346
-
3347
- buttonPressed(widgetName: string) {
3348
-
3349
- if (widgetName == this.#LEFT_BUTTON) {
3350
-
3351
- this.#Left_Button_Holder?.click()
3352
-
3353
-
3354
- } else if (widgetName == this.#READYUP_BUTTON) {
3355
-
3356
- if (!this.#playerProfile.readyUp) {
3357
- this.#playerProfile.readyUp = true;
3358
-
3359
- } else {
3360
- this.#playerProfile.readyUp = false;
3361
- }
3362
-
3363
- this.#Readyup_Button_Holder?.click()
3364
-
3365
- currentRace.playersInRace.forEach(pp => {
3366
- pp.VehicleShopUI?.UIUpdatePlayersReady()
3367
- });
3368
-
3369
- } else if (widgetName == this.#RIGHT_BUTTON) {
3370
-
3371
- this.#Right_Button_Holder?.click()
3372
-
3373
- }
3374
- }
3375
- }
3376
-
3377
- // === UI_VersionNB.ts ===
3378
-
3379
-
3380
-
3381
- class HoH_Version {
3382
-
3383
- VersionWidget: mod.UIWidget | undefined;
3384
-
3385
- constructor(playerProfile: PlayerProfile) {
3386
- const bfBlueColor = [0.678, 0.753, 0.800]
3387
-
3388
- this.VersionWidget = ParseUI({
3389
- type: "Container",
3390
- size: [200, 25],
3391
- position: [0, 0],
3392
- anchor: mod.UIAnchor.BottomRight,
3393
- bgFill: mod.UIBgFill.Blur,
3394
- bgColor: [0.2, 0.2, 0.3],
3395
- bgAlpha: 0.7,
3396
- playerId: playerProfile.player,
3397
- children: [{
3398
- type: "Text",
3399
- name: "game_version_" + playerProfile.playerProfileId,
3400
- size: [200, 25],
3401
- position: [0, 0],
3402
- anchor: mod.UIAnchor.Center,
3403
- bgFill: mod.UIBgFill.None,
3404
- textColor: bfBlueColor,
3405
- textAnchor: mod.UIAnchor.Center,
3406
- textLabel: MakeMessage(mod.stringkeys.modversion, VERSION[0], VERSION[1], VERSION[2]),
3407
- textSize: 20
3408
- }]
3409
- })
3410
- }
3411
-
3412
- Close() {
3413
- this.VersionWidget && mod.SetUIWidgetVisible(this.VersionWidget, false)
3414
- }
3415
-
3416
- Delete() {
3417
- this.VersionWidget && mod.DeleteUIWidget(this.VersionWidget)
3418
- }
3419
-
3420
- }
3421
-