Tiberian Technologies Scripts Reference Revision: 9000
Loading...
Searching...
No Matches
jmgMetroid.h
1/* Renegade Roll Play 2 Scripts by Jerad Gray
2 Scripts by Jerad Gray
3 Copyright 2010 Jerad Gray
4
5 This file is part of the Renegade scripts.dll
6 The Renegade scripts.dll is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version. See the file COPYING for more details.
10 In addition, an exemption is given to allow Run Time Dynamic Linking of this code with any closed source module that does not contain code covered by this licence.
11 Only the source code to the module(s) containing the licenced code has to be released.
12*/
13#pragma once
14#include "jmgUtility.h"
15#include "direct.h"
16#define PI 3.14159265f
17#define PI180 PI/180
18
19NewObjectiveSystem MetroidObjectiveSystemControl = NewObjectiveSystem(1,true,"mObjective","null","null");
20NewObjectiveSystem MetroidRoomObjectives = NewObjectiveSystem(1,false,"mObjective","null","null");
21
22bool PerkSystemIncreasePlayerPerkUnlockAmount(GameObject *obj,int PerkID,unsigned int IncreaseAmount);
23void AddPerkTypes();
24void SavePlayerPerkData(){};
25void FindPlayerPerkList(GameObject *obj,bool Display){};
26void ClearPlayerSelectedPerks(GameObject *obj){};
27bool CheckIfPlayerHasPerkUnlocked(GameObject *obj,int PerkID);
28void IncreasePlayerPerkSlotCount(GameObject *poker){};
29struct MetroidScoreSystem
30{
31 bool hasLoaded;
32 int selectRandomMatchingScore;
33 bool saveInProgress;
34 #define MetroidHIGHSCORELISTCOUNT 155
35 char metroidSavePath[256];
36public:
37 struct MetroidHighScoresNode
38 {
39 char PlayerName[256];
40 double PlayTime;
41 double IdleTime;
42 double Points;
43 double MostPointsInARound;
44 double HealthPackPoints;
45 double RechargePoints;
46 double DefenseGunPoints;
47 double TeleportPoints;
48 double ShieldUpgradePoints;
49 double WeaponSpawnPoints;
50 unsigned long Deaths;
51 unsigned long DeathFromElectrifiedWater;
52 unsigned long DeathFromSpikePit;
53 unsigned long DeathFromFallingOffTheTrain;
54 unsigned long DeathInLava;
55 unsigned long DeathInRadioactivePit;
56 unsigned long DeathFromReactorRadiation;
57 unsigned long DeathInFire;
58 unsigned long DeathFromMiniBoss;
59 unsigned long KilledMiniBoss;
60 unsigned long DeathFromDefenseCameras;
61 unsigned long DeathFromAliens;
62 unsigned long DeathFromRobots;
63 unsigned long DeathFromTraitors;
64 unsigned long DeathFromAttackCameras;
65 unsigned long DeathFromGunEmplacements;
66 unsigned long DeathFromShredderTurret;
67 unsigned long DeathFromBansheeBoss;
68 unsigned long DeathFromMineBoss;
69 unsigned long DeathFromMineBossSquish;
70 unsigned long DeathFromMineBossResources;
71 unsigned long Kills;
72 unsigned long Suicides;
73 unsigned long KilledPlayers;
74 unsigned long KilledDefenseCameras;
75 unsigned long KilledAliens;
76 unsigned long KilledRobots;
77 unsigned long KilledTraitors;
78 unsigned long KilledSecurityCameras;
79 unsigned long KilledAttackCameras;
80 unsigned long KilledGunEmplacements;
81 unsigned long KilledTurretBoss;
82 unsigned long KilledBansheeBoss;
83 unsigned long KilledMineBoss;
84 unsigned long Chapter1Completed;
85 unsigned long Chapter2Completed;
86 unsigned long Chapter3Completed;
87 unsigned long Chapter4Completed;
88 unsigned long Chapter5Completed;
89 unsigned long Chapter6Completed;
90 unsigned long Chapter7Completed;
91 unsigned long Chapter8Completed;
92 unsigned long Chapter9Completed;
93 unsigned long Chapter10Completed;
94 unsigned long TriggeredLockdown0;
95 unsigned long TriggeredLockdown1;
96 unsigned long TriggeredLockdown2;
97 unsigned long TriggeredLockdown3;
98 unsigned long TriggeredLockdown4;
99 unsigned long TriggeredLockdown5;
100 unsigned long TriggeredLockdown6;
101 unsigned long TriggeredLockdown7;
102 unsigned long TriggeredLockdown8;
103 unsigned long TriggeredLockdown9;
104 unsigned long PickedUpPlayerPlacedWeapon;
105 unsigned long PickedUpLaser;
106 unsigned long PickedUpShotgun;
107 unsigned long PickedUpSniper;
108 unsigned long PickedUpFlame;
109 unsigned long PickedUpShockCoil;
110 unsigned long PickedUpMachineGun;
111 unsigned long PickedUpRoboticLaser;
112 unsigned long PickedUpRoboticShotgun;
113 unsigned long PickedUpRoboticSniper;
114 unsigned long PickedUpRoboticFlame;
115 unsigned long PickedUpRoboticShockCoil;
116 unsigned long PickedUpRoboticMachineGun;
117 unsigned long PickedUpGlitchGun;
118 unsigned long PickedUpHealthPack;
119 unsigned long PickedUpPlayerPlacedHealthPack;
120 unsigned long PickedUpShieldUpgrade;
121 unsigned long PickedUpPlayerShieldUpgrade;
122 unsigned long PlacedMedPacks;
123 unsigned long PlacedRechargers;
124 unsigned long PlacedTurrets;
125 unsigned long PlacedTeleports;
126 unsigned long PlacedShieldUpgrades;
127 unsigned long PlacedWeaponSpawners;
128 unsigned long UsedPlayerPlacedTeleport;
129 double PlayTimeAsClass0;
130 double PlayTimeAsClass1;//Armor
131 double PlayTimeAsClass2;//Speed
132 double PlayTimeAsClass3;//FirePower
133 double PlayTimeAsClass4;//Support
134 double PlayTimeAsClass5;//Defense
135 double PlayTimeAsClass6;//Supply
136 double PlayTimeAsClass7;
137 double PlayTimeAsClass8;
138 double PlayTimeAsClass9;
139 double PlayTimeAsClass10;//Cheat
140 double PlayTimeAsClass11;//Training
141 double PlayTimeInSpawnRoom;
142 unsigned long CompletedPlayThroughs;
143 unsigned long DeathFromPlayers;
144 double LongestPlayTimeInARound;
145 unsigned long SpawnedAsCharacter0;
146 unsigned long SpawnedAsCharacter1;
147 unsigned long SpawnedAsCharacter2;
148 unsigned long SpawnedAsCharacter3;
149 unsigned long SpawnedAsCharacter4;
150 unsigned long SpawnedAsCharacter5;
151 unsigned long SpawnedAsCharacter6;
152 unsigned long SpawnedAsCharacter7;
153 unsigned long SpawnedAsCharacter8;
154 unsigned long SpawnedAsCharacter9;
155 unsigned long KilledCrates;
156 unsigned long PickedUpGrenadeLaunchers;
157 unsigned long ElevatorButtonsPressed;
158 unsigned long ElevatorLockdownButton;
159 unsigned long KilledBrokenDoors;
160 unsigned long GlitchModeFound;
161 unsigned long GlitchModeCompleted;
162 unsigned long FoundCheatGun;
163 unsigned long OpenedFirstDoor;
164 unsigned long GotKeycard;
165 unsigned long KilledByRapids;
166 unsigned long KilledByFall;
167 unsigned long TurnedOffLaserFence;
168 unsigned long BackLaserFence;
169 unsigned long ReactorPowerRestored;
170 unsigned long ComputerConsolesDeactivated;
171 unsigned long CityShieldLowered;
172 unsigned long ElectrifiedWaterTurnedOff;
173 unsigned long TunnelEntryLowered;
174 unsigned long KillsWithDefenseGun;
175 unsigned long KillsWithCheatGun;
176 unsigned long KillsWithFlameUpgrade;
177 unsigned long KillsWithRoboticFlameUpgrade;
178 unsigned long KillsWithGlitchGun;
179 unsigned long KillsWithImperialist;
180 unsigned long KillsWithRoboticImperialist;
181 unsigned long KillsWithLaserShotgun;
182 unsigned long KillsWithRoboticLaserShotgun;
183 unsigned long KillsWithMachineGun;
184 unsigned long KillsWithRoboticMachineGun;
185 unsigned long KillsWithShockCoil;
186 unsigned long KillsWithRoboticShockCoil;
187 unsigned long KillsWithLaser;
188 unsigned long KillsWithRoboticLaser;
189 unsigned long KillsWithHyperdeath;
190 unsigned long KillsWithSuperHyperdeath;
191 unsigned long KillsWithKnife;
192 unsigned long KillsWithGrenade;
193 unsigned long KillsWithRoboticGrenade;
194 unsigned long KillsWithUnknownWeapon;
195 JmgUtility::GenericDateTime LastPlayTime;
196
197
198
199 MetroidHighScoresNode *next;
200 float LastFacing;
201 Vector3 LastPos;
202 bool IsMoving;
203 bool IsTurning;
204 unsigned int IdleDelay;
205 double pointsThisRound;
206 double playTimeThisRound;
207 MetroidHighScoresNode(void)
208 {
209 PlayTime = 0.0;
210 IdleTime = 0.0;
211 Points = 0.0;
212 MostPointsInARound = 0.0;
213 HealthPackPoints = 0.0;
214 RechargePoints = 0.0;
215 DefenseGunPoints = 0.0;
216 TeleportPoints = 0.0;
217 ShieldUpgradePoints = 0.0;
218 WeaponSpawnPoints = 0.0;
219 Deaths = 0;
220 DeathFromElectrifiedWater = 0;
221 DeathFromSpikePit = 0;
222 DeathFromFallingOffTheTrain = 0;
223 DeathInLava = 0;
224 DeathInRadioactivePit = 0;
225 DeathFromReactorRadiation = 0;
226 DeathInFire = 0;
227 DeathFromMiniBoss = 0;
228 KilledMiniBoss = 0;
229 DeathFromDefenseCameras = 0;
230 DeathFromAliens = 0;
231 DeathFromRobots = 0;
232 DeathFromTraitors = 0;
233 DeathFromAttackCameras = 0;
234 DeathFromGunEmplacements = 0;
235 DeathFromShredderTurret = 0;
236 DeathFromBansheeBoss = 0;
237 DeathFromMineBoss = 0;
238 DeathFromMineBossSquish = 0;
239 DeathFromMineBossResources = 0;
240 Kills = 0;
241 Suicides = 0;
242 KilledPlayers = 0;
243 KilledDefenseCameras = 0;
244 KilledAliens = 0;
245 KilledRobots = 0;
246 KilledTraitors = 0;
247 KilledSecurityCameras = 0;
248 KilledAttackCameras = 0;
249 KilledGunEmplacements = 0;
250 KilledTurretBoss = 0;
251 KilledBansheeBoss = 0;
252 KilledMineBoss = 0;
253 Chapter1Completed = 0;
254 Chapter2Completed = 0;
255 Chapter3Completed = 0;
256 Chapter4Completed = 0;
257 Chapter5Completed = 0;
258 Chapter6Completed = 0;
259 Chapter7Completed = 0;
260 Chapter8Completed = 0;
261 Chapter9Completed = 0;
262 Chapter10Completed = 0;
263 TriggeredLockdown0 = 0;
264 TriggeredLockdown1 = 0;
265 TriggeredLockdown2 = 0;
266 TriggeredLockdown3 = 0;
267 TriggeredLockdown4 = 0;
268 TriggeredLockdown5 = 0;
269 TriggeredLockdown6 = 0;
270 TriggeredLockdown7 = 0;
271 TriggeredLockdown8 = 0;
272 TriggeredLockdown9 = 0;
273 PickedUpPlayerPlacedWeapon = 0;
274 PickedUpLaser = 0;
275 PickedUpShotgun = 0;
276 PickedUpSniper = 0;
277 PickedUpFlame = 0;
278 PickedUpShockCoil = 0;
279 PickedUpMachineGun = 0;
280 PickedUpRoboticLaser = 0;
281 PickedUpRoboticShotgun = 0;
282 PickedUpRoboticSniper = 0;
283 PickedUpRoboticFlame = 0;
284 PickedUpRoboticShockCoil = 0;
285 PickedUpRoboticMachineGun = 0;
286 PickedUpGlitchGun = 0;
287 PickedUpHealthPack = 0;
288 PickedUpPlayerPlacedHealthPack = 0;
289 PickedUpShieldUpgrade = 0;
290 PickedUpPlayerShieldUpgrade = 0;
291 PlacedMedPacks = 0;
292 PlacedRechargers = 0;
293 PlacedTurrets = 0;
294 PlacedTeleports = 0;
295 PlacedShieldUpgrades = 0;
296 PlacedWeaponSpawners = 0;
297 UsedPlayerPlacedTeleport = 0;
298 PlayTimeAsClass0 = 0.0;
299 PlayTimeAsClass1 = 0.0;
300 PlayTimeAsClass2 = 0.0;
301 PlayTimeAsClass3 = 0.0;
302 PlayTimeAsClass4 = 0.0;
303 PlayTimeAsClass5 = 0.0;
304 PlayTimeAsClass6 = 0.0;
305 PlayTimeAsClass7 = 0.0;
306 PlayTimeAsClass8 = 0.0;
307 PlayTimeAsClass9 = 0.0;
308 PlayTimeAsClass10 = 0.0;
309 PlayTimeAsClass11 = 0.0;
310 PlayTimeInSpawnRoom = 0.0;
311 CompletedPlayThroughs = 0;
312 DeathFromPlayers = 0;
313 LongestPlayTimeInARound = 0.0;
314 SpawnedAsCharacter0 = 0;
315 SpawnedAsCharacter1 = 0;
316 SpawnedAsCharacter2 = 0;
317 SpawnedAsCharacter3 = 0;
318 SpawnedAsCharacter4 = 0;
319 SpawnedAsCharacter5 = 0;
320 SpawnedAsCharacter6 = 0;
321 SpawnedAsCharacter7 = 0;
322 SpawnedAsCharacter8 = 0;
323 SpawnedAsCharacter9 = 0;
324 KilledCrates = 0;
325 PickedUpGrenadeLaunchers = 0;
326 ElevatorButtonsPressed = 0;
327 ElevatorLockdownButton = 0;
328 KilledBrokenDoors = 0;
329 GlitchModeFound = 0;
330 GlitchModeCompleted = 0;
331 FoundCheatGun = 0;
332 OpenedFirstDoor = 0;
333 GotKeycard = 0;
334 KilledByRapids = 0;
335 KilledByFall = 0;
336 TurnedOffLaserFence = 0;
337 BackLaserFence = 0;
338 ReactorPowerRestored = 0;
339 ComputerConsolesDeactivated = 0;
340 CityShieldLowered = 0;
341 ElectrifiedWaterTurnedOff = 0;
342 TunnelEntryLowered = 0;
343 KillsWithDefenseGun= 0;
344 KillsWithCheatGun= 0;
345 KillsWithFlameUpgrade= 0;
346 KillsWithRoboticFlameUpgrade= 0;
347 KillsWithGlitchGun= 0;
348 KillsWithImperialist= 0;
349 KillsWithRoboticImperialist= 0;
350 KillsWithLaserShotgun= 0;
351 KillsWithRoboticLaserShotgun= 0;
352 KillsWithMachineGun= 0;
353 KillsWithRoboticMachineGun= 0;
354 KillsWithShockCoil= 0;
355 KillsWithRoboticShockCoil= 0;
356 KillsWithLaser= 0;
357 KillsWithRoboticLaser= 0;
358 KillsWithHyperdeath= 0;
359 KillsWithSuperHyperdeath= 0;
360 KillsWithKnife= 0;
361 KillsWithGrenade= 0;
362 KillsWithRoboticGrenade= 0;
363 KillsWithUnknownWeapon = 0;
364 LastPlayTime = JmgUtility::GenericDateTime();
365
366
367 next = NULL;
368 LastPos = Vector3(0.0f,0.0f,0.0f);
369 IdleDelay = 0;
370 pointsThisRound = 0.0;
371 playTimeThisRound = 0.0;
372 }
373 };
374 MetroidHighScoresNode *MetroidPlayerHighScoreNodes[128];
375private:
376 MetroidHighScoresNode *MetroidHighScoresNodeList;
377 MetroidHighScoresNode *MetroidHighScoresNodeEmptyNode;
378 void LoadHighestScores()
379 {
380 if (!MetroidHighScoresNodeList)
381 return;
382 for (int x = 0;x < MetroidHIGHSCORELISTCOUNT;x++)
383 {
384 MetroidHighScoresNode *Current = MetroidHighScoresNodeList,*Best = NULL;
385 while (Current)
386 {
387 Best = CompareHighScoreNodes(Best,Current,x);
388 Current = Current->next;
389 }
390 }
391 }
392 MetroidHighScoresNode *FindOrAddPlayerMetroidHighScoreNode(const char *PlayerName)
393 {
394 if (!MetroidHighScoresNodeList)
395 {
396 MetroidHighScoresNodeList = new MetroidHighScoresNode();
397 sprintf(MetroidHighScoresNodeList->PlayerName,"%s",PlayerName);
398 return MetroidHighScoresNodeList;
399 }
400 MetroidHighScoresNode *Current = MetroidHighScoresNodeList;
401 while (Current)
402 {
403 if (!_stricmp(Current->PlayerName,PlayerName))
404 return Current;
405 if (!Current->next)
406 {
407 Current->next = new MetroidHighScoresNode();
408 Current = Current->next;
409 sprintf(Current->PlayerName,"%s",PlayerName);
410 return Current;
411 }
412 Current = Current->next;
413 }
414 return NULL;
415 }
416public:
417 MetroidScoreSystem()
418 {
419 saveInProgress = false;
420 hasLoaded = false;
421 if (Exe != EXE_LEVELEDIT)
422 {
423 sprintf(metroidSavePath, "%s\\Save\\", Get_File_Path());
424 }
425 MetroidHighScoresNodeList = NULL;
426 MetroidHighScoresNodeEmptyNode = NULL;
427 for (int x = 0;x < 128;x++)
428 MetroidPlayerHighScoreNodes[x] = NULL;
429 };
430 MetroidHighScoresNode *Get_Current_Player_Score_Node(int PlayerID)
431 {
432 const char *PlayerName = Get_Player_Name_By_ID(PlayerID);
433 if (!PlayerName)
434 {
435 if (!MetroidHighScoresNodeEmptyNode)
436 MetroidHighScoresNodeEmptyNode = new MetroidHighScoresNode();
437 return MetroidHighScoresNodeEmptyNode;
438 }
439 if (!MetroidPlayerHighScoreNodes[PlayerID])
440 {
441 MetroidPlayerHighScoreNodes[PlayerID] = FindOrAddPlayerMetroidHighScoreNode(PlayerName);
442 }
443 else if (_stricmp(MetroidPlayerHighScoreNodes[PlayerID]->PlayerName,PlayerName))
444 {
445 MetroidPlayerHighScoreNodes[PlayerID] = FindOrAddPlayerMetroidHighScoreNode(PlayerName);
446 }
447 return MetroidPlayerHighScoreNodes[PlayerID];
448 }
449 void Cleanup()
450 {
451 if (saveInProgress)
452 {
453 Console_Input("msg MetroidScoreSystem ERROR: clean list, save in progress!");
454 return;
455 }
456 hasLoaded = false;
457 if (MetroidHighScoresNodeEmptyNode)
458 {
459 delete MetroidHighScoresNodeEmptyNode;
460 MetroidHighScoresNodeEmptyNode = NULL;
461 }
462 for (int x = 0;x < 128;x++)
463 {
464 if (MetroidPlayerHighScoreNodes[x])
465 MetroidPlayerHighScoreNodes[x] = NULL;
466 }
467 if (MetroidHighScoresNodeList)
468 {
469 MetroidHighScoresNode *temp,*die;
470 temp = MetroidHighScoresNodeList;
471 while (temp != NULL)
472 {
473 die = temp;
474 temp = temp->next;
475 delete die;
476 }
477 MetroidHighScoresNodeList = NULL;
478 }
479 }
480 void SaveData()
481 {
482 if (!hasLoaded)
483 {
484 Console_Input("msg MetroidScoreSystem ERROR: cannot save!");
485 return;
486 }
487 if (saveInProgress)
488 {
489 Console_Input("msg MetroidScoreSystem ERROR: cannot save, save already in progress!");
490 return;
491 }
492 saveInProgress = true;
493 FILE *SaveScores;
494 FILE *SaveScores2;
495 char tempFileName[256],finalFileName[256],textFileName[256],textTmpFileName[256];
496 _mkdir(metroidSavePath);
497 sprintf(finalFileName,"%sBetaMetroidPlayerRecords.Rp2",metroidSavePath);
498 sprintf(textFileName,"%sMetroidPlayerRecords.txt",metroidSavePath);
499 sprintf(textTmpFileName,"%sMetroidPlayerRecordsTmp.txt",metroidSavePath);
500 sprintf(tempFileName,"%sBetaMetroidPlayerRecords.tmp",metroidSavePath);
501 SaveScores = fopen(tempFileName,"w");
502 SaveScores2 = fopen(textTmpFileName,"w");
503 MetroidHighScoresNode *Current = MetroidHighScoresNodeList;
504 while (Current)
505 {
506 //CalculateKillToDeathRatio(Current);
507 if (Current->MostPointsInARound < Current->pointsThisRound)
508 Current->MostPointsInARound = Current->pointsThisRound;
509 if (Current->LongestPlayTimeInARound < Current->playTimeThisRound)
510 Current->LongestPlayTimeInARound = Current->playTimeThisRound;
511 char EncryptString[4096];
512 sprintf(EncryptString,"%.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %lu %lu %.2lf %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d %d %d %d %d %lu 0",Current->PlayTime,Current->IdleTime,Current->Points,Current->MostPointsInARound,Current->HealthPackPoints,Current->RechargePoints,Current->DefenseGunPoints,Current->TeleportPoints,Current->ShieldUpgradePoints,Current->WeaponSpawnPoints,Current->Deaths,Current->DeathFromElectrifiedWater,Current->DeathFromSpikePit,Current->DeathFromFallingOffTheTrain,Current->DeathInLava,Current->DeathInRadioactivePit,Current->DeathFromReactorRadiation,Current->DeathInFire,Current->DeathFromMiniBoss,Current->KilledMiniBoss,Current->DeathFromDefenseCameras,Current->DeathFromAliens,Current->DeathFromRobots,Current->DeathFromTraitors,Current->DeathFromAttackCameras,Current->DeathFromGunEmplacements,Current->DeathFromShredderTurret,Current->DeathFromBansheeBoss,Current->DeathFromMineBoss,Current->DeathFromMineBossSquish,Current->DeathFromMineBossResources,Current->Kills,Current->Suicides,Current->KilledPlayers,Current->KilledDefenseCameras,Current->KilledAliens,Current->KilledRobots,Current->KilledTraitors,Current->KilledSecurityCameras,Current->KilledAttackCameras,Current->KilledGunEmplacements,Current->KilledTurretBoss,Current->KilledBansheeBoss,Current->KilledMineBoss,Current->Chapter1Completed,Current->Chapter2Completed,Current->Chapter3Completed,Current->Chapter4Completed,Current->Chapter5Completed,Current->Chapter6Completed,Current->Chapter7Completed,Current->Chapter8Completed,Current->Chapter9Completed,Current->Chapter10Completed,Current->TriggeredLockdown0,Current->TriggeredLockdown1,Current->TriggeredLockdown2,Current->TriggeredLockdown3,Current->TriggeredLockdown4,Current->TriggeredLockdown5,Current->TriggeredLockdown6,Current->TriggeredLockdown7,Current->TriggeredLockdown8,Current->TriggeredLockdown9,Current->PickedUpPlayerPlacedWeapon,Current->PickedUpLaser,Current->PickedUpShotgun,Current->PickedUpSniper,Current->PickedUpFlame,Current->PickedUpShockCoil,Current->PickedUpMachineGun,Current->PickedUpRoboticLaser,Current->PickedUpRoboticShotgun,Current->PickedUpRoboticSniper,Current->PickedUpRoboticFlame,Current->PickedUpRoboticShockCoil,Current->PickedUpRoboticMachineGun,Current->PickedUpGlitchGun,Current->PickedUpHealthPack,Current->PickedUpPlayerPlacedHealthPack,Current->PickedUpShieldUpgrade,Current->PickedUpPlayerShieldUpgrade,Current->PlacedMedPacks,Current->PlacedRechargers,Current->PlacedTurrets,Current->PlacedTeleports,Current->PlacedShieldUpgrades,Current->PlacedWeaponSpawners,Current->UsedPlayerPlacedTeleport,Current->PlayTimeAsClass0,Current->PlayTimeAsClass1,Current->PlayTimeAsClass2,Current->PlayTimeAsClass3,Current->PlayTimeAsClass4,Current->PlayTimeAsClass5,Current->PlayTimeAsClass6,Current->PlayTimeAsClass7,Current->PlayTimeAsClass8,Current->PlayTimeAsClass9,Current->PlayTimeAsClass10,Current->PlayTimeAsClass11,Current->PlayTimeInSpawnRoom,Current->CompletedPlayThroughs,Current->DeathFromPlayers,Current->LongestPlayTimeInARound,Current->SpawnedAsCharacter0,Current->SpawnedAsCharacter1,Current->SpawnedAsCharacter2,Current->SpawnedAsCharacter3,Current->SpawnedAsCharacter4,Current->SpawnedAsCharacter5,Current->SpawnedAsCharacter6,Current->SpawnedAsCharacter7,Current->SpawnedAsCharacter8,Current->SpawnedAsCharacter9,Current->KilledCrates,Current->PickedUpGrenadeLaunchers,Current->ElevatorButtonsPressed,Current->ElevatorLockdownButton,Current->KilledBrokenDoors,Current->GlitchModeFound,Current->GlitchModeCompleted,Current->FoundCheatGun,Current->OpenedFirstDoor,Current->GotKeycard,Current->KilledByRapids,Current->KilledByFall,Current->TurnedOffLaserFence,Current->BackLaserFence,Current->ReactorPowerRestored,Current->ComputerConsolesDeactivated,Current->CityShieldLowered,Current->ElectrifiedWaterTurnedOff,Current->TunnelEntryLowered,Current->KillsWithDefenseGun,Current->KillsWithCheatGun,Current->KillsWithFlameUpgrade,Current->KillsWithRoboticFlameUpgrade,Current->KillsWithGlitchGun,Current->KillsWithImperialist,Current->KillsWithRoboticImperialist,Current->KillsWithLaserShotgun,Current->KillsWithRoboticLaserShotgun,Current->KillsWithMachineGun,Current->KillsWithRoboticMachineGun,Current->KillsWithShockCoil,Current->KillsWithRoboticShockCoil,Current->KillsWithLaser,Current->KillsWithRoboticLaser,Current->KillsWithHyperdeath,Current->KillsWithSuperHyperdeath,Current->KillsWithKnife,Current->KillsWithGrenade,Current->KillsWithRoboticGrenade,Current->KillsWithUnknownWeapon,Current->LastPlayTime.day,Current->LastPlayTime.month,Current->LastPlayTime.year,Current->LastPlayTime.second,Current->LastPlayTime.minute,Current->LastPlayTime.hour,Current->LastPlayTime.lTime);
513 fprintf(SaveScores2,"%s\n%s\n",Current->PlayerName,EncryptString);
514 fprintf(SaveScores,"%s\n%s",JmgUtility::Rp2Encrypt(Current->PlayerName,25,5),JmgUtility::Rp2Encrypt2(EncryptString,Current->PlayerName[0],Current->PlayerName[1]));
515 if (Current->next)
516 fprintf(SaveScores,"\n");
517 Current = Current->next;
518 }
519 fclose(SaveScores);
520 fclose(SaveScores2);
521 remove(finalFileName);
522 rename(tempFileName,finalFileName);
523 remove(textFileName);
524 rename(textTmpFileName,textFileName);
525 saveInProgress = false;
526 }
527 void LoadData()
528 {
529 hasLoaded = true;
530 if (!MetroidHighScoresNodeEmptyNode)
531 MetroidHighScoresNodeEmptyNode = new MetroidHighScoresNode();
532 for (int x = 0;x < 128;x++)
533 MetroidPlayerHighScoreNodes[x] = MetroidHighScoresNodeEmptyNode;
534 FILE *LoadScores;
535 char FileName[64];
536 sprintf(FileName,"%sBetaMetroidPlayerRecords.Rp2",metroidSavePath);
537 LoadScores = fopen(FileName,"r");
538 if (!LoadScores)
539 return;
540 while (!feof(LoadScores))
541 {
542 char PlayerName[256];
543 fgets(PlayerName,256,LoadScores);
544 int Length = strlen(PlayerName);
545 if (Length <= 0)
546 {
547 Console_Input("msg MutantAssaultHighScoreSystem::LoadData ERROR: Length is less than 1");
548 continue;
549 }
550 PlayerName[Length-1] = '\0';
551 MetroidHighScoresNode *Current = FindOrAddPlayerMetroidHighScoreNode(JmgUtility::Rp2Decrypt(PlayerName,25,5));
552 char DecryptString[4096];
553 fgets(DecryptString,4096,LoadScores);
554 sscanf(JmgUtility::Rp2Decrypt(DecryptString,Current->PlayerName[0],Current->PlayerName[1]),"%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lu %lu %lf %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d %d %d %d %d %lu ",&Current->PlayTime,&Current->IdleTime,&Current->Points,&Current->MostPointsInARound,&Current->HealthPackPoints,&Current->RechargePoints,&Current->DefenseGunPoints,&Current->TeleportPoints,&Current->ShieldUpgradePoints,&Current->WeaponSpawnPoints,&Current->Deaths,&Current->DeathFromElectrifiedWater,&Current->DeathFromSpikePit,&Current->DeathFromFallingOffTheTrain,&Current->DeathInLava,&Current->DeathInRadioactivePit,&Current->DeathFromReactorRadiation,&Current->DeathInFire,&Current->DeathFromMiniBoss,&Current->KilledMiniBoss,&Current->DeathFromDefenseCameras,&Current->DeathFromAliens,&Current->DeathFromRobots,&Current->DeathFromTraitors,&Current->DeathFromAttackCameras,&Current->DeathFromGunEmplacements,&Current->DeathFromShredderTurret,&Current->DeathFromBansheeBoss,&Current->DeathFromMineBoss,&Current->DeathFromMineBossSquish,&Current->DeathFromMineBossResources,&Current->Kills,&Current->Suicides,&Current->KilledPlayers,&Current->KilledDefenseCameras,&Current->KilledAliens,&Current->KilledRobots,&Current->KilledTraitors,&Current->KilledSecurityCameras,&Current->KilledAttackCameras,&Current->KilledGunEmplacements,&Current->KilledTurretBoss,&Current->KilledBansheeBoss,&Current->KilledMineBoss,&Current->Chapter1Completed,&Current->Chapter2Completed,&Current->Chapter3Completed,&Current->Chapter4Completed,&Current->Chapter5Completed,&Current->Chapter6Completed,&Current->Chapter7Completed,&Current->Chapter8Completed,&Current->Chapter9Completed,&Current->Chapter10Completed,&Current->TriggeredLockdown0,&Current->TriggeredLockdown1,&Current->TriggeredLockdown2,&Current->TriggeredLockdown3,&Current->TriggeredLockdown4,&Current->TriggeredLockdown5,&Current->TriggeredLockdown6,&Current->TriggeredLockdown7,&Current->TriggeredLockdown8,&Current->TriggeredLockdown9,&Current->PickedUpPlayerPlacedWeapon,&Current->PickedUpLaser,&Current->PickedUpShotgun,&Current->PickedUpSniper,&Current->PickedUpFlame,&Current->PickedUpShockCoil,&Current->PickedUpMachineGun,&Current->PickedUpRoboticLaser,&Current->PickedUpRoboticShotgun,&Current->PickedUpRoboticSniper,&Current->PickedUpRoboticFlame,&Current->PickedUpRoboticShockCoil,&Current->PickedUpRoboticMachineGun,&Current->PickedUpGlitchGun,&Current->PickedUpHealthPack,&Current->PickedUpPlayerPlacedHealthPack,&Current->PickedUpShieldUpgrade,&Current->PickedUpPlayerShieldUpgrade,&Current->PlacedMedPacks,&Current->PlacedRechargers,&Current->PlacedTurrets,&Current->PlacedTeleports,&Current->PlacedShieldUpgrades,&Current->PlacedWeaponSpawners,&Current->UsedPlayerPlacedTeleport,&Current->PlayTimeAsClass0,&Current->PlayTimeAsClass1,&Current->PlayTimeAsClass2,&Current->PlayTimeAsClass3,&Current->PlayTimeAsClass4,&Current->PlayTimeAsClass5,&Current->PlayTimeAsClass6,&Current->PlayTimeAsClass7,&Current->PlayTimeAsClass8,&Current->PlayTimeAsClass9,&Current->PlayTimeAsClass10,&Current->PlayTimeAsClass11,&Current->PlayTimeInSpawnRoom,&Current->CompletedPlayThroughs,&Current->DeathFromPlayers,&Current->LongestPlayTimeInARound,&Current->SpawnedAsCharacter0,&Current->SpawnedAsCharacter1,&Current->SpawnedAsCharacter2,&Current->SpawnedAsCharacter3,&Current->SpawnedAsCharacter4,&Current->SpawnedAsCharacter5,&Current->SpawnedAsCharacter6,&Current->SpawnedAsCharacter7,&Current->SpawnedAsCharacter8,&Current->SpawnedAsCharacter9,&Current->KilledCrates,&Current->PickedUpGrenadeLaunchers,&Current->ElevatorButtonsPressed,&Current->ElevatorLockdownButton,&Current->KilledBrokenDoors,&Current->GlitchModeFound,&Current->GlitchModeCompleted,&Current->FoundCheatGun,&Current->OpenedFirstDoor,&Current->GotKeycard,&Current->KilledByRapids,&Current->KilledByFall,&Current->TurnedOffLaserFence,&Current->BackLaserFence,&Current->ReactorPowerRestored,&Current->ComputerConsolesDeactivated,&Current->CityShieldLowered,&Current->ElectrifiedWaterTurnedOff,&Current->TunnelEntryLowered,&Current->KillsWithDefenseGun,&Current->KillsWithCheatGun,&Current->KillsWithFlameUpgrade,&Current->KillsWithRoboticFlameUpgrade,&Current->KillsWithGlitchGun,&Current->KillsWithImperialist,&Current->KillsWithRoboticImperialist,&Current->KillsWithLaserShotgun,&Current->KillsWithRoboticLaserShotgun,&Current->KillsWithMachineGun,&Current->KillsWithRoboticMachineGun,&Current->KillsWithShockCoil,&Current->KillsWithRoboticShockCoil,&Current->KillsWithLaser,&Current->KillsWithRoboticLaser,&Current->KillsWithHyperdeath,&Current->KillsWithSuperHyperdeath,&Current->KillsWithKnife,&Current->KillsWithGrenade,&Current->KillsWithRoboticGrenade,&Current->KillsWithUnknownWeapon,&Current->LastPlayTime.day,&Current->LastPlayTime.month,&Current->LastPlayTime.year,&Current->LastPlayTime.second,&Current->LastPlayTime.minute,&Current->LastPlayTime.hour,&Current->LastPlayTime.lTime);
555 }
556 fclose(LoadScores);
557 LoadHighestScores();
558 }
559 inline MetroidHighScoresNode *EveluateHighestScore(double highValue,double currentValue,MetroidHighScoresNode *High,MetroidHighScoresNode *Current)
560 {
561 if (highValue == currentValue)
562 {
563 selectRandomMatchingScore++;
564 if (Commands->Get_Random(0.0f,(float)selectRandomMatchingScore) < 0.5)
565 return Current;
566 }
567 else if (highValue < currentValue)
568 selectRandomMatchingScore = 0;
569 return (highValue >= currentValue ? High : Current);
570 }
571 inline MetroidHighScoresNode *EveluateHighestScore(unsigned long highValue,unsigned long currentValue,MetroidHighScoresNode *High,MetroidHighScoresNode *Current)
572 {
573 if (highValue == currentValue)
574 {
575 selectRandomMatchingScore++;
576 if (Commands->Get_Random(0.0f,(float)selectRandomMatchingScore) < 0.5)
577 return Current;
578 }
579 else if (highValue < currentValue)
580 selectRandomMatchingScore = 0;
581 return (highValue >= currentValue ? High : Current);
582 }
583 MetroidHighScoresNode *CompareHighScoreNodes(MetroidHighScoresNode *High,MetroidHighScoresNode *Current,int CompVal)
584 {
585 if (!High)
586 return Current;
587 switch (CompVal)
588 {
589 case 0:return EveluateHighestScore(High->PlayTime,Current->PlayTime,High,Current);
590 case 1:return EveluateHighestScore(High->IdleTime,Current->IdleTime,High,Current);
591 case 2:return EveluateHighestScore(High->Points,Current->Points,High,Current);
592 case 3:return EveluateHighestScore(High->MostPointsInARound,Current->MostPointsInARound,High,Current);
593 case 4:return EveluateHighestScore(High->HealthPackPoints,Current->HealthPackPoints,High,Current);
594 case 5:return EveluateHighestScore(High->RechargePoints,Current->RechargePoints,High,Current);
595 case 6:return EveluateHighestScore(High->DefenseGunPoints,Current->DefenseGunPoints,High,Current);
596 case 7:return EveluateHighestScore(High->TeleportPoints,Current->TeleportPoints,High,Current);
597 case 8:return EveluateHighestScore(High->ShieldUpgradePoints,Current->ShieldUpgradePoints,High,Current);
598 case 9:return EveluateHighestScore(High->WeaponSpawnPoints,Current->WeaponSpawnPoints,High,Current);
599 case 10:return EveluateHighestScore(High->Deaths,Current->Deaths,High,Current);
600 case 11:return EveluateHighestScore(High->DeathFromElectrifiedWater,Current->DeathFromElectrifiedWater,High,Current);
601 case 12:return EveluateHighestScore(High->DeathFromSpikePit,Current->DeathFromSpikePit,High,Current);
602 case 13:return EveluateHighestScore(High->DeathFromFallingOffTheTrain,Current->DeathFromFallingOffTheTrain,High,Current);
603 case 14:return EveluateHighestScore(High->DeathInLava,Current->DeathInLava,High,Current);
604 case 15:return EveluateHighestScore(High->DeathInRadioactivePit,Current->DeathInRadioactivePit,High,Current);
605 case 16:return EveluateHighestScore(High->DeathFromReactorRadiation,Current->DeathFromReactorRadiation,High,Current);
606 case 17:return EveluateHighestScore(High->DeathInFire,Current->DeathInFire,High,Current);
607 case 18:return EveluateHighestScore(High->DeathFromMiniBoss,Current->DeathFromMiniBoss,High,Current);
608 case 19:return EveluateHighestScore(High->KilledMiniBoss,Current->KilledMiniBoss,High,Current);
609 case 20:return EveluateHighestScore(High->DeathFromDefenseCameras,Current->DeathFromDefenseCameras,High,Current);
610 case 21:return EveluateHighestScore(High->DeathFromAliens,Current->DeathFromAliens,High,Current);
611 case 22:return EveluateHighestScore(High->DeathFromRobots,Current->DeathFromRobots,High,Current);
612 case 23:return EveluateHighestScore(High->DeathFromTraitors,Current->DeathFromTraitors,High,Current);
613 case 24:return EveluateHighestScore(High->DeathFromAttackCameras,Current->DeathFromAttackCameras,High,Current);
614 case 25:return EveluateHighestScore(High->DeathFromGunEmplacements,Current->DeathFromGunEmplacements,High,Current);
615 case 26:return EveluateHighestScore(High->DeathFromShredderTurret,Current->DeathFromShredderTurret,High,Current);
616 case 27:return EveluateHighestScore(High->DeathFromBansheeBoss,Current->DeathFromBansheeBoss,High,Current);
617 case 28:return EveluateHighestScore(High->DeathFromMineBoss,Current->DeathFromMineBoss,High,Current);
618 case 29:return EveluateHighestScore(High->DeathFromMineBossSquish,Current->DeathFromMineBossSquish,High,Current);
619 case 30:return EveluateHighestScore(High->DeathFromMineBossResources,Current->DeathFromMineBossResources,High,Current);
620 case 31:return EveluateHighestScore(High->Kills,Current->Kills,High,Current);
621 case 32:return EveluateHighestScore(High->Suicides,Current->Suicides,High,Current);
622 case 33:return EveluateHighestScore(High->KilledPlayers,Current->KilledPlayers,High,Current);
623 case 34:return EveluateHighestScore(High->KilledDefenseCameras,Current->KilledDefenseCameras,High,Current);
624 case 35:return EveluateHighestScore(High->KilledAliens,Current->KilledAliens,High,Current);
625 case 36:return EveluateHighestScore(High->KilledRobots,Current->KilledRobots,High,Current);
626 case 37:return EveluateHighestScore(High->KilledTraitors,Current->KilledTraitors,High,Current);
627 case 38:return EveluateHighestScore(High->KilledSecurityCameras,Current->KilledSecurityCameras,High,Current);
628 case 39:return EveluateHighestScore(High->KilledAttackCameras,Current->KilledAttackCameras,High,Current);
629 case 40:return EveluateHighestScore(High->KilledGunEmplacements,Current->KilledGunEmplacements,High,Current);
630 case 41:return EveluateHighestScore(High->KilledTurretBoss,Current->KilledTurretBoss,High,Current);
631 case 42:return EveluateHighestScore(High->KilledBansheeBoss,Current->KilledBansheeBoss,High,Current);
632 case 43:return EveluateHighestScore(High->KilledMineBoss,Current->KilledMineBoss,High,Current);
633 case 44:return EveluateHighestScore(High->Chapter1Completed,Current->Chapter1Completed,High,Current);
634 case 45:return EveluateHighestScore(High->Chapter2Completed,Current->Chapter2Completed,High,Current);
635 case 46:return EveluateHighestScore(High->Chapter3Completed,Current->Chapter3Completed,High,Current);
636 case 47:return EveluateHighestScore(High->Chapter4Completed,Current->Chapter4Completed,High,Current);
637 case 48:return EveluateHighestScore(High->Chapter5Completed,Current->Chapter5Completed,High,Current);
638 case 49:return EveluateHighestScore(High->Chapter6Completed,Current->Chapter6Completed,High,Current);
639 case 50:return EveluateHighestScore(High->Chapter7Completed,Current->Chapter7Completed,High,Current);
640 case 51:return EveluateHighestScore(High->Chapter8Completed,Current->Chapter8Completed,High,Current);
641 case 52:return EveluateHighestScore(High->Chapter9Completed,Current->Chapter9Completed,High,Current);
642 case 53:return EveluateHighestScore(High->Chapter10Completed,Current->Chapter10Completed,High,Current);
643 case 54:return EveluateHighestScore(High->TriggeredLockdown0,Current->TriggeredLockdown0,High,Current);
644 case 55:return EveluateHighestScore(High->TriggeredLockdown1,Current->TriggeredLockdown1,High,Current);
645 case 56:return EveluateHighestScore(High->TriggeredLockdown2,Current->TriggeredLockdown2,High,Current);
646 case 57:return EveluateHighestScore(High->TriggeredLockdown3,Current->TriggeredLockdown3,High,Current);
647 case 58:return EveluateHighestScore(High->TriggeredLockdown4,Current->TriggeredLockdown4,High,Current);
648 case 59:return EveluateHighestScore(High->TriggeredLockdown5,Current->TriggeredLockdown5,High,Current);
649 case 60:return EveluateHighestScore(High->TriggeredLockdown6,Current->TriggeredLockdown6,High,Current);
650 case 61:return EveluateHighestScore(High->TriggeredLockdown7,Current->TriggeredLockdown7,High,Current);
651 case 62:return EveluateHighestScore(High->TriggeredLockdown8,Current->TriggeredLockdown8,High,Current);
652 case 63:return EveluateHighestScore(High->TriggeredLockdown9,Current->TriggeredLockdown9,High,Current);
653 case 64:return EveluateHighestScore(High->PickedUpPlayerPlacedWeapon,Current->PickedUpPlayerPlacedWeapon,High,Current);
654 case 65:return EveluateHighestScore(High->PickedUpLaser,Current->PickedUpLaser,High,Current);
655 case 66:return EveluateHighestScore(High->PickedUpShotgun,Current->PickedUpShotgun,High,Current);
656 case 67:return EveluateHighestScore(High->PickedUpSniper,Current->PickedUpSniper,High,Current);
657 case 68:return EveluateHighestScore(High->PickedUpFlame,Current->PickedUpFlame,High,Current);
658 case 69:return EveluateHighestScore(High->PickedUpShockCoil,Current->PickedUpShockCoil,High,Current);
659 case 70:return EveluateHighestScore(High->PickedUpMachineGun,Current->PickedUpMachineGun,High,Current);
660 case 71:return EveluateHighestScore(High->PickedUpRoboticLaser,Current->PickedUpRoboticLaser,High,Current);
661 case 72:return EveluateHighestScore(High->PickedUpRoboticShotgun,Current->PickedUpRoboticShotgun,High,Current);
662 case 73:return EveluateHighestScore(High->PickedUpRoboticSniper,Current->PickedUpRoboticSniper,High,Current);
663 case 74:return EveluateHighestScore(High->PickedUpRoboticFlame,Current->PickedUpRoboticFlame,High,Current);
664 case 75:return EveluateHighestScore(High->PickedUpRoboticShockCoil,Current->PickedUpRoboticShockCoil,High,Current);
665 case 76:return EveluateHighestScore(High->PickedUpRoboticMachineGun,Current->PickedUpRoboticMachineGun,High,Current);
666 case 77:return EveluateHighestScore(High->PickedUpGlitchGun,Current->PickedUpGlitchGun,High,Current);
667 case 78:return EveluateHighestScore(High->PickedUpHealthPack,Current->PickedUpHealthPack,High,Current);
668 case 79:return EveluateHighestScore(High->PickedUpPlayerPlacedHealthPack,Current->PickedUpPlayerPlacedHealthPack,High,Current);
669 case 80:return EveluateHighestScore(High->PickedUpShieldUpgrade,Current->PickedUpShieldUpgrade,High,Current);
670 case 81:return EveluateHighestScore(High->PickedUpPlayerShieldUpgrade,Current->PickedUpPlayerShieldUpgrade,High,Current);
671 case 82:return EveluateHighestScore(High->PlacedMedPacks,Current->PlacedMedPacks,High,Current);
672 case 83:return EveluateHighestScore(High->PlacedRechargers,Current->PlacedRechargers,High,Current);
673 case 84:return EveluateHighestScore(High->PlacedTurrets,Current->PlacedTurrets,High,Current);
674 case 85:return EveluateHighestScore(High->PlacedTeleports,Current->PlacedTeleports,High,Current);
675 case 86:return EveluateHighestScore(High->PlacedShieldUpgrades,Current->PlacedShieldUpgrades,High,Current);
676 case 87:return EveluateHighestScore(High->PlacedWeaponSpawners,Current->PlacedWeaponSpawners,High,Current);
677 case 88:return EveluateHighestScore(High->UsedPlayerPlacedTeleport,Current->UsedPlayerPlacedTeleport,High,Current);
678 case 89:return EveluateHighestScore(High->PlayTimeAsClass0,Current->PlayTimeAsClass0,High,Current);
679 case 90:return EveluateHighestScore(High->PlayTimeAsClass1,Current->PlayTimeAsClass1,High,Current);
680 case 91:return EveluateHighestScore(High->PlayTimeAsClass2,Current->PlayTimeAsClass2,High,Current);
681 case 92:return EveluateHighestScore(High->PlayTimeAsClass3,Current->PlayTimeAsClass3,High,Current);
682 case 93:return EveluateHighestScore(High->PlayTimeAsClass4,Current->PlayTimeAsClass4,High,Current);
683 case 94:return EveluateHighestScore(High->PlayTimeAsClass5,Current->PlayTimeAsClass5,High,Current);
684 case 95:return EveluateHighestScore(High->PlayTimeAsClass6,Current->PlayTimeAsClass6,High,Current);
685 case 96:return EveluateHighestScore(High->PlayTimeAsClass7,Current->PlayTimeAsClass7,High,Current);
686 case 97:return EveluateHighestScore(High->PlayTimeAsClass8,Current->PlayTimeAsClass8,High,Current);
687 case 98:return EveluateHighestScore(High->PlayTimeAsClass9,Current->PlayTimeAsClass9,High,Current);
688 case 99:return EveluateHighestScore(High->PlayTimeAsClass10,Current->PlayTimeAsClass10,High,Current);
689 case 100:return EveluateHighestScore(High->PlayTimeAsClass11,Current->PlayTimeAsClass11,High,Current);
690 case 101:return EveluateHighestScore(High->CompletedPlayThroughs,Current->CompletedPlayThroughs,High,Current);
691 case 102:return EveluateHighestScore(High->DeathFromPlayers,Current->DeathFromPlayers,High,Current);
692 case 103:return EveluateHighestScore(High->LongestPlayTimeInARound,Current->LongestPlayTimeInARound,High,Current);
693 case 104:return EveluateHighestScore(High->SpawnedAsCharacter0,Current->SpawnedAsCharacter0,High,Current);
694 case 105:return EveluateHighestScore(High->SpawnedAsCharacter1,Current->SpawnedAsCharacter1,High,Current);
695 case 106:return EveluateHighestScore(High->SpawnedAsCharacter2,Current->SpawnedAsCharacter2,High,Current);
696 case 107:return EveluateHighestScore(High->SpawnedAsCharacter3,Current->SpawnedAsCharacter3,High,Current);
697 case 108:return EveluateHighestScore(High->SpawnedAsCharacter4,Current->SpawnedAsCharacter4,High,Current);
698 case 109:return EveluateHighestScore(High->SpawnedAsCharacter5,Current->SpawnedAsCharacter5,High,Current);
699 case 110:return EveluateHighestScore(High->SpawnedAsCharacter6,Current->SpawnedAsCharacter6,High,Current);
700 case 111:return EveluateHighestScore(High->SpawnedAsCharacter7,Current->SpawnedAsCharacter7,High,Current);
701 case 112:return EveluateHighestScore(High->SpawnedAsCharacter8,Current->SpawnedAsCharacter8,High,Current);
702 case 113:return EveluateHighestScore(High->SpawnedAsCharacter9,Current->SpawnedAsCharacter9,High,Current);
703 case 114:return EveluateHighestScore(High->KilledCrates,Current->KilledCrates,High,Current);
704 case 115:return EveluateHighestScore(High->PickedUpGrenadeLaunchers,Current->PickedUpGrenadeLaunchers,High,Current);
705 case 116:return EveluateHighestScore(High->ElevatorButtonsPressed,Current->ElevatorButtonsPressed,High,Current);
706 case 117:return EveluateHighestScore(High->ElevatorLockdownButton,Current->ElevatorLockdownButton,High,Current);
707 case 118:return EveluateHighestScore(High->KilledBrokenDoors,Current->KilledBrokenDoors,High,Current);
708 case 119:return EveluateHighestScore(High->GlitchModeFound,Current->GlitchModeFound,High,Current);
709 case 120:return EveluateHighestScore(High->GlitchModeCompleted,Current->GlitchModeCompleted,High,Current);
710 case 121:return EveluateHighestScore(High->FoundCheatGun,Current->FoundCheatGun,High,Current);
711 case 122:return EveluateHighestScore(High->OpenedFirstDoor,Current->OpenedFirstDoor,High,Current);
712 case 123:return EveluateHighestScore(High->GotKeycard,Current->GotKeycard,High,Current);
713 case 124:return EveluateHighestScore(High->KilledByRapids,Current->KilledByRapids,High,Current);
714 case 125:return EveluateHighestScore(High->KilledByFall,Current->KilledByFall,High,Current);
715 case 126:return EveluateHighestScore(High->TurnedOffLaserFence,Current->TurnedOffLaserFence,High,Current);
716 case 127:return EveluateHighestScore(High->BackLaserFence,Current->BackLaserFence,High,Current);
717 case 128:return EveluateHighestScore(High->ReactorPowerRestored,Current->ReactorPowerRestored,High,Current);
718 case 129:return EveluateHighestScore(High->ComputerConsolesDeactivated,Current->ComputerConsolesDeactivated,High,Current);
719 case 130:return EveluateHighestScore(High->CityShieldLowered,Current->CityShieldLowered,High,Current);
720 case 131:return EveluateHighestScore(High->ElectrifiedWaterTurnedOff,Current->ElectrifiedWaterTurnedOff,High,Current);
721 case 132:return EveluateHighestScore(High->TunnelEntryLowered,Current->TunnelEntryLowered,High,Current);
722 case 133:return EveluateHighestScore(High->KillsWithDefenseGun,Current->KillsWithDefenseGun,High,Current);
723 case 134:return EveluateHighestScore(High->KillsWithCheatGun,Current->KillsWithCheatGun,High,Current);
724 case 135:return EveluateHighestScore(High->KillsWithFlameUpgrade,Current->KillsWithFlameUpgrade,High,Current);
725 case 136:return EveluateHighestScore(High->KillsWithRoboticFlameUpgrade,Current->KillsWithRoboticFlameUpgrade,High,Current);
726 case 137:return EveluateHighestScore(High->KillsWithGlitchGun,Current->KillsWithGlitchGun,High,Current);
727 case 138:return EveluateHighestScore(High->KillsWithImperialist,Current->KillsWithImperialist,High,Current);
728 case 139:return EveluateHighestScore(High->KillsWithRoboticImperialist,Current->KillsWithRoboticImperialist,High,Current);
729 case 140:return EveluateHighestScore(High->KillsWithLaserShotgun,Current->KillsWithLaserShotgun,High,Current);
730 case 141:return EveluateHighestScore(High->KillsWithRoboticLaserShotgun,Current->KillsWithRoboticLaserShotgun,High,Current);
731 case 142:return EveluateHighestScore(High->KillsWithMachineGun,Current->KillsWithMachineGun,High,Current);
732 case 143:return EveluateHighestScore(High->KillsWithRoboticMachineGun,Current->KillsWithRoboticMachineGun,High,Current);
733 case 144:return EveluateHighestScore(High->KillsWithShockCoil,Current->KillsWithShockCoil,High,Current);
734 case 145:return EveluateHighestScore(High->KillsWithRoboticShockCoil,Current->KillsWithRoboticShockCoil,High,Current);
735 case 146:return EveluateHighestScore(High->KillsWithLaser,Current->KillsWithLaser,High,Current);
736 case 147:return EveluateHighestScore(High->KillsWithRoboticLaser,Current->KillsWithRoboticLaser,High,Current);
737 case 148:return EveluateHighestScore(High->KillsWithHyperdeath,Current->KillsWithHyperdeath,High,Current);
738 case 149:return EveluateHighestScore(High->KillsWithSuperHyperdeath,Current->KillsWithSuperHyperdeath,High,Current);
739 case 150:return EveluateHighestScore(High->KillsWithKnife,Current->KillsWithKnife,High,Current);
740 case 151:return EveluateHighestScore(High->KillsWithGrenade,Current->KillsWithGrenade,High,Current);
741 case 152:return EveluateHighestScore(High->KillsWithRoboticGrenade,Current->KillsWithRoboticGrenade,High,Current);
742 case 153:return EveluateHighestScore(High->KillsWithUnknownWeapon,Current->KillsWithUnknownWeapon,High,Current);
743 default:return EveluateHighestScore(High->PlayTimeInSpawnRoom,Current->PlayTimeInSpawnRoom,High,Current);
744 }
745 }
746 bool ReturnHighScoreNodeValue(MetroidHighScoresNode *Node,int CompVal)
747 {
748 if (!Node)
749 return false;
750 switch (CompVal)
751 {
752 case 0:return Node->PlayTime ? true : false;
753 case 1:return Node->IdleTime ? true : false;
754 case 2:return Node->Points ? true : false;
755 case 3:return Node->MostPointsInARound ? true : false;
756 case 4:return Node->HealthPackPoints ? true : false;
757 case 5:return Node->RechargePoints ? true : false;
758 case 6:return Node->DefenseGunPoints ? true : false;
759 case 7:return Node->TeleportPoints ? true : false;
760 case 8:return Node->ShieldUpgradePoints ? true : false;
761 case 9:return Node->WeaponSpawnPoints ? true : false;
762 case 10:return Node->Deaths ? true : false;
763 case 11:return Node->DeathFromElectrifiedWater ? true : false;
764 case 12:return Node->DeathFromSpikePit ? true : false;
765 case 13:return Node->DeathFromFallingOffTheTrain ? true : false;
766 case 14:return Node->DeathInLava ? true : false;
767 case 15:return Node->DeathInRadioactivePit ? true : false;
768 case 16:return Node->DeathFromReactorRadiation ? true : false;
769 case 17:return Node->DeathInFire ? true : false;
770 case 18:return Node->DeathFromMiniBoss ? true : false;
771 case 19:return Node->KilledMiniBoss ? true : false;
772 case 20:return Node->DeathFromDefenseCameras ? true : false;
773 case 21:return Node->DeathFromAliens ? true : false;
774 case 22:return Node->DeathFromRobots ? true : false;
775 case 23:return Node->DeathFromTraitors ? true : false;
776 case 24:return Node->DeathFromAttackCameras ? true : false;
777 case 25:return Node->DeathFromGunEmplacements ? true : false;
778 case 26:return Node->DeathFromShredderTurret ? true : false;
779 case 27:return Node->DeathFromBansheeBoss ? true : false;
780 case 28:return Node->DeathFromMineBoss ? true : false;
781 case 29:return Node->DeathFromMineBossSquish ? true : false;
782 case 30:return Node->DeathFromMineBossResources ? true : false;
783 case 31:return Node->Kills ? true : false;
784 case 32:return Node->Suicides ? true : false;
785 case 33:return Node->KilledPlayers ? true : false;
786 case 34:return Node->KilledDefenseCameras ? true : false;
787 case 35:return Node->KilledAliens ? true : false;
788 case 36:return Node->KilledRobots ? true : false;
789 case 37:return Node->KilledTraitors ? true : false;
790 case 38:return Node->KilledSecurityCameras ? true : false;
791 case 39:return Node->KilledAttackCameras ? true : false;
792 case 40:return Node->KilledGunEmplacements ? true : false;
793 case 41:return Node->KilledTurretBoss ? true : false;
794 case 42:return Node->KilledBansheeBoss ? true : false;
795 case 43:return Node->KilledMineBoss ? true : false;
796 case 44:return Node->Chapter1Completed ? true : false;
797 case 45:return Node->Chapter2Completed ? true : false;
798 case 46:return Node->Chapter3Completed ? true : false;
799 case 47:return Node->Chapter4Completed ? true : false;
800 case 48:return Node->Chapter5Completed ? true : false;
801 case 49:return Node->Chapter6Completed ? true : false;
802 case 50:return Node->Chapter7Completed ? true : false;
803 case 51:return Node->Chapter8Completed ? true : false;
804 case 52:return Node->Chapter9Completed ? true : false;
805 case 53:return Node->Chapter10Completed ? true : false;
806 case 54:return Node->TriggeredLockdown0 ? true : false;
807 case 55:return Node->TriggeredLockdown1 ? true : false;
808 case 56:return Node->TriggeredLockdown2 ? true : false;
809 case 57:return Node->TriggeredLockdown3 ? true : false;
810 case 58:return Node->TriggeredLockdown4 ? true : false;
811 case 59:return Node->TriggeredLockdown5 ? true : false;
812 case 60:return Node->TriggeredLockdown6 ? true : false;
813 case 61:return Node->TriggeredLockdown7 ? true : false;
814 case 62:return Node->TriggeredLockdown8 ? true : false;
815 case 63:return Node->TriggeredLockdown9 ? true : false;
816 case 64:return Node->PickedUpPlayerPlacedWeapon ? true : false;
817 case 65:return Node->PickedUpLaser ? true : false;
818 case 66:return Node->PickedUpShotgun ? true : false;
819 case 67:return Node->PickedUpSniper ? true : false;
820 case 68:return Node->PickedUpFlame ? true : false;
821 case 69:return Node->PickedUpShockCoil ? true : false;
822 case 70:return Node->PickedUpMachineGun ? true : false;
823 case 71:return Node->PickedUpRoboticLaser ? true : false;
824 case 72:return Node->PickedUpRoboticShotgun ? true : false;
825 case 73:return Node->PickedUpRoboticSniper ? true : false;
826 case 74:return Node->PickedUpRoboticFlame ? true : false;
827 case 75:return Node->PickedUpRoboticShockCoil ? true : false;
828 case 76:return Node->PickedUpRoboticMachineGun ? true : false;
829 case 77:return Node->PickedUpGlitchGun ? true : false;
830 case 78:return Node->PickedUpHealthPack ? true : false;
831 case 79:return Node->PickedUpPlayerPlacedHealthPack ? true : false;
832 case 80:return Node->PickedUpShieldUpgrade ? true : false;
833 case 81:return Node->PickedUpPlayerShieldUpgrade ? true : false;
834 case 82:return Node->PlacedMedPacks ? true : false;
835 case 83:return Node->PlacedRechargers ? true : false;
836 case 84:return Node->PlacedTurrets ? true : false;
837 case 85:return Node->PlacedTeleports ? true : false;
838 case 86:return Node->PlacedShieldUpgrades ? true : false;
839 case 87:return Node->PlacedWeaponSpawners ? true : false;
840 case 88:return Node->UsedPlayerPlacedTeleport ? true : false;
841 case 89:return Node->PlayTimeAsClass0 ? true : false;
842 case 90:return Node->PlayTimeAsClass1 ? true : false;
843 case 91:return Node->PlayTimeAsClass2 ? true : false;
844 case 92:return Node->PlayTimeAsClass3 ? true : false;
845 case 93:return Node->PlayTimeAsClass4 ? true : false;
846 case 94:return Node->PlayTimeAsClass5 ? true : false;
847 case 95:return Node->PlayTimeAsClass6 ? true : false;
848 case 96:return Node->PlayTimeAsClass7 ? true : false;
849 case 97:return Node->PlayTimeAsClass8 ? true : false;
850 case 98:return Node->PlayTimeAsClass9 ? true : false;
851 case 99:return Node->PlayTimeAsClass10 ? true : false;
852 case 100:return Node->PlayTimeAsClass11 ? true : false;
853 case 101:return Node->CompletedPlayThroughs ? true : false;
854 case 102:return Node->DeathFromPlayers ? true : false;
855 case 103:return Node->LongestPlayTimeInARound ? true : false;
856 case 104:return Node->SpawnedAsCharacter0 ? true : false;
857 case 105:return Node->SpawnedAsCharacter1 ? true : false;
858 case 106:return Node->SpawnedAsCharacter2 ? true : false;
859 case 107:return Node->SpawnedAsCharacter3 ? true : false;
860 case 108:return Node->SpawnedAsCharacter4 ? true : false;
861 case 109:return Node->SpawnedAsCharacter5 ? true : false;
862 case 110:return Node->SpawnedAsCharacter6 ? true : false;
863 case 111:return Node->SpawnedAsCharacter7 ? true : false;
864 case 112:return Node->SpawnedAsCharacter8 ? true : false;
865 case 113:return Node->SpawnedAsCharacter9 ? true : false;
866 case 114:return Node->KilledCrates ? true : false;
867 case 115:return Node->PickedUpGrenadeLaunchers ? true : false;
868 case 116:return Node->ElevatorButtonsPressed ? true : false;
869 case 117:return Node->ElevatorLockdownButton ? true : false;
870 case 118:return Node->KilledBrokenDoors ? true : false;
871 case 119:return Node->GlitchModeFound ? true : false;
872 case 120:return Node->GlitchModeCompleted ? true : false;
873 case 121:return Node->FoundCheatGun ? true : false;
874 case 122:return Node->OpenedFirstDoor ? true : false;
875 case 123:return Node->FoundCheatGun ? true : false;
876 case 124:return Node->KilledByRapids ? true : false;
877 case 125:return Node->KilledByFall ? true : false;
878 case 126:return Node->TurnedOffLaserFence ? true : false;
879 case 127:return Node->BackLaserFence ? true : false;
880 case 128:return Node->ReactorPowerRestored ? true : false;
881 case 129:return Node->ComputerConsolesDeactivated ? true : false;
882 case 130:return Node->CityShieldLowered ? true : false;
883 case 131:return Node->ElectrifiedWaterTurnedOff ? true : false;
884 case 132:return Node->TunnelEntryLowered ? true : false;
885 case 133:return Node->KillsWithDefenseGun ? true : false;
886 case 134:return Node->KillsWithCheatGun ? true : false;
887 case 135:return Node->KillsWithFlameUpgrade ? true : false;
888 case 136:return Node->KillsWithRoboticFlameUpgrade ? true : false;
889 case 137:return Node->KillsWithGlitchGun ? true : false;
890 case 138:return Node->KillsWithImperialist ? true : false;
891 case 139:return Node->KillsWithRoboticImperialist ? true : false;
892 case 140:return Node->KillsWithLaserShotgun ? true : false;
893 case 141:return Node->KillsWithRoboticLaserShotgun ? true : false;
894 case 142:return Node->KillsWithMachineGun ? true : false;
895 case 143:return Node->KillsWithRoboticMachineGun ? true : false;
896 case 144:return Node->KillsWithShockCoil ? true : false;
897 case 145:return Node->KillsWithRoboticShockCoil ? true : false;
898 case 146:return Node->KillsWithLaser ? true : false;
899 case 147:return Node->KillsWithRoboticLaser ? true : false;
900 case 148:return Node->KillsWithHyperdeath ? true : false;
901 case 149:return Node->KillsWithSuperHyperdeath ? true : false;
902 case 150:return Node->KillsWithKnife ? true : false;
903 case 151:return Node->KillsWithGrenade ? true : false;
904 case 152:return Node->KillsWithRoboticGrenade ? true : false;
905 case 153:return Node->KillsWithUnknownWeapon ? true : false;
906 default:return Node->PlayTimeInSpawnRoom ? true : false;
907 }
908 }
909 char *ReturnScore(MetroidHighScoresNode *High,int CompVal)
910 {
911 static char RetChar[200];
912 if (!High)
913 return " ";
914 switch (CompVal)
915 {
916 case 0:sprintf(RetChar,"Server Record: %s has played for %.0lf minutes.",High->PlayerName,High->PlayTime/60.0f);return RetChar;
917 case 1:sprintf(RetChar,"Server Record: %s been ilde for %.0lf minutes.",High->PlayerName,High->IdleTime/60.0f);return RetChar;
918 case 2:sprintf(RetChar,"Server Record: %s has scored a total of %.0lf points.",High->PlayerName,High->Points);return RetChar;
919 case 3:sprintf(RetChar,"Server Record: %s has socred %.0lf points in a single round.",High->PlayerName,High->MostPointsInARound);return RetChar;
920 case 4:sprintf(RetChar,"Server Record: %s has socred %.0lf points from placed Health Packs.",High->PlayerName,High->HealthPackPoints);return RetChar;
921 case 5:sprintf(RetChar,"Server Record: %s has socred %.0lf points Recharging Shields.",High->PlayerName,High->RechargePoints);return RetChar;
922 case 6:sprintf(RetChar,"Server Record: %s has scored %.0lf points via Defense Guns.",High->PlayerName,High->DefenseGunPoints);return RetChar;
923 case 7:sprintf(RetChar,"Server Record: %s has socred %.0lf points from Telepad use.",High->PlayerName,High->TeleportPoints);return RetChar;
924 case 8:sprintf(RetChar,"Server Record: %s has scored %.0lf points by handing out Shield Upgrades.",High->PlayerName,High->ShieldUpgradePoints);return RetChar;
925 case 9:sprintf(RetChar,"Server Record: %s has scored %.0lf points from placed Weapon Spawners.",High->PlayerName,High->WeaponSpawnPoints);return RetChar;
926 case 10:sprintf(RetChar,"Server Record: %s has been killed a total of %lu times.",High->PlayerName,High->Deaths);return RetChar;
927 case 11:sprintf(RetChar,"Server Record: %s has fallen into Electrified Water %lu times.",High->PlayerName,High->DeathFromElectrifiedWater);return RetChar;
928 case 12:sprintf(RetChar,"Server Record: %s has fallen into Spike Pits %lu times.",High->PlayerName,High->DeathFromSpikePit);return RetChar;
929 case 13:sprintf(RetChar,"Server Record: %s has fallen off the Train %lu times.",High->PlayerName,High->DeathFromFallingOffTheTrain);return RetChar;
930 case 14:sprintf(RetChar,"Server Record: %s has died in Lava %lu times.",High->PlayerName,High->DeathInLava);return RetChar;
931 case 15:sprintf(RetChar,"Server Record: %s has died in the Radioactive Pit %lu times.",High->PlayerName,High->DeathInRadioactivePit);return RetChar;
932 case 16:sprintf(RetChar,"Server Record: %s has died from radiation from the Reactor %lu times.",High->PlayerName,High->DeathFromReactorRadiation);return RetChar;
933 case 17:sprintf(RetChar,"Server Record: %s has died in Fire %lu times.",High->PlayerName,High->DeathInFire);return RetChar;
934 case 18:sprintf(RetChar,"Server Record: %s has been killed by the Boss Alien %lu times.",High->PlayerName,High->DeathFromMiniBoss);return RetChar;
935 case 19:sprintf(RetChar,"Server Record: %s has killed the Boss Alien %lu times.",High->PlayerName,High->KilledMiniBoss);return RetChar;
936 case 20:sprintf(RetChar,"Server Record: %s has been killed by Defense Turrets %lu times.",High->PlayerName,High->DeathFromDefenseCameras);return RetChar;
937 case 21:sprintf(RetChar,"Server Record: %s has been killed by Aliens %lu times.",High->PlayerName,High->DeathFromAliens);return RetChar;
938 case 22:sprintf(RetChar,"Server Record: %s has been killed by Robots %lu times.",High->PlayerName,High->DeathFromRobots);return RetChar;
939 case 23:sprintf(RetChar,"Server Record: %s has been killed by Traitors %lu times.",High->PlayerName,High->DeathFromTraitors);return RetChar;
940 case 24:sprintf(RetChar,"Server Record: %s has been killed by Attack Cameras %lu times.",High->PlayerName,High->DeathFromAttackCameras);return RetChar;
941 case 25:sprintf(RetChar,"Server Record: %s has been killed by Gun Emplacements %lu times.",High->PlayerName,High->DeathFromGunEmplacements);return RetChar;
942 case 26:sprintf(RetChar,"Server Record: %s has been killed by the Shredder Turret %lu times.",High->PlayerName,High->DeathFromShredderTurret);return RetChar;
943 case 27:sprintf(RetChar,"Server Record: %s has been killed by the Alien Strike Craft %lu times.",High->PlayerName,High->DeathFromBansheeBoss);return RetChar;
944 case 28:sprintf(RetChar,"Server Record: %s has been killed by the Mine Equipment %lu times.",High->PlayerName,High->DeathFromMineBoss);return RetChar;
945 case 29:sprintf(RetChar,"Server Record: %s has been squished by the Mine Equipment %lu times.",High->PlayerName,High->DeathFromMineBossSquish);return RetChar;
946 case 30:sprintf(RetChar,"Server Record: %s has been turned to resources by the Mine Equipment %lu times.",High->PlayerName,High->DeathFromMineBossResources);return RetChar;
947 case 31:sprintf(RetChar,"Server Record: %s has killed %lu enemies.",High->PlayerName,High->Kills);return RetChar;
948 case 32:sprintf(RetChar,"Server Record: %s has killed theirself %lu times.",High->PlayerName,High->Suicides);return RetChar;
949 case 33:sprintf(RetChar,"Server Record: %s has killed other players %lu times.",High->PlayerName,High->KilledPlayers);return RetChar;
950 case 34:sprintf(RetChar,"Server Record: %s has destroyed %lu Defense Cameras.",High->PlayerName,High->KilledDefenseCameras);return RetChar;
951 case 35:sprintf(RetChar,"Server Record: %s has killed %lu Aliens.",High->PlayerName,High->KilledAliens);return RetChar;
952 case 36:sprintf(RetChar,"Server Record: %s has destroyed %lu Robots.",High->PlayerName,High->KilledRobots);return RetChar;
953 case 37:sprintf(RetChar,"Server Record: %s has killed %lu Traitors.",High->PlayerName,High->KilledTraitors);return RetChar;
954 case 38:sprintf(RetChar,"Server Record: %s has destroyed %lu Security Cameras.",High->PlayerName,High->KilledSecurityCameras);return RetChar;
955 case 39:sprintf(RetChar,"Server Record: %s has destroyed %lu Attack Cameras.",High->PlayerName,High->KilledAttackCameras);return RetChar;
956 case 40:sprintf(RetChar,"Server Record: %s has destroyed %lu Gun Emplacements.",High->PlayerName,High->KilledGunEmplacements);return RetChar;
957 case 41:sprintf(RetChar,"Server Record: %s has destroyed the Shredder Turret %lu times.",High->PlayerName,High->KilledTurretBoss);return RetChar;
958 case 42:sprintf(RetChar,"Server Record: %s has destroyed the Alien Attack Craft %lu times.",High->PlayerName,High->KilledBansheeBoss);return RetChar;
959 case 43:sprintf(RetChar,"Server Record: %s has destroyed the Mine Equipment %lu times.",High->PlayerName,High->KilledMineBoss);return RetChar;
960 case 44:sprintf(RetChar,"Server Record: %s has completed Chapter 1 %lu times.",High->PlayerName,High->Chapter1Completed);return RetChar;
961 case 45:sprintf(RetChar,"Server Record: %s has completed Chapter 2 %lu times.",High->PlayerName,High->Chapter2Completed);return RetChar;
962 case 46:sprintf(RetChar,"Server Record: %s has completed Chapter 3 %lu times.",High->PlayerName,High->Chapter3Completed);return RetChar;
963 case 47:sprintf(RetChar,"Server Record: %s has completed Chapter 4 %lu times.",High->PlayerName,High->Chapter4Completed);return RetChar;
964 case 48:sprintf(RetChar,"Server Record: %s has completed Chapter 5 %lu times.",High->PlayerName,High->Chapter5Completed);return RetChar;
965 case 49:sprintf(RetChar,"Server Record: %s has completed Chapter 6 %lu times.",High->PlayerName,High->Chapter6Completed);return RetChar;
966 case 50:sprintf(RetChar,"Server Record: %s has completed Chapter 7 %lu times.",High->PlayerName,High->Chapter7Completed);return RetChar;
967 case 51:sprintf(RetChar,"Server Record: %s has completed Chapter 8 %lu times",High->PlayerName,High->Chapter8Completed);return RetChar;
968 case 52:sprintf(RetChar,"Server Record: %s has completed Chapter 9 %lu times",High->PlayerName,High->Chapter9Completed);return RetChar;
969 case 53:sprintf(RetChar,"Server Record: %s has completed Chapter 10 %lu times",High->PlayerName,High->Chapter10Completed);return RetChar;
970 case 54:sprintf(RetChar,"Server Record: %s has triggered Lockdown Zone 1 %lu times.",High->PlayerName,High->TriggeredLockdown0);return RetChar;
971 case 55:sprintf(RetChar,"Server Record: %s has triggered Lockdown Zone 2 %lu times.",High->PlayerName,High->TriggeredLockdown1);return RetChar;
972 case 56:sprintf(RetChar,"Server Record: %s has triggered Lockdown Zone 3 %lu times.",High->PlayerName,High->TriggeredLockdown2);return RetChar;
973 case 57:sprintf(RetChar,"Server Record: %s has triggered Lockdown Zone 4 %lu times.",High->PlayerName,High->TriggeredLockdown3);return RetChar;
974 case 58:sprintf(RetChar,"Server Record: %s has triggered Lockdown Zone 5 %lu times.",High->PlayerName,High->TriggeredLockdown4);return RetChar;
975 case 59:sprintf(RetChar,"Server Record: %s has triggered Lockdown Zone 6 %lu times.",High->PlayerName,High->TriggeredLockdown5);return RetChar;
976 case 60:sprintf(RetChar,"Server Record: %s has triggered Lockdown Zone 7 %lu times.",High->PlayerName,High->TriggeredLockdown6);return RetChar;
977 case 61:sprintf(RetChar,"Server Record: %s has triggered Lockdown Zone 8 %lu times.",High->PlayerName,High->TriggeredLockdown7);return RetChar;
978 case 62:sprintf(RetChar,"Server Record: %s has triggered Lockdown Zone 9 %lu times.",High->PlayerName,High->TriggeredLockdown8);return RetChar;
979 case 63:sprintf(RetChar,"Server Record: %s has triggered Lockdown Zone 10 %lu times.",High->PlayerName,High->TriggeredLockdown9);return RetChar;
980 case 64:sprintf(RetChar,"Server Record: %s has acquired %lu weapons placed by other players.",High->PlayerName,High->PickedUpPlayerPlacedWeapon);return RetChar;
981 case 65:sprintf(RetChar,"Server Record: %s has acquired %lu Laser Gun upgrades.",High->PlayerName,High->PickedUpLaser);return RetChar;
982 case 66:sprintf(RetChar,"Server Record: %s has acquired %lu Laser Shotgun upgrades.",High->PlayerName,High->PickedUpShotgun);return RetChar;
983 case 67:sprintf(RetChar,"Server Record: %s has acquired %lu Imperialist upgrades.",High->PlayerName,High->PickedUpSniper);return RetChar;
984 case 68:sprintf(RetChar,"Server Record: %s has acquired %lu Flame upgrades.",High->PlayerName,High->PickedUpFlame);return RetChar;
985 case 69:sprintf(RetChar,"Server Record: %s has acquired %lu Shock Coil upgrades.",High->PlayerName,High->PickedUpShockCoil);return RetChar;
986 case 70:sprintf(RetChar,"Server Record: %s has acquired %lu Machinegun upgrades.",High->PlayerName,High->PickedUpMachineGun);return RetChar;
987 case 71:sprintf(RetChar,"Server Record: %s has acquired %lu Robotic Laser Gun upgrades.",High->PlayerName,High->PickedUpRoboticLaser);return RetChar;
988 case 72:sprintf(RetChar,"Server Record: %s has acquired %lu Robotic Laser Shotgun upgrades.",High->PlayerName,High->PickedUpRoboticShotgun);return RetChar;
989 case 73:sprintf(RetChar,"Server Record: %s has acquired %lu Robotic Imperialist upgrades.",High->PlayerName,High->PickedUpRoboticSniper);return RetChar;
990 case 74:sprintf(RetChar,"Server Record: %s has acquired %lu Robotic Flame upgrades.",High->PlayerName,High->PickedUpRoboticFlame);return RetChar;
991 case 75:sprintf(RetChar,"Server Record: %s has acquired %lu Robotic Shock Coil upgrades.",High->PlayerName,High->PickedUpRoboticShockCoil);return RetChar;
992 case 76:sprintf(RetChar,"Server Record: %s has acquired %lu Robotic Machinegun upgrades.",High->PlayerName,High->PickedUpRoboticMachineGun);return RetChar;
993 case 77:sprintf(RetChar,"Server Record: %s has acquired %lu Glitch Guns.",High->PlayerName,High->PickedUpGlitchGun);return RetChar;
994 case 78:sprintf(RetChar,"Server Record: %s has acquired %lu Health Packs.",High->PlayerName,High->PickedUpHealthPack);return RetChar;
995 case 79:sprintf(RetChar,"Server Record: %s has acquired %lu player placed Health Packs.",High->PlayerName,High->PickedUpPlayerPlacedHealthPack);return RetChar;
996 case 80:sprintf(RetChar,"Server Record: %s has acquired %lu Shield Upgrades.",High->PlayerName,High->PickedUpShieldUpgrade);return RetChar;
997 case 81:sprintf(RetChar,"Server Record: %s has acquired %lu player placed Shield Upgrades.",High->PlayerName,High->PickedUpPlayerShieldUpgrade);return RetChar;
998 case 82:sprintf(RetChar,"Server Record: %s has placed %lu Med Packs.",High->PlayerName,High->PlacedMedPacks);return RetChar;
999 case 83:sprintf(RetChar,"Server Record: %s has placed %lu Shield Rechargers.",High->PlayerName,High->PlacedRechargers);return RetChar;
1000 case 84:sprintf(RetChar,"Server Record: %s has placed %lu Defense Turrets.",High->PlayerName,High->PlacedTurrets);return RetChar;
1001 case 85:sprintf(RetChar,"Server Record: %s has placed %lu Telepads.",High->PlayerName,High->PlacedTeleports);return RetChar;
1002 case 86:sprintf(RetChar,"Server Record: %s has placed %lu Shield Upgrades.",High->PlayerName,High->PlacedShieldUpgrades);return RetChar;
1003 case 87:sprintf(RetChar,"Server Record: %s has placed %lu Weapon Spawners.",High->PlayerName,High->PlacedWeaponSpawners);return RetChar;
1004 case 88:sprintf(RetChar,"Server Record: %s has used %lu player placed Telepads.",High->PlayerName,High->UsedPlayerPlacedTeleport);return RetChar;
1005 case 89:sprintf(RetChar,"Server Record: %s has played as Armor Mode for %.0lf mintues.",High->PlayerName,High->PlayTimeAsClass0/60.0);return RetChar;
1006 case 90:sprintf(RetChar,"Server Record: %s has played as Speed Mode for %.0lf mintues.",High->PlayerName,High->PlayTimeAsClass1/60.0);return RetChar;
1007 case 91:sprintf(RetChar,"Server Record: %s has played as Firepower Mode for %.0lf mintues.",High->PlayerName,High->PlayTimeAsClass2/60.0);return RetChar;
1008 case 92:sprintf(RetChar,"Server Record: %s has played as Support Mode for %.0lf mintues.",High->PlayerName,High->PlayTimeAsClass3/60.0);return RetChar;
1009 case 93:sprintf(RetChar,"Server Record: %s has played as Defense Mode for %.0lf mintues.",High->PlayerName,High->PlayTimeAsClass4/60.0);return RetChar;
1010 case 94:sprintf(RetChar,"Server Record: %s has played as Mode for %.0lf mintues.",High->PlayerName,High->PlayTimeAsClass5/60.0);return RetChar;
1011 case 95:sprintf(RetChar,"Server Record: %s has played as Supply Mode for %.0lf mintues.",High->PlayerName,High->PlayTimeAsClass6/60.0);return RetChar;
1012 case 96:sprintf(RetChar,"Server Record: %s has played as N/A Mode for %.0lf mintues.",High->PlayerName,High->PlayTimeAsClass7/60.0);return RetChar;
1013 case 97:sprintf(RetChar,"Server Record: %s has played as N/A Mode for %.0lf mintues.",High->PlayerName,High->PlayTimeAsClass8/60.0);return RetChar;
1014 case 98:sprintf(RetChar,"Server Record: %s has played as Cheat Mode for %.0lf mintues.",High->PlayerName,High->PlayTimeAsClass9/60.0);return RetChar;
1015 case 99:sprintf(RetChar,"Server Record: %s has played as Training Mode for %.0lf mintues.",High->PlayerName,High->PlayTimeAsClass10/60.0);return RetChar;
1016 case 100:sprintf(RetChar,"Server Record: %s has played as N/A Mode for %.0lf mintues.",High->PlayerName,High->PlayTimeAsClass11/60.0);return RetChar;
1017 case 101:sprintf(RetChar,"Server Record: %s has completed the story %lu times.",High->PlayerName,High->CompletedPlayThroughs);return RetChar;
1018 case 102:sprintf(RetChar,"Server Record: %s has been killed by friendly fire %lu times.",High->PlayerName,High->DeathFromPlayers);return RetChar;
1019 case 103:sprintf(RetChar,"Server Record: %s has spent %.0lf minutes in a single game.",High->PlayerName,High->LongestPlayTimeInARound/60.0);return RetChar;
1020 case 104:sprintf(RetChar,"Server Record: %s has spawned as Armor Mode %lu times.",High->PlayerName,High->SpawnedAsCharacter0);return RetChar;
1021 case 105:sprintf(RetChar,"Server Record: %s has spawned as Speed Mode %lu times.",High->PlayerName,High->SpawnedAsCharacter1);return RetChar;
1022 case 106:sprintf(RetChar,"Server Record: %s has spawned as Firepower Mode %lu times.",High->PlayerName,High->SpawnedAsCharacter2);return RetChar;
1023 case 107:sprintf(RetChar,"Server Record: %s has spawned as Support Mode %lu times.",High->PlayerName,High->SpawnedAsCharacter3);return RetChar;
1024 case 108:sprintf(RetChar,"Server Record: %s has spawned as Defense Mode %lu times.",High->PlayerName,High->SpawnedAsCharacter4);return RetChar;
1025 case 109:sprintf(RetChar,"Server Record: %s has spawned as Supply Mode %lu times.",High->PlayerName,High->SpawnedAsCharacter5);return RetChar;
1026 case 110:sprintf(RetChar,"Server Record: %s has spawned as N/A Mode %lu times.",High->PlayerName,High->SpawnedAsCharacter6);return RetChar;
1027 case 111:sprintf(RetChar,"Server Record: %s has spawned as N/A Mode %lu times.",High->PlayerName,High->SpawnedAsCharacter7);return RetChar;
1028 case 112:sprintf(RetChar,"Server Record: %s has spawned as N/A Mode %lu times.",High->PlayerName,High->SpawnedAsCharacter8);return RetChar;
1029 case 113:sprintf(RetChar,"Server Record: %s has spawned as Cheat Mode %lu times.",High->PlayerName,High->SpawnedAsCharacter9);return RetChar;
1030 case 114:sprintf(RetChar,"Server Record: %s has destroyed %lu crates.",High->PlayerName,High->KilledCrates);return RetChar;
1031 case 115:sprintf(RetChar,"Server Record: %s has acquired %lu Grenade Launcher upgrades.",High->PlayerName,High->PickedUpGrenadeLaunchers);return RetChar;
1032 case 116:sprintf(RetChar,"Server Record: %s has activated %lu elevator buttons.",High->PlayerName,High->ElevatorButtonsPressed);return RetChar;
1033 case 117:sprintf(RetChar,"Server Record: %s has deactivated %lu drill security lockouts.",High->PlayerName,High->ElevatorLockdownButton);return RetChar;
1034 case 118:sprintf(RetChar,"Server Record: %s has destroyed the jammed doors %lu times.",High->PlayerName,High->KilledBrokenDoors);return RetChar;
1035 case 119:sprintf(RetChar,"Server Record: %s has found the glitch %lu times.",High->PlayerName,High->GlitchModeFound);return RetChar;
1036 case 120:sprintf(RetChar,"Server Record: %s has escaped the glitch %lu times.",High->PlayerName,High->GlitchModeCompleted);return RetChar;
1037 case 121:sprintf(RetChar,"Server Record: %s has acquired The Cheat Gun %lu times.",High->PlayerName,High->FoundCheatGun);return RetChar;
1038 case 122:sprintf(RetChar,"Server Record: %s has opened the security room door %lu times.",High->PlayerName,High->OpenedFirstDoor);return RetChar;
1039 case 123:sprintf(RetChar,"Server Record: %s has acquired %lu keycards.",High->PlayerName,High->GotKeycard);return RetChar;
1040 case 124:sprintf(RetChar,"Server Record: %s has fallen into the rapids %lu times.",High->PlayerName,High->KilledByRapids);return RetChar;
1041 case 125:sprintf(RetChar,"Server Record: %s has fallen off the cliff %lu times.",High->PlayerName,High->KilledByFall);return RetChar;
1042 case 126:sprintf(RetChar,"Server Record: %s has turned off the laser fence %lu times.",High->PlayerName,High->TurnedOffLaserFence);return RetChar;
1043 case 127:sprintf(RetChar,"Server Record: %s has turned off the back laser fence %lu times.",High->PlayerName,High->BackLaserFence);return RetChar;
1044 case 128:sprintf(RetChar,"Server Record: %s has restored the reactor power %lu times.",High->PlayerName,High->ReactorPowerRestored);return RetChar;
1045 case 129:sprintf(RetChar,"Server Record: %s has deactivated %lu computer consoles.",High->PlayerName,High->ComputerConsolesDeactivated);return RetChar;
1046 case 130:sprintf(RetChar,"Server Record: %s has lowered the city laser fence %lu times.",High->PlayerName,High->CityShieldLowered);return RetChar;
1047 case 131:sprintf(RetChar,"Server Record: %s has turned off the electrified water %lu times.",High->PlayerName,High->ElectrifiedWaterTurnedOff);return RetChar;
1048 case 132:sprintf(RetChar,"Server Record: %s has turned off the laser fence blocking the building %lu times.",High->PlayerName,High->TunnelEntryLowered);return RetChar;
1049 case 133:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Deployable Defense Turret.",High->PlayerName,High->KillsWithDefenseGun);return RetChar;
1050 case 134:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Cheating Gun.",High->PlayerName,High->KillsWithCheatGun);return RetChar;
1051 case 135:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Flame Upgrade.",High->PlayerName,High->KillsWithFlameUpgrade);return RetChar;
1052 case 136:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Robotic Flame Upgrade.",High->PlayerName,High->KillsWithRoboticFlameUpgrade);return RetChar;
1053 case 137:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Glitch Gun.",High->PlayerName,High->KillsWithGlitchGun);return RetChar;
1054 case 138:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Imperialist.",High->PlayerName,High->KillsWithImperialist);return RetChar;
1055 case 139:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Robotic Imperalist.",High->PlayerName,High->KillsWithRoboticImperialist);return RetChar;
1056 case 140:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Laser Shotgun.",High->PlayerName,High->KillsWithLaserShotgun);return RetChar;
1057 case 141:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Robotic Laser Shotgun.",High->PlayerName,High->KillsWithRoboticLaserShotgun);return RetChar;
1058 case 142:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Machinegun.",High->PlayerName,High->KillsWithMachineGun);return RetChar;
1059 case 143:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Robotic Machinegun.",High->PlayerName,High->KillsWithRoboticMachineGun);return RetChar;
1060 case 144:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Shock Coil.",High->PlayerName,High->KillsWithShockCoil);return RetChar;
1061 case 145:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Robotic Shock Coil.",High->PlayerName,High->KillsWithRoboticShockCoil);return RetChar;
1062 case 146:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Laser.",High->PlayerName,High->KillsWithLaser);return RetChar;
1063 case 147:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Robotic Laser.",High->PlayerName,High->KillsWithRoboticLaser);return RetChar;
1064 case 148:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Kinetic Cannon.",High->PlayerName,High->KillsWithHyperdeath);return RetChar;
1065 case 149:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Energy Beam.",High->PlayerName,High->KillsWithSuperHyperdeath);return RetChar;
1066 case 150:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Knife.",High->PlayerName,High->KillsWithKnife);return RetChar;
1067 case 151:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Grenade Launcher.",High->PlayerName,High->KillsWithGrenade);return RetChar;
1068 case 152:sprintf(RetChar,"Server Record: %s has killed %ld enemies with the Robotic Grenade Launcher.",High->PlayerName,High->KillsWithRoboticGrenade);return RetChar;
1069 case 153:sprintf(RetChar,"Server Record: %s has killed %ld enemies with an Unknown Device.",High->PlayerName,High->KillsWithUnknownWeapon);return RetChar;
1070 default:sprintf(RetChar,"Server Record: %s has spent %.0lf minutes in the spawn room.",High->PlayerName,High->PlayTimeInSpawnRoom/60.0);return RetChar;
1071 }
1072 }
1073 void StateHighScore()
1074 {
1075 int LastHighScoreList = 1;
1076 int Random = Commands->Get_Random_Int(0,MetroidHIGHSCORELISTCOUNT+1);
1077 int attempts = 0;
1078MetroidStartOfHighScoreSelectProcess:
1079 selectRandomMatchingScore = 0;
1080 MetroidHighScoresNode *Current = MetroidHighScoresNodeList,*Best = NULL;
1081 while (Current)
1082 {
1083 Best = CompareHighScoreNodes(Best,Current,Random);
1084 Current = Current->next;
1085 }
1086 if (!ReturnHighScoreNodeValue(Best,Random))
1087 {
1088 if (LastHighScoreList <= 5)
1089 {
1090 LastHighScoreList++;
1091 if (Random+1 < MetroidHIGHSCORELISTCOUNT)
1092 Random++;
1093 else
1094 Random = 1;
1095 }
1096 else
1097 {
1098 LastHighScoreList = 0;
1099 Random = 0;
1100 }
1101 attempts++;
1102 if (attempts < 100)
1103 goto MetroidStartOfHighScoreSelectProcess;
1104 else
1105 return;
1106 }
1107 char DisplayMessage[128];
1108 sprintf(DisplayMessage,"%s",ReturnScore(Best,Random));
1109 for (int x = 1;x < 128;x++)
1110 {
1111 GameObject *Player = Get_GameObj(x);
1112 if (Player)
1113 JmgUtility::DisplayChatMessage(Player,6,145,148,DisplayMessage);
1114 }
1115 }
1116};
1117
1118MetroidScoreSystem MetroidScoreControl = MetroidScoreSystem();
1119
1120void SaveMetroidHighScores()
1121{
1122 MetroidScoreControl.SaveData();
1123}
1124char *MetroidStringLibrary(int StringID)
1125{
1126 switch (StringID)
1127 {
1128 //case :return "";
1129 case 0:return "Checkpoint 1 Unlocked!";
1130 case 1:return "Checkpoint 2 Unlocked!";
1131 case 2:return "Checkpoint 3 Unlocked!";
1132 case 3:return "Checkpoint 4 Unlocked!";
1133 case 4:return "Checkpoint 5 Unlocked!";
1134 case 5:return "Final checkpoint unlocked!";
1135 case 6:return "Laser Wall Deactivated.";
1136 case 7:return "The back gate has been unlocked.";
1137 case 8:return "Power has been shut off.";
1138 case 9:return "Emergency power restored.";
1139 case 10:return "Power failure! Please re activate power!";
1140 case 11:return "Shield lowered.";
1141 case 12:return "Lockdown ended. Gate has been lowered.";
1142 case 13:return "Proceed to the mining facility.";
1143 case 14:return "Deactivate the lockdown and clear all security alerts.";
1144 case 15:return "All-clear, reactivating operations.";
1145 case 16:return "Dactivate the facility's shielding via the 3 control panels.";
1146 case 17:return "Mining Equipment Destroyed!";
1147 case 18:return "Quarantine lifted, laser gate powered off.";
1148 case 19:return "Eliminate the hazardous lifeform to end the quarantine.";
1149 case 20:return "Kill the guards to cancel the lockdown.";
1150 case 21:return "?????";
1151 case 22:return "Turret destroyed lockdown averted.";
1152 case 23:return "Lockdown canceled, laser gate powered off.";
1153 case 24:return "Mash the action key to hack the terminal.";
1154 case 25:return "Good work!";
1155 default:return "HUD STRING NOT FOUND!";
1156 }
1157}
1158
1159void Set_Shader_Number_Vector(GameObject *Player,int eventid,Vector4 parameter)
1160{
1161 if (eventid == -1)
1162 return;
1163 if (parameter.X == 4920036.0f)
1164 {// Metroid HUD Text
1165 char text[220];
1166 sprintf_s(text,"%s",MetroidStringLibrary(eventid));
1167 JmgUtility::DisplayChatMessage(Player,(int)(parameter.Y*255),(int)(parameter.Z*255),(int)(parameter.W*255),text);
1168 }
1169 if (parameter.X == 4920037.0f)
1170 {// Metroid Disarm HUD text
1171 char textString[256];
1172 switch (eventid)
1173 {
1174 case 99:sprintf_s(textString,"Control panel deactivated (%.0f/3)",parameter.Y); Set_HUD_Help_Text_Player_Text(Player,7233,textString,Vector3(0.0,1.0,0.0));break;
1175 case 999:sprintf_s(textString,"Incorrect code! Counter measures activated!");break;
1176 case 998:sprintf_s(textString,"A terminal has been reset!");break;
1177 case 997:sprintf_s(textString,"You moved out of range!");break;
1178 case 0:sprintf_s(textString,"Press Numpad 0!");break;
1179 case 1:sprintf_s(textString,"Press Numpad 1!");break;
1180 case 2:sprintf_s(textString,"Press Numpad 2!");break;
1181 case 3:sprintf_s(textString,"Press Numpad 3!");break;
1182 case 4:sprintf_s(textString,"Press Numpad 4!");break;
1183 case 5:sprintf_s(textString,"Press Numpad 5!");break;
1184 case 6:sprintf_s(textString,"Press Numpad 6!");break;
1185 case 7:sprintf_s(textString,"Press Numpad 7!");break;
1186 case 8:sprintf_s(textString,"Press Numpad 8!");break;
1187 case 9:sprintf_s(textString,"Press Numpad 9!");break;
1188 default:sprintf_s(textString,"INVALID DISARM STRING!");break;
1189 }
1190 if (eventid == 999 || eventid == 998 || eventid == 997)
1191 JmgUtility::DisplayChatMessage(Player,(int)(1.0f*255),(int)(0.1f*255),(int)(0.1f*255),textString);
1192 else if (eventid == 99)
1193 JmgUtility::DisplayChatMessage(Player,(int)(0.0f*255),(int)(0.5f*255),(int)(1.0f*255),textString);
1194 else
1195 JmgUtility::DisplayChatMessage(Player,(int)(0.1f*255),(int)(1.0f*255),(int)(0.1f*255),textString);
1196 }
1197
1198 if (parameter.X == 4920038.0f)
1199 {// Metroid Special Objective HUD text
1200 char textString[256];
1201 switch (eventid)
1202 {
1203 case 0:
1204 if ((int)parameter.Y != 3)
1205 {
1206 sprintf_s(textString,"Security Console Deactivated (%d/3)",(int)parameter.Y);
1207 Set_HUD_Help_Text_Player_Text(Player,7233,textString,Vector3(0.0,1.0,0.0));
1208 }
1209 else
1210 sprintf_s(textString,"Security restrictions cleared, resuming operations.");
1211 break;
1212 default:sprintf_s(textString,"INVALID DISARM STRING!");break;
1213 }
1214 JmgUtility::DisplayChatMessage(Player,(int)(0.0f*255),(int)(0.5f*255),(int)(1.0f*255),textString);
1215 }
1216}
1217Vector3 JMGGetClosestStar(const Vector3 &Pos)
1218{
1219 GameObject *AStar = Commands->Get_A_Star(Pos);
1220 if (AStar)
1221 return Commands->Get_Position(AStar);
1222 return Pos;
1223}
1224
1225class MetroidTempPlayerData
1226{
1227public:
1228 struct TempPlayerDataNode
1229 {
1230 char playerName[128];
1231 bool firstJoin;
1232 time_t destroyTime;
1233 struct TempPlayerDataNode *next;
1234 TempPlayerDataNode(const char *playerName)
1235 {
1236 firstJoin = true;
1237 destroyTime = NULL;
1238 if (playerName)
1239 sprintf(this->playerName,"%s",playerName);
1240 else
1241 sprintf(this->playerName,"");
1242 next = NULL;
1243 }
1244 void clearData()
1245 {
1246 }
1247 };
1248 struct TempPlayerDataNode *players[128];
1249private:
1250 struct TempPlayerDataNode *inactivePlayerData;
1251 struct TempPlayerDataNode *dummyNode;
1252 TempPlayerDataNode *FindPlayerNode(const char *playerName)
1253 {
1254 TempPlayerDataNode *Current = inactivePlayerData;
1255 if (!inactivePlayerData)
1256 return (inactivePlayerData = new TempPlayerDataNode(playerName));
1257 while (Current)
1258 {
1259 if (!_stricmp(Current->playerName,playerName))
1260 return Current;
1261 if (!Current->next)
1262 return (Current->next = new TempPlayerDataNode(playerName));
1263 Current = Current->next;
1264 }
1265 return NULL;
1266 }
1267public:
1268 MetroidTempPlayerData()
1269 {
1270 dummyNode = new TempPlayerDataNode("");
1271 for (int x = 0;x < 128;x++)
1272 players[x] = NULL;
1273 players[0] = dummyNode;
1274 inactivePlayerData = NULL;
1275 }
1276 void getPlayerNode(GameObject *player)
1277 {
1278 if (!player)
1279 return;
1280 int playerId = JmgUtility::JMG_Get_Player_ID(player);
1281 if (!playerId)
1282 return;
1283 if (!players[playerId] || _stricmp(players[playerId]->playerName,Get_Player_Name(player)))
1284 players[playerId] = FindPlayerNode(Get_Player_Name(player));
1285 }
1286 void Cleanup()
1287 {
1288 TempPlayerDataNode *temp = inactivePlayerData,*die;
1289 while (temp)
1290 {
1291 die = temp;
1292 die->clearData();
1293 temp = temp->next;
1294 delete die;
1295 }
1296 inactivePlayerData = NULL;
1297 for (int x = 1;x < 128;x++)
1298 players[x] = NULL;
1299 }
1300};
1301MetroidTempPlayerData mPlayerData;
1302
1303class JMG_Metroid_Hide_On_Enter : public ScriptImpClass {
1304 void Entered(GameObject *obj,GameObject *enter);
1305};
1306
1307class JMG_Metroid_Gibs_On_Enter : public ScriptImpClass {
1308 void Entered(GameObject *obj,GameObject *enter);
1309};
1310
1311class JMG_Metroid_Increase_Perk_Unlock_On_Enter : public ScriptImpClass {
1312 void Entered(GameObject *obj,GameObject *enter);
1313};
1314
1315class JMG_Metroid_HUD_Message_On_Enter : public ScriptImpClass {
1316 void Entered(GameObject *obj,GameObject *enter);
1317 void Timer_Expired(GameObject *obj,int number);
1318};
1319
1320class JMG_Metroid_Game_Initilization : public ScriptImpClass {
1321 void Created(GameObject *obj);
1322 void Destroyed(GameObject *obj);
1323public:
1324 static bool IsRp2Hosted;
1325};
1326bool JMG_Metroid_Game_Initilization::IsRp2Hosted = false;
1327
1328struct BriefingTextNode
1329{
1330 char Text[512];
1331 float Delay;
1332 BriefingTextNode *next;
1333 BriefingTextNode(const char *text)
1334 {
1335 Delay = 0.0f;
1336 sprintf(Text,"%s",text);
1337 next = NULL;
1338 }
1339 BriefingTextNode(const char *text,float delay)
1340 {
1341 Delay = delay;
1342 sprintf(Text,"%s",text);
1343 next = NULL;
1344 }
1345 BriefingTextNode()
1346 {
1347 next = NULL;
1348 }
1349};
1350
1351class JMG_Metroid_Game_Control : public ScriptImpClass {
1352 int lastPlayerCount;
1353 void Created(GameObject *obj);
1354 void Timer_Expired(GameObject *obj,int number);
1355 void Destroyed(GameObject *obj);
1356 void IncreasePlayerTimeScores();
1357 static void AddNewTextNode(int playerId);
1358 static void RemoveTextNodes(int playerId);
1359public:
1360 JMG_Metroid_Game_Control();
1361 static void ParseBriefingString(const char *text,int playerId);
1362 static int EnemyShieldRegenStartTime;
1363 static BriefingTextNode *briefingText[128];
1364 static BriefingTextNode *currentNode[128];
1365 static int currentBriefingId;
1366 static int gameRemainingTime;
1367};
1368int JMG_Metroid_Game_Control::EnemyShieldRegenStartTime = 5;
1369BriefingTextNode *JMG_Metroid_Game_Control::briefingText[128];
1370BriefingTextNode *JMG_Metroid_Game_Control::currentNode[128];
1371int JMG_Metroid_Game_Control::currentBriefingId;
1372int JMG_Metroid_Game_Control::gameRemainingTime = 0;
1373
1374class JMG_Metroid_Character_Control : public ScriptImpClass {
1375 int PlayerID;
1376 int LastWeaponID;
1377 int LastAmmoCount;
1378 float IgnoreDamage;
1379 void Created(GameObject *obj);
1380 void Timer_Expired(GameObject *obj,int number);
1381 void Custom(GameObject *obj,int message,int param,GameObject *sender);
1382 void Damaged(GameObject *obj,GameObject *damager,float damage);
1383 void Killed(GameObject *obj, GameObject *damager);
1384 void Destroyed(GameObject *obj);
1385 void ClearBeacons(GameObject *obj,int ArmorMode);
1386};
1387
1388class JMG_Metroid_Hide_Object_On_Death : public ScriptImpClass {
1389 void Killed(GameObject *obj, GameObject *damager);
1390};
1391
1392class AmbushPointSystem
1393{
1394private:
1395 struct AmbushPointNode
1396 {
1397 int ID;
1398 Vector3 targetPos;
1399 struct AmbushPointNode *next;
1400 AmbushPointNode(Vector3 Pos,int id)
1401 {
1402 ID = id;
1403 targetPos = Pos;
1404 next = NULL;
1405 }
1406 };
1407public:
1408 struct CoverPointNode
1409 {
1410 int ID;
1411 int gameID;
1412 int GroupID;
1413 int GuardCount;
1414 bool Crouch;
1415 bool HidingSpot;
1416 Vector3 coverPos;
1417 int AmbushPoints;
1418 AmbushPointNode *AmbushPointNodeList;
1419 struct CoverPointNode *next;
1420 CoverPointNode(GameObject *obj,int id,int groupID,bool crouch,bool hidingSpot)
1421 {
1422 GuardCount = 0;
1423 ID = id;
1424 gameID = Commands->Get_ID(obj);
1425 GroupID = groupID;
1426 Crouch = crouch;
1427 HidingSpot = hidingSpot;
1428 coverPos = Commands->Get_Position(obj);
1429 AmbushPoints = 0;
1430 AmbushPointNodeList = NULL;
1431 next = NULL;
1432 Commands->Destroy_Object(obj);
1433 }
1434 void AddPoint(GameObject *obj)
1435 {
1436 Vector3 Pos = Commands->Get_Position(obj);
1437 int id = Commands->Get_ID(obj);
1438 Commands->Destroy_Object(obj);
1439 AmbushPointNode *Current = AmbushPointNodeList;
1440 AmbushPoints++;
1441 if (!Current)
1442 AmbushPointNodeList = new AmbushPointNode(Pos,id);
1443 while (Current)
1444 {
1445 if (Current->ID == id)
1446 {
1447 AmbushPoints--;
1448 char Err[512];
1449 sprintf(Err,"msg ERROR: Ambush Point %d already in list!",id);
1450 Console_Input(Err);
1451 return;
1452 }
1453 if (!Current->next)
1454 {
1455 Current->next = new AmbushPointNode(Pos,id);
1456 return;
1457 }
1458 Current = Current->next;
1459 }
1460 };
1461 Vector3 GetRandomAmbushPoint()
1462 {
1463 if (!AmbushPoints)
1464 return Vector3(0.0f,0.0f,0.0f);
1465 int random = Commands->Get_Random_Int(0,AmbushPoints*2);
1466 AmbushPointNode *Current = AmbushPointNodeList;
1467 while (Current)
1468 {
1469 if (random)
1470 random--;
1471 if (!random)
1472 return Current->targetPos;
1473 Current = Current->next;
1474 if (!Current)
1475 Current = AmbushPointNodeList;
1476 }
1477 return Vector3(0.0f,0.0f,0.0f);
1478 }
1479 void Empty_List()
1480 {
1481 AmbushPointNode *temp = AmbushPointNodeList,*die;
1482 while (temp)
1483 {
1484 die = temp;
1485 temp = temp->next;
1486 delete die;
1487 }
1488 AmbushPointNodeList = NULL;
1489 }
1490 };
1491private:
1492 int CoverPointCount;
1493 CoverPointNode *CoverPointNodeList;
1494 int CountCoverPointsInGroup(int groupID)
1495 {
1496 int Count = 0;
1497 CoverPointNode *Current = CoverPointNodeList;
1498 while (Current)
1499 {
1500 if (Current->GroupID == groupID)
1501 Count++;
1502 Current = Current->next;
1503 }
1504 return Count;
1505 }
1506 float FindClosestStar(const Vector3 &Pos)
1507 {
1508 float Distance = -1;
1509 for (int x = 1;x < 128;x++)
1510 {
1511 GameObject *Star = Get_GameObj(x);
1512 if (!Star)
1513 continue;
1514 float Temp = JmgUtility::SimpleDistance(Commands->Get_Position(Star),Pos);
1515 if (Distance == -1 || Temp < Distance)
1516 Distance = Temp;
1517 }
1518 return Distance;
1519 }
1520public:
1521 AmbushPointSystem()
1522 {
1523 CoverPointCount = 1;
1524 CoverPointNodeList = NULL;
1525 }
1526 void NewCoverPoint(GameObject *obj,int ID,int groupID,bool crouch,bool hidingSpot)
1527 {
1528 CoverPointCount++;
1529 CoverPointNode *Current = CoverPointNodeList;
1530 if (!Current)
1531 CoverPointNodeList = new CoverPointNode(obj,ID,groupID,crouch,hidingSpot);
1532 while (Current)
1533 {
1534 if (Current->ID == ID)
1535 {
1536 CoverPointCount--;
1537 char Err[512];
1538 sprintf(Err,"msg ERROR: Cover Point %d already in list!",ID);
1539 Console_Input(Err);
1540 return;
1541 }
1542 if (!Current->next)
1543 {
1544 Current->next = new CoverPointNode(obj,ID,groupID,crouch,hidingSpot);
1545 return;
1546 }
1547 Current = Current->next;
1548 }
1549 }
1550 void AddAmbushPoint(GameObject *obj,int ID)
1551 {
1552 CoverPointNode *Current = CoverPointNodeList;
1553 while (Current)
1554 {
1555 if (Current->ID == ID)
1556 {
1557 Current->AddPoint(obj);
1558 return;
1559 }
1560 Current = Current->next;
1561 }
1562 char Err[512];
1563 sprintf(Err,"msg ERROR: Ambush Point %d does not exist!",ID);
1564 Console_Input(Err);
1565 }
1566 void CoverPointStabilityTest()
1567 {
1568 CoverPointNode *Current = CoverPointNodeList;
1569 while (Current)
1570 {
1571 if (!Current->AmbushPointNodeList)
1572 {
1573 char Err[512];
1574 sprintf(Err,"msg ERROR: Cover Point %d has no Ambush points!",Current->gameID);
1575 Console_Input(Err);
1576 }
1577 Current = Current->next;
1578 }
1579 }
1580 CoverPointNode *FindBestCoverPoint(const Vector3 &MyPos,Vector3 *TargetPos,int groupID,float MyMaxDistance,float TargetMaxDist,int MaxSoldiersAtCP)
1581 {
1582 CoverPointNode *Current = CoverPointNodeList;
1583 CoverPointNode *Best = NULL;
1584 Vector3 Closest;
1585 float dist = 0.0f;
1586 while (Current)
1587 {
1588 if (Current->GroupID == groupID && (!MaxSoldiersAtCP || Current->GuardCount < MaxSoldiersAtCP) && (MyMaxDistance <= 0 || MyMaxDistance >= JmgUtility::SimpleDistance(MyPos,Current->coverPos)))
1589 {
1590 AmbushPointNode *Current2 = Current->AmbushPointNodeList;
1591 while (Current2)
1592 {
1593 if (TargetMaxDist == 0.0f || FindClosestStar(Current2->targetPos) < TargetMaxDist)
1594 {
1595 float Temp = JmgUtility::SimpleDistance(*TargetPos,Current2->targetPos);
1596 if (!Best || Temp < dist)
1597 {
1598 Best = Current;
1599 dist = Temp;
1600 Closest = Current2->targetPos;
1601 }
1602 }
1603 Current2 = Current2->next;
1604 }
1605 }
1606 Current = Current->next;
1607 }
1608 return Best;
1609 }
1610 CoverPointNode *GetRandomCoverPoint(Vector3 *TargetPos,const Vector3 &SearchLocation,int groupID,int MaxSoldiersAtCP,float MaxDistance)
1611 {
1612 CoverPointNode *Current = CoverPointNodeList;
1613 int Random = Commands->Get_Random_Int(0,CoverPointCount);
1614 int Count = 0;
1615 int AttemptCount = 0;
1616 while (Current)
1617 {
1618 float Temp = MaxDistance ? JmgUtility::SimpleDistance(SearchLocation,Current->coverPos) : 0.0f;
1619 if (Current->GroupID == groupID && (!MaxSoldiersAtCP || Current->GuardCount < MaxSoldiersAtCP) && Temp <= MaxDistance)
1620 {
1621 if (Count >= Random)
1622 {
1623 Random = Commands->Get_Random_Int(0,Current->AmbushPoints*2);
1624 Count = 0;
1625 AmbushPointNode *Current2 = Current->AmbushPointNodeList;
1626 while (Current2)
1627 {
1628 if (Count >= Random)
1629 {
1630 *TargetPos = Current2->targetPos;
1631 return Current;
1632 }
1633 Count++;
1634 Current2 = Current2->next;
1635 if (!Current2)
1636 Current2 = Current->AmbushPointNodeList;
1637 }
1638 }
1639 Count++;
1640 }
1641 Current = Current->next;
1642 if (!Current && AttemptCount < 100)
1643 Current = CoverPointNodeList,AttemptCount++;
1644 }
1645 return NULL;
1646 }
1647 CoverPointNode *GetGoodHidingSpot(Vector3 *TargetDirection,int groupID,int MaxSoldiersAtCP)
1648 {
1649 int GroupPointCount = CountCoverPointsInGroup(groupID);
1650 int Random = Commands->Get_Random_Int(0,CoverPointCount*2);
1651 int HidingSpotBonus = JmgUtility::MathClampInt((int)(GroupPointCount*0.1f),1,99);
1652 int Count = 0;
1653 int MaxAttempts = 0;
1654 CoverPointNode *Current = CoverPointNodeList;
1655 while (Current)
1656 {
1657 if (Current->GroupID == groupID && FindClosestStar(Current->coverPos) >= 2500)
1658 {
1659 Count++;
1660 if (Count+(Current->HidingSpot ? HidingSpotBonus : 0) >= Random)
1661 return Current;
1662 }
1663 Current = Current->next;
1664 if (!Current && MaxAttempts < 10)
1665 {
1666 MaxAttempts++;
1667 Current = CoverPointNodeList;
1668 }
1669 }
1670 return NULL;
1671 }
1672 void CheckForErrors()
1673 {
1674 CoverPointNode *Current = CoverPointNodeList;
1675 while (Current)
1676 {
1677 if (!Current->AmbushPoints)
1678 {
1679 char errorMsg[512];
1680 sprintf(errorMsg,"msg AmbushPointSystem ERROR: ObjectID:%d PointID:%d has no target points!",Current->gameID,Current->ID);
1681 Console_Input(errorMsg);
1682 }
1683 Current = Current->next;
1684 }
1685 }
1686 void EmptyList()
1687 {
1688 CoverPointNode *Current = CoverPointNodeList,*die = NULL;
1689 while (Current)
1690 {
1691 Current->Empty_List();
1692 die = Current;
1693 Current = Current->next;
1694 delete die;
1695 }
1696 CoverPointNodeList = NULL;
1697 }
1698};
1699
1700AmbushPointSystem AmbushPointSystemControl = AmbushPointSystem();
1701
1702class JMG_Metroid_New_Ambush_Cover_Point : public ScriptImpClass {
1703 void Created(GameObject *obj);
1704};
1705
1706class JMG_Metroid_New_Ambush_Attack_Point : public ScriptImpClass {
1707 void Created(GameObject *obj);
1708 void Timer_Expired(GameObject *obj,int number);
1709};
1710
1711class JMG_Metroid_Move_To_Random_Ambush_Spot : public ScriptImpClass {
1712 AmbushPointSystem::CoverPointNode *AmbushPoint;
1713 AmbushPointSystem::CoverPointNode *CurrentAmbushPoint;
1714 Vector3 StartPos;
1715 Vector3 FaceLocation;
1716 Vector3 LastMoveToLocation;
1717 Vector3 MyLastPos;
1718 int faceReset;
1719 int LastEnemyID;
1720 bool ImAtPoint;
1721 bool InnateEnabled;
1722 int EnemySeen;
1723 int currentEnemyID;
1724 void Created(GameObject *obj);
1725 void Enemy_Seen(GameObject *obj,GameObject *seen);
1726 void Timer_Expired(GameObject *obj,int number);
1727 void Damaged(GameObject *obj,GameObject *damager,float damage);
1728 void Action_Complete(GameObject *obj,int action,ActionCompleteReason reason);
1729 void Destroyed(GameObject *obj);
1730 bool SelectRandomAmbushSpot(GameObject *obj);
1731 void QuitAmbushMove(GameObject *obj);
1732 void FaceAmbushLocation(GameObject *obj);
1733public:
1734 JMG_Metroid_Move_To_Random_Ambush_Spot()
1735 {
1736 AmbushPoint = NULL;
1737 CurrentAmbushPoint = NULL;
1738 }
1739};
1740
1741class JMG_Metroid_Mine_Tower_Control : public ScriptImpClass {
1742 int LockDownSignIDs[3];
1743 int LockDownButtonIDs[3];
1744 bool Activated[3];
1745 int PendingActivation;
1746 void Created(GameObject *obj);
1747 void Timer_Expired(GameObject *obj,int number);
1748 void Custom(GameObject *obj,int message,int param,GameObject *sender);
1749 void Destroyed(GameObject *obj);
1750};
1751
1752class JMG_Metroid_Send_Custom_On_Poke : public ScriptImpClass {
1753 void Poked(GameObject *obj,GameObject *poker);
1754};
1755
1756class MetroidBossPathControl
1757{
1758public:
1759 struct AIPathNode;
1760private:
1761 struct LinkedAIPathNodes
1762 {
1763 struct AIPathNode *Node;
1764 struct LinkedAIPathNodes *next;
1765 LinkedAIPathNodes(AIPathNode *LinkNode)
1766 {
1767 Node = LinkNode;
1768 next = NULL;
1769 };
1770 };
1771public:
1772 struct AIPathNode
1773 {
1774 int PointID;
1775 char PathName[128];
1776 float MaxDeviation;
1777 int NumberOfLinks;
1778 Vector3 Position;
1779 struct LinkedAIPathNodes *MyLinks;
1780 struct AIPathNode *next;
1781 AIPathNode(GameObject *obj,const char *NodeName,float MaxDeviation)
1782 {
1783 sprintf(PathName,"%s",NodeName);
1784 MaxDeviation = abs(MaxDeviation);
1785 NumberOfLinks = 0;
1786 Position = Commands->Get_Position(obj);
1787 PointID = Commands->Get_ID(obj);
1788 MyLinks = NULL;
1789 next = NULL;
1790 }
1791 void AddLinkNode(AIPathNode *LinkNode)
1792 {
1793 if (!LinkNode)
1794 return;
1795 LinkedAIPathNodes *Current = MyLinks;
1796 if (!Current)
1797 MyLinks = new LinkedAIPathNodes(LinkNode);
1798 while (Current)
1799 {
1800 if (!Current->next)
1801 {
1802 Current->next = new LinkedAIPathNodes(LinkNode);
1803 return;
1804 }
1805 Current = Current->next;
1806 }
1807 }
1808 AIPathNode *GetNextRoadPoint()
1809 {
1810 if (NumberOfLinks == 1)
1811 return MyLinks->Node;
1812 int x = 0,Rand = Commands->Get_Random_Int(0,(NumberOfLinks+1));
1813 LinkedAIPathNodes *Current = MyLinks;
1814 while (Current)
1815 {
1816 if (Rand <= x)
1817 return Current->Node;
1818 x++;
1819 Current = Current->next;
1820 if (!Current)
1821 Current = MyLinks;
1822 }
1823 return NULL;
1824 }
1825 void Empty_List()
1826 {
1827 LinkedAIPathNodes *temp = MyLinks,*die;
1828 while (temp)
1829 {
1830 die = temp;
1831 temp = temp->next;
1832 delete die;
1833 }
1834 MyLinks = NULL;
1835 }
1836 const char *ReturnNodes()
1837 {
1838 static char String[512];
1839 sprintf(String,"");
1840 LinkedAIPathNodes *temp = MyLinks;
1841 while (temp)
1842 {
1843 sprintf(String,"%s%s ",String,temp->Node->PathName);
1844 temp = temp->next;
1845 }
1846 return String;
1847 }
1848 };
1849private:
1850 AIPathNode *AIPathNodeList;
1851public:
1852 MetroidBossPathControl()
1853 {
1854 AIPathNodeList = NULL;
1855 };
1856 AIPathNode *AddNode(GameObject *obj,const char *NodeName,float MaxDeviation)
1857 {
1858 AIPathNode *Current = AIPathNodeList;
1859 if (!Current)
1860 {
1861 AIPathNodeList = new AIPathNode(obj,NodeName,MaxDeviation);
1862 return AIPathNodeList;
1863 }
1864 while (Current)
1865 {
1866 if (!_stricmp(Current->PathName,NodeName))
1867 {
1868 char aERROR[512];
1869 sprintf(aERROR,"MESSAGE ERROR There is already a node with the name %s the list!",NodeName);
1870 Console_Input(aERROR);
1871 return Current;
1872 }
1873 else if (!Current->next)
1874 {
1875 Current->next = new AIPathNode(obj,NodeName,MaxDeviation);
1876 return Current->next;
1877 }
1878 Current = Current->next;
1879 }
1880 return NULL;
1881 }
1882 AIPathNode *Find_AIPathNode_Node(const char *NodeName)
1883 {
1884 if (!AIPathNodeList)
1885 return NULL;
1886 AIPathNode *Current = AIPathNodeList;
1887 while (Current)
1888 {
1889 if (!_stricmp(Current->PathName,NodeName))
1890 return Current;
1891 Current = Current->next;
1892 }
1893 return NULL;
1894 }
1895 int Find_AIPathNode_Node_ID(const char *NodeName)
1896 {
1897 if (!AIPathNodeList)
1898 return 0;
1899 AIPathNode *Current = AIPathNodeList;
1900 while (Current)
1901 {
1902 if (!_stricmp(Current->PathName,NodeName))
1903 return Current->PointID;
1904 Current = Current->next;
1905 }
1906 char aERROR[128];
1907 sprintf(aERROR,"MESSAGE Find_AIPathNode_Node_ID - ERROR: NODE ID FOR %s NOT FOUND!",NodeName);
1908 Console_Input(aERROR);
1909 return 0;
1910 }
1911 AIPathNode *GetNearestRoadNode(const Vector3 &Pos)
1912 {
1913 float ClosestDistance = 99999.0f;
1914 AIPathNode *Best = NULL;
1915 AIPathNode *Current = AIPathNodeList;
1916 while (Current)
1917 {
1918 float TempDistance = JmgUtility::SimpleDistance(Pos,Current->Position);
1919 if (TempDistance < ClosestDistance)
1920 {
1921 ClosestDistance = TempDistance;
1922 Best = Current;
1923 }
1924 Current = Current->next;
1925 }
1926 return Best;
1927 }
1928 void EmptyList()
1929 {
1930 AIPathNode *Current = AIPathNodeList,*die = NULL;
1931 while (Current)
1932 {
1933 Current->Empty_List();
1934 die = Current;
1935 Current = Current->next;
1936 delete die;
1937 }
1938 AIPathNodeList = NULL;
1939 }
1940 void PrintNodes()
1941 {
1942 AIPathNode *Current = AIPathNodeList;
1943 while (Current)
1944 {
1945 char msg[256];
1946 sprintf(msg,"msg Node:%s->%s",Current->PathName,Current->ReturnNodes());
1947 Console_Input(msg);
1948 Current = Current->next;
1949 }
1950 }
1951};
1952
1953MetroidBossPathControl MetroidBossPathControlSystem = MetroidBossPathControl();
1954
1955class JMG_Metroid_AI_Path_Node : public ScriptImpClass {
1956 MetroidBossPathControl::AIPathNode *MyNode;//Low Risk
1957 void Created(GameObject *obj);
1958 void Timer_Expired(GameObject *obj,int number);
1959};
1960
1961class MetroidSabotagedCrateSystem
1962{
1963private:
1964 struct CrateNode
1965 {
1966 int ID;
1967 float Facing;
1968 Vector3 Position;
1969 struct CrateNode *next;
1970 CrateNode(GameObject *obj)
1971 {
1972 ID = Commands->Get_ID(obj);
1973 Facing = Commands->Get_Facing(obj);
1974 Position = Commands->Get_Position(obj);
1975 next = NULL;
1976 }
1977 };
1978 CrateNode *CrateNodeList;
1979 void deleteObject(int ID)
1980 {
1981 if (!CrateNodeList)
1982 return;
1983 CrateNode *Current = CrateNodeList,*Prev = NULL;
1984 while (Current)
1985 {
1986 if (Current->ID == ID)
1987 {
1988 if (!Prev)
1989 CrateNodeList = CrateNodeList->next;
1990 else if (Current->next)
1991 Prev->next = Current->next;
1992 else
1993 Prev->next = NULL;
1994 delete Current;
1995 break;
1996 }
1997 Prev = Current;
1998 Current = Current->next;
1999 }
2000 }
2001public:
2002 MetroidSabotagedCrateSystem()
2003 {
2004 CrateNodeList = NULL;
2005 }
2006 MetroidSabotagedCrateSystem &operator += (GameObject *obj)
2007 {
2008 Vector3 Pos = Commands->Get_Position(obj);
2009 CrateNode *Current = CrateNodeList;
2010 if (!CrateNodeList)
2011 CrateNodeList = new CrateNode(obj);
2012 while (Current)
2013 {
2014 if (JmgUtility::SimpleDistance(Pos,Current->Position) < 0.1f)
2015 {
2016 Current->ID = Commands->Get_ID(obj);
2017 return *this;
2018 }
2019 if (!Current->next)
2020 {
2021 Current->next = new CrateNode(obj);
2022 break;
2023 }
2024 Current = Current->next;
2025 }
2026 return *this;
2027 };
2028 void RecreateCrates()
2029 {
2030 CrateNode *Current = CrateNodeList;
2031 while (Current)
2032 {
2033 GameObject *Crate = Commands->Create_Object("Explosive_Rigged_Trooper_Crate",Current->Position);
2034 Commands->Set_Facing(Crate,Current->Facing);
2035 Current = Current->next;
2036 }
2037 }
2038 void TriggerExplosives()
2039 {
2040 CrateNode *Current = CrateNodeList;
2041 while (Current)
2042 {
2043 GameObject *Crate = Commands->Find_Object(Current->ID);
2044 if (Crate)
2045 Commands->Apply_Damage(Crate,9999.9f,"BlamoKiller",0);
2046 Current = Current->next;
2047 }
2048 }
2049 void EmptyList()
2050 {
2051 CrateNode *Current = CrateNodeList,*die = NULL;
2052 while (Current)
2053 {
2054 die = Current;
2055 Current = Current->next;
2056 delete die;
2057 }
2058 CrateNodeList = NULL;
2059 }
2060};
2061
2062MetroidSabotagedCrateSystem MetroidSabotagedCrateSystemControl = MetroidSabotagedCrateSystem();
2063
2064#define METROIDOBJECTIVECOUNT 22
2065struct MetroidGame
2066{
2067private:
2068 char *MetroidDialogStrings(int StringID)
2069 {
2070 switch (StringID)
2071 {
2072 //case :return "";
2073 case 0:return "Laser wall active, find the switch!";
2074 case 1:return "WARNING: DOOR JAMMED! Use explosives to proceed!";
2075 case 2:return "Security alert cancelled.";
2076 case 3:return "Power failure! Please re-activate power!";
2077 case 4:return "Train is loaded and ready for departure.";
2078 case 5:return "Planetary magma core unstable. Earthquake warning at level 5.";
2079 case 6:return "Warning: Reactor shields offline!";
2080 case 7:return "Reactor shields functioning normally.";
2081 case 8:return "WARNING: Waste leak detected! Drains activated.";
2082 case 9:return "Warning: Electrified water detected! Deactivate power to proceed.";
2083 case 10:return "Gary was here, Ash is a loser";
2084 case 11:return "Lockdown cancelled, laser wall shutdown.";
2085 case 12:return "Security Alert Cancelled.";
2086 case 13:return "Test your jumping here.";
2087 case 14:return "Target practice.";
2088 case 15:return "I AM A COMPUTER, PLEASE HAVE SEX WITH ME.";
2089 case 16:return "Rule 29: On the internet, all girls are men, and all kids are undercover FBI agents or Perverted Justice Decoys.";
2090 case 17:return "Look out for more secrets like this!";
2091 case 18:return "Elevator disabled while Lockdown is active.";
2092 case 19:return "Good job, you beat the map!";
2093 case 20:return "Sorry: Game was won and the area you were in had to be reset.";
2094 case 21:return "Console has already been deactivated!";
2095 case 22:return "Power restored to teleporter network.";
2096 case 23:return "Codes to mining facility 40351 acquired.";
2097 case 24:return "Hazardous Anomaly Detected Quarantine Activated.";
2098 case 25:return "Hazardous Anomaly Eliminated, Quarantine Deactivated, have a nice day.";
2099 case 26:return "Intruders detected, guards dispatched.";
2100 case 27:return "Contact lost with guards, lockdown canceled.";
2101 case 28:return "Welcome to teleporter base Alpha 006. Co-ordinates have been set. Standing by.";
2102 case 29:return "Operation Deep Penetration: Offworld resource colony Z416 has been captured by enemy forces. Recover the mining facility at all costs.";
2103 case 30:return "Plecos are awesome";
2104 case 31:return "You will have a much easier time if you just run past the camera up ahead; the operator is not paying much attention.";
2105 case 32:return "Cameras are often placed near remote or unguarded passageways; avoid or destroy them before they have a chance to spot you.";
2106 case 33:return "You were seen by a camera, try again.";
2107 case 34:return "Good work, looks like you've mastered cameras!";
2108 case 35:return "Practice avoiding cameras.";
2109 case 40:return "?????";
2110 case 41:return "Turret Destroyed";
2111 case 12821:return "Press E to activate this computer terminal, press 'E' when the screen is Green to hack, 'E' on red will reset progress and shock you, 10 successful presses will hack the terminal.";
2112 case 12822:return "Good Job!";
2113 default:return "DISPLAY STRING NOT FOUND!";
2114 }
2115 }
2116public:
2117 int BossID;
2118 int BossMode;
2119 bool BossDefeated;
2120 int NumberOfDeactivatedTerminals;
2121 int MineTerminalID[3];
2122 bool MineTerminalDeactivated[3];
2123 int MineTerminalReset[3];
2124 bool DisplayedObjective[METROIDOBJECTIVECOUNT];
2125 int FinalCheckpointShieldWallID;
2126 bool MainElevatorDown;
2127 int LastPlayerCount;
2128 float DamageMultiplier;
2129 int BossDefeatedMusicID;
2130 bool deactivatedLaserFence;
2131 bool backLaserFence;
2132 bool reactorPowerRestored;
2133 bool cityShieldLowered;
2134 bool electrifiedWaterTurnedOff;
2135 bool tunnelEntryLowered;
2136 int winMusicId;
2137 MetroidGame()
2138 {
2139 LastPlayerCount = 0;
2140 DamageMultiplier = 0;
2141 MainElevatorDown = false;
2142 NumberOfDeactivatedTerminals = 0;
2143 BossID = 0;
2144 BossMode = 0;
2145 BossDefeated = false;
2146 BossDefeatedMusicID = 0;
2147 winMusicId = 0;
2148 for (int x = 0;x < 3;x++)
2149 {
2150 MineTerminalID[x] = 0;
2151 MineTerminalDeactivated[x] = false;
2152 MineTerminalReset[x] = 0;
2153 }
2154 for (int x = 0;x < METROIDOBJECTIVECOUNT;x++)
2155 DisplayedObjective[x] = false;
2156 deactivatedLaserFence = false;
2157 backLaserFence = false;
2158 reactorPowerRestored = false;
2159 cityShieldLowered = false;
2160 electrifiedWaterTurnedOff = false;
2161 tunnelEntryLowered = false;
2162 }
2163 void CheckForPlayerCountUpdate()
2164 {
2165 int PlayerCount = Get_Player_Count();
2166 if (LastPlayerCount == PlayerCount)
2167 return;
2168 LastPlayerCount = PlayerCount;
2169 if (!PlayerCount)
2170 return;
2171 DamageMultiplier = (PlayerCount/(4.000f+PlayerCount)*2.000f)-1.0f;
2172 }
2173 void DeactivateTerminal(GameObject *obj,int TerminalID)
2174 {
2175 for (int x = 0;x < 3;x++)
2176 if (TerminalID == MineTerminalID[x])
2177 {
2178 if (!MineTerminalDeactivated[x])
2179 {
2180 GameObject *Terminal = Commands->Find_Object(MineTerminalID[x]);
2181 if (Terminal)
2182 {
2183 Commands->Enable_HUD_Pokable_Indicator(Terminal,false);
2184 Commands->Set_Animation(Terminal,"hackterminal.hackterminal",false,0,190.0f,190.0f,false);
2185 }
2186 MineTerminalDeactivated[x] = true;
2187 MineTerminalReset[x] = 300;
2188 NumberOfDeactivatedTerminals++;
2189 MetroidScoreControl.MetroidPlayerHighScoreNodes[JmgUtility::JMG_Get_Player_ID(obj)]->ComputerConsolesDeactivated++;
2190 for (int y = 1;y < 128;y++)
2191 {
2192 GameObject *Player = Get_GameObj(y);
2193 if (!Player)
2194 continue;
2195 Set_Shader_Number_Vector(Player,99,Vector4(4920037.0f,(float)NumberOfDeactivatedTerminals,0.0f,0.0f));
2196 Commands->Send_Custom_Event(Player,Player,9870923,TerminalID,0);
2197 }
2198 MetroidObjectiveSystemControl.Set_Objective_Status(34+x,NewObjectiveSystem::Accomplished);
2199 if (NumberOfDeactivatedTerminals == 3)
2200 WinMap();
2201 }
2202 return;
2203 }
2204 }
2205 void DisplayHUDMessage(int StringID,const Vector3 &Color = Vector3(0.0f,0.5f,1.0f))
2206 {
2207 char text[220];
2208 sprintf_s(text,"%s",MetroidStringLibrary(StringID));
2209 for (int x = 1;x < 128;x++)
2210 {
2211 GameObject *Player = Get_GameObj(x);
2212 if (!Player)
2213 continue;
2214 Set_HUD_Help_Text_Player_Text(Player,7233,text,Color);
2215 }
2216 }
2217 void DisplayDynamicHUDMessage(int StringID,float SpecialParam1,float SpecialParam2 = 0.0f,float SpecialParam3 = 0.0f)
2218 {
2219 Vector4 Temp = Vector4(4920038.0f,SpecialParam1,SpecialParam2,SpecialParam3);
2220 for (int x = 1;x < 128;x++)
2221 {
2222 GameObject *Player = Get_GameObj(x);
2223 if (!Player)
2224 continue;
2225 Set_Shader_Number_Vector(Player,StringID,Temp);
2226 }
2227 }
2228 void DisplayDialogMessage(GameObject *obj,int StringID)
2229 {
2230 if (StringID == -1)
2231 return;
2232 char dialog[1000];
2233 sprintf(dialog,"pamsg %d %s",JmgUtility::JMG_Get_Player_ID(obj),MetroidDialogStrings(StringID));
2234 Console_Input(dialog);
2235 }
2236 char *Get_String(int StringID)
2237 {
2238 return MetroidDialogStrings(StringID);
2239 }
2240 void WinMap();
2241};
2242MetroidGame MetroidGameControl = MetroidGame();
2243
2244class JMG_Metroid_Mine_Boss : public ScriptImpClass {
2245 OBBoxClass *DrillZone;// Low Risk
2246 float LastHealth;
2247 float LastArmor;
2248 int ZoneID;
2249 int SoundID;
2250 MetroidBossPathControl::AIPathNode *RoadPoint;// Low Risk
2251 int TurretID;
2252 int LightID[4];
2253 int WarningLightID;
2254 int EnemyID;
2255 int ChasingID;
2256 int ClearTarget;
2257 Vector3 RoadPointPos;
2258 Vector3 LastSpot;
2259 Vector3 CreationSpot;
2260 int StuckCount;
2261 int SuperStuckCount;
2262 void Created(GameObject *obj);
2263 void Enemy_Seen(GameObject *obj,GameObject *seen);
2264 void Timer_Expired(GameObject *obj,int number);
2265 void Action_Complete(GameObject *obj,int action,ActionCompleteReason reason);
2266 void Damaged(GameObject *obj,GameObject *damager,float damage);
2267 void Killed(GameObject *obj, GameObject *damager);
2268 void Destroyed(GameObject *obj);
2269 void Goto_Location(GameObject *obj,const Vector3 &TargetLocation,bool Pathfind,float ArriveDistance,bool Backward,bool Monitor,float Speed);
2270 bool Check_Road_Update(const Vector3 &Pos);
2271 void SetupAZoneBox(GameObject *obj);
2272public:
2273 JMG_Metroid_Mine_Boss()
2274 {
2275 LastHealth = 2000.0f;
2276 LastArmor = 2000.0f;
2277 SoundID = 0;
2278 MetroidGameControl.BossMode = 0;
2279 MetroidGameControl.BossDefeated = false;
2280 SuperStuckCount = StuckCount = 0;
2281 ChasingID = EnemyID = 0;
2282 RoadPoint = NULL;
2283 }
2284};
2285
2286class JMG_Metroid_Boss_Turret : public ScriptImpClass {
2287 int SeenID;
2288 int IgnoreID;
2289 int ClearTarget;
2290 float TargetDistance;
2291 float MinDistance;
2292 float MaxDistance;
2293 float RotateDirection;
2294 void Created(GameObject *obj);
2295 void Enemy_Seen(GameObject *obj,GameObject *seen);
2296 void Custom(GameObject *obj,int message,int param,GameObject *sender);
2297 void Action_Complete(GameObject *obj,int action,ActionCompleteReason reason);
2298 void Timer_Expired(GameObject *obj,int number);
2299 void Damaged(GameObject *obj,GameObject *damager,float damage);
2300};
2301
2302class JMG_Metroid_Boss_Grinder_Kill_Zone : public ScriptImpClass {
2303 void Entered(GameObject *obj,GameObject *enter);
2304};
2305
2306#define MAXDYNAMICPOWERUPS 50
2307class MetroidPowerupSystem
2308{
2309private:
2310 struct PowerupNode
2311 {
2312 int ID;
2313 struct PowerupNode *next;
2314 PowerupNode(int id)
2315 {
2316 ID = id;
2317 next = NULL;
2318 }
2319 };
2320 int PowerupCount;
2321 PowerupNode *PowerupNodeList;
2322 void deleteObject(int ID)
2323 {
2324 if (!PowerupNodeList)
2325 return;
2326 PowerupNode *Current = PowerupNodeList,*Prev = NULL;
2327 while (Current)
2328 {
2329 if (Current->ID == ID)
2330 {
2331 if (!Prev)
2332 PowerupNodeList = PowerupNodeList->next;
2333 else if (Current->next)
2334 Prev->next = Current->next;
2335 else
2336 Prev->next = NULL;
2337 delete Current;
2338 PowerupCount--;
2339 break;
2340 }
2341 Prev = Current;
2342 Current = Current->next;
2343 }
2344 }
2345public:
2346 MetroidPowerupSystem()
2347 {
2348 PowerupCount = 0;
2349 PowerupNodeList = NULL;
2350 }
2351 MetroidPowerupSystem &operator += (GameObject *obj)
2352 {
2353 int ID = Commands->Get_ID(obj);
2354 PowerupNode *Current = PowerupNodeList;
2355 if (!PowerupNodeList)
2356 {
2357 PowerupCount++;
2358 PowerupNodeList = new PowerupNode(ID);
2359 }
2360 while (Current)
2361 {
2362 if (Current->ID == ID)
2363 return *this;
2364 if (!Current->next)
2365 {
2366 PowerupCount++;
2367 Current->next = new PowerupNode(ID);
2368 break;
2369 }
2370 Current = Current->next;
2371 }
2372 if (PowerupCount > MAXDYNAMICPOWERUPS)
2373 {
2374 GameObject *object = Commands->Find_Object(PowerupNodeList->ID);
2375 if (object)
2376 Commands->Destroy_Object(object);
2377 }
2378 return *this;
2379 };
2380 MetroidPowerupSystem &operator -= (GameObject *obj)
2381 {
2382 int ID = Commands->Get_ID(obj);
2383 deleteObject(ID);
2384 return *this;
2385 };
2386 void EmptyList()
2387 {
2388 PowerupNode *Current = PowerupNodeList,*die = NULL;
2389 while (Current)
2390 {
2391 die = Current;
2392 Current = Current->next;
2393 delete die;
2394 }
2395 PowerupCount = 0;
2396 PowerupNodeList = NULL;
2397 }
2398};
2399
2400MetroidPowerupSystem MetroidPowerupSystemControl = MetroidPowerupSystem();
2401
2402class JMG_Metroid_Dynamic_Powerup_System : public ScriptImpClass {
2403 void Created(GameObject *obj);
2404 void Destroyed(GameObject *obj);
2405};
2406
2407class JMG_Metroid_Crate_Random_Powerup : public ScriptImpClass {
2408 void Killed(GameObject *obj, GameObject *damager);
2409};
2410
2411#define METROIDCHAPTERS 9
2412class MetroidPlayerSettingsSystem
2413{
2414 struct PlayerSettingsNode
2415 {
2416 bool ChaptersCompleted[METROIDCHAPTERS];
2417 char PlayerName[256];
2418 int ArmorMode;
2419 float BossDamage;
2420 int FeedBoss;
2421 int IsInTeleport;
2422 int ScreenColorZone;
2423 Vector3 ScreenColor;
2424 float ScreenOpacity;
2425 int InTrainingRoom;
2426 int InStartRoom;
2427 bool hasZeroBug;
2428 bool hasDied;
2429 bool openedSecurityDoor;
2430 bool hasKeycard;
2431 struct PlayerSettingsNode *next;
2432 PlayerSettingsNode(const char *playerName)
2433 {
2434 for (int x = 0;x < METROIDCHAPTERS;x++)
2435 ChaptersCompleted[x] = false;
2436 sprintf(PlayerName,"%s",playerName);
2437 ArmorMode = -1;
2438 BossDamage = 0;
2439 FeedBoss = 0;
2440 IsInTeleport = 0;
2441 ScreenColorZone = 0;
2442 ScreenColor = Vector3(0.0f,0.0f,0.0f);
2443 ScreenOpacity = 0;
2444 InTrainingRoom = false;
2445 InStartRoom = true;
2446 hasZeroBug = false;
2447 hasDied = false;
2448 openedSecurityDoor = false;
2449 hasKeycard = false;
2450 next = NULL;
2451 }
2452 void ChapterCompleted(GameObject *obj,int ChapterID)
2453 {
2454 if (!Commands->Is_A_Star(obj))
2455 return;
2456 if (ChapterID >= METROIDCHAPTERS)
2457 return;
2458 if (!ChaptersCompleted[ChapterID])
2459 {
2460 MetroidScoreSystem::MetroidHighScoresNode *msNode = MetroidScoreControl.MetroidPlayerHighScoreNodes[JmgUtility::JMG_Get_Player_ID(obj)];
2461 switch (ChapterID)
2462 {
2463 case 0:msNode->Chapter1Completed++;break;
2464 case 1:msNode->Chapter2Completed++;break;
2465 case 2:msNode->Chapter3Completed++;break;
2466 case 3:msNode->Chapter4Completed++;break;
2467 case 4:msNode->Chapter5Completed++;break;
2468 case 5:msNode->Chapter6Completed++;break;
2469 case 6:msNode->Chapter7Completed++;break;
2470 case 7:msNode->Chapter8Completed++;break;
2471 case 8:msNode->Chapter9Completed++;break;
2472 case 9:msNode->Chapter10Completed++;break;
2473 }
2474 msNode->CompletedPlayThroughs = msNode->Chapter1Completed;
2475 if (msNode->Chapter2Completed < msNode->CompletedPlayThroughs)
2476 msNode->CompletedPlayThroughs = msNode->Chapter2Completed;
2477 if (msNode->Chapter3Completed < msNode->CompletedPlayThroughs)
2478 msNode->CompletedPlayThroughs = msNode->Chapter3Completed;
2479 if (msNode->Chapter4Completed < msNode->CompletedPlayThroughs)
2480 msNode->CompletedPlayThroughs = msNode->Chapter4Completed;
2481 if (msNode->Chapter5Completed < msNode->CompletedPlayThroughs)
2482 msNode->CompletedPlayThroughs = msNode->Chapter5Completed;
2483 if (msNode->Chapter6Completed < msNode->CompletedPlayThroughs)
2484 msNode->CompletedPlayThroughs = msNode->Chapter6Completed;
2485 if (msNode->Chapter7Completed < msNode->CompletedPlayThroughs)
2486 msNode->CompletedPlayThroughs = msNode->Chapter7Completed;
2487 if (msNode->Chapter8Completed < msNode->CompletedPlayThroughs)
2488 msNode->CompletedPlayThroughs = msNode->Chapter8Completed;
2489 if (msNode->Chapter9Completed < msNode->CompletedPlayThroughs)
2490 msNode->CompletedPlayThroughs = msNode->Chapter9Completed;
2491 ChaptersCompleted[ChapterID] = true;
2492 int TotalChaptersCompleted = 0;
2493 for (int x = 0;x < METROIDCHAPTERS;x++)
2494 if (ChaptersCompleted[x])
2495 TotalChaptersCompleted++;
2496 char ChapterNames[METROIDCHAPTERS][128] = {"Ruined","We need moar power!","Ship Wrecked","Pitfall","Trained on victory","Bad Traffic","Freeze Dried","Going Deep","Those are mine resources"};
2497 char chpmsg[512];
2498 sprintf(chpmsg,"Chapter %d: \"%s\" Complete (%d/%d)",ChapterID+1,ChapterNames[ChapterID],TotalChaptersCompleted,METROIDCHAPTERS);
2499 JmgUtility::DisplayChatMessage(obj,220,220,220,chpmsg);
2500 if (msNode->Chapter1Completed && msNode->Chapter2Completed && msNode->Chapter3Completed && msNode->Chapter4Completed && msNode->Chapter5Completed && msNode->Chapter6Completed && msNode->Chapter7Completed && msNode->Chapter8Completed && msNode->Chapter9Completed)
2501 {
2502 if (!CheckIfPlayerHasPerkUnlocked(obj,79))
2503 {
2504 PerkSystemIncreasePlayerPerkUnlockAmount(obj,79,1);
2505 IncreasePlayerPerkSlotCount(obj);
2506 JmgUtility::DisplayChatMessage(obj,220,220,220,"Operation: Deep Penetration completed!");
2507 }
2508 else if (ChapterID == 8)
2509 JmgUtility::DisplayChatMessage(obj,220,220,220,"Operation: Deep Penetration completed!");
2510 }
2511 }
2512 }
2513 int GetChaptersCompleted()
2514 {
2515 int TotalChaptersCompleted = 0;
2516 for (int x = 0;x < METROIDCHAPTERS;x++)
2517 if (ChaptersCompleted[x])
2518 TotalChaptersCompleted++;
2519 return TotalChaptersCompleted;
2520 }
2521 };
2522 struct PlayerSettingsNode *PlayerSettingsNodeList;
2523 struct PlayerSettingsNode *PlaceHolderPlayerSettingsNode;
2524 PlayerSettingsNode *FindPlayerNode(const char *PlayerName)
2525 {
2526 PlayerSettingsNode *Current = PlayerSettingsNodeList;
2527 if (!PlayerSettingsNodeList)
2528 {
2529 PlayerSettingsNodeList = new PlayerSettingsNode(PlayerName);
2530 return PlayerSettingsNodeList;
2531 }
2532 while (Current)
2533 {
2534 if (!_stricmp(Current->PlayerName,PlayerName))
2535 return Current;
2536 if (!Current->next)
2537 {
2538 Current->next = new PlayerSettingsNode(PlayerName);
2539 return Current->next;
2540 }
2541 Current = Current->next;
2542 }
2543 return NULL;
2544 }
2545public:
2546 PlayerSettingsNode *PlayerSettings[128];
2547 MetroidPlayerSettingsSystem()
2548 {
2549 PlaceHolderPlayerSettingsNode = new PlayerSettingsNode("\0");
2550 PlayerSettingsNodeList = NULL;
2551 for (int x = 0;x < 128;x++)
2552 PlayerSettings[x] = PlaceHolderPlayerSettingsNode;
2553 }
2554 void SpawnPlayer(int PlayerID)
2555 {
2556 if (!PlayerID)
2557 return;
2558 const char *PlayerName = Get_Player_Name_By_ID(PlayerID);
2559 if (!PlayerSettings[PlayerID] || _stricmp(PlayerSettings[PlayerID]->PlayerName,PlayerName))
2560 PlayerSettings[PlayerID] = FindPlayerNode(PlayerName);
2561 PlayerSettings[PlayerID]->hasDied = false;
2562 PlayerSettings[PlayerID]->openedSecurityDoor = false;
2563 PlayerSettings[PlayerID]->hasKeycard = false;
2564 }
2565 void BossKilled()
2566 {
2567 float TotalDamage = 0;
2568 int PlayerCount = 0;
2569 PlayerSettingsNode *Current = PlayerSettingsNodeList;
2570 while (Current)
2571 {
2572 if (Current->BossDamage)
2573 {
2574 PlayerCount++;
2575 TotalDamage += Current->BossDamage;
2576 }
2577 Current = Current->next;
2578 }
2579 float Average = (TotalDamage/(float)PlayerCount)*0.5f;
2580 for (int x = 1;x < 128;x++)
2581 {
2582 GameObject *Player = Get_GameObj(x);
2583 if (!Player)
2584 continue;
2585 if (PlayerSettings[x]->BossDamage >= Average)
2586 {
2587 PerkSystemIncreasePlayerPerkUnlockAmount(Player,78,1);
2588 Commands->Give_PowerUp(Player,"POW_Robotic_Supergrenade",false);
2589 if (Has_Weapon(Player,"Weapon_Robotic_Supergrenade"))
2590 Commands->Select_Weapon(Player,"Weapon_Robotic_Supergrenade");
2591 }
2592 MetroidGameControl.DisplayHUDMessage(17);
2593 }
2594 }
2595 void EmptyList()
2596 {
2597 PlayerSettingsNode *Current = PlayerSettingsNodeList,*die = NULL;
2598 while (Current)
2599 {
2600 die = Current;
2601 Current = Current->next;
2602 delete die;
2603 }
2604 PlayerSettingsNodeList = NULL;
2605 for (int x = 0;x < 128;x++)
2606 PlayerSettings[x] = PlaceHolderPlayerSettingsNode;
2607 }
2608};
2609MetroidPlayerSettingsSystem MetroidPSSControl;
2610
2611inline void JMGGivePoints(GameObject *obj,float points,int playerId)
2612{
2613 Commands->Give_Points(obj,points,false);
2614 MetroidScoreControl.MetroidPlayerHighScoreNodes[playerId]->pointsThisRound += points;
2615 MetroidScoreControl.MetroidPlayerHighScoreNodes[playerId]->Points += points;
2616}
2617
2618class JMG_Metroid_Mine_Tower_Elevator : public ScriptImpClass {
2619 int ElevatorCurrentFloor;
2620 bool ElevatorInMotion;
2621 int ElevatorButtonIDs[4][5];
2622 int LockdownMode;
2623 int LockDownButtonID;
2624 void Created(GameObject *obj);
2625 void Timer_Expired(GameObject *obj,int number);
2626 void Custom(GameObject *obj,int message,int param,GameObject *sender);
2627 void Destroyed(GameObject *obj);
2628 void UpdateElevatorButtons();
2629};
2630
2631
2632class JMG_Metroid_Text_Dialog : public ScriptImpClass {
2633 void Entered(GameObject *obj,GameObject *enter);
2634 char *MetroidDialogStrings(int StringID);
2635};
2636
2637class JMG_Metroid_Mine_Computer_Console : public ScriptImpClass {
2638 int TerminalNumber;
2639 void Created(GameObject *obj);
2640 void Timer_Expired(GameObject *obj,int number);
2641 void Poked(GameObject *obj,GameObject *poker);
2642};
2643
2644class JMG_Metroid_Mine_Computer_Console_Disarm_Script : public ScriptImpClass {
2645 int CompletedCombos;
2646 int NextExpectedKey;
2647 int LastSelection;
2648 void Created(GameObject *obj);
2649 void Custom(GameObject *obj,int message,int param,GameObject *sender);
2650 void Timer_Expired(GameObject *obj,int number);
2651 void Killed(GameObject *obj,GameObject *killer);
2652 void SelectRandomKey(GameObject *obj);
2653 void PressKey(GameObject *obj,int message);
2654};
2655
2656class JMG_Metroid_Reset_Fall_Distance_On_Enter : public ScriptImpClass {
2657 void Entered(GameObject *obj,GameObject *enter);
2658};
2659
2660class JMG_Metroid_Recover_Fall_Damage_Once : public ScriptImpClass {
2661 bool Fall;
2662 void Created(GameObject *obj);
2663 void Damaged(GameObject *obj,GameObject *damager,float damage);
2664 void Timer_Expired(GameObject *obj,int number);
2665};
2666
2667class JMG_Metroid_Teleport_Zone : public ScriptImpClass {
2668 bool enabled;
2669 void Created(GameObject *obj);
2670 void Custom(GameObject *obj,int message,int param,GameObject *sender);
2671 void Entered(GameObject *obj,GameObject *enter);
2672};
2673
2674class JMG_Metroid_Tower_Put_AI_Down_Zone: public ScriptImpClass {
2675 void Entered(GameObject *obj,GameObject *enter);
2676};
2677
2678class JMG_Metroid_Electrified_Water : public ScriptImpClass {
2679 void Entered(GameObject *obj,GameObject *enter);
2680};
2681
2682class JMG_Metroid_Set_Screen_Color_While_In_Zone : public ScriptImpClass {
2683 void Entered(GameObject *obj,GameObject *enter);
2684 void Exited(GameObject *obj,GameObject *exiter);
2685};
2686
2687class SupportModeSystem
2688{
2689 int MedicalPackCount;
2690 struct MedicalPackNode
2691 {
2692 int ID;
2693 struct MedicalPackNode *next;
2694 MedicalPackNode(GameObject *obj)
2695 {
2696 ID = Commands->Get_ID(obj);
2697 next = NULL;
2698 }
2699 };
2700 MedicalPackNode *MedicalPackNodeList;
2701public:
2702 int GeneratorID;
2703 int LastDamaged;
2704 int LastFired;
2705 SupportModeSystem()
2706 {
2707 GeneratorID = 0;
2708 MedicalPackCount = 0;
2709 LastDamaged = 0;
2710 LastFired = 0;
2711 MedicalPackNodeList = NULL;
2712 }
2713 int FindFirstID()
2714 {
2715 if (!MedicalPackNodeList)
2716 return 0;
2717 MedicalPackNode *Current = MedicalPackNodeList;
2718 while (Current)
2719 {
2720 if (Current->ID)
2721 return Current->ID;
2722 Current = Current->next;
2723 }
2724 return 0;
2725 }
2726 void AddMedicalPack(GameObject *obj)
2727 {
2728 MedicalPackCount++;
2729 MedicalPackNode *Current = MedicalPackNodeList;
2730 if (!MedicalPackNodeList)
2731 MedicalPackNodeList = new MedicalPackNode(obj);
2732 while (Current)
2733 {
2734 if (!Current->next)
2735 {
2736 Current->next = new MedicalPackNode(obj);
2737 break;
2738 }
2739 Current = Current->next;
2740 }
2741 if (MedicalPackCount > 3)
2742 {
2743 GameObject *object = Commands->Find_Object(FindFirstID());
2744 if (object)
2745 Commands->Destroy_Object(object);
2746 }
2747 }
2748 void RemoveMedicalPack(GameObject *obj)
2749 {
2750 int ID = Commands->Get_ID(obj);
2751 MedicalPackNode *Current = MedicalPackNodeList,*Prev = NULL;
2752 while (Current)
2753 {
2754 if (Current->ID == ID)
2755 {
2756 MedicalPackCount--;
2757 Current->ID = 0;
2758 return;
2759 }
2760 Prev = Current;
2761 Current = Current->next;
2762 }
2763 }
2764 void EmptyList()
2765 {
2766 MedicalPackNode *Current = MedicalPackNodeList,*die = NULL;
2767 while (Current)
2768 {
2769 die = Current;
2770 Current = Current->next;
2771 delete die;
2772 }
2773 MedicalPackCount = 0;
2774 MedicalPackNodeList = NULL;
2775 }
2776};
2777
2778SupportModeSystem SupportModeSystemControl[128] = {SupportModeSystem()};
2779
2780class JMG_Metroid_Medic : public ScriptImpClass {
2781 int LastMedicalKitAmmo;
2782 int BlockMedicalKitRegen;
2783 int LastGeneratorAmmo;
2784 int BlockGeneratorRegen;
2785 void Created(GameObject *obj);
2786 void Timer_Expired(GameObject *obj,int number);
2787};
2788
2789class JMG_Metroid_Support_Health_Powerup_Beacon : public ScriptImpClass {
2790 int PlayerID;
2791 void Created(GameObject *obj);
2792 //void Timer_Expired(GameObject *obj,int number);
2793};
2794
2795class JMG_Metroid_Support_Health_Powerup : public ScriptImpClass {
2796 void Created(GameObject *obj);
2797 void Custom(GameObject *obj,int message,int param,GameObject *sender);
2798 void Destroyed(GameObject *obj);
2799};
2800
2801class JMG_Metroid_Support_Generator_Powerup_Beacon : public ScriptImpClass {
2802 void Created(GameObject *obj);
2803};
2804
2805class JMG_Metroid_Support_Generator_Powerup : public ScriptImpClass {
2806 int PlayerID;
2807 int currentCount;
2808 float vampireShield;
2809 void Created(GameObject *obj);
2810 void Timer_Expired(GameObject *obj,int number);
2811 void Destroyed(GameObject *obj);
2812};
2813
2814class JMG_Metroid_AI_Hunt_Attack : public ScriptImpClass {
2815 Vector3 MoveToLocation;
2816 Vector3 LastMoveToLocation;
2817 Vector3 StartPosition;
2818 Vector3 MyLastPos;
2819 float MaxRange;
2820 int EnemySeen;
2821 int EnemyID;
2822 int LastEnemyID;
2823 bool InnateEnabled;
2824 bool StarInRange;
2825 void Created(GameObject *obj);
2826 void Enemy_Seen(GameObject *obj,GameObject *seen);
2827 void Timer_Expired(GameObject *obj,int number);
2828 void Action_Complete(GameObject *obj,int action,ActionCompleteReason reason);
2829 void Damaged(GameObject *obj,GameObject *damager,float damage);
2830 void Update(GameObject *obj);
2831 void GetClosestStar(GameObject *obj);
2832};
2833
2834class JMG_Metroid_Powered_Teleport_Zone : public ScriptImpClass {
2835 bool Enabled;
2836 void Created(GameObject *obj);
2837 void Entered(GameObject *obj,GameObject *enter);
2838 void Custom(GameObject *obj,int message,int param,GameObject *sender);
2839};
2840
2841class JMG_Metroid_Send_Custom_On_Zone_Enter : public ScriptImpClass {
2842 void Entered(GameObject *obj,GameObject *enter);
2843};
2844
2845class JMG_Metroid_Sabotaged_Crate : public ScriptImpClass {
2846 void Created(GameObject *obj);
2847};
2848
2849class JMG_Metroid_Enable_Spawners_On_Death : public ScriptImpClass {
2850 void Killed(GameObject *obj, GameObject *damager);
2851};
2852
2853class RoomLockdownSystem
2854{
2855public:
2856 int LockDownInitiatedStringID;
2857 int LockDownAvertedStringID;
2858 char LockDownInitiatedSound[512];
2859 char LockDownAvertedSound[512];
2860 int HUDMessageLockdownInitiated;
2861 int HUDMessageLockdownAverted;
2862 int ResetLockoutTime;
2863private:
2864 int ResetLockout;
2865 Vector3 SpeakerPosition;
2866 bool LockdownInProgress;
2867 int CancelLockdownTerminalID;
2868 int EnemyArrivalDelay;
2869 struct SpawnedEnemyNode
2870 {
2871 int ID;
2872 int DeadTime;
2873 struct SpawnedEnemyNode *next;
2874 SpawnedEnemyNode(GameObject *obj)
2875 {
2876 ID = Commands->Get_ID(obj);
2877 DeadTime = 0;
2878 next = NULL;
2879 }
2880 };
2881 struct EnemySpawnNode
2882 {
2883 int NodeID;
2884 int ID;
2885 int RemainingSpawnTime;
2886 int CurrentSpawnedAtATimeCount;
2887 int CurrentTotalSpawnCount;
2888 int MaxSpawnedAtATime;
2889 int TotalSpawnLimit;
2890 int SpawnRate;
2891 int RespawnDelay;
2892 int RandomRespawnDelay;
2893 Vector3 Position;
2894 float Facing;
2895 char SpawnPresetName[1024];
2896 struct SpawnedEnemyNode *SpawnedEnemyNodeList;
2897 struct EnemySpawnNode *next;
2898 EnemySpawnNode(GameObject *obj,const char *PresetName,int maxSpawnedAtATime,int totalSpawnLimit,int spawnRate,int respawnDelay,int randomRespawnDelay,int nodeID)
2899 {
2900 NodeID = nodeID;
2901 ID = Commands->Get_ID(obj);
2902 CurrentSpawnedAtATimeCount = 0;
2903 CurrentTotalSpawnCount = 0;
2904 MaxSpawnedAtATime = maxSpawnedAtATime;
2905 TotalSpawnLimit = totalSpawnLimit;
2906 RespawnDelay = respawnDelay;
2907 RandomRespawnDelay = randomRespawnDelay;
2908 SpawnRate = spawnRate;
2909 RemainingSpawnTime = SpawnRate;
2910 Facing = Commands->Get_Facing(obj);
2911 Position = Commands->Get_Position(obj);
2912 Commands->Destroy_Object(obj);
2913 sprintf(SpawnPresetName,"%s",PresetName);
2914 SpawnedEnemyNodeList = NULL;
2915 next = NULL;
2916 }
2917 void SpawnEnemy()
2918 {
2919 CurrentTotalSpawnCount++;
2920 CurrentSpawnedAtATimeCount++;
2921 GameObject *AI = Commands->Create_Object(this->SpawnPresetName,this->Position);
2922 Commands->Set_Facing(AI,this->Facing);
2923 char params[512];
2924 sprintf(params,"%d",NodeID);
2925 Commands->Attach_Script(AI,"JMG_Metroid_Lockdown_zSpawned_Unit",params);
2926 SpawnedEnemyNode *Current = SpawnedEnemyNodeList;
2927 if (!SpawnedEnemyNodeList)
2928 SpawnedEnemyNodeList = new SpawnedEnemyNode(AI);
2929 while (Current)
2930 {
2931 if (!Current->next)
2932 {
2933 Current->next = new SpawnedEnemyNode(AI);
2934 break;
2935 }
2936 Current = Current->next;
2937 }
2938 }
2939 bool EnemyKilled(int killedId)
2940 {
2941 SpawnedEnemyNode *Current = SpawnedEnemyNodeList;
2942 while (Current)
2943 {
2944 if (Current->ID == killedId)
2945 {
2946 if (RandomRespawnDelay)
2947 Current->DeadTime = RespawnDelay+Commands->Get_Random_Int(-RandomRespawnDelay,RandomRespawnDelay);
2948 else
2949 Current->DeadTime = RespawnDelay;
2950 if (Current->DeadTime <= 0)
2951 Current->DeadTime = 1;
2952 return true;
2953 }
2954 Current = Current->next;
2955 }
2956 return false;
2957 }
2958 void RemoveEnemy(int removedId)
2959 {
2960 if (!SpawnedEnemyNodeList)
2961 return;
2962 SpawnedEnemyNode *Current = SpawnedEnemyNodeList,*Prev = NULL;
2963 while (Current)
2964 {
2965 if (Current->ID == removedId)
2966 {
2967 if (!Prev)
2968 SpawnedEnemyNodeList = SpawnedEnemyNodeList->next;
2969 else if (Current->next)
2970 Prev->next = Current->next;
2971 else
2972 Prev->next = NULL;
2973 delete Current;
2974 CurrentSpawnedAtATimeCount--;
2975 return;
2976 }
2977 Prev = Current;
2978 Current = Current->next;
2979 }
2980 }
2981 void Update()
2982 {
2983 SpawnedEnemyNode *Current = SpawnedEnemyNodeList;
2984 while (Current)
2985 {
2986 if (Current->DeadTime)
2987 {
2988 Current->DeadTime--;
2989 if (!Current->DeadTime)
2990 RemoveEnemy(Current->ID);
2991 }
2992 Current = Current->next;
2993 }
2994 if (RemainingSpawnTime && (this->MaxSpawnedAtATime > this->CurrentSpawnedAtATimeCount && (!this->TotalSpawnLimit || this->TotalSpawnLimit > this->CurrentTotalSpawnCount)))
2995 {
2996 RemainingSpawnTime--;
2997 if (!RemainingSpawnTime)
2998 {
2999 RemainingSpawnTime = SpawnRate;
3000 SpawnEnemy();
3001 }
3002 }
3003 }
3004 void ResetSystem()
3005 {
3006 SpawnedEnemyNode *Current = SpawnedEnemyNodeList,*Temp;
3007 while (Current)
3008 {
3009 Temp = Current;
3010 Current = Current->next;
3011 delete Temp;
3012 }
3013 SpawnedEnemyNodeList = NULL;
3014 CurrentTotalSpawnCount = 0;
3015 CurrentSpawnedAtATimeCount = 0;
3016 }
3017 ~EnemySpawnNode()
3018 {
3019 SpawnedEnemyNode *Current = SpawnedEnemyNodeList,*die = NULL;
3020 while (Current)
3021 {
3022 die = Current;
3023 Current = Current->next;
3024 delete die;
3025 }
3026 SpawnedEnemyNodeList = NULL;
3027 }
3028 };
3029 EnemySpawnNode *EnemySpawnNodeList;
3030 struct LockDownLightNode
3031 {
3032 int ID;
3033 int LightEffectIDs[4];
3034 char ModelName[16];
3035 struct LockDownLightNode *next;
3036 LockDownLightNode(GameObject *obj)
3037 {
3038 sprintf(ModelName,"%s",Get_Model(obj));
3039 char Anim[32];
3040 sprintf(Anim,"%sOf",ModelName);
3041 Commands->Set_Model(obj,Anim);
3042 sprintf(Anim,"%sOf.%sOf",ModelName,ModelName);
3043 Commands->Set_Animation(obj,Anim,false,0,0,0,false);
3044 ID = Commands->Get_ID(obj);
3045 for (int x = 0;x < 4;x++)
3046 LightEffectIDs[x] = 0;
3047 next = NULL;
3048 }
3049 };
3050 LockDownLightNode *LockDownLightNodeList;
3051 struct LockdownBlockerNode
3052 {
3053 int ID;
3054 char PresetName[1024];
3055 Vector3 Position;
3056 float Facing;
3057 struct LockdownBlockerNode *next;
3058 LockdownBlockerNode(GameObject *obj,bool destroy = true)
3059 {
3060 ID = Commands->Get_ID(obj);
3061 sprintf(PresetName,"%s",Commands->Get_Preset_Name(obj));
3062 Position = Commands->Get_Position(obj);
3063 Facing = Commands->Get_Facing(obj);
3064 if (destroy)
3065 Commands->Destroy_Object(obj);
3066 next = NULL;
3067 }
3068 };
3069 LockdownBlockerNode *LockdownBlockerNodeList;
3070 LockdownBlockerNode *PostLockdownBlockerNodeList;
3071 LockdownBlockerNode *PreLockdownBlockerNodeList;
3072 struct LockdownSendCustomObjectNode
3073 {
3074 int ID;
3075 int lockdownMsg;
3076 int preLockdownMsg;
3077 int postLockdownMsg;
3078 struct LockdownSendCustomObjectNode *next;
3079 LockdownSendCustomObjectNode(GameObject *obj,int lockdownMsg,int preLockdownMsg,int postLockdownMsg)
3080 {
3081 this->ID = Commands->Get_ID(obj);
3082 this->lockdownMsg = lockdownMsg;
3083 this->preLockdownMsg = preLockdownMsg;
3084 this->postLockdownMsg = postLockdownMsg;
3085 this->next = NULL;
3086 }
3087 void sendMessage(int lockdownState)
3088 {
3089 if (!ID)
3090 return;
3091 GameObject *obj = Commands->Find_Object(ID);
3092 switch (lockdownState)
3093 {
3094 case 0:if (preLockdownMsg)Commands->Send_Custom_Event(obj,obj,preLockdownMsg,0,0);break;
3095 case 1:if (lockdownMsg)Commands->Send_Custom_Event(obj,obj,lockdownMsg,0,0);break;
3096 case 2:if (postLockdownMsg)Commands->Send_Custom_Event(obj,obj,postLockdownMsg,0,0);break;
3097 }
3098 }
3099 };
3100 LockdownSendCustomObjectNode *LockdownSendCustomObjectNodeList;
3101public:
3102 RoomLockdownSystem()
3103 {
3104 this->HUDMessageLockdownInitiated = 19;
3105 this->HUDMessageLockdownAverted = 18;
3106 this->ResetLockout = 0;
3107 this->CancelLockdownTerminalID = 0;
3108 this->SpeakerPosition = Vector3(0.0f,0.0f,0.0f);
3109 this->LockDownInitiatedStringID = 24;
3110 this->LockDownAvertedStringID = 25;
3111 sprintf(this->LockDownInitiatedSound,"LockDownInitiated.wav");
3112 sprintf(this->LockDownAvertedSound,"LockDownAverted.wav");
3113 this->LockdownInProgress = false;
3114 this->EnemySpawnNodeList = NULL;
3115 this->LockDownLightNodeList = NULL;
3116 this->LockdownBlockerNodeList = NULL;
3117 this->PostLockdownBlockerNodeList = NULL;
3118 this->PreLockdownBlockerNodeList = NULL;
3119 this->LockdownSendCustomObjectNodeList = NULL;
3120 }
3121 bool BeginLockDown(int enemyArrivalDelay,int LockDownID)
3122 {
3123 if (LockdownInProgress || ResetLockout)
3124 return false;
3125 if (HUDMessageLockdownInitiated >= 0)
3126 MetroidGameControl.DisplayHUDMessage(HUDMessageLockdownInitiated);
3127 EnemyArrivalDelay = enemyArrivalDelay;
3128 GameObject *LockdownTerminal = Commands->Find_Object(CancelLockdownTerminalID);
3129 if (LockdownTerminal)
3130 {
3131 char params[32];
3132 sprintf(params,"%d",LockDownID);
3133 Commands->Attach_Script(LockdownTerminal,"JMG_Metroid_Lockdown_zComputer_Console_Special_Disarm_Script",params);
3134 char Animation[32];
3135 sprintf(Animation,"%s.%s",Get_Model(LockdownTerminal),Get_Model(LockdownTerminal));
3136 Commands->Set_Animation(LockdownTerminal,Animation,false,0,0,0,false);
3137 Commands->Enable_HUD_Pokable_Indicator(LockdownTerminal,true);
3138 }
3139 LockdownInProgress = true;
3140 if (LockDownInitiatedStringID >= 0)
3141 JmgUtility::MessageAllPlayers(127,10,10,MetroidGameControl.Get_String(LockDownInitiatedStringID));
3142 Commands->Create_Sound(LockDownInitiatedSound,SpeakerPosition,0);
3143 DestroyPlacedBlockers(PostLockdownBlockerNodeList);
3144 DestroyPlacedBlockers(PreLockdownBlockerNodeList);
3145 CreatePlacedBlockers(LockdownBlockerNodeList);
3146 SendLockdownCustoms(1);
3147 LockDownLightNode *Current2 = LockDownLightNodeList;
3148 while (Current2)
3149 {
3150 GameObject *Light = Commands->Find_Object(Current2->ID);
3151 if (Light)
3152 {
3153 float AnimationFrame = Get_Animation_Frame(Light);
3154 Commands->Set_Model(Light,Current2->ModelName);
3155 char Anim[32];
3156 sprintf(Anim,"%s.%s",Current2->ModelName,Current2->ModelName);
3157 Commands->Set_Animation(Light,Anim,true,0,AnimationFrame,-1,false);
3158 char bonename[32];
3159 for (int x = 0;x < 4;x++)
3160 {
3161 GameObject *LightEffect = Commands->Create_Object("Warning_Light_Effect",Commands->Get_Position(Light));
3162 sprintf(bonename,"LightPos%d",x+1);
3163 Commands->Attach_To_Object_Bone(LightEffect,Light,bonename);
3164 Current2->LightEffectIDs[x] = Commands->Get_ID(LightEffect);
3165 }
3166 }
3167 Current2 = Current2->next;
3168 }
3169 return true;
3170 }
3171 void EndLockDown(bool resetEnemySpawners,int lockdownLockoutTime)
3172 {
3173 if (!LockdownInProgress)
3174 return;
3175 ResetLockoutTime = lockdownLockoutTime;
3176 if (HUDMessageLockdownAverted >= 0)
3177 MetroidGameControl.DisplayHUDMessage(HUDMessageLockdownAverted);
3178 LockdownInProgress = false;
3179 ResetLockout = ResetLockoutTime;
3180 GameObject *LockdownTerminal = Commands->Find_Object(CancelLockdownTerminalID);
3181 if (LockdownTerminal)
3182 {
3183 Remove_All_Scripts(LockdownTerminal);
3184 char Animation[32];
3185 sprintf(Animation,"%s.%s",Get_Model(LockdownTerminal),Get_Model(LockdownTerminal));
3186 Commands->Set_Animation(LockdownTerminal,Animation,false,0,0,0,false);
3187 Commands->Enable_HUD_Pokable_Indicator(LockdownTerminal,false);
3188 }
3189 for (int y = 1;y < 128;y++)
3190 {
3191 GameObject *Player = Get_GameObj(y);
3192 if (!Player)
3193 continue;
3194 Commands->Send_Custom_Event(Player,Player,9870924,0,0);
3195 }
3196 if (LockDownAvertedStringID >= 0)
3197 JmgUtility::MessageAllPlayers(127,10,10,MetroidGameControl.Get_String(LockDownAvertedStringID));
3198 Commands->Create_Sound(LockDownAvertedSound,SpeakerPosition,0);
3199 DestroyPlacedBlockers(LockdownBlockerNodeList);
3200 if (ResetLockoutTime)
3201 {
3202 SendLockdownCustoms(2);
3203 CreatePlacedBlockers(PostLockdownBlockerNodeList);
3204 }
3205 else
3206 {
3207 SendLockdownCustoms(0);
3208 CreatePlacedBlockers(PreLockdownBlockerNodeList);
3209 }
3210 LockDownLightNode *Current2 = LockDownLightNodeList;
3211 while (Current2)
3212 {
3213 GameObject *Light = Commands->Find_Object(Current2->ID);
3214 if (Light)
3215 {
3216 float AnimationFrame = Get_Animation_Frame(Light);
3217 char Anim[32];
3218 sprintf(Anim,"%sOf",Current2->ModelName);
3219 Commands->Set_Model(Light,Anim);
3220 sprintf(Anim,"%sOf.%sOf",Current2->ModelName,Current2->ModelName);
3221 Commands->Set_Animation(Light,Anim,false,0,AnimationFrame,AnimationFrame,false);
3222 }
3223 for (int x = 0;x < 4;x++)
3224 {
3225 GameObject *LightEffect = Commands->Find_Object(Current2->LightEffectIDs[x]);
3226 if (LightEffect)
3227 Commands->Destroy_Object(LightEffect);
3228 }
3229 Current2 = Current2->next;
3230 }
3231 if (resetEnemySpawners)
3232 {
3233 EnemySpawnNode *Current3 = EnemySpawnNodeList;
3234 while (Current3)
3235 {
3236 Current3->ResetSystem();
3237 Current3 = Current3->next;
3238 }
3239 }
3240 }
3241 void AddSpawnPoint(GameObject *obj,const char *PresetName,int NodeID,int MaxSpawnedAtATime,int TotalSpawnLimit,int SpawnRate,int RespawnDelay,int RandomRespawnDelay)
3242 {
3243 int ID = Commands->Get_ID(obj);
3244 EnemySpawnNode *Current = EnemySpawnNodeList;
3245 if (!EnemySpawnNodeList)
3246 EnemySpawnNodeList = new EnemySpawnNode(obj,PresetName,MaxSpawnedAtATime,TotalSpawnLimit,SpawnRate,RespawnDelay,RandomRespawnDelay,NodeID);
3247 while (Current)
3248 {
3249 if (Current->ID == ID)
3250 return;
3251 if (!Current->next)
3252 {
3253 Current->next = new EnemySpawnNode(obj,PresetName,MaxSpawnedAtATime,TotalSpawnLimit,SpawnRate,RespawnDelay,RandomRespawnDelay,NodeID);
3254 break;
3255 }
3256 Current = Current->next;
3257 }
3258 };
3259 void AddLockdownLight(GameObject *obj)
3260 {
3261 int ID = Commands->Get_ID(obj);
3262 LockDownLightNode *Current = LockDownLightNodeList;
3263 if (!LockDownLightNodeList)
3264 LockDownLightNodeList = new LockDownLightNode(obj);
3265 while (Current)
3266 {
3267 if (Current->ID == ID)
3268 return;
3269 if (!Current->next)
3270 {
3271 Current->next = new LockDownLightNode(obj);
3272 break;
3273 }
3274 Current = Current->next;
3275 }
3276 };
3277 void RemoveLockdownLight(GameObject *obj)
3278 {
3279 int ID = Commands->Get_ID(obj);
3280 if (!LockDownLightNodeList)
3281 return;
3282 LockDownLightNode *Current = LockDownLightNodeList,*Prev = NULL;
3283 while (Current)
3284 {
3285 if (Current->ID == ID)
3286 {
3287 if (!Prev)
3288 LockDownLightNodeList = LockDownLightNodeList->next;
3289 else if (Current->next)
3290 Prev->next = Current->next;
3291 else
3292 Prev->next = NULL;
3293 delete Current;
3294 break;
3295 }
3296 Prev = Current;
3297 Current = Current->next;
3298 }
3299 };
3300 void AddLockdownBlocker(GameObject *obj)
3301 {
3302 int ID = Commands->Get_ID(obj);
3303 LockdownBlockerNode *Current = LockdownBlockerNodeList;
3304 if (!LockdownBlockerNodeList)
3305 LockdownBlockerNodeList = new LockdownBlockerNode(obj);
3306 while (Current)
3307 {
3308 if (Current->ID == ID)
3309 return;
3310 if (!Current->next)
3311 {
3312 Current->next = new LockdownBlockerNode(obj);
3313 return;
3314 }
3315 Current = Current->next;
3316 }
3317 };
3318 void AddLockdownPostBlocker(GameObject *obj)
3319 {
3320 int ID = Commands->Get_ID(obj);
3321 LockdownBlockerNode *Current = PostLockdownBlockerNodeList;
3322 if (!PostLockdownBlockerNodeList)
3323 PostLockdownBlockerNodeList = new LockdownBlockerNode(obj);
3324 while (Current)
3325 {
3326 if (Current->ID == ID)
3327 return;
3328 if (!Current->next)
3329 {
3330 Current->next = new LockdownBlockerNode(obj);
3331 return;
3332 }
3333 Current = Current->next;
3334 }
3335 };
3336 void AddLockdownPreBlocker(GameObject *obj)
3337 {
3338 int ID = Commands->Get_ID(obj);
3339 LockdownBlockerNode *Current = PreLockdownBlockerNodeList;
3340 if (!PreLockdownBlockerNodeList)
3341 PreLockdownBlockerNodeList = new LockdownBlockerNode(obj,false);
3342 while (Current)
3343 {
3344 if (Current->ID == ID)
3345 return;
3346 if (!Current->next)
3347 {
3348 Current->next = new LockdownBlockerNode(obj,false);
3349 return;
3350 }
3351 Current = Current->next;
3352 }
3353 };
3354 void AddLockdownCustomObject(GameObject *obj,int lockdownMsg,int preLockdownMsg,int postLockdownMsg)
3355 {
3356 int ID = Commands->Get_ID(obj);
3357 LockdownSendCustomObjectNode *Current = LockdownSendCustomObjectNodeList;
3358 if (!LockdownSendCustomObjectNodeList)
3359 LockdownSendCustomObjectNodeList = new LockdownSendCustomObjectNode(obj,lockdownMsg,preLockdownMsg,postLockdownMsg);
3360 while (Current)
3361 {
3362 if (Current->ID == ID)
3363 return;
3364 if (!Current->ID)
3365 {
3366 Current->ID = ID;
3367 Current->lockdownMsg = lockdownMsg;
3368 Current->postLockdownMsg = postLockdownMsg;
3369 Current->preLockdownMsg = preLockdownMsg;
3370 return;
3371 }
3372 if (!Current->next)
3373 {
3374 Current->next = new LockdownSendCustomObjectNode(obj,lockdownMsg,preLockdownMsg,postLockdownMsg);
3375 return;
3376 }
3377 Current = Current->next;
3378 }
3379 };
3380 void RemoveLockdownCustomObject(GameObject *obj)
3381 {
3382 int ID = Commands->Get_ID(obj);
3383 LockdownSendCustomObjectNode *Current = LockdownSendCustomObjectNodeList;
3384 while (Current)
3385 {
3386 if (Current->ID == ID)
3387 Current->ID = 0;
3388 Current = Current->next;
3389 }
3390 };
3391 void SendLockdownCustoms(int lockdownState)
3392 {
3393 LockdownSendCustomObjectNode *Current = LockdownSendCustomObjectNodeList;
3394 while (Current)
3395 {
3396 if (Current->ID)
3397 Current->sendMessage(lockdownState);
3398 Current = Current->next;
3399 }
3400 };
3401 void CreatePlacedBlockers(LockdownBlockerNode *Current)
3402 {
3403 while (Current)
3404 {
3405 GameObject *Blocker = Commands->Create_Object(Current->PresetName,Current->Position);
3406 Commands->Set_Facing(Blocker,Current->Facing);
3407 Current->ID = Commands->Get_ID(Blocker);
3408 Current = Current->next;
3409 }
3410 }
3411 void DestroyPlacedBlockers(LockdownBlockerNode *Current)
3412 {
3413 while (Current)
3414 {
3415 GameObject *LockDownBlocker = Commands->Find_Object(Current->ID);
3416 if (LockDownBlocker)
3417 Commands->Destroy_Object(LockDownBlocker);
3418 Current = Current->next;
3419 }
3420 }
3421 void SpawnedUnitKilled(GameObject *obj)
3422 {
3423 int ID = Commands->Get_ID(obj);
3424 EnemySpawnNode *Current = EnemySpawnNodeList;
3425 while (Current)
3426 {
3427 if (Current->EnemyKilled(ID))
3428 return;
3429 Current = Current->next;
3430 }
3431 };
3432 void Update()
3433 {
3434 if (EnemyArrivalDelay)
3435 EnemyArrivalDelay--;
3436 if (!LockdownInProgress)
3437 {
3438 if (ResetLockout)
3439 {
3440 ResetLockout--;
3441 if (!ResetLockout)
3442 {
3443 DestroyPlacedBlockers(PostLockdownBlockerNodeList);
3444 CreatePlacedBlockers(PreLockdownBlockerNodeList);
3445 SendLockdownCustoms(0);
3446 }
3447 }
3448 return;
3449 }
3450 if (!EnemyArrivalDelay)
3451 {
3452 EnemySpawnNode *Current = EnemySpawnNodeList;
3453 while (Current)
3454 {
3455 Current->Update();
3456 Current = Current->next;
3457 }
3458 }
3459 }
3460 void SetSpeakerLocation(const Vector3 &Pos)
3461 {
3462 SpeakerPosition = Pos;
3463 }
3464 void SetLockdownTerminal(GameObject *obj)
3465 {
3466 CancelLockdownTerminalID = Commands->Get_ID(obj);
3467 char Animation[32];
3468 sprintf(Animation,"%s.%s",Get_Model(obj),Get_Model(obj));
3469 Commands->Set_Animation(obj,Animation,false,0,0,0,false);
3470 };
3471 void EmptyList()
3472 {
3473 {
3474 EnemySpawnNode *Current = EnemySpawnNodeList,*die = NULL;
3475 while (Current)
3476 {
3477 die = Current;
3478 Current = Current->next;
3479 delete die;
3480 }
3481 EnemySpawnNodeList = NULL;
3482 }
3483 {
3484 LockDownLightNode *Current = LockDownLightNodeList,*die = NULL;
3485 while (Current)
3486 {
3487 die = Current;
3488 Current = Current->next;
3489 delete die;
3490 }
3491 LockDownLightNodeList = NULL;
3492 }
3493 {
3494 LockdownBlockerNode *Current = LockdownBlockerNodeList,*die = NULL;
3495 while (Current)
3496 {
3497 die = Current;
3498 Current = Current->next;
3499 delete die;
3500 }
3501 LockdownBlockerNodeList = NULL;
3502 }
3503 {
3504 LockdownBlockerNode *Current = PostLockdownBlockerNodeList,*die = NULL;
3505 while (Current)
3506 {
3507 die = Current;
3508 Current = Current->next;
3509 delete die;
3510 }
3511 PostLockdownBlockerNodeList = NULL;
3512 }
3513 {
3514 LockdownBlockerNode *Current = PreLockdownBlockerNodeList,*die = NULL;
3515 while (Current)
3516 {
3517 die = Current;
3518 Current = Current->next;
3519 delete die;
3520 }
3521 PreLockdownBlockerNodeList = NULL;
3522 }
3523 {
3524 LockdownSendCustomObjectNode *Current = LockdownSendCustomObjectNodeList,*die = NULL;
3525 while (Current)
3526 {
3527 die = Current;
3528 Current = Current->next;
3529 delete die;
3530 }
3531 LockdownSendCustomObjectNodeList = NULL;
3532 }
3533 this->RoomLockdownSystem::RoomLockdownSystem();
3534 }
3535 bool GetLockdownInProgress()
3536 {
3537 return LockdownInProgress;
3538 }
3539};
3540
3541#define LOCKDOWNZONECOUNT 9
3542RoomLockdownSystem RoomLockdownControl[LOCKDOWNZONECOUNT] = {RoomLockdownSystem()};
3543
3544class JMG_Metroid_Lockdown_Controller : public ScriptImpClass {
3545 void Created(GameObject *obj);
3546 void Timer_Expired(GameObject *obj,int number);
3547};
3548
3549class JMG_Metroid_Lockdown_Lockdown_Object : public ScriptImpClass {
3550 void Created(GameObject *obj);
3551};
3552
3553class JMG_Metroid_Lockdown_Post_Lockdown_Object : public ScriptImpClass {
3554 void Created(GameObject *obj);
3555};
3556
3557class JMG_Metroid_Lockdown_Pre_Lockdown_Object : public ScriptImpClass {
3558 void Created(GameObject *obj);
3559};
3560
3561class JMG_Metroid_Lockdown_Unit_Spawner : public ScriptImpClass {
3562 void Created(GameObject *obj);
3563};
3564
3565class JMG_Metroid_Lockdown_Light : public ScriptImpClass {
3566 void Created(GameObject *obj);
3567};
3568
3569class JMG_Metroid_Lockdown_Lockdown_Send_Custom_Object : public ScriptImpClass {
3570 void Created(GameObject *obj);
3571 void Destroyed(GameObject *obj);
3572};
3573
3574class JMG_Metroid_Lockdown_zSpawned_Unit : public ScriptImpClass {
3575 void Killed(GameObject *obj, GameObject *damager);
3576};
3577
3578class JMG_Metroid_Lockdown_Trigger_Zone : public ScriptImpClass {
3579 void Entered(GameObject *obj,GameObject *enter);
3580};
3581
3582class JMG_Metroid_Lockdown_Disable_Lockdown_Terminal : public ScriptImpClass {
3583 void Created(GameObject *obj);
3584};
3585
3586class JMG_Metroid_Lockdown_zComputer_Console : public ScriptImpClass {
3587 void Poked(GameObject *obj,GameObject *poker);
3588};
3589
3590class JMG_Metroid_Lockdown_zComputer_Console_Disarm_Script : public ScriptImpClass {
3591 int CompletedCombos;
3592 int NextExpectedKey;
3593 int LastSelection;
3594 void Created(GameObject *obj);
3595 void Custom(GameObject *obj,int message,int param,GameObject *sender);
3596 void Timer_Expired(GameObject *obj,int number);
3597 void Killed(GameObject *obj,GameObject *killer);
3598 void SelectRandomKey(GameObject *obj);
3599 void PressKey(GameObject *obj,int message);
3600};
3601
3602class JMG_Metroid_Lockdown_Disable_Lockdown_On_Custom_Count : public ScriptImpClass {
3603 float MessageCount;
3604 void Created(GameObject *obj);
3605 void Custom(GameObject *obj,int message,int param,GameObject *sender);
3606};
3607
3608class JMG_Metroid_Lockdown_Disable_Lockdown_On_Death : public ScriptImpClass {
3609 void Killed(GameObject *obj,GameObject *killer);
3610};
3611
3612class JMG_Metroid_Lockdown_Trigger_On_Message : public ScriptImpClass {
3613 void Custom(GameObject *obj,int message,int param,GameObject *sender);
3614};
3615
3616class JMG_Metroid_Lockdown_Disable_Lockdown_On_Time_Without_Message : public ScriptImpClass {
3617 int Count;
3618 void Created(GameObject *obj);
3619 void Custom(GameObject *obj,int message,int param,GameObject *sender);
3620 void Timer_Expired(GameObject *obj,int number);
3621};
3622
3623class JMG_Metroid_Complete_Chapter : public ScriptImpClass {
3624 bool enabled;
3625 void Created(GameObject *obj);
3626 void Custom(GameObject *obj,int message,int param,GameObject *sender);
3627 void Entered(GameObject *obj,GameObject *enter);
3628};
3629
3630class JMG_Metroid_Defense_Mode : public ScriptImpClass {
3631 int LastGunAmmo;
3632 int BlockSupportGunRegen;
3633 int LastTelepadAmmo;
3634 int BlockTelepadRegen;
3635 void Created(GameObject *obj);
3636 void Timer_Expired(GameObject *obj,int number);
3637 void Destroyed(GameObject *obj);
3638};
3639
3640class JMG_Metroid_Defense_Gun_Beacon : public ScriptImpClass {
3641 void Created(GameObject *obj);
3642};
3643
3644class JMG_Metroid_Defense_Gun_Powerup : public ScriptImpClass {
3645 int Count;
3646 int PlayerID;
3647 void Created(GameObject *obj);
3648 void Timer_Expired(GameObject *obj,int number);
3649 void Destroyed(GameObject *obj);
3650};
3651
3652class JMG_Metroid_Defense_Telepad_Beacon : public ScriptImpClass {
3653 void Created(GameObject *obj);
3654};
3655
3656class JMG_Metroid_Defense_Telepad_Powerup : public ScriptImpClass {
3657 int dieTime;
3658 int Count;
3659 int PlayerID;
3660 void Created(GameObject *obj);
3661 void Timer_Expired(GameObject *obj,int number);
3662 void Destroyed(GameObject *obj);
3663};
3664
3665class DefenseModeSystem
3666{
3667public:
3668 struct TelepadNode
3669 {
3670 int PlayerID;
3671 int ID;
3672 int ZoneID;
3673 Vector3 Pos;
3674 int playerDeathCount;
3675 struct TelepadNode *next;
3676 TelepadNode(GameObject *telepad,int playerID)
3677 {
3678 PlayerID = playerID;
3679 ID = Commands->Get_ID(telepad);
3680 Pos = Commands->Get_Position(telepad);
3681 Matrix3 rotation(true);
3682 rotation.Rotate_Z(Commands->Get_Facing(telepad));
3683 OBBoxClass TheBox(Pos,Vector3(0.5f,0.5f,0.5f),rotation);
3684 GameObject *theZone = Create_Zone("Script_Zone_All",TheBox);
3685 char params[32];
3686 sprintf(params,"%d,%d",PlayerID,ID);
3687 Commands->Attach_Script(theZone,"JMG_Metroid_Defense_Telepad_Zone",params);
3688 ZoneID = Commands->Get_ID(theZone);
3689 playerDeathCount = 0;
3690 next = NULL;
3691 }
3692 };
3693private:
3694 TelepadNode *TelepadNodeList;
3695 struct DefensePlayerDataNode
3696 {
3697 int TelepadID;
3698 int DefGunID;
3699 DefensePlayerDataNode()
3700 {
3701 TelepadID = 0;
3702 DefGunID = 0;
3703 }
3704 };
3705public:
3706 DefensePlayerDataNode DefensePlayerDataNodes[128];
3707 DefenseModeSystem()
3708 {
3709 for (int x = 0;x < 128;x++)
3710 DefensePlayerDataNodes[x] = DefensePlayerDataNode();
3711 TelepadNodeList = NULL;
3712 }
3713 void AddTelepad(GameObject *TelePad,int PlayerID)
3714 {
3715 TelepadNode *Current = TelepadNodeList;
3716 if (!TelepadNodeList)
3717 TelepadNodeList = new TelepadNode(TelePad,PlayerID);
3718 while (Current)
3719 {
3720 if (Current->PlayerID == PlayerID)
3721 {
3722 GameObject *OldPad = Commands->Find_Object(Current->ID);
3723 if (OldPad)
3724 Commands->Destroy_Object(OldPad);
3725 }
3726 if (!Current->next)
3727 {
3728 Current->next = new TelepadNode(TelePad,PlayerID);
3729 break;
3730 }
3731 Current = Current->next;
3732 }
3733 GameObject *Telepad = Commands->Find_Object(TelepadNodeList->ID);
3734 if (Telepad)
3735 Commands->Set_Animation(Telepad,"DefModeTelepad.DefModeTelepad",false,0,1,1,false);
3736 }
3737 void RemoveTelepad(GameObject *telepad)
3738 {
3739 int ID = Commands->Get_ID(telepad);
3740 TelepadNode *Current = TelepadNodeList;
3741 while (Current)
3742 {
3743 if (Current->ID == ID)
3744 {
3745 GameObject *Zone = Commands->Find_Object(Current->ZoneID);
3746 if (Zone)
3747 Commands->Destroy_Object(Zone);
3748 Current->ID = 0;
3749 Current->PlayerID = 0;
3750 Current->ZoneID = 0;
3751 break;
3752 }
3753 Current = Current->next;
3754 }
3755 bool activeTeleporter = false;
3756 Current = TelepadNodeList;
3757 while (Current)
3758 {
3759 if (Current->ID && TelepadNodeList->ID != Current->ID)
3760 {
3761 activeTeleporter = true;
3762 break;
3763 }
3764 Current = Current->next;
3765 }
3766 if (activeTeleporter)
3767 return;
3768 if (TelepadNodeList)
3769 {
3770 GameObject *Telepad = Commands->Find_Object(TelepadNodeList->ID);
3771 if (Telepad)
3772 Commands->Set_Animation(Telepad,"DefModeTelepad.DefModeTelepad",false,0,0,0,false);
3773 }
3774 }
3775 void RemoveAllButSpecial()
3776 {
3777 TelepadNode *Current = TelepadNodeList;
3778 if (Current)
3779 Current = Current->next;
3780 while (Current)
3781 {
3782 GameObject *Zone = Commands->Find_Object(Current->ZoneID);
3783 if (Zone)
3784 Commands->Destroy_Object(Zone);
3785 Current->ID = 0;
3786 Current = Current->next;
3787 }
3788 GameObject *Telepad = Commands->Find_Object(TelepadNodeList->ID);
3789 if (Telepad)
3790 Commands->Set_Animation(Telepad,"DefModeTelepad.DefModeTelepad",false,0,0,0,false);
3791 }
3792 TelepadNode *FindNextTelepad(int TelepadID)
3793 {
3794 if (!TelepadNodeList || !TelepadNodeList->next)
3795 return NULL;
3796 bool goodToGo = false;
3797 TelepadNode *Current = TelepadNodeList;
3798 while (Current)
3799 {
3800 if (goodToGo && Current->ID)
3801 return Current;
3802 if (Current->ID == TelepadID)
3803 goodToGo = true;
3804 Current = Current->next;
3805 }
3806 return TelepadNodeList->ID == TelepadID ? NULL : TelepadNodeList;
3807 }
3808 TelepadNode *FindPlayerTelepad(int TelepadPlayerID)
3809 {
3810 if (!TelepadNodeList || !TelepadNodeList->next)
3811 return NULL;
3812 TelepadNode *Current = TelepadNodeList;
3813 while (Current)
3814 {
3815 if (Current->PlayerID == TelepadPlayerID)
3816 return Current;
3817 Current = Current->next;
3818 }
3819 return NULL;
3820 }
3821 void EmptyList()
3822 {
3823 TelepadNode *Current = TelepadNodeList,*die = NULL;
3824 while (Current)
3825 {
3826 die = Current;
3827 Current = Current->next;
3828 delete die;
3829 }
3830 TelepadNodeList = NULL;
3831 for (int x = 0;x < 128;x++)
3832 DefensePlayerDataNodes[x] = DefensePlayerDataNode();
3833 }
3834};
3835
3836DefenseModeSystem DefenseModeSystemControl = DefenseModeSystem();
3837
3838class JMG_Metroid_Defense_Telepad_Zone : public ScriptImpClass {
3839 void Entered(GameObject *obj,GameObject *enter);
3840};
3841
3842class JMG_Metroid_Preplaced_Player_Telepad : public ScriptImpClass {
3843 void Created(GameObject *obj);
3844};
3845
3846class JMG_Metroid_Player_Turret_Damage : public ScriptImpClass {
3847 void Damaged(GameObject *obj,GameObject *damager,float damage);
3848 void Killed(GameObject *obj, GameObject *damager);
3849};
3850
3851class JMG_Metroid_Screen_Fade_Red_On_Damage : public ScriptImpClass {
3852 float InjuryRatio;
3853 float ScreenOpacicity;
3854 void Created(GameObject *obj);
3855 void Timer_Expired(GameObject *obj,int number);
3856 void Damaged(GameObject *obj,GameObject *damager,float damage);
3857 void ScreenFade(GameObject *obj);
3858 void Custom(GameObject *obj,int message,int param,GameObject *sender);
3859};
3860
3861class JMG_Metroid_Kill_On_Damage_Amounts : public ScriptImpClass {
3862 bool Enabled;
3863 float DamageAmounts[256];
3864 void Created(GameObject *obj);
3865 void Damaged(GameObject *obj,GameObject *damager,float damage);
3866};
3867
3868class JMG_Metroid_Grant_Keycard : public ScriptImpClass {
3869 void Entered(GameObject *obj,GameObject *enter);
3870};
3871
3872class JMG_Metroid_AI_Move_To_Position : public ScriptImpClass {
3873 void Created(GameObject *obj);
3874 void Timer_Expired(GameObject *obj,int number);
3875};
3876
3877class JMG_Metroid_Reset_Screen_Color_On_Enter : public ScriptImpClass {
3878 void Entered(GameObject *obj,GameObject *enter);
3879};
3880
3881class MetroidEquipmentSystem
3882{
3883private:
3884 struct EquipmentNode
3885 {
3886 int ID;
3887 Vector3 Pos;
3888 struct EquipmentNode *next;
3889 EquipmentNode(GameObject *obj)
3890 {
3891 ID = Commands->Get_ID(obj);
3892 Pos = Commands->Get_Position(obj);
3893 next = NULL;
3894 }
3895 };
3896 EquipmentNode *EquipmentNodeList;
3897 void deleteObject(int ID)
3898 {
3899 if (!EquipmentNodeList)
3900 return;
3901 EquipmentNode *Current = EquipmentNodeList,*Prev = NULL;
3902 while (Current)
3903 {
3904 if (Current->ID == ID)
3905 {
3906 Current->ID = 0;
3907 break;
3908 }
3909 Prev = Current;
3910 Current = Current->next;
3911 }
3912 }
3913public:
3914 MetroidEquipmentSystem()
3915 {
3916 EquipmentNodeList = NULL;
3917 }
3918 MetroidEquipmentSystem &operator += (GameObject *obj)
3919 {
3920 int ID = Commands->Get_ID(obj);
3921 EquipmentNode *Current = EquipmentNodeList;
3922 if (!EquipmentNodeList)
3923 EquipmentNodeList = new EquipmentNode(obj);
3924 while (Current)
3925 {
3926 if (Current->ID == ID)
3927 return *this;
3928 if (!Current->next)
3929 {
3930 Current->next = new EquipmentNode(obj);
3931 break;
3932 }
3933 Current = Current->next;
3934 }
3935 return *this;
3936 };
3937 MetroidEquipmentSystem &operator -= (GameObject *obj)
3938 {
3939 int ID = Commands->Get_ID(obj);
3940 deleteObject(ID);
3941 return *this;
3942 };
3943 void EmptyList()
3944 {
3945 EquipmentNode *Current = EquipmentNodeList,*die = NULL;
3946 while (Current)
3947 {
3948 die = Current;
3949 Current = Current->next;
3950 delete die;
3951 }
3952 EquipmentNodeList = NULL;
3953 }
3954 float FindNearestEquipment(Vector3 *Pos,int *EquipmentID)
3955 {
3956 float Dist = -1;
3957 EquipmentNode *Current = EquipmentNodeList,*Nearest = NULL;
3958 while (Current)
3959 {
3960 if (!Current->ID)
3961 {
3962 Current = Current->next;
3963 continue;
3964 }
3965 float Temp = JmgUtility::SimpleDistance(*Pos,Current->Pos);
3966 if ((!Nearest || Temp < Dist) && Current->ID != *EquipmentID)
3967 {
3968 Dist = Temp;
3969 Nearest = Current;
3970 }
3971 Current = Current->next;
3972 }
3973 if (Nearest)
3974 {
3975 *Pos = Nearest->Pos;
3976 *EquipmentID = Nearest->ID;
3977 }
3978 else
3979 *EquipmentID = 0;
3980 return Dist;
3981 };
3982};
3983
3984MetroidEquipmentSystem MetroidEquipmentSystemControl = MetroidEquipmentSystem();
3985
3986class JMG_Metroid_Equipment_Tracking_Script : public ScriptImpClass {
3987 void Created(GameObject *obj);
3988 void Destroyed(GameObject *obj);
3989};
3990
3991class JMG_Metroid_AI_Hunt_Equipment : public ScriptImpClass {
3992 Vector3 MoveToLocation;
3993 Vector3 LastMoveToLocation;
3994 Vector3 StartPosition;
3995 Vector3 MyLastPos;
3996 int TargetEquipmentID;
3997 float MaxRange;
3998 int EnemySeen;
3999 int EnemyID;
4000 int LastEnemyID;
4001 bool InnateEnabled;
4002 bool StarInRange;
4003 bool StandingStill;
4004 void Created(GameObject *obj);
4005 void Enemy_Seen(GameObject *obj,GameObject *seen);
4006 void Timer_Expired(GameObject *obj,int number);
4007 void Action_Complete(GameObject *obj,int action,ActionCompleteReason reason);
4008 void Damaged(GameObject *obj,GameObject *damager,float damage);
4009 void Update(GameObject *obj);
4010 void GetClosestStar(GameObject *obj);
4011};
4012
4013class JMG_Metroid_Base_Defense : public ScriptImpClass {
4014 int enemyID;
4015 float resetTime;
4016 float MinDist;
4017 float MaxDist;
4018 void Created(GameObject *obj);
4019 void Enemy_Seen(GameObject *obj,GameObject *seen);
4020 void Timer_Expired(GameObject *obj,int number);
4021 void Damaged(GameObject *obj,GameObject *damager,float damage);
4022};
4023
4024class JMG_Metroid_Camera_Behavior : public ScriptImpClass {
4025 int EnemyID;
4026 int CameraFacingCount;
4027 int IncreaseOrDecreaseCount;
4028 int SeenTime;
4029 Vector3 CameraFacingLocation[5];
4030 float CameraFacingUpdateTime;
4031 void Created(GameObject *obj);
4032 void Enemy_Seen(GameObject *obj,GameObject *seen);
4033 void Timer_Expired(GameObject *obj,int number);
4034 void Custom(GameObject *obj,int message,int param,GameObject *sender);
4035};
4036
4037class JMG_Metroid_Zone_Create_Explosion : public ScriptImpClass {
4038 void Entered(GameObject *obj,GameObject *enter);
4039};
4040
4041class JMG_Metroid_Create_Object_Once_On_Enter : public ScriptImpClass {
4042 bool wasCreated;
4043 void Created(GameObject *obj);
4044 void Entered(GameObject *obj,GameObject *enter);
4045};
4046
4047class JMG_Metroid_Remove_Object_On_Enter : public ScriptImpClass {
4048 void Entered(GameObject *obj,GameObject *enter);
4049};
4050
4051class JMG_Metroid_AI_Snow_Mini_Boss : public ScriptImpClass {
4052 int LastSeen;
4053 int currentTargetID;
4054 int huntorattack;
4055 int waitcount;
4056 Vector3 homelocation;
4057 float speed;
4058 void Created(GameObject *obj);
4059 void Timer_Expired(GameObject *obj,int number);
4060 void Enemy_Seen(GameObject *obj,GameObject *seen);
4061 void Damaged(GameObject *obj,GameObject *damager,float damage);
4062};
4063
4064class JMG_Metroid_Banshee_Strike_Craft : public ScriptImpClass {
4065 int lastAnimation;
4066 int BansheeID;
4067 void Created(GameObject *obj);
4068 void Animation_Complete(GameObject *obj,const char *anim);
4069 void Destroyed(GameObject *obj);
4070};
4071
4072class JMG_Metroid_Cheat_Mode_Death_Counter : public ScriptImpClass {
4073 void Damaged(GameObject *obj,GameObject *damager,float damage);
4074};
4075
4076class JMG_Metroid_ZeroBug_Tracker : public ScriptImpClass {
4077 int PlayerID;
4078 void Created(GameObject *obj);
4079 void Timer_Expired(GameObject *obj,int number);
4080};
4081
4082class JMG_Metroid_Zone_Damage_Object_While_In_Zone : public ScriptImpClass {
4083 void Entered(GameObject *obj,GameObject *enter);
4084 void Exited(GameObject *obj,GameObject *exiter);
4085};
4086
4087class JMG_Metroid_Attached_Zone_Damage_Object_While_In_Zone : public ScriptImpClass {
4088 void Created(GameObject *obj);
4089 void Timer_Expired(GameObject *obj,int number);
4090};
4091
4092class MetroidRandomSpawnSystem
4093{
4094public:
4095 struct MetroidRandomSpawnNode
4096 {
4097 int id;
4098 Vector3 pos;
4099 int groupId;
4100 struct MetroidRandomSpawnNode *next;
4101 MetroidRandomSpawnNode(GameObject *obj,int groupId)
4102 {
4103 this->id = Commands->Get_ID(obj);
4104 this->pos = Commands->Get_Position(obj);
4105 this->groupId = groupId;
4106 this->next = NULL;
4107 Commands->Destroy_Object(obj);
4108 }
4109 };
4110private:
4111 int totalPointCount;
4112 struct MetroidRandomSpawnNode *MetroidRandomSpawnNodeList;
4113public:
4114 MetroidRandomSpawnSystem()
4115 {
4116 totalPointCount = 0;
4117 MetroidRandomSpawnNodeList = NULL;
4118 }
4119 void AddNode(GameObject *obj,int groupId)
4120 {
4121 totalPointCount++;
4122 int id = Commands->Get_ID(obj);
4123 MetroidRandomSpawnNode *Current = MetroidRandomSpawnNodeList;
4124 if (!MetroidRandomSpawnNodeList)
4125 MetroidRandomSpawnNodeList = new MetroidRandomSpawnNode(obj,groupId);
4126 while (Current)
4127 {
4128 if (Current->id == id)
4129 {
4130 totalPointCount--;
4131 Console_Input("msg MetroidRandomSpawnSystem AddNode ERROR: ID already exists in list!");
4132 return;
4133 }
4134 if (!Current->next)
4135 {
4136 Current->next = new MetroidRandomSpawnNode(obj,groupId);
4137 return;
4138 }
4139 Current = Current->next;
4140 }
4141 }
4142 void EmptyList()
4143 {
4144 MetroidRandomSpawnNode *Current = MetroidRandomSpawnNodeList,*die = NULL;
4145 while (Current)
4146 {
4147 die = Current;
4148 Current = Current->next;
4149 delete die;
4150 }
4151 MetroidRandomSpawnNodeList = NULL;
4152 }
4153 bool SelectRandomSpawnPoint(Vector3 *pos,int groupId)
4154 {
4155 int Random = Commands->Get_Random_Int(0,totalPointCount*2);
4156 MetroidRandomSpawnNode *Current = MetroidRandomSpawnNodeList;
4157 while (Current)
4158 {
4159 if (Current->groupId == groupId)
4160 {
4161 if (Random)
4162 Random--;
4163 if (Random <= 0)
4164 {
4165 *pos = Current->pos;
4166 return true;
4167 }
4168 }
4169 Current = Current->next;
4170 }
4171 return false;
4172 }
4173 float GetNearestStar(const Vector3 &pos)
4174 {
4175 float minDist = 0;
4176 for (int x = 1;x < 128;x++)
4177 {
4178 GameObject *player = Get_GameObj(x);
4179 if (!player)
4180 continue;
4181 float tempDist = JmgUtility::SimpleDistance(pos,Commands->Get_Position(player));
4182 if (!minDist || tempDist < minDist)
4183 minDist = tempDist;
4184 }
4185 return minDist;
4186 }
4187 Vector3 SelectFurthestSpawnPoint(const Vector3 &pos,int groupId)
4188 {
4189 Vector3 bestPos = pos;
4190 float maxDist = 0;
4191 MetroidRandomSpawnNode *Current = MetroidRandomSpawnNodeList;
4192 while (Current)
4193 {
4194 if (Current->groupId == groupId)
4195 {
4196 float tempDist = GetNearestStar(Current->pos);
4197 if (!maxDist || tempDist > maxDist)
4198 {
4199 maxDist = tempDist;
4200 bestPos = Current->pos;
4201 }
4202 }
4203 Current = Current->next;
4204 }
4205 return bestPos;
4206 }
4207};
4208
4209MetroidRandomSpawnSystem MetroidRandomSpawnControl = MetroidRandomSpawnSystem();
4210
4211class JMG_Metroid_Random_Spawn_Point_Node : public ScriptImpClass {
4212 void Created(GameObject *obj);
4213};
4214
4215class JMG_Metroid_Spawn_At_Random_Spawn_Point : public ScriptImpClass {
4216 void Created(GameObject *obj);
4217 void Timer_Expired(GameObject *obj,int number);
4218};
4219
4220class JMG_Metroid_Granted_Shield_Powerup : public ScriptImpClass {
4221 void Custom(GameObject *obj,int message,int param,GameObject *sender);
4222};
4223
4224class SupplyModeSystem
4225{
4226 int UpgradePowerupCount;
4227 struct UpgradePowerupNode
4228 {
4229 int ID;
4230 struct UpgradePowerupNode *next;
4231 UpgradePowerupNode(GameObject *obj)
4232 {
4233 ID = Commands->Get_ID(obj);
4234 next = NULL;
4235 }
4236 };
4237 UpgradePowerupNode *UpgradePowerupNodeList;
4238public:
4239 int WeapoonSpawnerID;
4240 SupplyModeSystem()
4241 {
4242 WeapoonSpawnerID = 0;
4243 UpgradePowerupCount = 0;
4244 UpgradePowerupNodeList = NULL;
4245 }
4246 int GrabFirstID()
4247 {
4248 if (!UpgradePowerupNodeList)
4249 return 0;
4250 UpgradePowerupNode *Current = UpgradePowerupNodeList;
4251 while (Current)
4252 {
4253 if (Current->ID)
4254 return Current->ID;
4255 Current = Current->next;
4256 }
4257 return 0;
4258 }
4259 void AddUpgradePowerup(GameObject *obj)
4260 {
4261 UpgradePowerupCount++;
4262 UpgradePowerupNode *Current = UpgradePowerupNodeList;
4263 if (!UpgradePowerupNodeList)
4264 UpgradePowerupNodeList = new UpgradePowerupNode(obj);
4265 while (Current)
4266 {
4267 if (!Current->next)
4268 {
4269 Current->next = new UpgradePowerupNode(obj);
4270 break;
4271 }
4272 Current = Current->next;
4273 }
4274 if (UpgradePowerupCount > 5)
4275 {
4276 GameObject *object = Commands->Find_Object(GrabFirstID());
4277 if (object)
4278 Commands->Destroy_Object(object);
4279 }
4280 }
4281 void RemoveUpgradePowerup(GameObject *obj)
4282 {
4283 int ID = Commands->Get_ID(obj);
4284 UpgradePowerupNode *Current = UpgradePowerupNodeList,*Prev = NULL;
4285 while (Current)
4286 {
4287 if (Current->ID == ID)
4288 {
4289 UpgradePowerupCount--;
4290 Current->ID = 0;
4291 return;
4292 }
4293 Prev = Current;
4294 Current = Current->next;
4295 }
4296 }
4297 void EmptyList()
4298 {
4299 UpgradePowerupNode *Current = UpgradePowerupNodeList,*die = NULL;
4300 while (Current)
4301 {
4302 die = Current;
4303 Current = Current->next;
4304 delete die;
4305 }
4306 UpgradePowerupCount = 0;
4307 UpgradePowerupNodeList = NULL;
4308 }
4309 void DestroyList()
4310 {
4311 UpgradePowerupNode *Current = UpgradePowerupNodeList;
4312 while (Current)
4313 {
4314 GameObject *upgrade = Commands->Find_Object(Current->ID);
4315 if (upgrade)
4316 Commands->Destroy_Object(upgrade);
4317 Current = Current->next;
4318 }
4319 }
4320};
4321
4322SupplyModeSystem SupplyModeSystemControl[128] = {SupplyModeSystem()};
4323
4324class JMG_Metroid_Supply_Mode : public ScriptImpClass {
4325 int BlockArmorUpgradeRegen;
4326 int BlockWeaponSpawnRegen;
4327 int LastArmorUpgradeAmmo;
4328 int LastWeaponSpawnAmmo;
4329 void Created(GameObject *obj);
4330 void Timer_Expired(GameObject *obj,int number);
4331 void Destroyed(GameObject *obj);
4332public:
4333 static int ShieldUpgradeGrantedBy[128];
4334 static void ClearUpgrades(int playerId,const char *playerName);
4335};
4336int JMG_Metroid_Supply_Mode::ShieldUpgradeGrantedBy[128] = {0};
4337
4338class JMG_Metroid_Supply_Shield_Powerup_Beacon : public ScriptImpClass {
4339 void Created(GameObject *obj);
4340};
4341
4342class JMG_Metroid_Supply_Shield_Powerup : public ScriptImpClass {
4343 void Created(GameObject *obj);
4344 void Custom(GameObject *obj,int message,int param,GameObject *sender);
4345 void Destroyed(GameObject *obj);
4346};
4347
4348class JMG_Metroid_Supply_Weapon_Spawner_Beacon : public ScriptImpClass {
4349 void Created(GameObject *obj);
4350};
4351
4352class JMG_Metroid_Supply_Weapon_Spawner_Decoy : public ScriptImpClass {
4353 void Created(GameObject *obj);
4354 void Timer_Expired(GameObject *obj,int number);
4355};
4356
4357class JMG_Metroid_Supply_Weapon_Spawner_Weapon : public ScriptImpClass {
4358 void Custom(GameObject *obj,int message,int param,GameObject *sender);
4359};
4360
4361class JMG_Metroid_Display_Message_On_Pickup : public ScriptImpClass {
4362 void Custom(GameObject *obj,int message,int param,GameObject *sender);
4363};
4364
4365class JMG_Metroid_Tutorial_Teleport : public ScriptImpClass {
4366 void Custom(GameObject *obj,int message,int param,GameObject *sender);
4367};
4368
4369class JMG_Metroid_Shield_Regen : public ScriptImpClass {
4370 int playerId;
4371 void Created(GameObject *obj);
4372 void Timer_Expired(GameObject *obj,int number);
4373};
4374
4375class JMG_Metroid_Transform_Into_Cinematic_Object : public ScriptImpClass {
4376 void Created(GameObject *obj);
4377};
4378
4379class JMG_Metroid_Grant_Phone_If_Pkg_Is_Rp2 : public ScriptImpClass {
4380 void Created(GameObject *obj);
4381};
4382
4383class JMG_Metroid_Boss_HP_Modifier : public ScriptImpClass {
4384 float maxShield;
4385 void Created(GameObject *obj);
4386 void Timer_Expired(GameObject *obj,int number);
4387};
4388
4389class JMG_Metroid_Set_Is_Rendered_On_Custom : public ScriptImpClass {
4390 void Created(GameObject *obj);
4391 void Custom(GameObject *obj,int message,int param,GameObject *sender);
4392};
4393
4394class JMG_Metroid_AI_Shield_Regen : public ScriptImpClass {
4395 int lastDamaged;
4396 void Created(GameObject *obj);
4397 void Timer_Expired(GameObject *obj,int number);
4398 void Damaged(GameObject *obj,GameObject *damager,float damage);
4399};
4400
4401class JMG_Metroid_Invincible_Object : public ScriptImpClass {
4402 void Created(GameObject *obj);
4403};
4404
4405class JMG_Metroid_Damage_Score_Monitor : public ScriptImpClass {
4406 void Damaged(GameObject *obj,GameObject *damager,float damage);
4407 void Killed(GameObject *obj, GameObject *damager);
4408};
4409
4410class JMG_Metroid_Death_Zone_Score_Monitor : public ScriptImpClass {
4411 void Entered(GameObject *obj,GameObject *enter);
4412};
4413
4414class JMG_Metroid_Weapon_Pickup_Score_Monitor : public ScriptImpClass {
4415 void Custom(GameObject *obj,int message,int param,GameObject *sender);
4416};
4417
4418class JMG_Metroid_Count_Jammed_Door_Destruction : public ScriptImpClass {
4419 void Killed(GameObject *obj, GameObject *damager);
4420};
4421
4422class JMG_Metroid_Zone_Score_Monitor : public ScriptImpClass {
4423 void Entered(GameObject *obj,GameObject *enter);
4424};
4425
4426class JMG_Metroid_Lockdown_zComputer_Console_Special_Disarm_Script : public ScriptImpClass {
4427 float pokeAmount;
4428 int TerminalNumber;
4429 int subtractionGrowth;
4430 time_t lastPoke;
4431 void Created(GameObject *obj);
4432 void Poked(GameObject *obj,GameObject *poker);
4433 void Timer_Expired(GameObject *obj,int number);
4434 void Killed(GameObject *obj,GameObject *killer);
4435 void Timeout(GameObject *obj);
4436};
4437
4438class JMG_Metroid_Mine_Computer_Console_Script_Special : public ScriptImpClass {
4439 float pokeAmount;
4440 int TerminalNumber;
4441 int subtractionGrowth;
4442 time_t lastPoke;
4443 void Created(GameObject *obj);
4444 void Poked(GameObject *obj,GameObject *poker);
4445 void Timer_Expired(GameObject *obj,int number);
4446 void Timeout(GameObject *obj);
4447};
4448
4449class JMG_Metroid_Poke_Activate_Purchase_Terminal : public ScriptImpClass {
4450 void Created(GameObject *obj);
4451 void Poked(GameObject *obj,GameObject *poker);
4452};
4453
4454class JMG_Metroid_Update_And_Display_Briefing_On_Enter : public ScriptImpClass {
4455 void Entered(GameObject *obj,GameObject *enter);
4456};
4457
4458class JMG_Metroid_Objective_Update_On_Enter : public ScriptImpClass {
4459 bool triggered;
4460 void Entered(GameObject *obj,GameObject *enter);
4461 void Timer_Expired(GameObject *obj,int number);
4462public:
4463 JMG_Metroid_Objective_Update_On_Enter()
4464 {
4465 triggered = false;
4466 }
4467};
4468
4469class JMG_Metroid_Objective_Update_On_Pickup : public ScriptImpClass {
4470 void Custom(GameObject *obj,int message,int param,GameObject *sender);
4471};
4472
4473
4474class JMG_Metroid_Objective_Update_On_Killed : public ScriptImpClass {
4475 void Killed(GameObject *obj, GameObject *damager);
4476};
4477
4478class JMG_Metroid_Objective_Update_On_Custom : public ScriptImpClass {
4479 void Custom(GameObject *obj,int message,int param,GameObject *sender);
4480};
4481
4482class JMG_AI_Artillery_Targeting_Fire_At_Custom : public ScriptImpClass {
4483 double velocity;
4484 double gravity;
4485 void Created(GameObject *obj);
4486 void Custom(GameObject *obj,int message,int param,GameObject *sender);
4487 void Timer_Expired(GameObject *obj,int number);
4488 bool CalculateAngle(double *returnAngle,double distance,double height,bool highAngle);
4489};
4490
4491class JMG_Metroid_AI_Forest_Mini_Boss : public ScriptImpClass {
4492 bool primary;
4493 int LastSeen;
4494 int currentTargetID;
4495 int huntorattack;
4496 int waitcount;
4497 float speed;
4498 void Created(GameObject *obj);
4499 void Timer_Expired(GameObject *obj,int number);
4500 void Enemy_Seen(GameObject *obj,GameObject *seen);
4501 void Damaged(GameObject *obj,GameObject *damager,float damage);
4502 void Attack_Target(GameObject *obj,GameObject *target);
4503 void Hide(GameObject *obj);
4504};
4505
4506class JMG_Metroid_SpawnRoom_Objective_Update_On_Enter : public ScriptImpClass {
4507 bool triggered;
4508 void Entered(GameObject *obj,GameObject *enter);
4509 void Timer_Expired(GameObject *obj,int number);
4510public:
4511 JMG_Metroid_SpawnRoom_Objective_Update_On_Enter()
4512 {
4513 triggered = false;
4514 }
4515};
4516
4517class JMG_AI_Artillery_Targeting_Fire_Vehicle_Projectile_At_Custom : public ScriptImpClass {
4518 bool reloadComplete;
4519 void Created(GameObject *obj);
4520 void Custom(GameObject *obj,int message,int param,GameObject *sender);
4521 void Timer_Expired(GameObject *obj,int number);
4522 bool CalculateAngle(double *returnAngle,double distance,double height,bool highAngle);
4523 void FireProjectile(GameObject *obj,double zAngle,double aimAngle);
4524};
4525
4526
4527class JMG_AI_Artillery_Targeting_Fire_Vehicle_Projectile_Attach : public ScriptImpClass {
4528 void Created(GameObject *obj);
4529 void Timer_Expired(GameObject *obj,int number);
4530 void Destroyed(GameObject *obj);
4531};
4532
4533class JMG_Metroid_Miniboss_Turret : public ScriptImpClass {
4534 void Created(GameObject *obj);
4535 void Destroyed(GameObject *obj);
4536};
4537
4538class JMG_AI_Artillery_Targeting_Fire_Vehicle_Projectile_Custom_Player : public ScriptImpClass {
4539 bool reloadComplete;
4540 void Created(GameObject *obj);
4541 void Custom(GameObject *obj,int message,int param,GameObject *sender);
4542 void Timer_Expired(GameObject *obj,int number);
4543 bool CalculateAngle(double *returnAngle,double distance,double height,bool highAngle);
4544 void FireProjectile(GameObject *obj,double zAngle,double aimAngle);
4545};