summaryrefslogtreecommitdiffstats
path: root/src/control
diff options
context:
space:
mode:
authorFire_Head <Fire-Head@users.noreply.github.com>2019-07-11 02:48:36 +0200
committerGitHub <noreply@github.com>2019-07-11 02:48:36 +0200
commitaa449b6fe162d8960351c5fe164a9120b8572652 (patch)
treefa82496d356ac2b77ffa1ab00684b0150907f009 /src/control
parentfixfixfix (diff)
parentMerge pull request #129 from erorcun/erorcun (diff)
downloadre3-aa449b6fe162d8960351c5fe164a9120b8572652.tar
re3-aa449b6fe162d8960351c5fe164a9120b8572652.tar.gz
re3-aa449b6fe162d8960351c5fe164a9120b8572652.tar.bz2
re3-aa449b6fe162d8960351c5fe164a9120b8572652.tar.lz
re3-aa449b6fe162d8960351c5fe164a9120b8572652.tar.xz
re3-aa449b6fe162d8960351c5fe164a9120b8572652.tar.zst
re3-aa449b6fe162d8960351c5fe164a9120b8572652.zip
Diffstat (limited to '')
-rw-r--r--src/control/AutoPilot.h39
-rw-r--r--src/control/Darkel.cpp332
-rw-r--r--src/control/Darkel.h42
-rw-r--r--src/control/PathFind.cpp14
-rw-r--r--src/control/Phones.cpp124
-rw-r--r--src/control/Phones.h49
-rw-r--r--src/control/Replay.cpp76
-rw-r--r--src/control/Script.cpp1150
-rw-r--r--src/control/Script.h234
-rw-r--r--src/control/ScriptCommands.h1158
10 files changed, 3128 insertions, 90 deletions
diff --git a/src/control/AutoPilot.h b/src/control/AutoPilot.h
index 97b02f5c..364cb633 100644
--- a/src/control/AutoPilot.h
+++ b/src/control/AutoPilot.h
@@ -59,9 +59,9 @@ enum eCarDrivingStyle : uint8
class CAutoPilot {
public:
- void *m_currentAddress;
- void *m_startingRouteNode;
- void *m_PreviousRouteNode;
+ uint32 m_nCurrentRouteNode;
+ uint32 m_nNextRouteNode;
+ uint32 m_nPrevRouteNode;
uint32 m_nTotalSpeedScaleFactor;
uint32 m_nSpeedScaleFactor;
uint32 m_nCurrentPathNodeInfo;
@@ -80,10 +80,41 @@ public:
uint8 m_nAnimationTime;
float m_fMaxTrafficSpeed;
uint8 m_nCruiseSpeed;
- uint8 m_nCarCtrlFlags;
+ uint8 m_flag1 : 1;
+ uint8 m_flag2 : 1;
+ uint8 m_flag4 : 1;
+ uint8 m_flag8 : 1;
+ uint8 m_flag10 : 1;
CVector m_vecDestinationCoors;
void *m_aPathFindNodesInfo[8];
uint16 m_nPathFindNodesCount;
CVehicle *m_pTargetCar;
+
+ CAutoPilot(void) {
+ m_nPrevRouteNode = 0;
+ m_nNextRouteNode = m_nPrevRouteNode;
+ m_nCurrentRouteNode = m_nNextRouteNode;
+ m_nTotalSpeedScaleFactor = 0;
+ m_nSpeedScaleFactor = 1000;
+ m_nPreviousPathNodeInfo = 0;
+ m_nNextPathNodeInfo = m_nPreviousPathNodeInfo;
+ m_nCurrentPathNodeInfo = m_nNextPathNodeInfo;
+ m_nNextDirection = 1;
+ m_nCurrentDirecton = m_nNextDirection;
+ m_nCurrentPathDirection = 0;
+ m_nPreviousPathDirection = m_nCurrentPathDirection;
+ m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
+ m_nCarMission = MISSION_NONE;
+ m_nAnimationId = TEMPACT_NONE;
+ m_nCruiseSpeed = 10;
+ m_fMaxTrafficSpeed = 10.0f;
+ m_flag2 = false;
+ m_flag1 = false;
+ m_nPathFindNodesCount = 0;
+ m_pTargetCar = 0;
+ m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
+ m_nTimeSwitchedToRealPhysics = m_nTimeToStartMission;
+ m_flag8 = false;
+ }
};
static_assert(sizeof(CAutoPilot) == 0x70, "CAutoPilot: error");
diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp
index 32d975e0..ab28f96e 100644
--- a/src/control/Darkel.cpp
+++ b/src/control/Darkel.cpp
@@ -1,12 +1,338 @@
#include "common.h"
#include "patcher.h"
+#include "main.h"
#include "Darkel.h"
+#include "Timer.h"
+#include "DMAudio.h"
+#include "Population.h"
+#include "Weapon.h"
+#include "World.h"
+#include "PlayerPed.h"
+#include "Stats.h"
+#include "Font.h"
+#include "Text.h"
+int32 &CDarkel::TimeLimit = *(int32*)0x885BAC;
+int32 &CDarkel::PreviousTime = *(int32*)0x885B00;
+int32 &CDarkel::TimeOfFrenzyStart = *(int32*)0x9430D8;
+int32 &CDarkel::WeaponType = *(int32*)0x9430F0;
+int32 &CDarkel::AmmoInterruptedWeapon = *(int32*)0x8E29C8;
+int32 &CDarkel::KillsNeeded = *(int32*)0x8F1AB8;
+int8 &CDarkel::InterruptedWeapon = *(int8*)0x95CD60;
+int8 &CDarkel::bStandardSoundAndMessages = *(int8*)0x95CDB6;
+int8 &CDarkel::bNeedHeadShot = *(int8*)0x95CDCA;
+int8 &CDarkel::bProperKillFrenzy = *(int8*)0x95CD98;
+eKillFrenzyStatus &CDarkel::Status = *(eKillFrenzyStatus*)0x95CCB4;
+int16 *CDarkel::RegisteredKills = (int16*)0x6EDBE0;
+int32 &CDarkel::ModelToKill = *(int32*)0x8F2C78;
+int32 &CDarkel::ModelToKill2 = *(int32*)0x885B40;
+int32 &CDarkel::ModelToKill3 = *(int32*)0x885B3C;
+int32 &CDarkel::ModelToKill4 = *(int32*)0x885B34;
+wchar *CDarkel::pStartMessage = (wchar*)0x8F2C08;
+
+int32 CDarkel::CalcFade(uint32 time, int32 start, uint32 end) {
+ if (time >= start && time <= end) {
+ if (time >= start + 500) {
+ if (time <= end - 500)
+ return 255;
+ else
+ return 255 * (end - time) / 500;
+ }
+ else
+ return 255 * (time - start) / 500;
+ }
+ else
+ return 0;
+}
+
+// This function has been cleaned up from unused stuff.
+#if 0
WRAPPER void CDarkel::DrawMessages(void) { EAXJMP(0x420920); }
+#else
+void CDarkel::DrawMessages()
+{
+ bool DisplayTimers = false;
+
+ switch (Status) {
+ case KILLFRENZY_ONGOING:
+ assert(pStartMessage != nil);
+ DisplayTimers = true;
+ break;
+ case KILLFRENZY_PASSED:
+ case KILLFRENZY_FAILED:
+ DisplayTimers = false;
+ break;
+ };
+
+ if (DisplayTimers) {
+ CFont::SetPropOn();
+ CFont::SetBackgroundOff();
+ CFont::SetBackGroundOnlyTextOn();
+ CFont::SetAlignment(ALIGN_RIGHT);
+ CFont::SetRightJustifyWrap(-SCREEN_WIDTH);
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
+
+ float AlignToHUD = SCREEN_SCALE_X(-10.0f);
+ int32 a = (TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart));
+ if (CTimer::GetFrameCounter() & 8 || a > 4000) {
+ sprintf(gString, "%d:%02d", a / 60000, a % 60000 / 1000);
+ AsciiToUnicode(gString, gUString);
+ CFont::SetColor(CRGBA(0, 0, 0, 255));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(25.0f) + AlignToHUD, SCREEN_SCALE_Y(112.0f), gUString);
+
+ CFont::SetColor(CRGBA(150, 100, 255, 255));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(27.0f) + AlignToHUD, SCREEN_SCALE_Y(110.0f), gUString);
+ }
+
+ if (KillsNeeded <= 0)
+ KillsNeeded = 0;
+
+ sprintf((char *)gString, "%d", KillsNeeded);
+ AsciiToUnicode(gString, gUString);
+
+ CFont::SetColor(CRGBA(0, 0, 0, 255));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(25.0f) + AlignToHUD, SCREEN_SCALE_Y(134.0f), gUString);
+
+ CFont::SetColor(CRGBA(255, 128, 128, 255));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(27.0f) + AlignToHUD, SCREEN_SCALE_Y(132.0f), gUString);
+ }
+}
+#endif
+
+void CDarkel::Init()
+{
+ Status = KILLFRENZY_NONE;
+}
+
+int16 CDarkel::QueryModelsKilledByPlayer(int32 modelId)
+{
+ return RegisteredKills[modelId];
+}
-bool CDarkel::Status = *(bool*)0x95CCB4;
bool CDarkel::FrenzyOnGoing()
{
- return Status == 1;
-} \ No newline at end of file
+ return Status == KILLFRENZY_ONGOING;
+}
+
+
+eKillFrenzyStatus CDarkel::ReadStatus()
+{
+ return Status;
+}
+
+#if 1
+WRAPPER void CDarkel::RegisterCarBlownUpByPlayer(CVehicle *vehicle) { EAXJMP(0x421070); }
+#else
+int32 CDarkel::RegisterCarBlownUpByPlayer(CVehicle *vehicle)
+{
+ return 0;
+}
+#endif
+
+#if 1
+WRAPPER void CDarkel::RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot) { EAXJMP(0x420F60); }
+#else
+void CDarkel::RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot)
+{
+
+
+}
+#endif
+
+void CDarkel::RegisterKillNotByPlayer()
+{
+ ++CStats::NumberKillFrenziesPassed;
+}
+
+void CDarkel::ResetModelsKilledByPlayer()
+{
+ for (int i = 0; i < 200; i++)
+ RegisteredKills[i] = 0;
+}
+
+#if 0
+WRAPPER void CDarkel::ResetOnPlayerDeath() { EAXJMP(0x420E70); }
+#else
+void CDarkel::ResetOnPlayerDeath()
+{
+ if (Status != KILLFRENZY_ONGOING)
+ return;
+
+ CPopulation::m_AllRandomPedsThisType = -1;
+ Status = KILLFRENZY_FAILED;
+ TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds();
+
+ if (WeaponType == WEAPONTYPE_UZI_DRIVEBY)
+ WeaponType = WEAPONTYPE_UZI;
+
+ if (WeaponType < WEAPONTYPE_TOTALWEAPONS) {
+ FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon;
+ CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon;
+ }
+
+ if (FindPlayerVehicle()) {
+ FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId);
+ FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType;
+ FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon);
+ }
+
+
+ CPopulation::m_AllRandomPedsThisType = -1;
+ Status = KILLFRENZY_FAILED;
+ TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds();
+
+ if (WeaponType == WEAPONTYPE_UZI_DRIVEBY)
+ WeaponType = WEAPONTYPE_UZI;
+
+ if (WeaponType < WEAPONTYPE_TOTALWEAPONS) {
+ FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon;
+ CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon;
+ }
+
+ if (FindPlayerVehicle()) {
+ FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId);
+ FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType;
+ FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon);
+ }
+}
+#endif
+
+#if 0
+WRAPPER void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot) { EAXJMP(0x4210E0); }
+#else
+void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot)
+{
+ if (weaponType == WEAPONTYPE_UZI_DRIVEBY)
+ weaponType = WEAPONTYPE_UZI;
+
+ WeaponType = weaponType;
+ Status = KILLFRENZY_ONGOING;
+ KillsNeeded = kill;
+ ModelToKill = modelId0;
+ ModelToKill2 = modelId2;
+ ModelToKill3 = modelId3;
+ ModelToKill4 = modelId4;
+ pStartMessage = text;
+
+ if (text == TheText.Get("PAGE_00")) {
+ CDarkel::bProperKillFrenzy = 1;
+ CDarkel::pStartMessage = 0;
+ }
+ else
+ bProperKillFrenzy = 0;
+
+ bStandardSoundAndMessages = standardSound;
+ bNeedHeadShot = needHeadShot;
+ TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds();
+ TimeLimit = time;
+ PreviousTime = time / 1000;
+
+ if (weaponType < WEAPONTYPE_TOTALWEAPONS) {
+ InterruptedWeapon = FindPlayerPed()->m_currentWeapon;
+ FindPlayerPed()->GiveWeapon(weaponType, 0);
+ AmmoInterruptedWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal;
+ FindPlayerPed()->GiveWeapon(weaponType, 30000);
+ FindPlayerPed()->m_bWeaponSlot = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType;
+ FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_bWeaponSlot);
+
+ if (FindPlayerVehicle()) {
+ FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType;
+ if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal <= CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoInClip)
+ CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoInClip = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal;
+
+ FindPlayerPed()->ClearWeaponTarget();
+ }
+ }
+ if (CDarkel::bStandardSoundAndMessages)
+ DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_START, 0);
+}
+#endif
+
+void CDarkel::Update()
+{
+ if (Status != KILLFRENZY_ONGOING)
+ return;
+
+ int32 FrameTime = TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart);
+ if ((TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart)) > 0 || TimeLimit < 0) {
+ DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_ONGOING, FrameTime);
+
+ int32 PrevTime = FrameTime / 1000;
+
+ if (PrevTime != PreviousTime) {
+ if (PreviousTime < 12)
+ DMAudio.PlayFrontEndSound(SOUND_CLOCK_TICK, PrevTime);
+ PreviousTime = PrevTime;
+ }
+
+ }
+ else {
+ CPopulation::m_AllRandomPedsThisType = -1;
+ Status = KILLFRENZY_FAILED;
+ TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds();
+
+ if (WeaponType == WEAPONTYPE_UZI_DRIVEBY)
+ WeaponType = WEAPONTYPE_UZI;
+
+ if (WeaponType < WEAPONTYPE_TOTALWEAPONS) {
+ FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon;
+ CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon;
+ }
+
+ if (FindPlayerVehicle()) {
+ FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId);
+ FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType;
+ FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon);
+ }
+
+ if (bStandardSoundAndMessages)
+ DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_FAILED, 0);
+ }
+
+ if (KillsNeeded <= 0) {
+ CPopulation::m_AllRandomPedsThisType = -1;
+ Status = KILLFRENZY_PASSED;
+
+ if (bProperKillFrenzy)
+ CStats::AnotherKillFrenzyPassed();
+
+ TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds();
+
+ FindPlayerPed()->m_pWanted->SetWantedLevel(NOTWANTED);
+
+ if (WeaponType == WEAPONTYPE_UZI_DRIVEBY)
+ WeaponType = WEAPONTYPE_UZI;
+
+ if (WeaponType < WEAPONTYPE_TOTALWEAPONS) {
+ FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon;
+ CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon;
+ }
+
+ if (FindPlayerVehicle()) {
+ FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId);
+ FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType;
+ FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon);
+ }
+
+ if (bStandardSoundAndMessages)
+ DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_PASSED, 0);
+ }
+}
+
+STARTPATCHES
+ /*InjectHook(0x421380, CDarkel::CalcFade, PATCH_JUMP);
+ InjectHook(0x420920, CDarkel::DrawMessages, PATCH_JUMP);
+ InjectHook(0x420E60, CDarkel::FrenzyOnGoing, PATCH_JUMP);
+ InjectHook(0x420650, CDarkel::Init, PATCH_JUMP);
+ InjectHook(0x421370, CDarkel::QueryModelsKilledByPlayer, PATCH_JUMP);
+ InjectHook(0x420E50, CDarkel::ReadStatus, PATCH_JUMP);
+ InjectHook(0x421070, CDarkel::RegisterCarBlownUpByPlayer, PATCH_JUMP);
+ InjectHook(0x420F60, CDarkel::RegisterKillByPlayer, PATCH_JUMP);
+ InjectHook(0x421060, CDarkel::RegisterKillNotByPlayer, PATCH_JUMP);
+ InjectHook(0x421310, CDarkel::ResetModelsKilledByPlayer, PATCH_JUMP);
+ InjectHook(0x420E70, CDarkel::ResetOnPlayerDeath, PATCH_JUMP);
+ InjectHook(0x4210E0, CDarkel::StartFrenzy, PATCH_JUMP);
+ InjectHook(0x420660, CDarkel::Update, PATCH_JUMP);*/
+ENDPATCHES \ No newline at end of file
diff --git a/src/control/Darkel.h b/src/control/Darkel.h
index ed78d4e1..35d849d2 100644
--- a/src/control/Darkel.h
+++ b/src/control/Darkel.h
@@ -1,11 +1,51 @@
#pragma once
+#include "Weapon.h"
+
+class CVehicle;
+class CPed;
+
+enum eKillFrenzyStatus
+{
+ KILLFRENZY_NONE,
+ KILLFRENZY_ONGOING,
+ KILLFRENZY_PASSED,
+ KILLFRENZY_FAILED,
+};
class CDarkel
{
private:
- static bool Status;
+ static int32 &TimeLimit;
+ static int32 &PreviousTime;
+ static int32 &TimeOfFrenzyStart;
+ static int32 &WeaponType;
+ static int32 &AmmoInterruptedWeapon;
+ static int32 &KillsNeeded;
+ static int8 &InterruptedWeapon;
+ static int8 &bStandardSoundAndMessages;
+ static int8 &bNeedHeadShot;
+ static int8 &bProperKillFrenzy;
+ static eKillFrenzyStatus &Status;
+ static int16 *RegisteredKills;
+ static int32 &ModelToKill;
+ static int32 &ModelToKill2;
+ static int32 &ModelToKill3;
+ static int32 &ModelToKill4;
+ static wchar *pStartMessage;
public:
+ static int32 CalcFade(uint32 time, int32 min, uint32 max);
static void DrawMessages(void);
static bool FrenzyOnGoing();
+ static void Init();
+ static int16 QueryModelsKilledByPlayer(int32 modelId);
+ static eKillFrenzyStatus ReadStatus();
+ static void RegisterCarBlownUpByPlayer(CVehicle *vehicle);
+ static void RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot = false);
+ static void RegisterKillNotByPlayer();
+ static void ResetModelsKilledByPlayer();
+ static void ResetOnPlayerDeath();
+ static void StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot);
+ static void Update();
+
};
diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp
index f9ce7f35..a92882db 100644
--- a/src/control/PathFind.cpp
+++ b/src/control/PathFind.cpp
@@ -146,8 +146,8 @@ CPathFind::PreparePathData(void)
numExtern++;
if(InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes > numLanes)
numLanes = InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes;
- maxX = max(maxX, fabs(InfoForTileCars[k].x));
- maxY = max(maxY, fabs(InfoForTileCars[k].y));
+ maxX = max(maxX, Abs(InfoForTileCars[k].x));
+ maxY = max(maxY, Abs(InfoForTileCars[k].y));
}else if(InfoForTileCars[k].type == NodeTypeIntern)
numIntern++;
}
@@ -327,10 +327,10 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
if(tempnodes[k].linkState != 1)
continue;
dx = tempnodes[k].pos.x - CoorsXFormed.x;
- if(fabs(dx) < nearestDist){
+ if(Abs(dx) < nearestDist){
dy = tempnodes[k].pos.y - CoorsXFormed.y;
- if(fabs(dy) < nearestDist){
- nearestDist = max(fabs(dx), fabs(dy));
+ if(Abs(dy) < nearestDist){
+ nearestDist = max(Abs(dx), Abs(dy));
nearestId = k;
}
}
@@ -369,7 +369,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
dx = m_pathNodes[tempnodes[nearestId].link1].pos.x - m_pathNodes[tempnodes[nearestId].link2].pos.x;
dy = m_pathNodes[tempnodes[nearestId].link1].pos.y - m_pathNodes[tempnodes[nearestId].link2].pos.y;
tempnodes[nearestId].pos = (tempnodes[nearestId].pos + CoorsXFormed)*0.5f;
- mag = sqrt(dx*dx + dy*dy);
+ mag = Sqrt(dx*dx + dy*dy);
tempnodes[nearestId].dirX = dx/mag;
tempnodes[nearestId].dirY = dy/mag;
// do something when number of lanes doesn't agree
@@ -464,7 +464,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
posy = (m_pathNodes[i].pos.y + m_pathNodes[j].pos.y)*0.5f;
dx = m_pathNodes[j].pos.x - m_pathNodes[i].pos.x;
dy = m_pathNodes[j].pos.y - m_pathNodes[i].pos.y;
- mag = sqrt(dx*dx + dy*dy);
+ mag = Sqrt(dx*dx + dy*dy);
dx /= mag;
dy /= mag;
if(i < j){
diff --git a/src/control/Phones.cpp b/src/control/Phones.cpp
index fa4f83e5..028d80a9 100644
--- a/src/control/Phones.cpp
+++ b/src/control/Phones.cpp
@@ -1,6 +1,130 @@
#include "common.h"
#include "patcher.h"
#include "Phones.h"
+#include "Pools.h"
+
+CPhoneInfo &gPhoneInfo = *(CPhoneInfo*)0x732A20;
+
+bool &CPhoneInfo::isPhonePickedUp = *(bool*)0x6283AC;
+bool &CPhoneInfo::isPhoneBeingPickedUp = *(bool*)0x6283B4;
+CPhone *&CPhoneInfo::pickedUpPhone = *(CPhone**)0x6283B0;
+
+int
+CPhoneInfo::FindNearestFreePhone(CVector *pos)
+{
+ int nearestPhoneId = -1;
+ float nearestPhoneDist = 60.0f;
+
+ for (int phoneId = 0; phoneId < m_nMax; phoneId++) {
+
+ if (gPhoneInfo.m_aPhones[phoneId].m_nState == PHONE_STATE_FREE) {
+ float phoneDist = (m_aPhones[phoneId].m_vecPos - *pos).Magnitude2D();
+
+ if (phoneDist < nearestPhoneDist) {
+ nearestPhoneDist = phoneDist;
+ nearestPhoneId = phoneId;
+ }
+ }
+ }
+ return nearestPhoneId;
+}
+
+bool
+CPhoneInfo::PhoneAtThisPosition(CVector pos)
+{
+ for (int phoneId = 0; phoneId < m_nMax; phoneId++) {
+ if (pos.x == m_aPhones[phoneId].m_vecPos.x && pos.y == m_aPhones[phoneId].m_vecPos.y)
+ return true;
+ }
+ return false;
+}
+
+bool
+CPhoneInfo::HasMessageBeenDisplayed(int phoneId)
+{
+ if (isPhonePickedUp)
+ return false;
+
+ int state = m_aPhones[phoneId].m_nState;
+
+ return state == PHONE_STATE_REPEATED_MESSAGE_SHOWN_ONCE ||
+ state == PHONE_STATE_ONETIME_MESSAGE_SHOWN ||
+ state == PHONE_STATE_REPEATED_MESSAGE_SHOWN;
+}
+
+bool
+CPhoneInfo::IsMessageBeingDisplayed(int phoneId)
+{
+ return pickedUpPhone == &m_aPhones[phoneId];
+}
+
+void
+CPhoneInfo::Load(CPhoneInfo *source, uint8 buffer)
+{
+ // Buffer isn't used.
+
+ m_nMax = source->m_nMax;
+ m_nNum = source->m_nNum;
+ for (int phoneId = 0; phoneId < 50; phoneId++) {
+ CPhone *phone = &source->m_aPhones[phoneId];
+
+ m_aPhones[phoneId].m_vecPos = phone->m_vecPos;
+ memcpy(m_aPhones[phoneId].m_apMessages, phone->m_apMessages, sizeof(uint16*) * 6);
+ m_aPhones[phoneId].m_pEntity = phone->m_pEntity;
+ m_aPhones[phoneId].m_nState = phone->m_nState;
+ m_aPhones[phoneId].field_30 = phone->field_30;
+
+ if (phone->m_pEntity) {
+ // It's saved as building pool index in save file, convert it to true entity
+ CBuilding *actualEntity = CPools::GetBuildingPool()->GetSlot((int)phone->m_pEntity - 1);
+ m_aPhones[phoneId].m_pEntity = actualEntity;
+ }
+ }
+}
+
+void
+CPhoneInfo::SetPhoneMessage_JustOnce(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6)
+{
+ // If there is at least one message, it should be msg1.
+ if (msg1) {
+ m_aPhones[phoneId].m_apMessages[0] = msg1;
+ m_aPhones[phoneId].m_apMessages[1] = msg2;
+ m_aPhones[phoneId].m_apMessages[2] = msg3;
+ m_aPhones[phoneId].m_apMessages[3] = msg4;
+ m_aPhones[phoneId].m_apMessages[4] = msg5;
+ m_aPhones[phoneId].m_apMessages[5] = msg6;
+ m_aPhones[phoneId].m_nState = PHONE_STATE_ONETIME_MESSAGE_SET;
+ } else {
+ m_aPhones[phoneId].m_nState = PHONE_STATE_MESSAGE_REMOVED;
+ }
+}
+
+void
+CPhoneInfo::SetPhoneMessage_Repeatedly(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6)
+{
+ // If there is at least one message, it should be msg1.
+ if (msg1) {
+ m_aPhones[phoneId].m_apMessages[0] = msg1;
+ m_aPhones[phoneId].m_apMessages[1] = msg2;
+ m_aPhones[phoneId].m_apMessages[2] = msg3;
+ m_aPhones[phoneId].m_apMessages[3] = msg4;
+ m_aPhones[phoneId].m_apMessages[4] = msg5;
+ m_aPhones[phoneId].m_apMessages[5] = msg6;
+ m_aPhones[phoneId].m_nState = PHONE_STATE_REPEATED_MESSAGE_SET;
+ } else {
+ m_aPhones[phoneId].m_nState = PHONE_STATE_MESSAGE_REMOVED;
+ }
+}
+
+STARTPATCHES
+ InjectHook(0x42F720, &CPhoneInfo::FindNearestFreePhone, PATCH_JUMP);
+ InjectHook(0x42FD50, &CPhoneInfo::PhoneAtThisPosition, PATCH_JUMP);
+ InjectHook(0x42FFF0, &CPhoneInfo::HasMessageBeenDisplayed, PATCH_JUMP);
+ InjectHook(0x430030, &CPhoneInfo::IsMessageBeingDisplayed, PATCH_JUMP);
+ InjectHook(0x430120, &CPhoneInfo::Load, PATCH_JUMP);
+ InjectHook(0x42FF90, &CPhoneInfo::SetPhoneMessage_JustOnce, PATCH_JUMP);
+ InjectHook(0x42FF30, &CPhoneInfo::SetPhoneMessage_Repeatedly, PATCH_JUMP);
+ENDPATCHES
WRAPPER void PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x42F570); }
WRAPPER void PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x42F470); }
diff --git a/src/control/Phones.h b/src/control/Phones.h
index a29043ed..74f24d25 100644
--- a/src/control/Phones.h
+++ b/src/control/Phones.h
@@ -1,6 +1,55 @@
#pragma once
+#include "Physical.h"
#include "AnimBlendAssociation.h"
+enum {
+ PHONE_STATE_FREE,
+ PHONE_STATE_1,
+ PHONE_STATE_2,
+ PHONE_STATE_MESSAGE_REMOVED,
+ PHONE_STATE_ONETIME_MESSAGE_SET,
+ PHONE_STATE_REPEATED_MESSAGE_SET,
+ PHONE_STATE_REPEATED_MESSAGE_SHOWN_ONCE,
+ PHONE_STATE_ONETIME_MESSAGE_SHOWN,
+ PHONE_STATE_REPEATED_MESSAGE_SHOWN,
+ PHONE_STATE_9
+};
+
+struct CPhone
+{
+ CVector m_vecPos;
+ uint16 *m_apMessages[6];
+ uint32 m_lastTimeRepeatedMsgShown;
+ CEntity *m_pEntity; // it's building pool index in save files
+ int32 m_nState;
+ uint8 field_30;
+};
+
+static_assert(sizeof(CPhone) == 0x34, "CPhone: error");
+
+class CPhoneInfo {
+ static bool &isPhonePickedUp;
+ static bool &isPhoneBeingPickedUp;
+ static CPhone *&pickedUpPhone;
+public:
+ int32 m_nMax;
+ int32 m_nNum;
+ CPhone m_aPhones[50];
+
+ CPhoneInfo() { }
+ ~CPhoneInfo() { }
+
+ int FindNearestFreePhone(CVector*);
+ bool PhoneAtThisPosition(CVector);
+ bool HasMessageBeenDisplayed(int);
+ bool IsMessageBeingDisplayed(int);
+ void Load(CPhoneInfo *source, uint8 buffer);
+ void SetPhoneMessage_JustOnce(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6);
+ void SetPhoneMessage_Repeatedly(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6);
+};
+
+extern CPhoneInfo &gPhoneInfo;
+
void PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg);
void PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg); \ No newline at end of file
diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp
index 06995663..3ce9085f 100644
--- a/src/control/Replay.cpp
+++ b/src/control/Replay.cpp
@@ -290,14 +290,14 @@ void CReplay::RecordThisFrame(void)
CPed* p = peds->GetSlot(i);
if (!p || !p->m_rwObject)
continue;
- if (!p->bRecordedForReplay){
+ if (!p->bHasAlreadyBeenRecorded){
tPedHeaderPacket* ph = (tPedHeaderPacket*)&Record.m_pBase[Record.m_nOffset];
ph->type = REPLAYPACKET_PED_HEADER;
ph->index = i;
ph->mi = p->GetModelIndex();
ph->pedtype = p->m_nPedType;
Record.m_nOffset += sizeof(*ph);
- p->bRecordedForReplay = true;
+ p->bHasAlreadyBeenRecorded = true;
}
StorePedUpdate(p, i);
}
@@ -469,7 +469,7 @@ void CReplay::ProcessPedUpdate(CPed *ped, float interpolation, CAddressInReplayB
CMatrix ped_matrix;
pp->matrix.DecompressIntoFullMatrix(ped_matrix);
ped->GetMatrix() = ped->GetMatrix() * CMatrix(1.0f - interpolation);
- *ped->GetMatrix().GetPosition() *= (1.0f - interpolation);
+ ped->GetMatrix().GetPosition() *= (1.0f - interpolation);
ped->GetMatrix() += CMatrix(interpolation) * ped_matrix;
if (pp->vehicle_index) {
ped->m_pMyVehicle = CPools::GetVehiclePool()->GetSlot(pp->vehicle_index - 1);
@@ -666,7 +666,7 @@ void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressI
CMatrix vehicle_matrix;
vp->matrix.DecompressIntoFullMatrix(vehicle_matrix);
vehicle->GetMatrix() = vehicle->GetMatrix() * CMatrix(1.0f - interpolation);
- *vehicle->GetMatrix().GetPosition() *= (1.0f - interpolation);
+ vehicle->GetMatrix().GetPosition() *= (1.0f - interpolation);
vehicle->GetMatrix() += CMatrix(interpolation) * vehicle_matrix;
vehicle->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
vehicle->m_fHealth = 4 * vp->health;
@@ -686,8 +686,8 @@ void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressI
car->m_aSuspensionSpringRatio[i] = vp->wheel_susp_dist[i] / 50.0f;
car->m_aWheelRotation[i] = vp->wheel_rotation[i] * M_PI / 128.0f;
}
- car->Doors[2].m_fAngle = car->Doors[2].m_fPreviousAngle = vp->door_angles[0] * M_PI / 127.0f;
- car->Doors[3].m_fAngle = car->Doors[3].m_fPreviousAngle = vp->door_angles[1] * M_PI / 127.0f;
+ car->Doors[2].m_fAngle = car->Doors[2].m_fPrevAngle = vp->door_angles[0] * M_PI / 127.0f;
+ car->Doors[3].m_fAngle = car->Doors[3].m_fPrevAngle = vp->door_angles[1] * M_PI / 127.0f;
if (vp->door_angles[0])
car->Damage.SetDoorStatus(2, 2);
if (vp->door_angles[1])
@@ -847,7 +847,7 @@ bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, flo
{
tGeneralPacket* pg = (tGeneralPacket*)&ptr[offset];
TheCamera.GetMatrix() = TheCamera.GetMatrix() * CMatrix(split);
- *TheCamera.GetMatrix().GetPosition() *= split;
+ TheCamera.GetMatrix().GetPosition() *= split;
TheCamera.GetMatrix() += CMatrix(interpolation) * pg->camera_pos;
RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera));
pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition();
@@ -979,40 +979,40 @@ void CReplay::ProcessReplayCamera(void)
switch (CameraMode) {
case REPLAYCAMMODE_TOPDOWN:
{
- *TheCamera.GetMatrix().GetPosition() = CVector(CameraFocusX, CameraFocusY, CameraFocusZ + 15.0f);
- *TheCamera.GetMatrix().GetForward() = CVector(0.0f, 0.0f, -1.0f);
- *TheCamera.GetMatrix().GetUp() = CVector(0.0f, 1.0f, 0.0f);
- *TheCamera.GetMatrix().GetRight() = CVector(1.0f, 0.0f, 0.0f);
+ TheCamera.GetMatrix().GetPosition() = CVector(CameraFocusX, CameraFocusY, CameraFocusZ + 15.0f);
+ TheCamera.GetMatrix().GetForward() = CVector(0.0f, 0.0f, -1.0f);
+ TheCamera.GetMatrix().GetUp() = CVector(0.0f, 1.0f, 0.0f);
+ TheCamera.GetMatrix().GetRight() = CVector(1.0f, 0.0f, 0.0f);
RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera));
- pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition();
- pm->at = *(RwV3d*)TheCamera.GetMatrix().GetForward();
- pm->up = *(RwV3d*)TheCamera.GetMatrix().GetUp();
- pm->right = *(RwV3d*)TheCamera.GetMatrix().GetRight();
+ pm->pos = *(RwV3d*)&TheCamera.GetMatrix().GetPosition();
+ pm->at = *(RwV3d*)&TheCamera.GetMatrix().GetForward();
+ pm->up = *(RwV3d*)&TheCamera.GetMatrix().GetUp();
+ pm->right = *(RwV3d*)&TheCamera.GetMatrix().GetRight();
break;
}
case REPLAYCAMMODE_FIXED:
{
- *TheCamera.GetMatrix().GetPosition() = CVector(CameraFixedX, CameraFixedY, CameraFixedZ);
+ TheCamera.GetMatrix().GetPosition() = CVector(CameraFixedX, CameraFixedY, CameraFixedZ);
CVector forward(CameraFocusX - CameraFixedX, CameraFocusY - CameraFixedY, CameraFocusZ - CameraFixedZ);
forward.Normalise();
CVector right = CrossProduct(CVector(0.0f, 0.0f, 1.0f), forward);
right.Normalise();
CVector up = CrossProduct(forward, right);
up.Normalise();
- *TheCamera.GetMatrix().GetForward() = forward;
- *TheCamera.GetMatrix().GetUp() = up;
- *TheCamera.GetMatrix().GetRight() = right;
+ TheCamera.GetMatrix().GetForward() = forward;
+ TheCamera.GetMatrix().GetUp() = up;
+ TheCamera.GetMatrix().GetRight() = right;
RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera));
- pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition();
- pm->at = *(RwV3d*)TheCamera.GetMatrix().GetForward();
- pm->up = *(RwV3d*)TheCamera.GetMatrix().GetUp();
- pm->right = *(RwV3d*)TheCamera.GetMatrix().GetRight();
+ pm->pos = *(RwV3d*)&TheCamera.GetMatrix().GetPosition();
+ pm->at = *(RwV3d*)&TheCamera.GetMatrix().GetForward();
+ pm->up = *(RwV3d*)&TheCamera.GetMatrix().GetUp();
+ pm->right = *(RwV3d*)&TheCamera.GetMatrix().GetRight();
break;
}
default:
break;
}
- TheCamera.m_vecGameCamPos = *TheCamera.GetMatrix().GetPosition();
+ TheCamera.m_vecGameCamPos = TheCamera.GetMatrix().GetPosition();
TheCamera.CalculateDerivedValues();
RwMatrixUpdate(RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)));
RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera));
@@ -1189,7 +1189,7 @@ void CReplay::RestoreStuffFromMem(void)
CMatrix tmp1;
tmp1.Attach(RwFrameGetMatrix(dodo->m_aCarNodes[CAR_WHEEL_RF]), false);
CMatrix tmp2(RwFrameGetMatrix(dodo->m_aCarNodes[CAR_WHEEL_LF]), false);
- *tmp1.GetPosition() += CVector(tmp2.GetPosition()->x + 0.1f, 0.0f, tmp2.GetPosition()->z);
+ tmp1.GetPosition() += CVector(tmp2.GetPosition().x + 0.1f, 0.0f, tmp2.GetPosition().z);
tmp1.UpdateRW();
}
if (vehicle->IsCar()){
@@ -1346,14 +1346,14 @@ void CReplay::MarkEverythingAsNew(void)
CVehicle* v = CPools::GetVehiclePool()->GetSlot(i);
if (!v)
continue;
- v->bRecordedForReplay = false;
+ v->bHasAlreadyBeenRecorded = false;
}
i = CPools::GetPedPool()->GetSize();
while (i--) {
CPed* p = CPools::GetPedPool()->GetSlot(i);
if (!p)
continue;
- p->bRecordedForReplay = false;
+ p->bHasAlreadyBeenRecorded = false;
}
}
#endif
@@ -1505,9 +1505,9 @@ void CReplay::ProcessLookAroundCam(void)
else
fAlphaAngleLookAroundCam = max(0.1f, min(1.5f, fAlphaAngleLookAroundCam + y_moved));
CVector camera_pt(
- fDistanceLookAroundCam * sin(fBetaAngleLookAroundCam) * cos(fAlphaAngleLookAroundCam),
- fDistanceLookAroundCam * cos(fBetaAngleLookAroundCam) * cos(fAlphaAngleLookAroundCam),
- fDistanceLookAroundCam * sin(fAlphaAngleLookAroundCam)
+ fDistanceLookAroundCam * Sin(fBetaAngleLookAroundCam) * Cos(fAlphaAngleLookAroundCam),
+ fDistanceLookAroundCam * Cos(fBetaAngleLookAroundCam) * Cos(fAlphaAngleLookAroundCam),
+ fDistanceLookAroundCam * Sin(fAlphaAngleLookAroundCam)
);
CVector focus = CVector(CameraFocusX, CameraFocusY, CameraFocusZ);
camera_pt += focus;
@@ -1525,15 +1525,15 @@ void CReplay::ProcessLookAroundCam(void)
right.Normalise();
CVector up = CrossProduct(forward, right);
up.Normalise();
- *TheCamera.GetMatrix().GetForward() = forward;
- *TheCamera.GetMatrix().GetUp() = up;
- *TheCamera.GetMatrix().GetRight() = right;
- *TheCamera.GetMatrix().GetPosition() = camera_pt;
+ TheCamera.GetMatrix().GetForward() = forward;
+ TheCamera.GetMatrix().GetUp() = up;
+ TheCamera.GetMatrix().GetRight() = right;
+ TheCamera.GetMatrix().GetPosition() = camera_pt;
RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera));
- pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition();
- pm->at = *(RwV3d*)TheCamera.GetMatrix().GetForward();
- pm->up = *(RwV3d*)TheCamera.GetMatrix().GetUp();
- pm->right = *(RwV3d*)TheCamera.GetMatrix().GetRight();
+ pm->pos = *(RwV3d*)&TheCamera.GetMatrix().GetPosition();
+ pm->at = *(RwV3d*)&TheCamera.GetMatrix().GetForward();
+ pm->up = *(RwV3d*)&TheCamera.GetMatrix().GetUp();
+ pm->right = *(RwV3d*)&TheCamera.GetMatrix().GetRight();
TheCamera.CalculateDerivedValues();
RwMatrixUpdate(RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)));
RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera));
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index 5e7f4936..b50c101e 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -2,33 +2,66 @@
#include "patcher.h"
#include "Script.h"
+#include "ScriptCommands.h"
#include "Camera.h"
#include "CarCtrl.h"
#include "DMAudio.h"
+#include "FileMgr.h"
#include "Hud.h"
+#include "Messages.h"
#include "ModelIndices.h"
+#include "Pad.h"
#include "PlayerInfo.h"
#include "PlayerPed.h"
#include "Pools.h"
#include "Population.h"
+#include "Replay.h"
#include "Streaming.h"
#include "User.h"
#include "Weather.h"
#include "World.h"
-uint8 (&CTheScripts::ScriptSpace)[160 * 1024] = *(uint8(*)[160 * 1024])*(uintptr*)0x74B248;
-CTextLine (&CTheScripts::IntroTextLines)[2] = *(CTextLine (*)[2])*(uintptr*)0x70EA74;
-CScriptRectangle (&CTheScripts::IntroRectangles)[16] = *(CScriptRectangle (*)[16])*(uintptr*)0x72D108;
-CSprite2d (&CTheScripts::ScriptSprites)[16] = *(CSprite2d(*)[16])*(uintptr*)0x72B090;
+uint8 (&CTheScripts::ScriptSpace)[SIZE_SCRIPT_SPACE] = *(uint8(*)[SIZE_SCRIPT_SPACE])*(uintptr*)0x74B248;
+CRunningScript(&CTheScripts::ScriptsArray)[MAX_NUM_SCRIPTS] = *(CRunningScript(*)[MAX_NUM_SCRIPTS])*(uintptr*)0x6F5C08;
+int32(&CTheScripts::BaseBriefIdForContact)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x880200;
+int32(&CTheScripts::OnAMissionForContactFlag)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x8622F0;
+CTextLine (&CTheScripts::IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES] = *(CTextLine (*)[MAX_NUM_INTRO_TEXT_LINES])*(uintptr*)0x70EA68;
+CScriptRectangle (&CTheScripts::IntroRectangles)[MAX_NUM_INTRO_RECTANGLES] = *(CScriptRectangle (*)[MAX_NUM_INTRO_RECTANGLES])*(uintptr*)0x72D108;
+CSprite2d (&CTheScripts::ScriptSprites)[MAX_NUM_SCRIPT_SRPITES] = *(CSprite2d(*)[MAX_NUM_SCRIPT_SRPITES])*(uintptr*)0x72B090;
+CScriptSphere(&CTheScripts::ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES] = *(CScriptSphere(*)[MAX_NUM_SCRIPT_SPHERES])*(uintptr*)0x727D60;
+tCollectiveData(&CTheScripts::CollectiveArray)[MAX_NUM_COLLECTIVES] = *(tCollectiveData(*)[MAX_NUM_COLLECTIVES])*(uintptr*)0x6FA008;
+tUsedObject(&CTheScripts::UsedObjectArray)[MAX_NUM_USED_OBJECTS] = *(tUsedObject(*)[MAX_NUM_USED_OBJECTS])*(uintptr*)0x6E69C8;
+int32(&CTheScripts::MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS] = *(int32(*)[MAX_NUM_MISSION_SCRIPTS])*(uintptr*)0x6F0558;
+tBuildingSwap(&CTheScripts::BuildingSwapArray)[MAX_NUM_BUILDING_SWAPS] = *(tBuildingSwap(*)[MAX_NUM_BUILDING_SWAPS])*(uintptr*)0x880E30;
+CEntity*(&CTheScripts::InvisibilitySettingArray)[MAX_NUM_INVISIBILITY_SETTINGS] = *(CEntity*(*)[MAX_NUM_INVISIBILITY_SETTINGS])*(uintptr*)0x8620F0;
bool &CTheScripts::DbgFlag = *(bool*)0x95CD87;
-uint32 &CTheScripts::OnAMissionFlag = *(uint32*)0x8F2A24;
+uint32 &CTheScripts::OnAMissionFlag = *(uint32*)0x8F1B64;
int32 &CTheScripts::StoreVehicleIndex = *(int32*)0x8F5F3C;
bool &CTheScripts::StoreVehicleWasRandom = *(bool*)0x95CDBC;
-
-CMissionCleanup(&CTheScripts::MissionCleanup) = *(CMissionCleanup*)0x8F2AD8;
-CUpsideDownCarCheck(&CTheScripts::UpsideDownCars) = *(CUpsideDownCarCheck*)0x6EE450;
-CStuckCarCheck(&CTheScripts::StuckCars) = *(CStuckCarCheck*)0x87C588;
+CRunningScript *&CTheScripts::pIdleScripts = *(CRunningScript**)0x9430D4;
+CRunningScript *&CTheScripts::pActiveScripts = *(CRunningScript**)0x8E2BF4;
+uint32 &CTheScripts::NextFreeCollectiveIndex = *(uint32*)0x942F98;
+int32 &CTheScripts::LastRandomPedId = *(int32*)0x8F251C;
+uint16 &CTheScripts::NumberOfUsedObjects = *(uint16*)0x95CC72;
+bool &CTheScripts::bAlreadyRunningAMissionScript = *(bool*)0x95CDB3;
+bool &CTheScripts::bUsingAMultiScriptFile = *(bool*)0x95CD55;
+uint16 &CTheScripts::NumberOfMissionScripts = *(uint16*)0x95CC9A;
+uint32 &CTheScripts::LargestMissionScriptSize = *(uint32*)0x9414C8;
+uint32 &CTheScripts::MainScriptSize = *(uint32*)0x9405A4;
+uint8 &CTheScripts::FailCurrentMission = *(uint8*)0x95CD41;
+uint8 &CTheScripts::CountdownToMakePlayerUnsafe = *(uint8*)0x95CD51;
+uint8 &CTheScripts::DelayMakingPlayerUnsafeThisTime = *(uint8*)0x95CD88;
+uint16 &CTheScripts::NumScriptDebugLines = *(uint16*)0x95CC42;
+uint16 &CTheScripts::NumberOfIntroRectanglesThisFrame = *(uint16*)0x95CC88;
+uint16 &CTheScripts::NumberOfIntroTextLinesThisFrame = *(uint16*)0x95CC32;
+bool &CTheScripts::UseTextCommands = *(bool*)0x95CD57;
+CMissionCleanup (&CTheScripts::MissionCleanup) = *(CMissionCleanup*)0x8F2A24;
+CUpsideDownCarCheck (&CTheScripts::UpsideDownCars) = *(CUpsideDownCarCheck*)0x6EE450;
+CStuckCarCheck (&CTheScripts::StuckCars) = *(CStuckCarCheck*)0x87C588;
+uint16 &CTheScripts::CommandsExecuted = *(uint16*)0x95CCA6;
+uint16 &CTheScripts::ScriptsUpdated = *(uint16*)0x95CC5E;
+int32(&ScriptParams)[32] = *(int32(*)[32])*(uintptr*)0x6ED460;
CMissionCleanup::CMissionCleanup()
{
@@ -66,7 +99,7 @@ void CMissionCleanup::AddEntityToList(int32 id, uint8 type)
void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type)
{
for (int i = 0; i < MAX_CLEANUP; i++){
- if (m_sEntities[i].type == type && m_sEntities[i].id == 0){
+ if (m_sEntities[i].type == type && m_sEntities[i].id == id){
m_sEntities[i].id = 0;
m_sEntities[i].type = CLEANUP_UNUSED;
}
@@ -277,11 +310,1095 @@ bool CStuckCarCheck::HasCarBeenStuckForAWhile(int32 id)
return false;
}
+void CRunningScript::CollectParameters(uint32* pIp, int16 total)
+{
+ for (int16 i = 0; i < total; i++){
+ float tmp;
+ switch (CTheScripts::Read1ByteFromScript(pIp))
+ {
+ case ARGUMENT_INT32:
+ ScriptParams[i] = CTheScripts::Read4BytesFromScript(pIp);
+ break;
+ case ARGUMENT_GLOBALVAR:
+ ScriptParams[i] = *((int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(pIp)]);
+ break;
+ case ARGUMENT_LOCALVAR:
+ ScriptParams[i] = m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)];
+ break;
+ case ARGUMENT_INT8:
+ ScriptParams[i] = CTheScripts::Read1ByteFromScript(pIp);
+ break;
+ case ARGUMENT_INT16:
+ ScriptParams[i] = CTheScripts::Read2BytesFromScript(pIp);
+ break;
+ case ARGUMENT_FLOAT:
+ tmp = CTheScripts::ReadFloatFromScript(pIp);
+ ScriptParams[i] = *(int32*)&tmp;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+}
+
+int32 CRunningScript::CollectNextParameterWithoutIncreasingPC(uint32 ip)
+{
+ uint32* pIp = &ip;
+ float tmp;
+ switch (CTheScripts::Read1ByteFromScript(pIp))
+ {
+ case ARGUMENT_INT32:
+ return CTheScripts::Read4BytesFromScript(pIp);
+ case ARGUMENT_GLOBALVAR:
+ return *((int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(pIp)]);
+ case ARGUMENT_LOCALVAR:
+ return m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)];
+ case ARGUMENT_INT8:
+ return CTheScripts::Read1ByteFromScript(pIp);
+ case ARGUMENT_INT16:
+ return CTheScripts::Read2BytesFromScript(pIp);
+ case ARGUMENT_FLOAT:
+ tmp = CTheScripts::ReadFloatFromScript(pIp);
+ return *(int32*)&tmp;
+ default:
+ assert(0);
+ }
+ return -1;
+}
+
+void CRunningScript::StoreParameters(uint32* pIp, int16 number)
+{
+ for (int16 i = 0; i < number; i++){
+ switch (CTheScripts::Read1ByteFromScript(pIp)) {
+ case ARGUMENT_GLOBALVAR:
+ *(int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(pIp)] = ScriptParams[i];
+ break;
+ case ARGUMENT_LOCALVAR:
+ m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)] = ScriptParams[i];
+ break;
+ default:
+ assert(0);
+ }
+ }
+}
+
+int32 *CRunningScript::GetPointerToScriptVariable(uint32* pIp, int16 type)
+{
+ switch (CTheScripts::Read1ByteFromScript(pIp))
+ {
+ case ARGUMENT_GLOBALVAR:
+ assert(type == VAR_GLOBAL);
+ return (int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(pIp)];
+ case ARGUMENT_LOCALVAR:
+ assert(type == VAR_LOCAL);
+ return &m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)];
+ default:
+ assert(0);
+ }
+ return nil;
+}
+
+void CRunningScript::Init()
+{
+ strcpy(m_abScriptName, "noname");
+ next = prev = nil;
+ m_nIp = 0;
+ for (int i = 0; i < MAX_STACK_DEPTH; i++)
+ m_anStack[i] = 0;
+ m_nStackPointer = 0;
+ m_nWakeTime = 0;
+ m_bCondResult = false;
+ m_bIsMissionScript = false;
+ m_bSkipWakeTime = false;
+ for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
+ m_anLocalVariables[i] = 0;
+ m_nAndOrState = 0;
+ m_bNotFlag = false;
+ m_bWBCheckEnabled = true;
+ m_bWBChecked = false;
+ m_bMissionFlag = false;
+}
+
+#ifdef USE_DEBUG_SCRIPT_LOADER
+int open_script()
+{
+ static int scriptToLoad = 1;
+
+ if (GetAsyncKeyState('G') & 0x8000)
+ scriptToLoad = 0;
+ if (GetAsyncKeyState('R') & 0x8000)
+ scriptToLoad = 1;
+ if (GetAsyncKeyState('D') & 0x8000)
+ scriptToLoad = 2;
+
+ switch (scriptToLoad) {
+ case 0: return CFileMgr::OpenFile("main.scm", "rb");
+ case 1: return CFileMgr::OpenFile("main_freeroam.scm", "rb");
+ case 2: return CFileMgr::OpenFile("main_d.scm", "rb");
+ }
+ return CFileMgr::OpenFile("main.scm", "rb");
+}
+#endif
+
+void CTextLine::Reset()
+{
+ m_fScaleX = 0.48f;
+ m_fScaleY = 1.12f;
+ m_sColor = CRGBA(225, 225, 225, 255);
+ m_bJustify = false;
+ m_bRightJustify = false;
+ m_bCentered = false;
+ m_bBackground = false;
+ m_bBackgroundOnly = false;
+ m_fWrapX = 182.0f; /* TODO: scaling as bugfix */
+ m_fCenterSize = 640.0f; /* --||-- */
+ m_sBackgroundColor = CRGBA(128, 128, 128, 128);
+ m_bTextProportional = true;
+ m_bTextBeforeFade = false;
+ m_nFont = 2; /* enum? */
+ m_fAtX = 0.0f;
+ m_fAtY = 0.0f;
+ memset(&m_Text, 0, sizeof(m_Text));
+}
+
+void CTheScripts::Init()
+{
+ for (int i = 0; i < SIZE_SCRIPT_SPACE; i++)
+ ScriptSpace[i] = 0;
+ pActiveScripts = pIdleScripts = nil;
+ for (int i = 0; i < MAX_NUM_SCRIPTS; i++){
+ ScriptsArray[i].Init();
+ ScriptsArray[i].AddScriptToList(&pIdleScripts);
+ }
+ MissionCleanup.Init();
+ UpsideDownCars.Init();
+ StuckCars.Init();
+ CFileMgr::SetDir("data");
+#ifdef USE_DEBUG_SCRIPT_LOADER
+ int mainf = open_script();
+#else
+ int mainf = CFileMgr::OpenFile("main.scm", "rb");
+#endif
+ CFileMgr::Read(mainf, (char*)ScriptSpace, SIZE_MAIN_SCRIPT);
+ CFileMgr::CloseFile(mainf);
+ CFileMgr::SetDir("");
+ StoreVehicleIndex = -1;
+ StoreVehicleWasRandom = true;
+ OnAMissionFlag = 0;
+ for (int i = 0; i < MAX_NUM_CONTACTS; i++){
+ BaseBriefIdForContact[i] = 0;
+ OnAMissionForContactFlag[i] = 0;
+ }
+ for (int i = 0; i < MAX_NUM_COLLECTIVES; i++){
+ CollectiveArray[i].index = -1;
+ CollectiveArray[i].unk_data = 0;
+ }
+ NextFreeCollectiveIndex = 0;
+ LastRandomPedId = -1;
+ for (int i = 0; i < MAX_NUM_USED_OBJECTS; i++){
+ memset(&UsedObjectArray[i].name, 0, sizeof(UsedObjectArray[i].name));
+ UsedObjectArray[i].index = 0;
+ }
+ NumberOfUsedObjects = 0;
+ ReadObjectNamesFromScript();
+ UpdateObjectIndices();
+ bAlreadyRunningAMissionScript = false;
+ bUsingAMultiScriptFile = true;
+ for (int i = 0; i < MAX_NUM_MISSION_SCRIPTS; i++)
+ MultiScriptArray[i] = 0;
+ NumberOfMissionScripts = 0;
+ LargestMissionScriptSize = 0;
+ MainScriptSize = 0;
+ ReadMultiScriptFileOffsetsFromScript();
+ FailCurrentMission = 0;
+ CountdownToMakePlayerUnsafe = 0;
+ DbgFlag = 0;
+ DelayMakingPlayerUnsafeThisTime = 0;
+ NumScriptDebugLines = 0;
+ for (int i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++){
+ ScriptSphereArray[i].m_bInUse = false;
+ ScriptSphereArray[i].m_Index = 1;
+ ScriptSphereArray[i].m_Id = 0;
+ ScriptSphereArray[i].m_vecCenter = CVector(0.0f, 0.0f, 0.0f);
+ ScriptSphereArray[i].m_fRadius = 0.0f;
+ }
+ for (int i = 0; i < MAX_NUM_INTRO_TEXT_LINES; i++){
+ IntroTextLines[i].Reset();
+ }
+ NumberOfIntroTextLinesThisFrame = 0;
+ UseTextCommands = false;
+ for (int i = 0; i < MAX_NUM_INTRO_RECTANGLES; i++){
+ IntroRectangles[i].m_bIsUsed = false;
+ IntroRectangles[i].m_bBeforeFade = false;
+ IntroRectangles[i].m_nTextureId = -1;
+ IntroRectangles[i].m_sRect = CRect(0.0f, 0.0f, 0.0f, 0.0f);
+ IntroRectangles[i].m_sColor = CRGBA(255, 255, 255, 255);
+ }
+ NumberOfIntroRectanglesThisFrame = 0;
+ for (int i = 0; i < MAX_NUM_BUILDING_SWAPS; i++){
+ BuildingSwapArray[i].m_pBuilding = nil;
+ BuildingSwapArray[i].m_nNewModel = -1;
+ BuildingSwapArray[i].m_nOldModel = -1;
+ }
+ for (int i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++)
+ InvisibilitySettingArray[i] = nil;
+}
+
+void CRunningScript::RemoveScriptFromList(CRunningScript** ppScript)
+{
+ if (prev)
+ prev->next = next;
+ else
+ *ppScript = next;
+ if (next)
+ next->prev = prev;
+}
+
+void CRunningScript::AddScriptToList(CRunningScript** ppScript)
+{
+ next = *ppScript;
+ prev = nil;
+ if (*ppScript)
+ (*ppScript)->prev = this;
+ *ppScript = this;
+}
+
+CRunningScript* CTheScripts::StartNewScript(uint32 ip)
+{
+ CRunningScript* pNew = pIdleScripts;
+ assert(pNew);
+ pNew->RemoveScriptFromList(&pIdleScripts);
+ pNew->Init();
+ pNew->SetIP(ip);
+ pNew->AddScriptToList(&pActiveScripts);
+ return pNew;
+}
+
+void CTheScripts::Process()
+{
+ if (CReplay::IsPlayingBack())
+ return;
+ CommandsExecuted = 0;
+ ScriptsUpdated = 0;
+ float timeStep = CTimer::GetTimeStepInMilliseconds();
+ UpsideDownCars.UpdateTimers();
+ StuckCars.Process();
+ DrawScriptSpheres();
+ if (FailCurrentMission)
+ --FailCurrentMission;
+ if (CountdownToMakePlayerUnsafe){
+ if (--CountdownToMakePlayerUnsafe == 0)
+ CWorld::Players[0].MakePlayerSafe(false);
+ }
+ if (UseTextCommands){
+ for (int i = 0; i < MAX_NUM_INTRO_TEXT_LINES; i++)
+ IntroTextLines[i].Reset();
+ NumberOfIntroRectanglesThisFrame = 0;
+ for (int i = 0; i < MAX_NUM_INTRO_RECTANGLES; i++){
+ IntroRectangles[i].m_bIsUsed = false;
+ IntroRectangles[i].m_bBeforeFade = false;
+ }
+ NumberOfIntroRectanglesThisFrame = 0;
+ if (UseTextCommands == 1)
+ UseTextCommands = 0;
+ }
+ CRunningScript* script = pActiveScripts;
+ while (script != nil){
+ CRunningScript* next = script->GetNext();
+ ++ScriptsUpdated;
+ script->UpdateTimers(timeStep);
+ script->Process();
+ script = next;
+ }
+ DbgFlag = false;
+}
+
+CRunningScript* CTheScripts::StartTestScript()
+{
+ return StartNewScript(0);
+}
+
+bool CTheScripts::IsPlayerOnAMission()
+{
+ return OnAMissionFlag && *(int32*)&ScriptSpace[OnAMissionFlag] == 1;
+}
+
+void CRunningScript::Process()
+{
+ if (m_bIsMissionScript)
+ DoDeatharrestCheck();
+ if (m_bMissionFlag && CTheScripts::FailCurrentMission == 1 && m_nStackPointer == 1)
+ m_nIp = m_anStack[--m_nStackPointer];
+ if (CTimer::GetTimeInMilliseconds() >= m_nWakeTime){
+ while (!ProcessOneCommand())
+ ;
+ return;
+ }
+ if (!m_bSkipWakeTime)
+ return;
+ if (!CPad::GetPad(0)->GetCrossJustDown())
+ return;
+ m_nWakeTime = 0;
+ for (int i = 0; i < 6; i++){ /* TODO: add constant for number of messages */
+ if (CMessages::BIGMessages[i].m_Current.m_pText)
+ CMessages::BIGMessages[i].m_Current.m_nStartTime = 0;
+ if (CMessages::BriefMessages[0].m_pText)
+ CMessages::BriefMessages[0].m_nStartTime = 0;
+ }
+}
+
+int8 CRunningScript::ProcessOneCommand()
+{
+ ++CTheScripts::CommandsExecuted;
+ int32 command = CTheScripts::Read2BytesFromScript(&m_nIp);
+ m_bNotFlag = (command & 0x8000);
+ command &= 0x7FFF;
+ if (command < 100)
+ return ProcessCommandsFrom0To99(command);
+ if (command < 200)
+ return ProcessCommandsFrom100To199(command);
+ if (command < 300)
+ return ProcessCommandsFrom200To299(command);
+ if (command < 400)
+ return ProcessCommandsFrom300To399(command);
+ if (command < 500)
+ return ProcessCommandsFrom400To499(command);
+ if (command < 600)
+ return ProcessCommandsFrom500To599(command);
+ if (command < 700)
+ return ProcessCommandsFrom600To699(command);
+ if (command < 800)
+ return ProcessCommandsFrom700To799(command);
+ if (command < 900)
+ return ProcessCommandsFrom800To899(command);
+ if (command < 1000)
+ return ProcessCommandsFrom900To999(command);
+ if (command < 1100)
+ return ProcessCommandsFrom1000To1099(command);
+ if (command < 1200)
+ return ProcessCommandsFrom1100To1199(command);
+ return -1;
+}
+
+int8 CRunningScript::ProcessCommandsFrom0To99(int32 command)
+{
+ switch (command) {
+ case COMMAND_NOP:
+ return 0;
+ case COMMAND_WAIT:
+ CollectParameters(&m_nIp, 1);
+ m_nWakeTime = CTimer::GetTimeInMilliseconds() + ScriptParams[0];
+ return 1;
+ case COMMAND_GOTO:
+ CollectParameters(&m_nIp, 1);
+ SetIP(ScriptParams[0] >= 0 ? ScriptParams[0] : SIZE_MAIN_SCRIPT - ScriptParams[0]);
+ /* Known issue: GOTO to 0. It might have been "better" to use > instead of >= */
+ /* simply because it never makes sense to jump to start of the script */
+ /* but jumping to start of a custom mission is an issue for simple mission-like scripts */
+ /* However, it's not an issue for actual mission scripts, because they follow a structure */
+ /* and never start with a loop. */
+ return 0;
+ case COMMAND_SHAKE_CAM:
+ CollectParameters(&m_nIp, 1);
+ TheCamera.CamShake(ScriptParams[0] / 1000.0f);
+ return 0;
+ case COMMAND_SET_VAR_INT:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ *ptr = ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_SET_VAR_FLOAT:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ *(float*)ptr = *(float*)&ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_SET_LVAR_INT:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ *ptr = ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_SET_LVAR_FLOAT:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ *(float*)ptr = *(float*)&ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_ADD_VAL_TO_INT_VAR:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ *ptr += ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_ADD_VAL_TO_FLOAT_VAR:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ *(float*)ptr += *(float*)&ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_ADD_VAL_TO_INT_LVAR:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ *ptr += ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_ADD_VAL_TO_FLOAT_LVAR:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ *(float*)ptr += *(float*)&ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_SUB_VAL_FROM_INT_VAR:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ *ptr -= ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_SUB_VAL_FROM_FLOAT_VAR:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ *(float*)ptr -= *(float*)&ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_SUB_VAL_FROM_INT_LVAR:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ *ptr -= ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_SUB_VAL_FROM_FLOAT_LVAR:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ *(float*)ptr -= *(float*)&ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_MULT_INT_VAR_BY_VAL:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ *ptr *= ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_MULT_FLOAT_VAR_BY_VAL:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ *(float*)ptr *= *(float*)&ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_MULT_INT_LVAR_BY_VAL:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ *ptr *= ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_MULT_FLOAT_LVAR_BY_VAL:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ *(float*)ptr *= *(float*)&ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_DIV_INT_VAR_BY_VAL:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ *ptr /= ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_DIV_FLOAT_VAR_BY_VAL:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ *(float*)ptr /= *(float*)&ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_DIV_INT_LVAR_BY_VAL:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ *ptr /= ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_DIV_FLOAT_LVAR_BY_VAL:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ *(float*)ptr /= *(float*)&ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_IS_INT_VAR_GREATER_THAN_NUMBER:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(*ptr > ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_IS_INT_LVAR_GREATER_THAN_NUMBER:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(*ptr > ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_IS_NUMBER_GREATER_THAN_INT_VAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ UpdateCompareFlag(ScriptParams[0] > *ptr);
+ return 0;
+ }
+ case COMMAND_IS_NUMBER_GREATER_THAN_INT_LVAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(ScriptParams[0] > *ptr);
+ return 0;
+ }
+ case COMMAND_IS_INT_VAR_GREATER_THAN_INT_VAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ UpdateCompareFlag(*ptr1 > *ptr2);
+ return 0;
+ }
+ case COMMAND_IS_INT_LVAR_GREATER_THAN_INT_VAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ UpdateCompareFlag(*ptr1 > *ptr2);
+ return 0;
+ }
+ case COMMAND_IS_INT_VAR_GREATER_THAN_INT_LVAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(*ptr1 > *ptr2);
+ return 0;
+ }
+ case COMMAND_IS_INT_LVAR_GREATER_THAN_INT_LVAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(*ptr1 > *ptr2);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_VAR_GREATER_THAN_NUMBER:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(*(float*)ptr > *(float*)&ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_LVAR_GREATER_THAN_NUMBER:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(*(float*)ptr > *(float*)&ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_IS_NUMBER_GREATER_THAN_FLOAT_VAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ UpdateCompareFlag(*(float*)&ScriptParams[0] > *(float*)ptr);
+ return 0;
+ }
+ case COMMAND_IS_NUMBER_GREATER_THAN_FLOAT_LVAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(*(float*)&ScriptParams[0] > *(float*)ptr);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_VAR_GREATER_THAN_FLOAT_VAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ UpdateCompareFlag(*(float*)ptr1 > *(float*)ptr2);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_LVAR_GREATER_THAN_FLOAT_VAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ UpdateCompareFlag(*(float*)ptr1 > *(float*)ptr2);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_VAR_GREATER_THAN_FLOAT_LVAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(*(float*)ptr1 > *(float*)ptr2);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_LVAR_GREATER_THAN_FLOAT_LVAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(*(float*)ptr1 > *(float*)ptr2);
+ return 0;
+ }
+ case COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_NUMBER:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(*ptr >= ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_NUMBER:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(*ptr >= ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_INT_VAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ UpdateCompareFlag(ScriptParams[0] >= *ptr);
+ return 0;
+ }
+ case COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_INT_LVAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(ScriptParams[0] >= *ptr);
+ return 0;
+ }
+ case COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_VAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ UpdateCompareFlag(*ptr1 >= *ptr2);
+ return 0;
+ }
+ case COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_VAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ UpdateCompareFlag(*ptr1 >= *ptr2);
+ return 0;
+ }
+ case COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_LVAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(*ptr1 >= *ptr2);
+ return 0;
+ }
+ case COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_LVAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(*ptr1 >= *ptr2);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_NUMBER:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(*(float*)ptr >= *(float*)&ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_NUMBER:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(*(float*)ptr >= *(float*)&ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_VAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ UpdateCompareFlag(*(float*)&ScriptParams[0] >= *(float*)ptr);
+ return 0;
+ }
+ case COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_LVAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(*(float*)&ScriptParams[0] >= *(float*)ptr);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_VAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ UpdateCompareFlag(*(float*)ptr1 >= *(float*)ptr2);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_VAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ UpdateCompareFlag(*(float*)ptr1 >= *(float*)ptr2);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(*(float*)ptr1 >= *(float*)ptr2);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(*(float*)ptr1 >= *(float*)ptr2);
+ return 0;
+ }
+ case COMMAND_IS_INT_VAR_EQUAL_TO_NUMBER:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(*ptr == ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_IS_INT_LVAR_EQUAL_TO_NUMBER:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(*ptr == ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_IS_INT_VAR_EQUAL_TO_INT_VAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ UpdateCompareFlag(*ptr1 == *ptr2);
+ return 0;
+ }
+ case COMMAND_IS_INT_VAR_EQUAL_TO_INT_LVAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(*ptr1 == *ptr2);
+ return 0;
+ }
+ case COMMAND_IS_INT_LVAR_EQUAL_TO_INT_LVAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(*ptr1 == *ptr2);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_VAR_EQUAL_TO_NUMBER:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(*(float*)ptr == *(float*)&ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_LVAR_EQUAL_TO_NUMBER:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(*(float*)ptr == *(float*)&ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_VAR_EQUAL_TO_FLOAT_VAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ UpdateCompareFlag(*(float*)ptr1 == *(float*)ptr2);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_VAR_EQUAL_TO_FLOAT_LVAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(*(float*)ptr1 == *(float*)ptr2);
+ return 0;
+ }
+ case COMMAND_IS_FLOAT_LVAR_EQUAL_TO_FLOAT_LVAR:
+ {
+ int32* ptr1 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ int32* ptr2 = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ UpdateCompareFlag(*(float*)ptr1 == *(float*)ptr2);
+ return 0;
+ }
+ case COMMAND_GOTO_IF_TRUE:
+ CollectParameters(&m_nIp, 1);
+ if (m_bCondResult)
+ SetIP(ScriptParams[0] >= 0 ? ScriptParams[0] : SIZE_MAIN_SCRIPT - ScriptParams[0]);
+ /* Check COMMAND_GOTO note. */
+ return 0;
+ case COMMAND_GOTO_IF_FALSE:
+ CollectParameters(&m_nIp, 1);
+ if (!m_bCondResult)
+ SetIP(ScriptParams[0] >= 0 ? ScriptParams[0] : SIZE_MAIN_SCRIPT - ScriptParams[0]);
+ /* Check COMMAND_GOTO note. */
+ return 0;
+ case COMMAND_TERMINATE_THIS_SCRIPT:
+ if (m_bMissionFlag)
+ CTheScripts::bAlreadyRunningAMissionScript = false;
+ RemoveScriptFromList(&CTheScripts::pActiveScripts);
+ AddScriptToList(&CTheScripts::pIdleScripts);
+ return 1;
+ case COMMAND_START_NEW_SCRIPT:
+ {
+ CollectParameters(&m_nIp, 1);
+ assert(ScriptParams[0] >= 0);
+ CRunningScript* pNew = CTheScripts::StartNewScript(ScriptParams[0]);
+ int8 type = CTheScripts::Read1ByteFromScript(&m_nIp);
+ float tmp;
+ for (int i = 0; type != ARGUMENT_END; type = CTheScripts::Read1ByteFromScript(&m_nIp), i++) {
+ switch (type) {
+ case ARGUMENT_INT32:
+ pNew->m_anLocalVariables[i] = CTheScripts::Read4BytesFromScript(&m_nIp);
+ break;
+ case ARGUMENT_GLOBALVAR:
+ pNew->m_anLocalVariables[i] = *(int32*)&CTheScripts::ScriptSpace[CTheScripts::Read2BytesFromScript(&m_nIp)];
+ break;
+ case ARGUMENT_LOCALVAR:
+ pNew->m_anLocalVariables[i] = m_anLocalVariables[CTheScripts::Read2BytesFromScript(&m_nIp)];
+ break;
+ case ARGUMENT_INT8:
+ pNew->m_anLocalVariables[i] = CTheScripts::Read1ByteFromScript(&m_nIp);
+ break;
+ case ARGUMENT_INT16:
+ pNew->m_anLocalVariables[i] = CTheScripts::Read2BytesFromScript(&m_nIp);
+ break;
+ case ARGUMENT_FLOAT:
+ tmp = CTheScripts::ReadFloatFromScript(&m_nIp);
+ pNew->m_anLocalVariables[i] = *(int32*)&tmp;
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+ }
+ case COMMAND_GOSUB:
+ CollectParameters(&m_nIp, 1);
+ assert(m_nStackPointer < MAX_STACK_DEPTH);
+ m_anStack[m_nStackPointer++] = m_nIp;
+ SetIP(ScriptParams[0] >= 0 ? ScriptParams[0] : SIZE_MAIN_SCRIPT - ScriptParams[0]);
+ return 0;
+ case COMMAND_RETURN:
+ assert(m_nStackPointer > 0); /* No more SSU */
+ SetIP(m_anStack[--m_nStackPointer]);
+ return 0;
+ case COMMAND_LINE:
+ CollectParameters(&m_nIp, 6);
+ /* Something must have been here */
+ return 0;
+ case COMMAND_CREATE_PLAYER:
+ {
+ CollectParameters(&m_nIp, 4);
+ int32 index = ScriptParams[0];
+ assert(index < 1); /* Constant? Also no more double player glitch */
+ debug("&&&&&&&&&&&&&Creating player: %d\n", index);
+ if (!CStreaming::HasModelLoaded(MI_PLAYER)) {
+ CStreaming::RequestSpecialModel(MI_PLAYER, "player", STREAMFLAGS_DONT_REMOVE | STREAMFLAGS_DEPENDENCY);
+ CStreaming::LoadAllRequestedModels(false);
+ }
+ CPlayerPed::SetupPlayerPed(index);
+ CWorld::Players[index].m_pPed->CharCreatedBy = MISSION_CHAR;
+ CPlayerPed::DeactivatePlayerPed(index);
+ CVector pos = *(CVector*)&ScriptParams[1];
+ if (pos.z <= -100.0f)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ pos.z += CWorld::Players[index].m_pPed->GetDistanceFromCentreOfMassToBaseOfModel();
+ CWorld::Players[index].m_pPed->GetPosition() = pos;
+ CTheScripts::ClearSpaceForMissionEntity(pos, CWorld::Players[index].m_pPed);
+ CPlayerPed::ReactivatePlayerPed(index);
+ ScriptParams[0] = index;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_GET_PLAYER_COORDINATES:
+ {
+ CVector pos;
+ CollectParameters(&m_nIp, 1);
+ if (CWorld::Players[ScriptParams[0]].m_pPed->bInVehicle)
+ pos = CWorld::Players[ScriptParams[0]].m_pPed->m_pMyVehicle->GetPosition();
+ else
+ pos = CWorld::Players[ScriptParams[0]].m_pPed->GetPosition();
+ *(CVector*)&ScriptParams[0] = pos;
+ StoreParameters(&m_nIp, 3);
+ return 0;
+ }
+ case COMMAND_SET_PLAYER_COORDINATES:
+ {
+ CollectParameters(&m_nIp, 4);
+ CVector pos = *(CVector*)&ScriptParams[1];
+ int index = ScriptParams[0];
+ if (pos.z <= -100.0f)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ CPlayerPed* ped = CWorld::Players[index].m_pPed;
+ if (!ped->bInVehicle) {
+ pos.z += ped->GetDistanceFromCentreOfMassToBaseOfModel();
+ ped->Teleport(pos);
+ CTheScripts::ClearSpaceForMissionEntity(pos, ped);
+ return 0;
+ }
+ pos.z += ped->m_pMyVehicle->GetDistanceFromCentreOfMassToBaseOfModel();
+ if (ped->m_pMyVehicle->IsBoat())
+ ped->m_pMyVehicle->Teleport(pos);
+ else
+ ped->m_pMyVehicle->Teleport(pos);
+ /* I'll keep this condition here but obviously it is absolutely pointless */
+ /* It's clearly present in disassembly so it had to be in original code */
+ CTheScripts::ClearSpaceForMissionEntity(pos, ped->m_pMyVehicle);
+ return 0;
+ }
+ case COMMAND_IS_PLAYER_IN_AREA_2D:
+ {
+ CollectParameters(&m_nIp, 6);
+ CPlayerPed* ped = CWorld::Players[ScriptParams[0]].m_pPed;
+ float x1, y1, x2, y2;
+ x1 = *(float*)&ScriptParams[1];
+ y1 = *(float*)&ScriptParams[2];
+ x2 = *(float*)&ScriptParams[3];
+ y2 = *(float*)&ScriptParams[4];
+ if (!ped->bInVehicle)
+ UpdateCompareFlag(ped->IsWithinArea(x1, y1, x2, y2));
+ else
+ UpdateCompareFlag(ped->m_pMyVehicle->IsWithinArea(x1, y1, x2, y2));
+ if (!ScriptParams[5])
+ return 0;
+ CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, -100.0f);
+ if (CTheScripts::DbgFlag)
+ CTheScripts::DrawDebugSquare(x1, y1, x2, y2);
+ return 0;
+ }
+ case COMMAND_IS_PLAYER_IN_AREA_3D:
+ {
+ CollectParameters(&m_nIp, 8);
+ CPlayerPed* ped = CWorld::Players[ScriptParams[0]].m_pPed;
+ float x1, y1, z1, x2, y2, z2;
+ x1 = *(float*)&ScriptParams[1];
+ y1 = *(float*)&ScriptParams[2];
+ z1 = *(float*)&ScriptParams[3];
+ x2 = *(float*)&ScriptParams[4];
+ y2 = *(float*)&ScriptParams[5];
+ z2 = *(float*)&ScriptParams[6];
+ if (ped->bInVehicle)
+ UpdateCompareFlag(ped->m_pMyVehicle->IsWithinArea(x1, y1, z1, x2, y2, z2));
+ else
+ UpdateCompareFlag(ped->IsWithinArea(x1, y1, z1, x2, y2, z2));
+ if (!ScriptParams[7])
+ return 0;
+ CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, -100.0f);
+ if (CTheScripts::DbgFlag)
+ CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2);
+ return 0;
+ }
+ case COMMAND_ADD_INT_VAR_TO_INT_VAR:
+ *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ return 0;
+ case COMMAND_ADD_INT_LVAR_TO_INT_VAR:
+ *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ return 0;
+ case COMMAND_ADD_INT_VAR_TO_INT_LVAR:
+ *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ return 0;
+ case COMMAND_ADD_INT_LVAR_TO_INT_LVAR:
+ *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ return 0;
+ case COMMAND_ADD_FLOAT_VAR_TO_FLOAT_VAR:
+ *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ return 0;
+ case COMMAND_ADD_FLOAT_LVAR_TO_FLOAT_VAR:
+ *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ return 0;
+ case COMMAND_ADD_FLOAT_VAR_TO_FLOAT_LVAR:
+ *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ return 0;
+ case COMMAND_ADD_FLOAT_LVAR_TO_FLOAT_LVAR:
+ *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ return 0;
+ case COMMAND_SUB_INT_VAR_FROM_INT_VAR:
+ *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) -= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ return 0;
+ case COMMAND_SUB_INT_LVAR_FROM_INT_LVAR:
+ *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) -= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ return 0;
+ case COMMAND_SUB_FLOAT_VAR_FROM_FLOAT_VAR:
+ *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) -= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL);
+ return 0;
+ case COMMAND_SUB_FLOAT_LVAR_FROM_FLOAT_LVAR:
+ *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) -= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ return 0;
+ default:
+ break;
+ }
+ return -1;
+}
+
+void CRunningScript::UpdateCompareFlag(bool flag)
+{
+ if (m_bNotFlag)
+ flag = !flag;
+ if (m_nAndOrState == 0){
+ m_bCondResult = flag;
+ return;
+ }
+ if (m_nAndOrState >= 1 && m_nAndOrState <= 8) { /* Maybe enums?*/
+ m_bCondResult &= flag;
+ if (m_nAndOrState == 1){
+ m_nAndOrState = 0;
+ return;
+ }
+ }else if (m_nAndOrState >= 21 && m_nAndOrState <= 28){
+ m_bCondResult |= flag;
+ if (m_nAndOrState == 21) {
+ m_nAndOrState = 0;
+ return;
+ }
+ }else{
+ return;
+ }
+ m_nAndOrState--;
+}
+
+
+WRAPPER int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) { EAXJMP(0x43AEA0); }
+WRAPPER int8 CRunningScript::ProcessCommandsFrom200To299(int32 command) { EAXJMP(0x43D530); }
+WRAPPER int8 CRunningScript::ProcessCommandsFrom300To399(int32 command) { EAXJMP(0x43ED30); }
+WRAPPER int8 CRunningScript::ProcessCommandsFrom400To499(int32 command) { EAXJMP(0x440CB0); }
+WRAPPER int8 CRunningScript::ProcessCommandsFrom500To599(int32 command) { EAXJMP(0x4429C0); }
+WRAPPER int8 CRunningScript::ProcessCommandsFrom600To699(int32 command) { EAXJMP(0x444B20); }
+WRAPPER int8 CRunningScript::ProcessCommandsFrom700To799(int32 command) { EAXJMP(0x4458A0); }
+WRAPPER int8 CRunningScript::ProcessCommandsFrom800To899(int32 command) { EAXJMP(0x448240); }
+WRAPPER int8 CRunningScript::ProcessCommandsFrom900To999(int32 command) { EAXJMP(0x44CB80); }
+WRAPPER int8 CRunningScript::ProcessCommandsFrom1000To1099(int32 command) { EAXJMP(0x588490); }
+WRAPPER int8 CRunningScript::ProcessCommandsFrom1100To1199(int32 command) { EAXJMP(0x589D00); }
+
+WRAPPER void CTheScripts::DrawScriptSpheres() { EAXJMP(0x44FAC0); }
+WRAPPER void CRunningScript::DoDeatharrestCheck() { EAXJMP(0x452A30); }
+WRAPPER void CTheScripts::DrawDebugSquare(float, float, float, float) { EAXJMP(0x452D00); }
+WRAPPER void CTheScripts::DrawDebugCube(float, float, float, float, float, float) { EAXJMP(0x453100); }
+WRAPPER void CTheScripts::ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2) { EAXJMP(0x4534E0); }
+WRAPPER void CTheScripts::ClearSpaceForMissionEntity(const CVector&, CEntity*) { EAXJMP(0x454060); }
+WRAPPER void CTheScripts::HighlightImportantArea(uint32, float, float, float, float, float) { EAXJMP(0x454320); }
WRAPPER void CTheScripts::CleanUpThisVehicle(CVehicle*) { EAXJMP(0x4548D0); }
WRAPPER void CTheScripts::CleanUpThisPed(CPed*) { EAXJMP(0x4547A0); }
WRAPPER void CTheScripts::CleanUpThisObject(CObject*) { EAXJMP(0x454910); }
-WRAPPER bool CTheScripts::IsPlayerOnAMission() { EAXJMP(0x439410); }
-WRAPPER void CTheScripts::ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2) { EAXJMP(0x4534E0); }
+WRAPPER void CTheScripts::ReadObjectNamesFromScript() { EAXJMP(0x454960); }
+WRAPPER void CTheScripts::UpdateObjectIndices() { EAXJMP(0x454AD0); }
+WRAPPER void CTheScripts::ReadMultiScriptFileOffsetsFromScript() { EAXJMP(0x454BC0); }
STARTPATCHES
InjectHook(0x437AE0, &CMissionCleanup::Init, PATCH_JUMP);
@@ -299,4 +1416,13 @@ InjectHook(0x4380A0, &CStuckCarCheck::Process, PATCH_JUMP);
InjectHook(0x4381C0, &CStuckCarCheck::AddCarToCheck, PATCH_JUMP);
InjectHook(0x438240, &CStuckCarCheck::RemoveCarFromCheck, PATCH_JUMP);
InjectHook(0x4382A0, &CStuckCarCheck::HasCarBeenStuckForAWhile, PATCH_JUMP);
+InjectHook(0x4382E0, &CRunningScript::CollectParameters, PATCH_JUMP);
+InjectHook(0x438460, &CRunningScript::CollectNextParameterWithoutIncreasingPC, PATCH_JUMP);
+InjectHook(0x4385A0, &CRunningScript::StoreParameters, PATCH_JUMP);
+InjectHook(0x438640, &CRunningScript::GetPointerToScriptVariable, PATCH_JUMP);
+InjectHook(0x438790, &CTheScripts::Init, PATCH_JUMP);
+InjectHook(0x439000, &CTheScripts::StartNewScript, PATCH_JUMP);
+InjectHook(0x439040, &CTheScripts::Process, PATCH_JUMP);
+InjectHook(0x439400, &CTheScripts::StartTestScript, PATCH_JUMP);
+InjectHook(0x439410, &CTheScripts::IsPlayerOnAMission, PATCH_JUMP);
ENDPATCHES \ No newline at end of file
diff --git a/src/control/Script.h b/src/control/Script.h
index 42e41c70..0cbd40c0 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -1,18 +1,28 @@
#pragma once
-#include "Ped.h"
-#include "Object.h"
+#include "common.h"
#include "Sprite2d.h"
-#include "Vehicle.h"
+
+class CEntity;
+class CBuilding;
+class CVehicle;
+class CPed;
+class CObject;
struct CScriptRectangle
{
- bool m_bIsUsed;
- bool m_bIsAntialiased;
- uint16 m_wTextureId;
+ int8 m_bIsUsed;
+ bool m_bBeforeFade;
+ int16 m_nTextureId;
CRect m_sRect;
CRGBA m_sColor;
};
+static_assert(sizeof(CScriptRectangle) == 0x18, "Script.h: error");
+
+enum {
+ SCRIPT_TEXT_MAX_LENGTH = 500
+};
+
struct CTextLine
{
float m_fScaleX;
@@ -26,33 +36,83 @@ struct CTextLine
float m_fCenterSize;
CRGBA m_sBackgroundColor;
bool m_bTextProportional;
- int32 field_29;
+ bool m_bTextBeforeFade;
bool m_bRightJustify;
- int32 field_31;
int32 m_nFont;
- float field_36;
- float field_40;
- wchar m_awText[500];
+ float m_fAtX;
+ float m_fAtY;
+ wchar m_Text[SCRIPT_TEXT_MAX_LENGTH];
+
+ void Reset();
};
-struct CRunningScript
+static_assert(sizeof(CTextLine) == 0x414, "Script.h: error");
+
+struct CScriptSphere
+{
+ bool m_bInUse;
+ uint16 m_Index;
+ uint32 m_Id;
+ CVector m_vecCenter;
+ float m_fRadius;
+};
+
+enum {
+ MAX_STACK_DEPTH = 6,
+ NUM_LOCAL_VARS = 16,
+ NUM_TIMERS = 2
+};
+
+class CRunningScript
{
CRunningScript *next;
CRunningScript *prev;
- uint8 m_abScriptName[8];
+ char m_abScriptName[8];
uint32 m_nIp;
- uint32 m_anStack[6];
+ uint32 m_anStack[MAX_STACK_DEPTH];
uint16 m_nStackPointer;
- void* m_anLocalVariables[18];
+ int32 m_anLocalVariables[NUM_LOCAL_VARS + NUM_TIMERS];
bool m_bCondResult;
- bool m_bIsMissionThread;
+ bool m_bIsMissionScript;
bool m_bSkipWakeTime;
uint32 m_nWakeTime;
- uint16 m_wIfOp;
+ uint16 m_nAndOrState;
bool m_bNotFlag;
- bool m_bWBCheck;
- bool m_bWastedOrBusted;
+ bool m_bWBCheckEnabled;
+ bool m_bWBChecked;
bool m_bMissionFlag;
+
+public:
+ void SetIP(uint32 ip) { m_nIp = ip; }
+ CRunningScript* GetNext() { return next; }
+ void UpdateTimers(float timeStep){
+ m_anLocalVariables[NUM_LOCAL_VARS] += timeStep;
+ m_anLocalVariables[NUM_LOCAL_VARS + 1] += timeStep;
+ }
+
+ void CollectParameters(uint32*, int16);
+ int32 CollectNextParameterWithoutIncreasingPC(uint32);
+ int32* GetPointerToScriptVariable(uint32*, int16);
+ void StoreParameters(uint32*, int16);
+ void Init();
+ void RemoveScriptFromList(CRunningScript**);
+ void AddScriptToList(CRunningScript**);
+ void Process();
+ int8 ProcessOneCommand();
+ void DoDeatharrestCheck();
+ int8 ProcessCommandsFrom0To99(int32);
+ int8 ProcessCommandsFrom100To199(int32);
+ int8 ProcessCommandsFrom200To299(int32);
+ int8 ProcessCommandsFrom300To399(int32);
+ int8 ProcessCommandsFrom400To499(int32);
+ int8 ProcessCommandsFrom500To599(int32);
+ int8 ProcessCommandsFrom600To699(int32);
+ int8 ProcessCommandsFrom700To799(int32);
+ int8 ProcessCommandsFrom800To899(int32);
+ int8 ProcessCommandsFrom900To999(int32);
+ int8 ProcessCommandsFrom1000To1099(int32);
+ int8 ProcessCommandsFrom1100To1199(int32);
+ void UpdateCompareFlag(bool);
};
enum {
@@ -133,13 +193,81 @@ public:
bool HasCarBeenStuckForAWhile(int32);
};
+enum {
+ ARGUMENT_END = 0,
+ ARGUMENT_INT32,
+ ARGUMENT_GLOBALVAR,
+ ARGUMENT_LOCALVAR,
+ ARGUMENT_INT8,
+ ARGUMENT_INT16,
+ ARGUMENT_FLOAT
+};
+
+struct tCollectiveData
+{
+ int32 index;
+ uint32 unk_data;
+};
+
+enum {
+ USED_OBJECT_NAME_LENGTH = 24
+};
+
+struct tUsedObject
+{
+ char name[USED_OBJECT_NAME_LENGTH];
+ int32 index;
+};
+
+struct tBuildingSwap
+{
+ CBuilding* m_pBuilding;
+ int32 m_nNewModel;
+ int32 m_nOldModel;
+};
+
+
+enum {
+ VAR_LOCAL = 1,
+ VAR_GLOBAL = 2,
+};
+
+enum {
+ SIZE_MAIN_SCRIPT = 128 * 1024,
+ SIZE_MISSION_SCRIPT = 32 * 1024,
+ SIZE_SCRIPT_SPACE = SIZE_MAIN_SCRIPT + SIZE_MISSION_SCRIPT
+};
+
+enum {
+ MAX_NUM_SCRIPTS = 128,
+ MAX_NUM_CONTACTS = 16,
+ MAX_NUM_INTRO_TEXT_LINES = 2,
+ MAX_NUM_INTRO_RECTANGLES = 16,
+ MAX_NUM_SCRIPT_SRPITES = 16,
+ MAX_NUM_SCRIPT_SPHERES = 16,
+ MAX_NUM_COLLECTIVES = 32,
+ MAX_NUM_USED_OBJECTS = 200,
+ MAX_NUM_MISSION_SCRIPTS = 120,
+ MAX_NUM_BUILDING_SWAPS = 25,
+ MAX_NUM_INVISIBILITY_SETTINGS = 20
+};
+
class CTheScripts
{
public:
- static uint8(&ScriptSpace)[160 * 1024];
- static CTextLine(&IntroTextLines)[2];
- static CScriptRectangle(&IntroRectangles)[16];
- static CSprite2d(&ScriptSprites)[16];
+ static uint8(&ScriptSpace)[SIZE_SCRIPT_SPACE];
+ static CRunningScript(&ScriptsArray)[MAX_NUM_SCRIPTS];
+ static int32(&BaseBriefIdForContact)[MAX_NUM_CONTACTS];
+ static int32(&OnAMissionForContactFlag)[MAX_NUM_CONTACTS];
+ static CTextLine(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES];
+ static CScriptRectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES];
+ static CSprite2d(&ScriptSprites)[MAX_NUM_SCRIPT_SRPITES];
+ static CScriptSphere(&ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES];
+ static tCollectiveData(&CollectiveArray)[MAX_NUM_COLLECTIVES];
+ static tUsedObject(&UsedObjectArray)[MAX_NUM_USED_OBJECTS];
+ static int32(&MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS];
+ static tBuildingSwap(&BuildingSwapArray)[MAX_NUM_BUILDING_SWAPS];
+ static CEntity*(&InvisibilitySettingArray)[MAX_NUM_INVISIBILITY_SETTINGS];
static bool &DbgFlag;
static uint32 &OnAMissionFlag;
static CMissionCleanup &MissionCleanup;
@@ -147,11 +275,67 @@ public:
static CUpsideDownCarCheck &UpsideDownCars;
static int32 &StoreVehicleIndex;
static bool &StoreVehicleWasRandom;
-
+ static CRunningScript *&pIdleScripts;
+ static CRunningScript *&pActiveScripts;
+ static uint32 &NextFreeCollectiveIndex;
+ static int32 &LastRandomPedId;
+ static uint16 &NumberOfUsedObjects;
+ static bool &bAlreadyRunningAMissionScript;
+ static bool &bUsingAMultiScriptFile;
+ static uint16 &NumberOfMissionScripts;
+ static uint32 &LargestMissionScriptSize;
+ static uint32 &MainScriptSize;
+ static uint8 &FailCurrentMission;
+ static uint8 &CountdownToMakePlayerUnsafe;
+ static uint8 &DelayMakingPlayerUnsafeThisTime;
+ static uint16 &NumScriptDebugLines;
+ static uint16 &NumberOfIntroRectanglesThisFrame;
+ static uint16 &NumberOfIntroTextLinesThisFrame;
+ static bool &UseTextCommands;
+ static uint16 &CommandsExecuted;
+ static uint16 &ScriptsUpdated;
public:
- static bool IsPlayerOnAMission();
static void ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2);
static void CleanUpThisVehicle(CVehicle*);
static void CleanUpThisPed(CPed*);
static void CleanUpThisObject(CObject*);
+ static void Init();
+ static CRunningScript* StartNewScript(uint32);
+ static void Process();
+ static CRunningScript* StartTestScript();
+ static bool IsPlayerOnAMission();
+
+ static void ReadObjectNamesFromScript();
+ static void UpdateObjectIndices();
+ static void ReadMultiScriptFileOffsetsFromScript();
+ static void DrawScriptSpheres();
+ static void ClearSpaceForMissionEntity(const CVector&, CEntity*);
+ static void HighlightImportantArea(uint32, float, float, float, float, float);
+ static void DrawDebugSquare(float, float, float, float);
+ static void DrawDebugCube(float, float, float, float, float, float);
+
+ static int32 Read4BytesFromScript(uint32* pIp){
+ int32 retval = 0;
+ for (int i = 0; i < 4; i++){
+ retval |= ScriptSpace[(*pIp)++] << (8 * i);
+ }
+ return retval;
+ }
+ static int16 Read2BytesFromScript(uint32* pIp){
+ int16 retval = 0;
+ for (int i = 0; i < 2; i++){
+ retval |= ScriptSpace[(*pIp)++] << (8 * i);
+ }
+ return retval;
+ }
+ static int8 Read1ByteFromScript(uint32* pIp){
+ int8 retval = 0;
+ for (int i = 0; i < 1; i++){
+ retval |= ScriptSpace[(*pIp)++] << (8 * i);
+ }
+ return retval;
+ }
+ static float ReadFloatFromScript(uint32* pIp){
+ return Read2BytesFromScript(pIp) / 16.0f;
+ }
};
diff --git a/src/control/ScriptCommands.h b/src/control/ScriptCommands.h
new file mode 100644
index 00000000..55ac4439
--- /dev/null
+++ b/src/control/ScriptCommands.h
@@ -0,0 +1,1158 @@
+#pragma once
+
+enum {
+ COMMAND_NOP = 0,
+ COMMAND_WAIT,
+ COMMAND_GOTO,
+ COMMAND_SHAKE_CAM,
+ COMMAND_SET_VAR_INT,
+ COMMAND_SET_VAR_FLOAT,
+ COMMAND_SET_LVAR_INT,
+ COMMAND_SET_LVAR_FLOAT,
+ COMMAND_ADD_VAL_TO_INT_VAR,
+ COMMAND_ADD_VAL_TO_FLOAT_VAR,
+ COMMAND_ADD_VAL_TO_INT_LVAR,
+ COMMAND_ADD_VAL_TO_FLOAT_LVAR,
+ COMMAND_SUB_VAL_FROM_INT_VAR,
+ COMMAND_SUB_VAL_FROM_FLOAT_VAR,
+ COMMAND_SUB_VAL_FROM_INT_LVAR,
+ COMMAND_SUB_VAL_FROM_FLOAT_LVAR,
+ COMMAND_MULT_INT_VAR_BY_VAL,
+ COMMAND_MULT_FLOAT_VAR_BY_VAL,
+ COMMAND_MULT_INT_LVAR_BY_VAL,
+ COMMAND_MULT_FLOAT_LVAR_BY_VAL,
+ COMMAND_DIV_INT_VAR_BY_VAL,
+ COMMAND_DIV_FLOAT_VAR_BY_VAL,
+ COMMAND_DIV_INT_LVAR_BY_VAL,
+ COMMAND_DIV_FLOAT_LVAR_BY_VAL,
+ COMMAND_IS_INT_VAR_GREATER_THAN_NUMBER,
+ COMMAND_IS_INT_LVAR_GREATER_THAN_NUMBER,
+ COMMAND_IS_NUMBER_GREATER_THAN_INT_VAR,
+ COMMAND_IS_NUMBER_GREATER_THAN_INT_LVAR,
+ COMMAND_IS_INT_VAR_GREATER_THAN_INT_VAR,
+ COMMAND_IS_INT_LVAR_GREATER_THAN_INT_LVAR,
+ COMMAND_IS_INT_VAR_GREATER_THAN_INT_LVAR,
+ COMMAND_IS_INT_LVAR_GREATER_THAN_INT_VAR,
+ COMMAND_IS_FLOAT_VAR_GREATER_THAN_NUMBER,
+ COMMAND_IS_FLOAT_LVAR_GREATER_THAN_NUMBER,
+ COMMAND_IS_NUMBER_GREATER_THAN_FLOAT_VAR,
+ COMMAND_IS_NUMBER_GREATER_THAN_FLOAT_LVAR,
+ COMMAND_IS_FLOAT_VAR_GREATER_THAN_FLOAT_VAR,
+ COMMAND_IS_FLOAT_LVAR_GREATER_THAN_FLOAT_LVAR,
+ COMMAND_IS_FLOAT_VAR_GREATER_THAN_FLOAT_LVAR,
+ COMMAND_IS_FLOAT_LVAR_GREATER_THAN_FLOAT_VAR,
+ COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_NUMBER,
+ COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_NUMBER,
+ COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_INT_VAR,
+ COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_INT_LVAR,
+ COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_VAR,
+ COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_LVAR,
+ COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_LVAR,
+ COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_VAR,
+ COMMAND_IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_NUMBER,
+ COMMAND_IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_NUMBER,
+ COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_VAR,
+ COMMAND_IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_LVAR,
+ COMMAND_IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_VAR,
+ COMMAND_IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR,
+ COMMAND_IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR,
+ COMMAND_IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_VAR,
+ COMMAND_IS_INT_VAR_EQUAL_TO_NUMBER,
+ COMMAND_IS_INT_LVAR_EQUAL_TO_NUMBER,
+ COMMAND_IS_INT_VAR_EQUAL_TO_INT_VAR,
+ COMMAND_IS_INT_LVAR_EQUAL_TO_INT_LVAR,
+ COMMAND_IS_INT_VAR_EQUAL_TO_INT_LVAR,
+ COMMAND_IS_INT_VAR_NOT_EQUAL_TO_NUMBER,
+ COMMAND_IS_INT_LVAR_NOT_EQUAL_TO_NUMBER,
+ COMMAND_IS_INT_VAR_NOT_EQUAL_TO_INT_VAR,
+ COMMAND_IS_INT_LVAR_NOT_EQUAL_TO_INT_LVAR,
+ COMMAND_IS_INT_VAR_NOT_EQUAL_TO_INT_LVAR,
+ COMMAND_IS_FLOAT_VAR_EQUAL_TO_NUMBER,
+ COMMAND_IS_FLOAT_LVAR_EQUAL_TO_NUMBER,
+ COMMAND_IS_FLOAT_VAR_EQUAL_TO_FLOAT_VAR,
+ COMMAND_IS_FLOAT_LVAR_EQUAL_TO_FLOAT_LVAR,
+ COMMAND_IS_FLOAT_VAR_EQUAL_TO_FLOAT_LVAR,
+ COMMAND_IS_FLOAT_VAR_NOT_EQUAL_TO_NUMBER,
+ COMMAND_IS_FLOAT_LVAR_NOT_EQUAL_TO_NUMBER,
+ COMMAND_IS_FLOAT_VAR_NOT_EQUAL_TO_FLOAT_VAR,
+ COMMAND_IS_FLOAT_LVAR_NOT_EQUAL_TO_FLOAT_LVAR,
+ COMMAND_IS_FLOAT_VAR_NOT_EQUAL_TO_FLOAT_LVAR,
+ COMMAND_GOTO_IF_TRUE,
+ COMMAND_GOTO_IF_FALSE,
+ COMMAND_TERMINATE_THIS_SCRIPT,
+ COMMAND_START_NEW_SCRIPT,
+ COMMAND_GOSUB,
+ COMMAND_RETURN,
+ COMMAND_LINE,
+ COMMAND_CREATE_PLAYER,
+ COMMAND_GET_PLAYER_COORDINATES,
+ COMMAND_SET_PLAYER_COORDINATES,
+ COMMAND_IS_PLAYER_IN_AREA_2D,
+ COMMAND_IS_PLAYER_IN_AREA_3D,
+ COMMAND_ADD_INT_VAR_TO_INT_VAR,
+ COMMAND_ADD_FLOAT_VAR_TO_FLOAT_VAR,
+ COMMAND_ADD_INT_LVAR_TO_INT_LVAR,
+ COMMAND_ADD_FLOAT_LVAR_TO_FLOAT_LVAR,
+ COMMAND_ADD_INT_VAR_TO_INT_LVAR,
+ COMMAND_ADD_FLOAT_VAR_TO_FLOAT_LVAR,
+ COMMAND_ADD_INT_LVAR_TO_INT_VAR,
+ COMMAND_ADD_FLOAT_LVAR_TO_FLOAT_VAR,
+ COMMAND_SUB_INT_VAR_FROM_INT_VAR,
+ COMMAND_SUB_FLOAT_VAR_FROM_FLOAT_VAR,
+ COMMAND_SUB_INT_LVAR_FROM_INT_LVAR,
+ COMMAND_SUB_FLOAT_LVAR_FROM_FLOAT_LVAR,
+ COMMAND_SUB_INT_VAR_FROM_INT_LVAR,
+ COMMAND_SUB_FLOAT_VAR_FROM_FLOAT_LVAR,
+ COMMAND_SUB_INT_LVAR_FROM_INT_VAR,
+ COMMAND_SUB_FLOAT_LVAR_FROM_FLOAT_VAR,
+ COMMAND_MULT_INT_VAR_BY_INT_VAR,
+ COMMAND_MULT_FLOAT_VAR_BY_FLOAT_VAR,
+ COMMAND_MULT_INT_LVAR_BY_INT_LVAR,
+ COMMAND_MULT_FLOAT_LVAR_BY_FLOAT_LVAR,
+ COMMAND_MULT_INT_VAR_BY_INT_LVAR,
+ COMMAND_MULT_FLOAT_VAR_BY_FLOAT_LVAR,
+ COMMAND_MULT_INT_LVAR_BY_INT_VAR,
+ COMMAND_MULT_FLOAT_LVAR_BY_FLOAT_VAR,
+ COMMAND_DIV_INT_VAR_BY_INT_VAR,
+ COMMAND_DIV_FLOAT_VAR_BY_FLOAT_VAR,
+ COMMAND_DIV_INT_LVAR_BY_INT_LVAR,
+ COMMAND_DIV_FLOAT_LVAR_BY_FLOAT_LVAR,
+ COMMAND_DIV_INT_VAR_BY_INT_LVAR,
+ COMMAND_DIV_FLOAT_VAR_BY_FLOAT_LVAR,
+ COMMAND_DIV_INT_LVAR_BY_INT_VAR,
+ COMMAND_DIV_FLOAT_LVAR_BY_FLOAT_VAR,
+ COMMAND_ADD_TIMED_VAL_TO_FLOAT_VAR,
+ COMMAND_ADD_TIMED_VAL_TO_FLOAT_LVAR,
+ COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_VAR,
+ COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_LVAR,
+ COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_VAR,
+ COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_LVAR,
+ COMMAND_SUB_TIMED_VAL_FROM_FLOAT_VAR,
+ COMMAND_SUB_TIMED_VAL_FROM_FLOAT_LVAR,
+ COMMAND_SUB_TIMED_FLOAT_VAR_FROM_FLOAT_VAR,
+ COMMAND_SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_LVAR,
+ COMMAND_SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_VAR,
+ COMMAND_SUB_TIMED_FLOAT_VAR_FROM_FLOAT_LVAR,
+ COMMAND_SET_VAR_INT_TO_VAR_INT,
+ COMMAND_SET_LVAR_INT_TO_LVAR_INT,
+ COMMAND_SET_VAR_FLOAT_TO_VAR_FLOAT,
+ COMMAND_SET_LVAR_FLOAT_TO_LVAR_FLOAT,
+ COMMAND_SET_VAR_FLOAT_TO_LVAR_FLOAT,
+ COMMAND_SET_LVAR_FLOAT_TO_VAR_FLOAT,
+ COMMAND_SET_VAR_INT_TO_LVAR_INT,
+ COMMAND_SET_LVAR_INT_TO_VAR_INT,
+ COMMAND_CSET_VAR_INT_TO_VAR_FLOAT,
+ COMMAND_CSET_VAR_FLOAT_TO_VAR_INT,
+ COMMAND_CSET_LVAR_INT_TO_VAR_FLOAT,
+ COMMAND_CSET_LVAR_FLOAT_TO_VAR_INT,
+ COMMAND_CSET_VAR_INT_TO_LVAR_FLOAT,
+ COMMAND_CSET_VAR_FLOAT_TO_LVAR_INT,
+ COMMAND_CSET_LVAR_INT_TO_LVAR_FLOAT,
+ COMMAND_CSET_LVAR_FLOAT_TO_LVAR_INT,
+ COMMAND_ABS_VAR_INT,
+ COMMAND_ABS_LVAR_INT,
+ COMMAND_ABS_VAR_FLOAT,
+ COMMAND_ABS_LVAR_FLOAT,
+ COMMAND_GENERATE_RANDOM_FLOAT,
+ COMMAND_GENERATE_RANDOM_INT,
+ COMMAND_CREATE_CHAR,
+ COMMAND_DELETE_CHAR,
+ COMMAND_CHAR_WANDER_DIR,
+ COMMAND_CHAR_WANDER_RANGE,
+ COMMAND_CHAR_FOLLOW_PATH,
+ COMMAND_CHAR_SET_IDLE,
+ COMMAND_GET_CHAR_COORDINATES,
+ COMMAND_SET_CHAR_COORDINATES,
+ COMMAND_IS_CHAR_STILL_ALIVE,
+ COMMAND_IS_CHAR_IN_AREA_2D,
+ COMMAND_IS_CHAR_IN_AREA_3D,
+ COMMAND_CREATE_CAR,
+ COMMAND_DELETE_CAR,
+ COMMAND_CAR_GOTO_COORDINATES,
+ COMMAND_CAR_WANDER_RANDOMLY,
+ COMMAND_CAR_SET_IDLE,
+ COMMAND_GET_CAR_COORDINATES,
+ COMMAND_SET_CAR_COORDINATES,
+ COMMAND_IS_CAR_STILL_ALIVE,
+ COMMAND_SET_CAR_CRUISE_SPEED,
+ COMMAND_SET_CAR_DRIVING_STYLE,
+ COMMAND_SET_CAR_MISSION,
+ COMMAND_IS_CAR_IN_AREA_2D,
+ COMMAND_IS_CAR_IN_AREA_3D,
+ COMMAND_SPECIAL_0,
+ COMMAND_SPECIAL_1,
+ COMMAND_SPECIAL_2,
+ COMMAND_SPECIAL_3,
+ COMMAND_SPECIAL_4,
+ COMMAND_SPECIAL_5,
+ COMMAND_SPECIAL_6,
+ COMMAND_SPECIAL_7,
+ COMMAND_PRINT_BIG,
+ COMMAND_PRINT,
+ COMMAND_PRINT_NOW,
+ COMMAND_PRINT_SOON,
+ COMMAND_CLEAR_PRINTS,
+ COMMAND_GET_TIME_OF_DAY,
+ COMMAND_SET_TIME_OF_DAY,
+ COMMAND_GET_MINUTES_TO_TIME_OF_DAY,
+ COMMAND_IS_POINT_ON_SCREEN,
+ COMMAND_DEBUG_ON,
+ COMMAND_DEBUG_OFF,
+ COMMAND_RETURN_TRUE,
+ COMMAND_RETURN_FALSE,
+ COMMAND_VAR_INT,
+ COMMAND_VAR_FLOAT,
+ COMMAND_LVAR_INT,
+ COMMAND_LVAR_FLOAT,
+ COMMAND_LBRACKET,
+ COMMAND_RBRACKET,
+ COMMAND_REPEAT,
+ COMMAND_ENDREPEAT,
+ COMMAND_IF_,
+ COMMAND_IFNOT,
+ COMMAND_ELSE,
+ COMMAND_ENDIF,
+ COMMAND_WHILE,
+ COMMAND_WHILENOT,
+ COMMAND_ENDWHILE,
+ COMMAND_ANDOR,
+ COMMAND_LAUNCH_MISSION,
+ COMMAND_MISSION_HAS_FINISHED,
+ COMMAND_STORE_CAR_CHAR_IS_IN,
+ COMMAND_STORE_CAR_PLAYER_IS_IN,
+ COMMAND_IS_CHAR_IN_CAR,
+ COMMAND_IS_PLAYER_IN_CAR,
+ COMMAND_IS_CHAR_IN_MODEL,
+ COMMAND_IS_PLAYER_IN_MODEL,
+ COMMAND_IS_CHAR_IN_ANY_CAR,
+ COMMAND_IS_PLAYER_IN_ANY_CAR,
+ COMMAND_IS_BUTTON_PRESSED,
+ COMMAND_GET_PAD_STATE,
+ COMMAND_LOCATE_PLAYER_ANY_MEANS_2D,
+ COMMAND_LOCATE_PLAYER_ON_FOOT_2D,
+ COMMAND_LOCATE_PLAYER_IN_CAR_2D,
+ COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_2D,
+ COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_2D,
+ COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_2D,
+ COMMAND_LOCATE_PLAYER_ANY_MEANS_CHAR_2D,
+ COMMAND_LOCATE_PLAYER_ON_FOOT_CHAR_2D,
+ COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_2D,
+ COMMAND_LOCATE_CHAR_ANY_MEANS_2D,
+ COMMAND_LOCATE_CHAR_ON_FOOT_2D,
+ COMMAND_LOCATE_CHAR_IN_CAR_2D,
+ COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_2D,
+ COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_2D,
+ COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_2D,
+ COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_2D,
+ COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_2D,
+ COMMAND_LOCATE_CHAR_IN_CAR_CHAR_2D,
+ COMMAND_LOCATE_PLAYER_ANY_MEANS_3D,
+ COMMAND_LOCATE_PLAYER_ON_FOOT_3D,
+ COMMAND_LOCATE_PLAYER_IN_CAR_3D,
+ COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_3D,
+ COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_3D,
+ COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_3D,
+ COMMAND_LOCATE_PLAYER_ANY_MEANS_CHAR_3D,
+ COMMAND_LOCATE_PLAYER_ON_FOOT_CHAR_3D,
+ COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_3D,
+ COMMAND_LOCATE_CHAR_ANY_MEANS_3D,
+ COMMAND_LOCATE_CHAR_ON_FOOT_3D,
+ COMMAND_LOCATE_CHAR_IN_CAR_3D,
+ COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_3D,
+ COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_3D,
+ COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_3D,
+ COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_3D,
+ COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_3D,
+ COMMAND_LOCATE_CHAR_IN_CAR_CHAR_3D,
+ COMMAND_CREATE_OBJECT,
+ COMMAND_DELETE_OBJECT,
+ COMMAND_ADD_SCORE,
+ COMMAND_IS_SCORE_GREATER,
+ COMMAND_STORE_SCORE,
+ COMMAND_GIVE_REMOTE_CONTROLLED_CAR_TO_PLAYER,
+ COMMAND_ALTER_WANTED_LEVEL,
+ COMMAND_ALTER_WANTED_LEVEL_NO_DROP,
+ COMMAND_IS_WANTED_LEVEL_GREATER,
+ COMMAND_CLEAR_WANTED_LEVEL,
+ COMMAND_SET_DEATHARREST_STATE,
+ COMMAND_HAS_DEATHARREST_BEEN_EXECUTED,
+ COMMAND_ADD_AMMO_TO_PLAYER,
+ COMMAND_ADD_AMMO_TO_CHAR,
+ COMMAND_ADD_AMMO_TO_CAR,
+ COMMAND_IS_PLAYER_STILL_ALIVE,
+ COMMAND_IS_PLAYER_DEAD,
+ COMMAND_IS_CHAR_DEAD,
+ COMMAND_IS_CAR_DEAD,
+ COMMAND_SET_CHAR_THREAT_SEARCH,
+ COMMAND_SET_CHAR_THREAT_REACTION,
+ COMMAND_SET_CHAR_OBJ_NO_OBJ,
+ COMMAND_ORDER_DRIVER_OUT_OF_CAR,
+ COMMAND_ORDER_CHAR_TO_DRIVE_CAR,
+ COMMAND_ADD_PATROL_POINT,
+ COMMAND_IS_PLAYER_IN_GANGZONE,
+ COMMAND_IS_PLAYER_IN_ZONE,
+ COMMAND_IS_PLAYER_PRESSING_HORN,
+ COMMAND_HAS_CHAR_SPOTTED_PLAYER,
+ COMMAND_ORDER_CHAR_TO_BACKDOOR,
+ COMMAND_ADD_CHAR_TO_GANG,
+ COMMAND_IS_CHAR_OBJECTIVE_PASSED,
+ COMMAND_SET_CHAR_DRIVE_AGGRESSION,
+ COMMAND_SET_CHAR_MAX_DRIVESPEED,
+ COMMAND_CREATE_CHAR_INSIDE_CAR,
+ COMMAND_WARP_PLAYER_FROM_CAR_TO_COORD,
+ COMMAND_MAKE_CHAR_DO_NOTHING,
+ COMMAND_SET_CHAR_INVINCIBLE,
+ COMMAND_SET_PLAYER_INVINCIBLE,
+ COMMAND_SET_CHAR_GRAPHIC_TYPE,
+ COMMAND_SET_PLAYER_GRAPHIC_TYPE,
+ COMMAND_HAS_PLAYER_BEEN_ARRESTED,
+ COMMAND_STOP_CHAR_DRIVING,
+ COMMAND_KILL_CHAR,
+ COMMAND_SET_FAVOURITE_CAR_MODEL_FOR_CHAR,
+ COMMAND_SET_CHAR_OCCUPATION,
+ COMMAND_CHANGE_CAR_LOCK,
+ COMMAND_SHAKE_CAM_WITH_POINT,
+ COMMAND_IS_CAR_MODEL,
+ COMMAND_IS_CAR_REMAP,
+ COMMAND_HAS_CAR_JUST_SUNK,
+ COMMAND_SET_CAR_NO_COLLIDE,
+ COMMAND_IS_CAR_DEAD_IN_AREA_2D,
+ COMMAND_IS_CAR_DEAD_IN_AREA_3D,
+ COMMAND_IS_TRAILER_ATTACHED,
+ COMMAND_IS_CAR_ON_TRAILER,
+ COMMAND_HAS_CAR_GOT_WEAPON,
+ COMMAND_PARK,
+ COMMAND_HAS_PARK_FINISHED,
+ COMMAND_KILL_ALL_PASSENGERS,
+ COMMAND_SET_CAR_BULLETPROOF,
+ COMMAND_SET_CAR_FLAMEPROOF,
+ COMMAND_SET_CAR_ROCKETPROOF,
+ COMMAND_IS_CARBOMB_ACTIVE,
+ COMMAND_GIVE_CAR_ALARM,
+ COMMAND_PUT_CAR_ON_TRAILER,
+ COMMAND_IS_CAR_CRUSHED,
+ COMMAND_CREATE_GANG_CAR,
+ COMMAND_CREATE_CAR_GENERATOR,
+ COMMAND_SWITCH_CAR_GENERATOR,
+ COMMAND_ADD_PAGER_MESSAGE,
+ COMMAND_DISPLAY_ONSCREEN_TIMER,
+ COMMAND_CLEAR_ONSCREEN_TIMER,
+ COMMAND_DISPLAY_ONSCREEN_COUNTER,
+ COMMAND_CLEAR_ONSCREEN_COUNTER,
+ COMMAND_SET_ZONE_CAR_INFO,
+ COMMAND_IS_CHAR_IN_GANG_ZONE,
+ COMMAND_IS_CHAR_IN_ZONE,
+ COMMAND_SET_CAR_DENSITY,
+ COMMAND_SET_PED_DENSITY,
+ COMMAND_POINT_CAMERA_AT_PLAYER,
+ COMMAND_POINT_CAMERA_AT_CAR,
+ COMMAND_POINT_CAMERA_AT_CHAR,
+ COMMAND_RESTORE_CAMERA,
+ COMMAND_SHAKE_PAD,
+ COMMAND_SET_ZONE_PED_INFO,
+ COMMAND_SET_TIME_SCALE,
+ COMMAND_IS_CAR_IN_AIR,
+ COMMAND_SET_FIXED_CAMERA_POSITION,
+ COMMAND_POINT_CAMERA_AT_POINT,
+ COMMAND_ADD_BLIP_FOR_CAR_OLD,
+ COMMAND_ADD_BLIP_FOR_CHAR_OLD,
+ COMMAND_ADD_BLIP_FOR_OBJECT_OLD,
+ COMMAND_REMOVE_BLIP,
+ COMMAND_CHANGE_BLIP_COLOUR,
+ COMMAND_DIM_BLIP,
+ COMMAND_ADD_BLIP_FOR_COORD_OLD,
+ COMMAND_CHANGE_BLIP_SCALE,
+ COMMAND_SET_FADING_COLOUR,
+ COMMAND_DO_FADE,
+ COMMAND_GET_FADING_STATUS,
+ COMMAND_ADD_HOSPITAL_RESTART,
+ COMMAND_ADD_POLICE_RESTART,
+ COMMAND_OVERRIDE_NEXT_RESTART,
+ COMMAND_DRAW_SHADOW,
+ COMMAND_GET_PLAYER_HEADING,
+ COMMAND_SET_PLAYER_HEADING,
+ COMMAND_GET_CHAR_HEADING,
+ COMMAND_SET_CHAR_HEADING,
+ COMMAND_GET_CAR_HEADING,
+ COMMAND_SET_CAR_HEADING,
+ COMMAND_GET_OBJECT_HEADING,
+ COMMAND_SET_OBJECT_HEADING,
+ COMMAND_IS_PLAYER_TOUCHING_OBJECT,
+ COMMAND_IS_CHAR_TOUCHING_OBJECT,
+ COMMAND_SET_PLAYER_AMMO,
+ COMMAND_SET_CHAR_AMMO,
+ COMMAND_SET_CAR_AMMO,
+ COMMAND_LOAD_CAMERA_SPLINE,
+ COMMAND_MOVE_CAMERA_ALONG_SPLINE,
+ COMMAND_GET_CAMERA_POSITION_ALONG_SPLINE,
+ COMMAND_DECLARE_MISSION_FLAG,
+ COMMAND_DECLARE_MISSION_FLAG_FOR_CONTACT,
+ COMMAND_DECLARE_BASE_BRIEF_ID_FOR_CONTACT,
+ COMMAND_IS_PLAYER_HEALTH_GREATER,
+ COMMAND_IS_CHAR_HEALTH_GREATER,
+ COMMAND_IS_CAR_HEALTH_GREATER,
+ COMMAND_ADD_BLIP_FOR_CAR,
+ COMMAND_ADD_BLIP_FOR_CHAR,
+ COMMAND_ADD_BLIP_FOR_OBJECT,
+ COMMAND_ADD_BLIP_FOR_CONTACT_POINT,
+ COMMAND_ADD_BLIP_FOR_COORD,
+ COMMAND_CHANGE_BLIP_DISPLAY,
+ COMMAND_ADD_ONE_OFF_SOUND,
+ COMMAND_ADD_CONTINUOUS_SOUND,
+ COMMAND_REMOVE_SOUND,
+ COMMAND_IS_CAR_STUCK_ON_ROOF,
+ COMMAND_ADD_UPSIDEDOWN_CAR_CHECK,
+ COMMAND_REMOVE_UPSIDEDOWN_CAR_CHECK,
+ COMMAND_SET_CHAR_OBJ_WAIT_ON_FOOT,
+ COMMAND_SET_CHAR_OBJ_FLEE_ON_FOOT_TILL_SAFE,
+ COMMAND_SET_CHAR_OBJ_GUARD_SPOT,
+ COMMAND_SET_CHAR_OBJ_GUARD_AREA,
+ COMMAND_SET_CHAR_OBJ_WAIT_IN_CAR,
+ COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_2D,
+ COMMAND_IS_PLAYER_IN_AREA_IN_CAR_2D,
+ COMMAND_IS_PLAYER_STOPPED_IN_AREA_2D,
+ COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_2D,
+ COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_2D,
+ COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_3D,
+ COMMAND_IS_PLAYER_IN_AREA_IN_CAR_3D,
+ COMMAND_IS_PLAYER_STOPPED_IN_AREA_3D,
+ COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_3D,
+ COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_3D,
+ COMMAND_IS_CHAR_IN_AREA_ON_FOOT_2D,
+ COMMAND_IS_CHAR_IN_AREA_IN_CAR_2D,
+ COMMAND_IS_CHAR_STOPPED_IN_AREA_2D,
+ COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_2D,
+ COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_2D,
+ COMMAND_IS_CHAR_IN_AREA_ON_FOOT_3D,
+ COMMAND_IS_CHAR_IN_AREA_IN_CAR_3D,
+ COMMAND_IS_CHAR_STOPPED_IN_AREA_3D,
+ COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_3D,
+ COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_3D,
+ COMMAND_IS_CAR_STOPPED_IN_AREA_2D,
+ COMMAND_IS_CAR_STOPPED_IN_AREA_3D,
+ COMMAND_LOCATE_CAR_2D,
+ COMMAND_LOCATE_STOPPED_CAR_2D,
+ COMMAND_LOCATE_CAR_3D,
+ COMMAND_LOCATE_STOPPED_CAR_3D,
+ COMMAND_GIVE_WEAPON_TO_PLAYER,
+ COMMAND_GIVE_WEAPON_TO_CHAR,
+ COMMAND_GIVE_WEAPON_TO_CAR,
+ COMMAND_SET_PLAYER_CONTROL,
+ COMMAND_FORCE_WEATHER,
+ COMMAND_FORCE_WEATHER_NOW,
+ COMMAND_RELEASE_WEATHER,
+ COMMAND_SET_CURRENT_PLAYER_WEAPON,
+ COMMAND_SET_CURRENT_CHAR_WEAPON,
+ COMMAND_SET_CURRENT_CAR_WEAPON,
+ COMMAND_GET_OBJECT_COORDINATES,
+ COMMAND_SET_OBJECT_COORDINATES,
+ COMMAND_GET_GAME_TIMER,
+ COMMAND_TURN_CHAR_TO_FACE_COORD,
+ COMMAND_TURN_PLAYER_TO_FACE_COORD,
+ COMMAND_STORE_WANTED_LEVEL,
+ COMMAND_IS_CAR_STOPPED,
+ COMMAND_MARK_CHAR_AS_NO_LONGER_NEEDED,
+ COMMAND_MARK_CAR_AS_NO_LONGER_NEEDED,
+ COMMAND_MARK_OBJECT_AS_NO_LONGER_NEEDED,
+ COMMAND_DONT_REMOVE_CHAR,
+ COMMAND_DONT_REMOVE_CAR,
+ COMMAND_DONT_REMOVE_OBJECT,
+ COMMAND_CREATE_CHAR_AS_PASSENGER,
+ COMMAND_SET_CHAR_OBJ_KILL_CHAR_ON_FOOT,
+ COMMAND_SET_CHAR_OBJ_KILL_PLAYER_ON_FOOT,
+ COMMAND_SET_CHAR_OBJ_KILL_CHAR_ANY_MEANS,
+ COMMAND_SET_CHAR_OBJ_KILL_PLAYER_ANY_MEANS,
+ COMMAND_SET_CHAR_OBJ_FLEE_CHAR_ON_FOOT_TILL_SAFE,
+ COMMAND_SET_CHAR_OBJ_FLEE_PLAYER_ON_FOOT_TILL_SAFE,
+ COMMAND_SET_CHAR_OBJ_FLEE_CHAR_ON_FOOT_ALWAYS,
+ COMMAND_SET_CHAR_OBJ_FLEE_PLAYER_ON_FOOT_ALWAYS,
+ COMMAND_SET_CHAR_OBJ_GOTO_CHAR_ON_FOOT,
+ COMMAND_SET_CHAR_OBJ_GOTO_PLAYER_ON_FOOT,
+ COMMAND_SET_CHAR_OBJ_LEAVE_CAR,
+ COMMAND_SET_CHAR_OBJ_ENTER_CAR_AS_PASSENGER,
+ COMMAND_SET_CHAR_OBJ_ENTER_CAR_AS_DRIVER,
+ COMMAND_SET_CHAR_OBJ_FOLLOW_CAR_IN_CAR,
+ COMMAND_SET_CHAR_OBJ_FIRE_AT_OBJECT_FROM_VEHICLE,
+ COMMAND_SET_CHAR_OBJ_DESTROY_OBJECT,
+ COMMAND_SET_CHAR_OBJ_DESTROY_CAR,
+ COMMAND_SET_CHAR_OBJ_GOTO_AREA_ON_FOOT,
+ COMMAND_SET_CHAR_OBJ_GOTO_AREA_IN_CAR,
+ COMMAND_SET_CHAR_OBJ_FOLLOW_CAR_ON_FOOT_WITH_OFFSET,
+ COMMAND_SET_CHAR_OBJ_GUARD_ATTACK,
+ COMMAND_SET_CHAR_AS_LEADER,
+ COMMAND_SET_PLAYER_AS_LEADER,
+ COMMAND_LEAVE_GROUP,
+ COMMAND_SET_CHAR_OBJ_FOLLOW_ROUTE,
+ COMMAND_ADD_ROUTE_POINT,
+ COMMAND_PRINT_WITH_NUMBER_BIG,
+ COMMAND_PRINT_WITH_NUMBER,
+ COMMAND_PRINT_WITH_NUMBER_NOW,
+ COMMAND_PRINT_WITH_NUMBER_SOON,
+ COMMAND_SWITCH_ROADS_ON,
+ COMMAND_SWITCH_ROADS_OFF,
+ COMMAND_GET_NUMBER_OF_PASSENGERS,
+ COMMAND_GET_MAXIMUM_NUMBER_OF_PASSENGERS,
+ COMMAND_SET_CAR_DENSITY_MULTIPLIER,
+ COMMAND_SET_CAR_HEAVY,
+ COMMAND_CLEAR_CHAR_THREAT_SEARCH,
+ COMMAND_ACTIVATE_CRANE,
+ COMMAND_DEACTIVATE_CRANE,
+ COMMAND_SET_MAX_WANTED_LEVEL,
+ COMMAND_SAVE_VAR_INT,
+ COMMAND_SAVE_VAR_FLOAT,
+ COMMAND_IS_CAR_IN_AIR_PROPER,
+ COMMAND_IS_CAR_UPSIDEDOWN,
+ COMMAND_GET_PLAYER_CHAR,
+ COMMAND_CANCEL_OVERRIDE_RESTART,
+ COMMAND_SET_POLICE_IGNORE_PLAYER,
+ COMMAND_ADD_PAGER_MESSAGE_WITH_NUMBER,
+ COMMAND_START_KILL_FRENZY,
+ COMMAND_READ_KILL_FRENZY_STATUS,
+ COMMAND_SQRT,
+ COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_2D,
+ COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_2D,
+ COMMAND_LOCATE_PLAYER_IN_CAR_CAR_2D,
+ COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_3D,
+ COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_3D,
+ COMMAND_LOCATE_PLAYER_IN_CAR_CAR_3D,
+ COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_2D,
+ COMMAND_LOCATE_CHAR_ON_FOOT_CAR_2D,
+ COMMAND_LOCATE_CHAR_IN_CAR_CAR_2D,
+ COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_3D,
+ COMMAND_LOCATE_CHAR_ON_FOOT_CAR_3D,
+ COMMAND_LOCATE_CHAR_IN_CAR_CAR_3D,
+ COMMAND_GENERATE_RANDOM_FLOAT_IN_RANGE,
+ COMMAND_GENERATE_RANDOM_INT_IN_RANGE,
+ COMMAND_LOCK_CAR_DOORS,
+ COMMAND_EXPLODE_CAR,
+ COMMAND_ADD_EXPLOSION,
+ COMMAND_IS_CAR_UPRIGHT,
+ COMMAND_TURN_CHAR_TO_FACE_CHAR,
+ COMMAND_TURN_CHAR_TO_FACE_PLAYER,
+ COMMAND_TURN_PLAYER_TO_FACE_CHAR,
+ COMMAND_SET_CHAR_OBJ_GOTO_COORD_ON_FOOT,
+ COMMAND_SET_CHAR_OBJ_GOTO_COORD_IN_CAR,
+ COMMAND_CREATE_PICKUP,
+ COMMAND_HAS_PICKUP_BEEN_COLLECTED,
+ COMMAND_REMOVE_PICKUP,
+ COMMAND_SET_TAXI_LIGHTS,
+ COMMAND_PRINT_BIG_Q,
+ COMMAND_PRINT_WITH_NUMBER_BIG_Q,
+ COMMAND_SET_GARAGE,
+ COMMAND_SET_GARAGE_WITH_CAR_MODEL,
+ COMMAND_SET_TARGET_CAR_FOR_MISSION_GARAGE,
+ COMMAND_IS_CAR_IN_MISSION_GARAGE,
+ COMMAND_SET_FREE_BOMBS,
+ COMMAND_SET_POWERPOINT,
+ COMMAND_SET_ALL_TAXI_LIGHTS,
+ COMMAND_IS_CAR_ARMED_WITH_ANY_BOMB,
+ COMMAND_APPLY_BRAKES_TO_PLAYERS_CAR,
+ COMMAND_SET_PLAYER_HEALTH,
+ COMMAND_SET_CHAR_HEALTH,
+ COMMAND_SET_CAR_HEALTH,
+ COMMAND_GET_PLAYER_HEALTH,
+ COMMAND_GET_CHAR_HEALTH,
+ COMMAND_GET_CAR_HEALTH,
+ COMMAND_IS_CAR_ARMED_WITH_BOMB,
+ COMMAND_CHANGE_CAR_COLOUR,
+ COMMAND_SWITCH_PED_ROADS_ON,
+ COMMAND_SWITCH_PED_ROADS_OFF,
+ COMMAND_CHAR_LOOK_AT_CHAR_ALWAYS,
+ COMMAND_CHAR_LOOK_AT_PLAYER_ALWAYS,
+ COMMAND_PLAYER_LOOK_AT_CHAR_ALWAYS,
+ COMMAND_STOP_CHAR_LOOKING,
+ COMMAND_STOP_PLAYER_LOOKING,
+ COMMAND_SWITCH_HELICOPTER,
+ COMMAND_SET_GANG_ATTITUDE,
+ COMMAND_SET_GANG_GANG_ATTITUDE,
+ COMMAND_SET_GANG_PLAYER_ATTITUDE,
+ COMMAND_SET_GANG_PED_MODELS,
+ COMMAND_SET_GANG_CAR_MODEL,
+ COMMAND_SET_GANG_WEAPONS,
+ COMMAND_SET_CHAR_OBJ_RUN_TO_AREA,
+ COMMAND_SET_CHAR_OBJ_RUN_TO_COORD,
+ COMMAND_IS_PLAYER_TOUCHING_OBJECT_ON_FOOT,
+ COMMAND_IS_CHAR_TOUCHING_OBJECT_ON_FOOT,
+ COMMAND_LOAD_SPECIAL_CHARACTER,
+ COMMAND_HAS_SPECIAL_CHARACTER_LOADED,
+ COMMAND_FLASH_CAR,
+ COMMAND_FLASH_CHAR,
+ COMMAND_FLASH_OBJECT,
+ COMMAND_IS_PLAYER_IN_REMOTE_MODE,
+ COMMAND_ARM_CAR_WITH_BOMB,
+ COMMAND_SET_CHAR_PERSONALITY,
+ COMMAND_SET_CUTSCENE_OFFSET,
+ COMMAND_SET_ANIM_GROUP_FOR_CHAR,
+ COMMAND_SET_ANIM_GROUP_FOR_PLAYER,
+ COMMAND_REQUEST_MODEL,
+ COMMAND_HAS_MODEL_LOADED,
+ COMMAND_MARK_MODEL_AS_NO_LONGER_NEEDED,
+ COMMAND_GRAB_PHONE,
+ COMMAND_SET_REPEATED_PHONE_MESSAGE,
+ COMMAND_SET_PHONE_MESSAGE,
+ COMMAND_HAS_PHONE_DISPLAYED_MESSAGE,
+ COMMAND_TURN_PHONE_OFF,
+ COMMAND_DRAW_CORONA,
+ COMMAND_DRAW_LIGHT,
+ COMMAND_STORE_WEATHER,
+ COMMAND_RESTORE_WEATHER,
+ COMMAND_STORE_CLOCK,
+ COMMAND_RESTORE_CLOCK,
+ COMMAND_RESTART_CRITICAL_MISSION,
+ COMMAND_IS_PLAYER_PLAYING,
+ COMMAND_SET_COLL_OBJ_NO_OBJ,
+ COMMAND_SET_COLL_OBJ_WAIT_ON_FOOT,
+ COMMAND_SET_COLL_OBJ_FLEE_ON_FOOT_TILL_SAFE,
+ COMMAND_SET_COLL_OBJ_GUARD_SPOT,
+ COMMAND_SET_COLL_OBJ_GUARD_AREA,
+ COMMAND_SET_COLL_OBJ_WAIT_IN_CAR,
+ COMMAND_SET_COLL_OBJ_KILL_CHAR_ON_FOOT,
+ COMMAND_SET_COLL_OBJ_KILL_PLAYER_ON_FOOT,
+ COMMAND_SET_COLL_OBJ_KILL_CHAR_ANY_MEANS,
+ COMMAND_SET_COLL_OBJ_KILL_PLAYER_ANY_MEANS,
+ COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_TILL_SAFE,
+ COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_TILL_SAFE,
+ COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_ALWAYS,
+ COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_ALWAYS,
+ COMMAND_SET_COLL_OBJ_GOTO_CHAR_ON_FOOT,
+ COMMAND_SET_COLL_OBJ_GOTO_PLAYER_ON_FOOT,
+ COMMAND_SET_COLL_OBJ_LEAVE_CAR,
+ COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_PASSENGER,
+ COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_DRIVER,
+ COMMAND_SET_COLL_OBJ_FOLLOW_CAR_IN_CAR,
+ COMMAND_SET_COLL_OBJ_FIRE_AT_OBJECT_FROM_VEHICLE,
+ COMMAND_SET_COLL_OBJ_DESTROY_OBJECT,
+ COMMAND_SET_COLL_OBJ_DESTROY_CAR,
+ COMMAND_SET_COLL_OBJ_GOTO_AREA_ON_FOOT,
+ COMMAND_SET_COLL_OBJ_GOTO_AREA_IN_CAR,
+ COMMAND_SET_COLL_OBJ_FOLLOW_CAR_ON_FOOT_WITH_OFFSET,
+ COMMAND_SET_COLL_OBJ_GUARD_ATTACK,
+ COMMAND_SET_COLL_OBJ_FOLLOW_ROUTE,
+ COMMAND_SET_COLL_OBJ_GOTO_COORD_ON_FOOT,
+ COMMAND_SET_COLL_OBJ_GOTO_COORD_IN_CAR,
+ COMMAND_SET_COLL_OBJ_RUN_TO_AREA,
+ COMMAND_SET_COLL_OBJ_RUN_TO_COORD,
+ COMMAND_ADD_PEDS_IN_AREA_TO_COLL,
+ COMMAND_ADD_PEDS_IN_VEHICLE_TO_COLL,
+ COMMAND_CLEAR_COLL,
+ COMMAND_IS_COLL_IN_CARS,
+ COMMAND_LOCATE_COLL_ANY_MEANS_2D,
+ COMMAND_LOCATE_COLL_ON_FOOT_2D,
+ COMMAND_LOCATE_COLL_IN_CAR_2D,
+ COMMAND_LOCATE_STOPPED_COLL_ANY_MEANS_2D,
+ COMMAND_LOCATE_STOPPED_COLL_ON_FOOT_2D,
+ COMMAND_LOCATE_STOPPED_COLL_IN_CAR_2D,
+ COMMAND_LOCATE_COLL_ANY_MEANS_CHAR_2D,
+ COMMAND_LOCATE_COLL_ON_FOOT_CHAR_2D,
+ COMMAND_LOCATE_COLL_IN_CAR_CHAR_2D,
+ COMMAND_LOCATE_COLL_ANY_MEANS_CAR_2D,
+ COMMAND_LOCATE_COLL_ON_FOOT_CAR_2D,
+ COMMAND_LOCATE_COLL_IN_CAR_CAR_2D,
+ COMMAND_LOCATE_COLL_ANY_MEANS_PLAYER_2D,
+ COMMAND_LOCATE_COLL_ON_FOOT_PLAYER_2D,
+ COMMAND_LOCATE_COLL_IN_CAR_PLAYER_2D,
+ COMMAND_IS_COLL_IN_AREA_2D,
+ COMMAND_IS_COLL_IN_AREA_ON_FOOT_2D,
+ COMMAND_IS_COLL_IN_AREA_IN_CAR_2D,
+ COMMAND_IS_COLL_STOPPED_IN_AREA_2D,
+ COMMAND_IS_COLL_STOPPED_IN_AREA_ON_FOOT_2D,
+ COMMAND_IS_COLL_STOPPED_IN_AREA_IN_CAR_2D,
+ COMMAND_GET_NUMBER_OF_PEDS_IN_COLL,
+ COMMAND_SET_CHAR_HEED_THREATS,
+ COMMAND_SET_PLAYER_HEED_THREATS,
+ COMMAND_GET_CONTROLLER_MODE,
+ COMMAND_SET_CAN_RESPRAY_CAR,
+ COMMAND_IS_TAXI,
+ COMMAND_UNLOAD_SPECIAL_CHARACTER,
+ COMMAND_RESET_NUM_OF_MODELS_KILLED_BY_PLAYER,
+ COMMAND_GET_NUM_OF_MODELS_KILLED_BY_PLAYER,
+ COMMAND_ACTIVATE_GARAGE,
+ COMMAND_SWITCH_TAXI_TIMER,
+ COMMAND_CREATE_OBJECT_NO_OFFSET,
+ COMMAND_IS_BOAT,
+ COMMAND_SET_CHAR_OBJ_GOTO_AREA_ANY_MEANS,
+ COMMAND_SET_COLL_OBJ_GOTO_AREA_ANY_MEANS,
+ COMMAND_IS_PLAYER_STOPPED,
+ COMMAND_IS_CHAR_STOPPED,
+ COMMAND_MESSAGE_WAIT,
+ COMMAND_ADD_PARTICLE_EFFECT,
+ COMMAND_SWITCH_WIDESCREEN,
+ COMMAND_ADD_SPRITE_BLIP_FOR_CAR,
+ COMMAND_ADD_SPRITE_BLIP_FOR_CHAR,
+ COMMAND_ADD_SPRITE_BLIP_FOR_OBJECT,
+ COMMAND_ADD_SPRITE_BLIP_FOR_CONTACT_POINT,
+ COMMAND_ADD_SPRITE_BLIP_FOR_COORD,
+ COMMAND_SET_CHAR_ONLY_DAMAGED_BY_PLAYER,
+ COMMAND_SET_CAR_ONLY_DAMAGED_BY_PLAYER,
+ COMMAND_SET_CHAR_PROOFS,
+ COMMAND_SET_CAR_PROOFS,
+ COMMAND_IS_PLAYER_IN_ANGLED_AREA_2D,
+ COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_2D,
+ COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_2D,
+ COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_2D,
+ COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_2D,
+ COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_2D,
+ COMMAND_IS_PLAYER_IN_ANGLED_AREA_3D,
+ COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_3D,
+ COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_3D,
+ COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_3D,
+ COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_3D,
+ COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_3D,
+ COMMAND_DEACTIVATE_GARAGE,
+ COMMAND_GET_NUMBER_OF_CARS_COLLECTED_BY_GARAGE,
+ COMMAND_HAS_CAR_BEEN_TAKEN_TO_GARAGE,
+ COMMAND_SET_SWAT_REQUIRED,
+ COMMAND_SET_FBI_REQUIRED,
+ COMMAND_SET_ARMY_REQUIRED,
+ COMMAND_IS_CAR_IN_WATER,
+ COMMAND_GET_CLOSEST_CHAR_NODE,
+ COMMAND_GET_CLOSEST_CAR_NODE,
+ COMMAND_CAR_GOTO_COORDINATES_ACCURATE,
+ COMMAND_START_PACMAN_RACE,
+ COMMAND_START_PACMAN_RECORD,
+ COMMAND_GET_NUMBER_OF_POWER_PILLS_EATEN,
+ COMMAND_CLEAR_PACMAN,
+ COMMAND_START_PACMAN_SCRAMBLE,
+ COMMAND_GET_NUMBER_OF_POWER_PILLS_CARRIED,
+ COMMAND_CLEAR_NUMBER_OF_POWER_PILLS_CARRIED,
+ COMMAND_IS_CAR_ON_SCREEN,
+ COMMAND_IS_CHAR_ON_SCREEN,
+ COMMAND_IS_OBJECT_ON_SCREEN,
+ COMMAND_GOSUB_FILE,
+ COMMAND_GET_GROUND_Z_FOR_3D_COORD,
+ COMMAND_START_SCRIPT_FIRE,
+ COMMAND_IS_SCRIPT_FIRE_EXTINGUISHED,
+ COMMAND_REMOVE_SCRIPT_FIRE,
+ COMMAND_SET_COMEDY_CONTROLS,
+ COMMAND_BOAT_GOTO_COORDS,
+ COMMAND_BOAT_STOP,
+ COMMAND_IS_PLAYER_SHOOTING_IN_AREA,
+ COMMAND_IS_CHAR_SHOOTING_IN_AREA,
+ COMMAND_IS_CURRENT_PLAYER_WEAPON,
+ COMMAND_IS_CURRENT_CHAR_WEAPON,
+ COMMAND_CLEAR_NUMBER_OF_POWER_PILLS_EATEN,
+ COMMAND_ADD_POWER_PILL,
+ COMMAND_SET_BOAT_CRUISE_SPEED,
+ COMMAND_GET_RANDOM_CHAR_IN_AREA,
+ COMMAND_GET_RANDOM_CHAR_IN_ZONE,
+ COMMAND_IS_PLAYER_IN_TAXI,
+ COMMAND_IS_PLAYER_SHOOTING,
+ COMMAND_IS_CHAR_SHOOTING,
+ COMMAND_CREATE_MONEY_PICKUP,
+ COMMAND_SET_CHAR_ACCURACY,
+ COMMAND_GET_CAR_SPEED,
+ COMMAND_LOAD_CUTSCENE,
+ COMMAND_CREATE_CUTSCENE_OBJECT,
+ COMMAND_SET_CUTSCENE_ANIM,
+ COMMAND_START_CUTSCENE,
+ COMMAND_GET_CUTSCENE_TIME,
+ COMMAND_HAS_CUTSCENE_FINISHED,
+ COMMAND_CLEAR_CUTSCENE,
+ COMMAND_RESTORE_CAMERA_JUMPCUT,
+ COMMAND_CREATE_COLLECTABLE1,
+ COMMAND_SET_COLLECTABLE1_TOTAL,
+ COMMAND_IS_PROJECTILE_IN_AREA,
+ COMMAND_DESTROY_PROJECTILES_IN_AREA,
+ COMMAND_DROP_MINE,
+ COMMAND_DROP_NAUTICAL_MINE,
+ COMMAND_IS_CHAR_MODEL,
+ COMMAND_LOAD_SPECIAL_MODEL,
+ COMMAND_CREATE_CUTSCENE_HEAD,
+ COMMAND_SET_CUTSCENE_HEAD_ANIM,
+ COMMAND_SIN,
+ COMMAND_COS,
+ COMMAND_GET_CAR_FORWARD_X,
+ COMMAND_GET_CAR_FORWARD_Y,
+ COMMAND_CHANGE_GARAGE_TYPE,
+ COMMAND_ACTIVATE_CRUSHER_CRANE,
+ COMMAND_PRINT_WITH_2_NUMBERS,
+ COMMAND_PRINT_WITH_2_NUMBERS_NOW,
+ COMMAND_PRINT_WITH_2_NUMBERS_SOON,
+ COMMAND_PRINT_WITH_3_NUMBERS,
+ COMMAND_PRINT_WITH_3_NUMBERS_NOW,
+ COMMAND_PRINT_WITH_3_NUMBERS_SOON,
+ COMMAND_PRINT_WITH_4_NUMBERS,
+ COMMAND_PRINT_WITH_4_NUMBERS_NOW,
+ COMMAND_PRINT_WITH_4_NUMBERS_SOON,
+ COMMAND_PRINT_WITH_5_NUMBERS,
+ COMMAND_PRINT_WITH_5_NUMBERS_NOW,
+ COMMAND_PRINT_WITH_5_NUMBERS_SOON,
+ COMMAND_PRINT_WITH_6_NUMBERS,
+ COMMAND_PRINT_WITH_6_NUMBERS_NOW,
+ COMMAND_PRINT_WITH_6_NUMBERS_SOON,
+ COMMAND_SET_CHAR_OBJ_FOLLOW_CHAR_IN_FORMATION,
+ COMMAND_PLAYER_MADE_PROGRESS,
+ COMMAND_SET_PROGRESS_TOTAL,
+ COMMAND_REGISTER_JUMP_DISTANCE,
+ COMMAND_REGISTER_JUMP_HEIGHT,
+ COMMAND_REGISTER_JUMP_FLIPS,
+ COMMAND_REGISTER_JUMP_SPINS,
+ COMMAND_REGISTER_JUMP_STUNT,
+ COMMAND_REGISTER_UNIQUE_JUMP_FOUND,
+ COMMAND_SET_UNIQUE_JUMPS_TOTAL,
+ COMMAND_REGISTER_PASSENGER_DROPPED_OFF_TAXI,
+ COMMAND_REGISTER_MONEY_MADE_TAXI,
+ COMMAND_REGISTER_MISSION_GIVEN,
+ COMMAND_REGISTER_MISSION_PASSED,
+ COMMAND_SET_CHAR_RUNNING,
+ COMMAND_REMOVE_ALL_SCRIPT_FIRES,
+ COMMAND_IS_FIRST_CAR_COLOUR,
+ COMMAND_IS_SECOND_CAR_COLOUR,
+ COMMAND_HAS_CHAR_BEEN_DAMAGED_BY_WEAPON,
+ COMMAND_HAS_CAR_BEEN_DAMAGED_BY_WEAPON,
+ COMMAND_IS_CHAR_IN_CHARS_GROUP,
+ COMMAND_IS_CHAR_IN_PLAYERS_GROUP,
+ COMMAND_EXPLODE_CHAR_HEAD,
+ COMMAND_EXPLODE_PLAYER_HEAD,
+ COMMAND_ANCHOR_BOAT,
+ COMMAND_SET_ZONE_GROUP,
+ COMMAND_START_CAR_FIRE,
+ COMMAND_START_CHAR_FIRE,
+ COMMAND_GET_RANDOM_CAR_OF_TYPE_IN_AREA,
+ COMMAND_GET_RANDOM_CAR_OF_TYPE_IN_ZONE,
+ COMMAND_HAS_RESPRAY_HAPPENED,
+ COMMAND_SET_CAMERA_ZOOM,
+ COMMAND_CREATE_PICKUP_WITH_AMMO,
+ COMMAND_SET_CAR_RAM_CAR,
+ COMMAND_SET_CAR_BLOCK_CAR,
+ COMMAND_SET_CHAR_OBJ_CATCH_TRAIN,
+ COMMAND_SET_COLL_OBJ_CATCH_TRAIN,
+ COMMAND_SET_PLAYER_NEVER_GETS_TIRED,
+ COMMAND_SET_PLAYER_FAST_RELOAD,
+ COMMAND_SET_CHAR_BLEEDING,
+ COMMAND_SET_CAR_FUNNY_SUSPENSION,
+ COMMAND_SET_CAR_BIG_WHEELS,
+ COMMAND_SET_FREE_RESPRAYS,
+ COMMAND_SET_PLAYER_VISIBLE,
+ COMMAND_SET_CHAR_VISIBLE,
+ COMMAND_SET_CAR_VISIBLE,
+ COMMAND_IS_AREA_OCCUPIED,
+ COMMAND_START_DRUG_RUN,
+ COMMAND_HAS_DRUG_RUN_BEEN_COMPLETED,
+ COMMAND_HAS_DRUG_PLANE_BEEN_SHOT_DOWN,
+ COMMAND_SAVE_PLAYER_FROM_FIRES,
+ COMMAND_DISPLAY_TEXT,
+ COMMAND_SET_TEXT_SCALE,
+ COMMAND_SET_TEXT_COLOUR,
+ COMMAND_SET_TEXT_JUSTIFY,
+ COMMAND_SET_TEXT_CENTRE,
+ COMMAND_SET_TEXT_WRAPX,
+ COMMAND_SET_TEXT_CENTRE_SIZE,
+ COMMAND_SET_TEXT_BACKGROUND,
+ COMMAND_SET_TEXT_BACKGROUND_COLOUR,
+ COMMAND_SET_TEXT_BACKGROUND_ONLY_TEXT,
+ COMMAND_SET_TEXT_PROPORTIONAL,
+ COMMAND_SET_TEXT_FONT,
+ COMMAND_INDUSTRIAL_PASSED,
+ COMMAND_COMMERCIAL_PASSED,
+ COMMAND_SUBURBAN_PASSED,
+ COMMAND_ROTATE_OBJECT,
+ COMMAND_SLIDE_OBJECT,
+ COMMAND_REMOVE_CHAR_ELEGANTLY,
+ COMMAND_SET_CHAR_STAY_IN_SAME_PLACE,
+ COMMAND_IS_NASTY_GAME,
+ COMMAND_UNDRESS_CHAR,
+ COMMAND_DRESS_CHAR,
+ COMMAND_START_CHASE_SCENE,
+ COMMAND_STOP_CHASE_SCENE,
+ COMMAND_IS_EXPLOSION_IN_AREA,
+ COMMAND_IS_EXPLOSION_IN_ZONE,
+ COMMAND_START_DRUG_DROP_OFF,
+ COMMAND_HAS_DROP_OFF_PLANE_BEEN_SHOT_DOWN,
+ COMMAND_FIND_DROP_OFF_PLANE_COORDINATES,
+ COMMAND_CREATE_FLOATING_PACKAGE,
+ COMMAND_PLACE_OBJECT_RELATIVE_TO_CAR,
+ COMMAND_MAKE_OBJECT_TARGETTABLE,
+ COMMAND_ADD_ARMOUR_TO_PLAYER,
+ COMMAND_ADD_ARMOUR_TO_CHAR,
+ COMMAND_OPEN_GARAGE,
+ COMMAND_CLOSE_GARAGE,
+ COMMAND_WARP_CHAR_FROM_CAR_TO_COORD,
+ COMMAND_SET_VISIBILITY_OF_CLOSEST_OBJECT_OF_TYPE,
+ COMMAND_HAS_CHAR_SPOTTED_CHAR,
+ COMMAND_SET_CHAR_OBJ_HAIL_TAXI,
+ COMMAND_HAS_OBJECT_BEEN_DAMAGED,
+ COMMAND_START_KILL_FRENZY_HEADSHOT,
+ COMMAND_ACTIVATE_MILITARY_CRANE,
+ COMMAND_WARP_PLAYER_INTO_CAR,
+ COMMAND_WARP_CHAR_INTO_CAR,
+ COMMAND_SWITCH_CAR_RADIO,
+ COMMAND_SET_AUDIO_STREAM,
+ COMMAND_PRINT_WITH_2_NUMBERS_BIG,
+ COMMAND_PRINT_WITH_3_NUMBERS_BIG,
+ COMMAND_PRINT_WITH_4_NUMBERS_BIG,
+ COMMAND_PRINT_WITH_5_NUMBERS_BIG,
+ COMMAND_PRINT_WITH_6_NUMBERS_BIG,
+ COMMAND_SET_CHAR_WAIT_STATE,
+ COMMAND_SET_CAMERA_BEHIND_PLAYER,
+ COMMAND_SET_MOTION_BLUR,
+ COMMAND_PRINT_STRING_IN_STRING,
+ COMMAND_CREATE_RANDOM_CHAR,
+ COMMAND_SET_CHAR_OBJ_STEAL_ANY_CAR,
+ COMMAND_SET_2_REPEATED_PHONE_MESSAGES,
+ COMMAND_SET_2_PHONE_MESSAGES,
+ COMMAND_SET_3_REPEATED_PHONE_MESSAGES,
+ COMMAND_SET_3_PHONE_MESSAGES,
+ COMMAND_SET_4_REPEATED_PHONE_MESSAGES,
+ COMMAND_SET_4_PHONE_MESSAGES,
+ COMMAND_IS_SNIPER_BULLET_IN_AREA,
+ COMMAND_GIVE_PLAYER_DETONATOR,
+ COMMAND_SET_COLL_OBJ_STEAL_ANY_CAR,
+ COMMAND_SET_OBJECT_VELOCITY,
+ COMMAND_SET_OBJECT_COLLISION,
+ COMMAND_IS_ICECREAM_JINGLE_ON,
+ COMMAND_PRINT_STRING_IN_STRING_NOW,
+ COMMAND_PRINT_STRING_IN_STRING_SOON,
+ COMMAND_SET_5_REPEATED_PHONE_MESSAGES,
+ COMMAND_SET_5_PHONE_MESSAGES,
+ COMMAND_SET_6_REPEATED_PHONE_MESSAGES,
+ COMMAND_SET_6_PHONE_MESSAGES,
+ COMMAND_IS_POINT_OBSCURED_BY_A_MISSION_ENTITY,
+ COMMAND_LOAD_ALL_MODELS_NOW,
+ COMMAND_ADD_TO_OBJECT_VELOCITY,
+ COMMAND_DRAW_SPRITE,
+ COMMAND_DRAW_RECT,
+ COMMAND_LOAD_SPRITE,
+ COMMAND_LOAD_TEXTURE_DICTIONARY,
+ COMMAND_REMOVE_TEXTURE_DICTIONARY,
+ COMMAND_SET_OBJECT_DYNAMIC,
+ COMMAND_SET_CHAR_ANIM_SPEED,
+ COMMAND_PLAY_MISSION_PASSED_TUNE,
+ COMMAND_CLEAR_AREA,
+ COMMAND_FREEZE_ONSCREEN_TIMER,
+ COMMAND_SWITCH_CAR_SIREN,
+ COMMAND_SWITCH_PED_ROADS_ON_ANGLED,
+ COMMAND_SWITCH_PED_ROADS_OFF_ANGLED,
+ COMMAND_SWITCH_ROADS_ON_ANGLED,
+ COMMAND_SWITCH_ROADS_OFF_ANGLED,
+ COMMAND_SET_CAR_WATERTIGHT,
+ COMMAND_ADD_MOVING_PARTICLE_EFFECT,
+ COMMAND_SET_CHAR_CANT_BE_DRAGGED_OUT,
+ COMMAND_TURN_CAR_TO_FACE_COORD,
+ COMMAND_IS_CRANE_LIFTING_CAR,
+ COMMAND_DRAW_SPHERE,
+ COMMAND_SET_CAR_STATUS,
+ COMMAND_IS_CHAR_MALE,
+ COMMAND_SCRIPT_NAME,
+ COMMAND_CHANGE_GARAGE_TYPE_WITH_CAR_MODEL,
+ COMMAND_FIND_DRUG_PLANE_COORDINATES,
+ COMMAND_SAVE_INT_TO_DEBUG_FILE,
+ COMMAND_SAVE_FLOAT_TO_DEBUG_FILE,
+ COMMAND_SAVE_NEWLINE_TO_DEBUG_FILE,
+ COMMAND_POLICE_RADIO_MESSAGE,
+ COMMAND_SET_CAR_STRONG,
+ COMMAND_REMOVE_ROUTE,
+ COMMAND_SWITCH_RUBBISH,
+ COMMAND_REMOVE_PARTICLE_EFFECTS_IN_AREA,
+ COMMAND_SWITCH_STREAMING,
+ COMMAND_IS_GARAGE_OPEN,
+ COMMAND_IS_GARAGE_CLOSED,
+ COMMAND_START_CATALINA_HELI,
+ COMMAND_CATALINA_HELI_TAKE_OFF,
+ COMMAND_REMOVE_CATALINA_HELI,
+ COMMAND_HAS_CATALINA_HELI_BEEN_SHOT_DOWN,
+ COMMAND_SWAP_NEAREST_BUILDING_MODEL,
+ COMMAND_SWITCH_WORLD_PROCESSING,
+ COMMAND_REMOVE_ALL_PLAYER_WEAPONS,
+ COMMAND_GRAB_CATALINA_HELI,
+ COMMAND_CLEAR_AREA_OF_CARS,
+ COMMAND_SET_ROTATING_GARAGE_DOOR,
+ COMMAND_ADD_SPHERE,
+ COMMAND_REMOVE_SPHERE,
+ COMMAND_CATALINA_HELI_FLY_AWAY,
+ COMMAND_SET_EVERYONE_IGNORE_PLAYER,
+ COMMAND_STORE_CAR_CHAR_IS_IN_NO_SAVE,
+ COMMAND_STORE_CAR_PLAYER_IS_IN_NO_SAVE,
+ COMMAND_IS_PHONE_DISPLAYING_MESSAGE,
+ COMMAND_DISPLAY_ONSCREEN_TIMER_WITH_STRING,
+ COMMAND_DISPLAY_ONSCREEN_COUNTER_WITH_STRING,
+ COMMAND_CREATE_RANDOM_CAR_FOR_CAR_PARK,
+ COMMAND_IS_COLLISION_IN_MEMORY,
+ COMMAND_SET_WANTED_MULTIPLIER,
+ COMMAND_SET_CAMERA_IN_FRONT_OF_PLAYER,
+ COMMAND_IS_CAR_VISIBLY_DAMAGED,
+ COMMAND_DOES_OBJECT_EXIST,
+ COMMAND_LOAD_SCENE,
+ COMMAND_ADD_STUCK_CAR_CHECK,
+ COMMAND_REMOVE_STUCK_CAR_CHECK,
+ COMMAND_IS_CAR_STUCK,
+ COMMAND_LOAD_MISSION_AUDIO,
+ COMMAND_HAS_MISSION_AUDIO_LOADED,
+ COMMAND_PLAY_MISSION_AUDIO,
+ COMMAND_HAS_MISSION_AUDIO_FINISHED,
+ COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING,
+ COMMAND_HAS_IMPORT_GARAGE_SLOT_BEEN_FILLED,
+ COMMAND_CLEAR_THIS_PRINT,
+ COMMAND_CLEAR_THIS_BIG_PRINT,
+ COMMAND_SET_MISSION_AUDIO_POSITION,
+ COMMAND_ACTIVATE_SAVE_MENU,
+ COMMAND_HAS_SAVE_GAME_FINISHED,
+ COMMAND_NO_SPECIAL_CAMERA_FOR_THIS_GARAGE,
+ COMMAND_ADD_BLIP_FOR_PICKUP_OLD,
+ COMMAND_ADD_BLIP_FOR_PICKUP,
+ COMMAND_ADD_SPRITE_BLIP_FOR_PICKUP,
+ COMMAND_SET_PED_DENSITY_MULTIPLIER,
+ COMMAND_FORCE_RANDOM_PED_TYPE,
+ COMMAND_SET_TEXT_DRAW_BEFORE_FADE,
+ COMMAND_GET_COLLECTABLE1S_COLLECTED,
+ COMMAND_REGISTER_EL_BURRO_TIME,
+ COMMAND_SET_SPRITES_DRAW_BEFORE_FADE,
+ COMMAND_SET_TEXT_RIGHT_JUSTIFY,
+ COMMAND_PRINT_HELP,
+ COMMAND_CLEAR_HELP,
+ COMMAND_FLASH_HUD_OBJECT,
+ COMMAND_FLASH_RADAR_BLIP,
+ COMMAND_IS_CHAR_IN_CONTROL,
+ COMMAND_SET_GENERATE_CARS_AROUND_CAMERA,
+ COMMAND_CLEAR_SMALL_PRINTS,
+ COMMAND_HAS_MILITARY_CRANE_COLLECTED_ALL_CARS,
+ COMMAND_SET_UPSIDEDOWN_CAR_NOT_DAMAGED,
+ COMMAND_CAN_PLAYER_START_MISSION,
+ COMMAND_MAKE_PLAYER_SAFE_FOR_CUTSCENE,
+ COMMAND_USE_TEXT_COMMANDS,
+ COMMAND_SET_THREAT_FOR_PED_TYPE,
+ COMMAND_CLEAR_THREAT_FOR_PED_TYPE,
+ COMMAND_GET_CAR_COLOURS,
+ COMMAND_SET_ALL_CARS_CAN_BE_DAMAGED,
+ COMMAND_SET_CAR_CAN_BE_DAMAGED,
+ COMMAND_MAKE_PLAYER_UNSAFE,
+ COMMAND_LOAD_COLLISION,
+ COMMAND_GET_BODY_CAST_HEALTH,
+ COMMAND_SET_CHARS_CHATTING,
+ COMMAND_MAKE_PLAYER_SAFE,
+ COMMAND_SET_CAR_STAYS_IN_CURRENT_LEVEL,
+ COMMAND_SET_CHAR_STAYS_IN_CURRENT_LEVEL,
+ COMMAND_REGISTER_4X4_ONE_TIME,
+ COMMAND_REGISTER_4X4_TWO_TIME,
+ COMMAND_REGISTER_4X4_THREE_TIME,
+ COMMAND_REGISTER_4X4_MAYHEM_TIME,
+ COMMAND_REGISTER_LIFE_SAVED,
+ COMMAND_REGISTER_CRIMINAL_CAUGHT,
+ COMMAND_REGISTER_AMBULANCE_LEVEL,
+ COMMAND_REGISTER_FIRE_EXTINGUISHED,
+ COMMAND_TURN_PHONE_ON,
+ COMMAND_REGISTER_LONGEST_DODO_FLIGHT,
+ COMMAND_REGISTER_DEFUSE_BOMB_TIME,
+ COMMAND_SET_TOTAL_NUMBER_OF_KILL_FRENZIES,
+ COMMAND_BLOW_UP_RC_BUGGY,
+ COMMAND_REMOVE_CAR_FROM_CHASE,
+ COMMAND_IS_FRENCH_GAME,
+ COMMAND_IS_GERMAN_GAME,
+ COMMAND_CLEAR_MISSION_AUDIO,
+ COMMAND_SET_FADE_IN_AFTER_NEXT_ARREST,
+ COMMAND_SET_FADE_IN_AFTER_NEXT_DEATH,
+ COMMAND_SET_GANG_PED_MODEL_PREFERENCE,
+ COMMAND_SET_CHAR_USE_PEDNODE_SEEK,
+ COMMAND_SWITCH_VEHICLE_WEAPONS,
+ COMMAND_SET_GET_OUT_OF_JAIL_FREE,
+ COMMAND_SET_FREE_HEALTH_CARE,
+ COMMAND_IS_CAR_DOOR_CLOSED,
+ COMMAND_LOAD_AND_LAUNCH_MISSION,
+ COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL,
+ COMMAND_SET_OBJECT_DRAW_LAST,
+ COMMAND_GET_AMMO_IN_PLAYER_WEAPON,
+ COMMAND_GET_AMMO_IN_CHAR_WEAPON,
+ COMMAND_REGISTER_KILL_FRENZY_PASSED,
+ COMMAND_SET_CHAR_SAY,
+ COMMAND_SET_NEAR_CLIP,
+ COMMAND_SET_RADIO_CHANNEL,
+ COMMAND_OVERRIDE_HOSPITAL_LEVEL,
+ COMMAND_OVERRIDE_POLICE_STATION_LEVEL,
+ COMMAND_FORCE_RAIN,
+ COMMAND_DOES_GARAGE_CONTAIN_CAR,
+ COMMAND_SET_CAR_TRACTION,
+ COMMAND_ARE_MEASUREMENTS_IN_METRES,
+ COMMAND_CONVERT_METRES_TO_FEET,
+ COMMAND_MARK_ROADS_BETWEEN_LEVELS,
+ COMMAND_MARK_PED_ROADS_BETWEEN_LEVELS,
+ COMMAND_SET_CAR_AVOID_LEVEL_TRANSITIONS,
+ COMMAND_SET_CHAR_AVOID_LEVEL_TRANSITIONS,
+ COMMAND_IS_THREAT_FOR_PED_TYPE,
+ COMMAND_CLEAR_AREA_OF_CHARS,
+ COMMAND_SET_TOTAL_NUMBER_OF_MISSIONS,
+ COMMAND_CONVERT_METRES_TO_FEET_INT,
+ COMMAND_REGISTER_FASTEST_TIME,
+ COMMAND_REGISTER_HIGHEST_SCORE,
+ COMMAND_WARP_CHAR_INTO_CAR_AS_PASSENGER,
+ COMMAND_IS_CAR_PASSENGER_SEAT_FREE,
+ COMMAND_GET_CHAR_IN_CAR_PASSENGER_SEAT,
+ COMMAND_SET_CHAR_IS_CHRIS_CRIMINAL,
+ COMMAND_START_CREDITS,
+ COMMAND_STOP_CREDITS,
+ COMMAND_ARE_CREDITS_FINISHED,
+ COMMAND_CREATE_SINGLE_PARTICLE,
+ COMMAND_SET_CHAR_IGNORE_LEVEL_TRANSITIONS,
+ COMMAND_GET_CHASE_CAR,
+ COMMAND_START_BOAT_FOAM_ANIMATION,
+ COMMAND_UPDATE_BOAT_FOAM_ANIMATION,
+ COMMAND_SET_MUSIC_DOES_FADE,
+ COMMAND_SET_INTRO_IS_PLAYING,
+ COMMAND_SET_PLAYER_HOOKER,
+ COMMAND_PLAY_END_OF_GAME_TUNE,
+ COMMAND_STOP_END_OF_GAME_TUNE,
+ COMMAND_GET_CAR_MODEL,
+ COMMAND_IS_PLAYER_SITTING_IN_CAR,
+ COMMAND_IS_PLAYER_SITTING_IN_ANY_CAR,
+ COMMAND_SET_SCRIPT_FIRE_AUDIO,
+ COMMAND_ARE_ANY_CAR_CHEATS_ACTIVATED,
+ COMMAND_SET_CHAR_SUFFERS_CRITICAL_HITS,
+ COMMAND_IS_PLAYER_LIFTING_A_PHONE,
+ COMMAND_IS_CHAR_SITTING_IN_CAR,
+ COMMAND_IS_CHAR_SITTING_IN_ANY_CAR,
+ COMMAND_IS_PLAYER_ON_FOOT,
+ COMMAND_IS_CHAR_ON_FOOT,
+ COMMAND_LOAD_COLLISION_WITH_SCREEN,
+ COMMAND_LOAD_SPLASH_SCREEN,
+ COMMAND_SET_CAR_IGNORE_LEVEL_TRANSITIONS,
+ COMMAND_MAKE_CRAIGS_CAR_A_BIT_STRONGER,
+ COMMAND_SET_JAMES_CAR_ON_PATH_TO_PLAYER,
+ COMMAND_LOAD_END_OF_GAME_TUNE,
+ COMMAND_ENABLE_PLAYER_CONTROL_CAMERA,
+ COMMAND_SET_OBJECT_ROTATION,
+ COMMAND_GET_DEBUG_CAMERA_COORDINATES,
+ COMMAND_GET_DEBUG_CAMERA_FRONT_VECTOR,
+ COMMAND_IS_PLAYER_TARGETTING_ANY_CHAR,
+ COMMAND_IS_PLAYER_TARGETTING_CHAR,
+ COMMAND_IS_PLAYER_TARGETTING_OBJECT,
+ COMMAND_TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME,
+ COMMAND_DISPLAY_TEXT_WITH_NUMBER,
+ COMMAND_DISPLAY_TEXT_WITH_2_NUMBERS,
+ COMMAND_FAIL_CURRENT_MISSION,
+ COMMAND_GET_CLOSEST_OBJECT_OF_TYPE,
+ COMMAND_PLACE_OBJECT_RELATIVE_TO_OBJECT,
+ COMMAND_SET_ALL_OCCUPANTS_OF_CAR_LEAVE_CAR,
+ COMMAND_SET_INTERPOLATION_PARAMETERS,
+ COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_TOWARDS_POINT,
+ COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_AWAY_POINT,
+ COMMAND_GET_DEBUG_CAMERA_POINT_AT,
+ COMMAND_ATTACH_CHAR_TO_CAR,
+ COMMAND_DETACH_CHAR_FROM_CAR,
+ COMMAND_SET_CAR_CHANGE_LANE,
+ COMMAND_CLEAR_CHAR_LAST_WEAPON_DAMAGE,
+ COMMAND_CLEAR_CAR_LAST_WEAPON_DAMAGE,
+ COMMAND_GET_RANDOM_COP_IN_AREA,
+ COMMAND_GET_RANDOM_COP_IN_ZONE,
+ COMMAND_SET_CHAR_OBJ_FLEE_CAR,
+ COMMAND_GET_DRIVER_OF_CAR,
+ COMMAND_GET_NUMBER_OF_FOLLOWERS,
+ COMMAND_GIVE_REMOTE_CONTROLLED_MODEL_TO_PLAYER,
+ COMMAND_GET_CURRENT_PLAYER_WEAPON,
+ COMMAND_GET_CURRENT_CHAR_WEAPON,
+ COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_2D,
+ COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_2D,
+ COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_2D,
+ COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_3D,
+ COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_3D,
+ COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_3D,
+ COMMAND_SET_CAR_TEMP_ACTION,
+ COMMAND_SET_CAR_HANDBRAKE_TURN_RIGHT,
+ COMMAND_SET_CAR_HANDBRAKE_STOP,
+ COMMAND_IS_CHAR_ON_ANY_BIKE,
+ COMMAND_LOCATE_SNIPER_BULLET_2D,
+ COMMAND_LOCATE_SNIPER_BULLET_3D,
+ COMMAND_GET_NUMBER_OF_SEATS_IN_MODEL,
+ COMMAND_IS_PLAYER_ON_ANY_BIKE,
+ COMMAND_IS_CHAR_LYING_DOWN,
+ COMMAND_CAN_CHAR_SEE_DEAD_CHAR,
+ COMMAND_SET_ENTER_CAR_RANGE_MULTIPLIER,
+}; \ No newline at end of file