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