summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/control/Cranes.cpp1
-rw-r--r--src/control/Cranes.h1
-rw-r--r--src/control/Garages.cpp1
-rw-r--r--src/control/Garages.h1
-rw-r--r--src/control/PathFind.cpp4
-rw-r--r--src/control/PathFind.h2
-rw-r--r--src/control/Population.cpp1
-rw-r--r--src/control/Population.h2
-rw-r--r--src/control/Record.cpp2
-rw-r--r--src/control/Record.h4
-rw-r--r--src/control/Script.cpp1003
-rw-r--r--src/control/Script.h2
-rw-r--r--src/control/ScriptCommands.h6
-rw-r--r--src/core/Camera.cpp8
-rw-r--r--src/core/Camera.h2
-rw-r--r--src/core/CutsceneMgr.h1
-rw-r--r--src/core/Stats.cpp93
-rw-r--r--src/core/Stats.h32
-rw-r--r--src/core/World.cpp1
-rw-r--r--src/core/World.h1
-rw-r--r--src/core/config.h2
-rw-r--r--src/peds/PedType.h3
-rw-r--r--src/render/SpecialFX.cpp74
-rw-r--r--src/render/SpecialFX.h13
24 files changed, 1225 insertions, 35 deletions
diff --git a/src/control/Cranes.cpp b/src/control/Cranes.cpp
index 0bd4f171..c8d64077 100644
--- a/src/control/Cranes.cpp
+++ b/src/control/Cranes.cpp
@@ -5,6 +5,7 @@
WRAPPER bool CCranes::IsThisCarBeingTargettedByAnyCrane(CVehicle*) { EAXJMP(0x5451E0); }
WRAPPER bool CCranes::IsThisCarBeingCarriedByAnyCrane(CVehicle*) { EAXJMP(0x545190); }
WRAPPER bool CCranes::IsThisCarPickedUp(float, float, CVehicle*) { EAXJMP(0x543940); }
+WRAPPER bool CCranes::HaveAllCarsBeenCollectedByMilitaryCrane() { EAXJMP(0x544BE0); }
WRAPPER void CCranes::ActivateCrane(float, float, float, float, float, float, float, float, bool, bool, float, float) { EAXJMP(0x543650); }
WRAPPER void CCranes::DeActivateCrane(float, float) { EAXJMP(0x543890); }
WRAPPER void CCranes::InitCranes(void) { EAXJMP(0x543360); }
diff --git a/src/control/Cranes.h b/src/control/Cranes.h
index 7e5fd7ce..4625463e 100644
--- a/src/control/Cranes.h
+++ b/src/control/Cranes.h
@@ -9,6 +9,7 @@ public:
static bool IsThisCarBeingTargettedByAnyCrane(CVehicle*);
static bool IsThisCarBeingCarriedByAnyCrane(CVehicle*);
static bool IsThisCarPickedUp(float, float, CVehicle*);
+ static bool HaveAllCarsBeenCollectedByMilitaryCrane();
static void ActivateCrane(float, float, float, float, float, float, float, float, bool, bool, float, float);
static void DeActivateCrane(float, float);
static void InitCranes(void);
diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp
index 10ebd6cb..8270780d 100644
--- a/src/control/Garages.cpp
+++ b/src/control/Garages.cpp
@@ -99,6 +99,7 @@ void CGarages::GivePlayerDetonator()
WRAPPER bool CGarages::HasThisCarBeenCollected(int16 garage, uint8 id) { EAXJMP(0x426D50); }
WRAPPER void CGarages::ChangeGarageType(int16 garage, eGarageType type, int32 mi) { EAXJMP(0x4222A0); }
WRAPPER bool CGarages::HasResprayHappened(int16 garage) { EAXJMP(0x4274F0); }
+WRAPPER bool CGarages::IsThisCarWithinGarageArea(int16 garage, CEntity* pCar) { EAXJMP(0x427570); }
void CGarage::OpenThisGarage()
{
diff --git a/src/control/Garages.h b/src/control/Garages.h
index 8945e311..fe0d1a20 100644
--- a/src/control/Garages.h
+++ b/src/control/Garages.h
@@ -162,6 +162,7 @@ public:
static void SetGarageDoorToRotate(int16);
static bool HasImportExportGarageCollectedThisCar(int16, int8);
static void SetLeaveCameraForThisGarage(int16);
+ static bool IsThisCarWithinGarageArea(int16, CEntity*);
static int GetCarsCollectedIndexForGarageType(eGarageType type) { return type - GARAGE_COLLECTCARS_1; }
};
diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp
index dad879b1..3a959049 100644
--- a/src/control/PathFind.cpp
+++ b/src/control/PathFind.cpp
@@ -893,7 +893,7 @@ CPathFind::MarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2,
}
void
-CPathFind::MarkPedRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2)
+CPathFind::PedMarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2)
{
int i;
@@ -1476,7 +1476,7 @@ STARTPATCHES
InjectHook(0x42DB50, &CPathFind::SwitchRoadsInAngledArea, PATCH_JUMP);
InjectHook(0x42E140, &CPathFind::MarkRoadsBetweenLevelsNodeAndNeighbours, PATCH_JUMP);
InjectHook(0x42DF50, &CPathFind::MarkRoadsBetweenLevelsInArea, PATCH_JUMP);
- InjectHook(0x42E040, &CPathFind::MarkPedRoadsBetweenLevelsInArea, PATCH_JUMP);
+ InjectHook(0x42E040, &CPathFind::PedMarkRoadsBetweenLevelsInArea, PATCH_JUMP);
InjectHook(0x42CC30, &CPathFind::FindNodeClosestToCoors, PATCH_JUMP);
InjectHook(0x42CDC0, &CPathFind::FindNodeClosestToCoorsFavourDirection, PATCH_JUMP);
InjectHook(0x42CFC0, &CPathFind::FindNodeOrientationForCarPlacement, PATCH_JUMP);
diff --git a/src/control/PathFind.h b/src/control/PathFind.h
index 70b431f6..d42b8bb3 100644
--- a/src/control/PathFind.h
+++ b/src/control/PathFind.h
@@ -186,7 +186,7 @@ public:
void SwitchRoadsInAngledArea(float x1, float y1, float z1, float x2, float y2, float z2, float length, uint8 type, uint8 enable);
void MarkRoadsBetweenLevelsNodeAndNeighbours(int32 nodeId);
void MarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2);
- void MarkPedRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2);
+ void PedMarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2);
int32 FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled = false, bool ignoreBetweenLevels = false);
int32 FindNodeClosestToCoorsFavourDirection(CVector coors, uint8 type, float dirX, float dirY);
float FindNodeOrientationForCarPlacement(int32 nodeId);
diff --git a/src/control/Population.cpp b/src/control/Population.cpp
index d7e32dbf..46831d7e 100644
--- a/src/control/Population.cpp
+++ b/src/control/Population.cpp
@@ -38,6 +38,7 @@ WRAPPER void CPopulation::UpdatePedCount(uint32, bool) { EAXJMP(0x4F5A60); }
WRAPPER void CPopulation::DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool) { EAXJMP(0x4F6200); }
WRAPPER CPed *CPopulation::AddPedInCar(CVehicle *vehicle) { EAXJMP(0x4F5800); }
WRAPPER bool CPopulation::IsPointInSafeZone(CVector *coors) { EAXJMP(0x4F60C0); }
+WRAPPER void CPopulation::ConvertToRealObject(CDummyObject* obj) { EAXJMP(0x4F45A0); }
void
CPopulation::Initialise()
diff --git a/src/control/Population.h b/src/control/Population.h
index 572d6f58..d3bc3e39 100644
--- a/src/control/Population.h
+++ b/src/control/Population.h
@@ -4,6 +4,7 @@
class CPed;
class CVehicle;
+class CDummyObject;
struct PedGroup
{
@@ -48,4 +49,5 @@ public:
static bool IsPointInSafeZone(CVector *coors);
static void RemovePed(CEntity* ent);
static int32 ChooseCivilianOccupation(int32);
+ static void ConvertToRealObject(CDummyObject*);
};
diff --git a/src/control/Record.cpp b/src/control/Record.cpp
index 9db9dea1..ab0b478c 100644
--- a/src/control/Record.cpp
+++ b/src/control/Record.cpp
@@ -13,3 +13,5 @@ WRAPPER void CRecordDataForChase::ProcessControlCars(void) { EAXJMP(0x435540); }
WRAPPER void CRecordDataForChase::SaveOrRetrieveCarPositions(void) { EAXJMP(0x434B20); }
WRAPPER void CRecordDataForChase::StartChaseScene(float) { EAXJMP(0x435690); }
WRAPPER void CRecordDataForChase::CleanUpChaseScene() { EAXJMP(0x4357C0); }
+WRAPPER void CRecordDataForChase::RemoveCarFromChase(int32) { EAXJMP(0x435BC0); }
+WRAPPER CVehicle* CRecordDataForChase::TurnChaseCarIntoScriptCar(int32) { EAXJMP(0x435C00); }
diff --git a/src/control/Record.h b/src/control/Record.h
index f36c2fd2..f36c2718 100644
--- a/src/control/Record.h
+++ b/src/control/Record.h
@@ -1,5 +1,7 @@
#pragma once
+class CVehicle;
+
enum {
RECORDSTATE_0,
RECORDSTATE_1,
@@ -16,6 +18,8 @@ public:
static void SaveOrRetrieveCarPositions(void);
static void StartChaseScene(float);
static void CleanUpChaseScene();
+ static void RemoveCarFromChase(int32);
+ static CVehicle* TurnChaseCarIntoScriptCar(int32);
};
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index 148b35dc..a43a86a6 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -15,6 +15,7 @@
#include "CopPed.h"
#include "Coronas.h"
#include "Cranes.h"
+#include "Credits.h"
#include "CutsceneMgr.h"
#include "Darkel.h"
#include "DMAudio.h"
@@ -28,9 +29,11 @@
#include "HandlingMgr.h"
#include "Heli.h"
#include "Hud.h"
+#include "main.h"
#include "Messages.h"
#include "ModelIndices.h"
#include "Pad.h"
+#include "Particle.h"
#include "ParticleObject.h"
#include "PedRoutes.h"
#include "Phones.h"
@@ -71,6 +74,14 @@
#define SPHERE_MARKER_PULSE_PERIOD 2048
#define SPHERE_MARKER_PULSE_FRACTION 0.1f
+#ifdef USE_PRECISE_MEASUREMENT_CONVERTION
+#define METERS_IN_FEET 0.3048f
+#define FEET_IN_METER 3.28084f
+#else
+#define METERS_IN_FEET 0.3f
+#define FEET_IN_METER 3.33f
+#endif
+
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;
@@ -732,10 +743,15 @@ int8 CRunningScript::ProcessOneCommand()
return ProcessCommands800To899(command);
if (command < 1000)
return ProcessCommands900To999(command);
+#ifdef GTA_PS2
+ if (command < 1200)
+ return ProcessCommands1000To1099(command);
+#else
if (command < 1100)
return ProcessCommands1000To1099(command);
if (command < 1200)
return ProcessCommands1100To1199(command);
+#endif
return -1;
}
@@ -8433,339 +8449,1272 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
}
#endif
-#if 1
-WRAPPER int8 CRunningScript::ProcessCommands1000To1099(int32 command) { EAXJMP(0x588490); }
-#else
int8 CRunningScript::ProcessCommands1000To1099(int32 command)
{
- switch (command){
- case COMMAND_FLASH_RADAR_BLIP:
- return 0;
+#ifdef GTA_PS2
+ char tmp[48];
+#endif
+ switch (command) {
+ //case COMMAND_FLASH_RADAR_BLIP:
case COMMAND_IS_CHAR_IN_CONTROL:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ UpdateCompareFlag(pPed->IsPedInControl());
return 0;
+ }
case COMMAND_SET_GENERATE_CARS_AROUND_CAMERA:
+ CollectParameters(&m_nIp, 1);
+ CCarCtrl::bCarsGeneratedAroundCamera = (ScriptParams[0] != 0);
return 0;
case COMMAND_CLEAR_SMALL_PRINTS:
+ CMessages::ClearSmallMessagesOnly();
return 0;
case COMMAND_HAS_MILITARY_CRANE_COLLECTED_ALL_CARS:
+ UpdateCompareFlag(CCranes::HaveAllCarsBeenCollectedByMilitaryCrane());
return 0;
case COMMAND_SET_UPSIDEDOWN_CAR_NOT_DAMAGED:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR);
+ CAutomobile* pCar = (CAutomobile*)pVehicle;
+ pCar->bNotDamagedUpsideDown = (ScriptParams[1] != 0);
return 0;
+ }
case COMMAND_CAN_PLAYER_START_MISSION:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerPed* pPlayerPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ assert(pPlayerPed);
+ UpdateCompareFlag(pPlayerPed->IsPedInControl() || pPlayerPed->m_nPedState == PED_DRIVING);
return 0;
+ }
case COMMAND_MAKE_PLAYER_SAFE_FOR_CUTSCENE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ CPad::GetPad(ScriptParams[0])->DisablePlayerControls |= PLAYERCONTROL_DISABLED_80;
+ pPlayerInfo->MakePlayerSafe(true);
+ CCutsceneMgr::SetRunning(true);
return 0;
+ }
case COMMAND_USE_TEXT_COMMANDS:
+ CollectParameters(&m_nIp, 1);
+ CTheScripts::UseTextCommands = ScriptParams[0] != 0 ? 2 : 1;
return 0;
case COMMAND_SET_THREAT_FOR_PED_TYPE:
+ CollectParameters(&m_nIp, 2);
+ CPedType::AddThreat(ScriptParams[0], ScriptParams[1]);
return 0;
case COMMAND_CLEAR_THREAT_FOR_PED_TYPE:
+ CollectParameters(&m_nIp, 2);
+ CPedType::RemoveThreat(ScriptParams[0], ScriptParams[1]);
return 0;
case COMMAND_GET_CAR_COLOURS:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ ScriptParams[0] = pVehicle->m_currentColour1;
+ ScriptParams[1] = pVehicle->m_currentColour2;
+ StoreParameters(&m_nIp, 2);
return 0;
+ }
case COMMAND_SET_ALL_CARS_CAN_BE_DAMAGED:
+ CollectParameters(&m_nIp, 1);
+ CWorld::SetAllCarsCanBeDamaged(ScriptParams[0] != 0);
+ if (!ScriptParams[0])
+ CWorld::ExtinguishAllCarFiresInArea(FindPlayerCoors(), 4000.0f);
return 0;
case COMMAND_SET_CAR_CAN_BE_DAMAGED:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ pVehicle->bCanBeDamaged = ScriptParams[1] != 0;
+ if (!ScriptParams[1])
+ pVehicle->ExtinguishCarFire();
return 0;
- case COMMAND_MAKE_PLAYER_UNSAFE:
- return 0;
+ }
+ //case COMMAND_MAKE_PLAYER_UNSAFE:
case COMMAND_LOAD_COLLISION:
+ {
+ CollectParameters(&m_nIp, 1);
+ CTimer::Stop();
+ CGame::currLevel = (eLevelName)ScriptParams[0];
+ CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
+ CStreaming::RemoveIslandsNotUsed(CGame::currLevel);
+ CCollision::SortOutCollisionAfterLoad();
+ CStreaming::RequestIslands(CGame::currLevel);
+ CStreaming::LoadAllRequestedModels(true);
+ CTimer::Update();
return 0;
+ }
case COMMAND_GET_BODY_CAST_HEALTH:
+ ScriptParams[0] = CObject::nBodyCastHealth;
+ StoreParameters(&m_nIp, 1);
return 0;
case COMMAND_SET_CHARS_CHATTING:
+ {
+ CollectParameters(&m_nIp, 3);
+ CPed* pPed1 = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ CPed* pPed2 = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ assert(pPed1 && pPed2);
+ pPed1->SetChat(pPed2, ScriptParams[2]);
+ pPed2->SetChat(pPed1, ScriptParams[2]);
return 0;
- case COMMAND_MAKE_PLAYER_SAFE:
- return 0;
+ }
+ //case COMMAND_MAKE_PLAYER_SAFE:
case COMMAND_SET_CAR_STAYS_IN_CURRENT_LEVEL:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ if (ScriptParams[1])
+ pVehicle->m_nZoneLevel = CTheZones::GetLevelFromPosition(pVehicle->GetPosition());
+ else
+ pVehicle->m_nZoneLevel = LEVEL_NONE;
return 0;
+ }
case COMMAND_SET_CHAR_STAYS_IN_CURRENT_LEVEL:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pPed);
+ if (ScriptParams[1])
+ pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(pPed->GetPosition());
+ else
+ pPed->m_nZoneLevel = LEVEL_NONE;
return 0;
+ }
case COMMAND_REGISTER_4X4_ONE_TIME:
+ CollectParameters(&m_nIp, 1);
+ CStats::Register4x4OneTime(ScriptParams[0]);
return 0;
case COMMAND_REGISTER_4X4_TWO_TIME:
+ CollectParameters(&m_nIp, 1);
+ CStats::Register4x4TwoTime(ScriptParams[0]);
return 0;
case COMMAND_REGISTER_4X4_THREE_TIME:
+ CollectParameters(&m_nIp, 1);
+ CStats::Register4x4ThreeTime(ScriptParams[0]);
return 0;
case COMMAND_REGISTER_4X4_MAYHEM_TIME:
+ CollectParameters(&m_nIp, 1);
+ CStats::Register4x4MayhemTime(ScriptParams[0]);
return 0;
case COMMAND_REGISTER_LIFE_SAVED:
+ CStats::AnotherLifeSavedWithAmbulance();
return 0;
case COMMAND_REGISTER_CRIMINAL_CAUGHT:
+ CStats::AnotherCriminalCaught();
return 0;
case COMMAND_REGISTER_AMBULANCE_LEVEL:
+ CollectParameters(&m_nIp, 1);
+ CStats::RegisterLevelAmbulanceMission(ScriptParams[0]);
return 0;
case COMMAND_REGISTER_FIRE_EXTINGUISHED:
+ CStats::AnotherFireExtinguished();
return 0;
case COMMAND_TURN_PHONE_ON:
+ CollectParameters(&m_nIp, 1);
+ gPhoneInfo.m_aPhones[ScriptParams[0]].m_nState = PHONE_STATE_9;
return 0;
case COMMAND_REGISTER_LONGEST_DODO_FLIGHT:
+ CollectParameters(&m_nIp, 1);
+ CStats::RegisterLongestFlightInDodo(ScriptParams[0]);
return 0;
case COMMAND_REGISTER_DEFUSE_BOMB_TIME:
+ CollectParameters(&m_nIp, 1);
+ CStats::RegisterTimeTakenDefuseMission(ScriptParams[0]);
return 0;
case COMMAND_SET_TOTAL_NUMBER_OF_KILL_FRENZIES:
+ CollectParameters(&m_nIp, 1);
+ CStats::SetTotalNumberKillFrenzies(ScriptParams[0]);
return 0;
case COMMAND_BLOW_UP_RC_BUGGY:
+ CWorld::Players[CWorld::PlayerInFocus].BlowUpRCBuggy();
return 0;
case COMMAND_REMOVE_CAR_FROM_CHASE:
+ CollectParameters(&m_nIp, 1);
+ CRecordDataForChase::RemoveCarFromChase(ScriptParams[0]);
return 0;
case COMMAND_IS_FRENCH_GAME:
+ UpdateCompareFlag(CGame::frenchGame);
return 0;
case COMMAND_IS_GERMAN_GAME:
+ UpdateCompareFlag(CGame::germanGame);
return 0;
case COMMAND_CLEAR_MISSION_AUDIO:
+ DMAudio.ClearMissionAudio();
return 0;
case COMMAND_SET_FADE_IN_AFTER_NEXT_ARREST:
+ CollectParameters(&m_nIp, 1);
+ CRestart::bFadeInAfterNextArrest = !!ScriptParams[0];
return 0;
case COMMAND_SET_FADE_IN_AFTER_NEXT_DEATH:
+ CollectParameters(&m_nIp, 1);
+ CRestart::bFadeInAfterNextDeath = !!ScriptParams[0];
return 0;
case COMMAND_SET_GANG_PED_MODEL_PREFERENCE:
+ CollectParameters(&m_nIp, 2);
+ CGangs::SetGangPedModelOverride(ScriptParams[0], ScriptParams[1]);
return 0;
case COMMAND_SET_CHAR_USE_PEDNODE_SEEK:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pPed);
+ if (ScriptParams[1])
+ pPed->m_pNextPathNode = nil;
+ pPed->bUsePedNodeSeek = !!ScriptParams[1];
return 0;
+ }
case COMMAND_SWITCH_VEHICLE_WEAPONS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ pVehicle->bGunSwitchedOff = !ScriptParams[1];
return 0;
+ }
case COMMAND_SET_GET_OUT_OF_JAIL_FREE:
+ CollectParameters(&m_nIp, 2);
+ CWorld::Players[ScriptParams[0]].m_bGetOutOfJailFree = !!ScriptParams[1];
return 0;
case COMMAND_SET_FREE_HEALTH_CARE:
+ CollectParameters(&m_nIp, 2);
+ CWorld::Players[ScriptParams[0]].m_bGetOutOfHospitalFree = !!ScriptParams[1];
return 0;
case COMMAND_IS_CAR_DOOR_CLOSED:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ UpdateCompareFlag(!pVehicle->IsDoorMissing((eDoors)ScriptParams[1]) && pVehicle->IsDoorClosed((eDoors)ScriptParams[1]));
return 0;
+ }
case COMMAND_LOAD_AND_LAUNCH_MISSION:
return 0;
case COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL:
+ {
+ CollectParameters(&m_nIp, 1);
+ CTimer::Suspend();
+ int offset = CTheScripts::MultiScriptArray[ScriptParams[0]];
+ CFileMgr::ChangeDir("\\");
+ int handle = CFileMgr::OpenFile("data\\main.scm", "rb");
+ CFileMgr::Seek(handle, offset, 0);
+ CFileMgr::Read(handle, (const char*)&CTheScripts::ScriptSpace[SIZE_MAIN_SCRIPT], SIZE_MISSION_SCRIPT);
+ CFileMgr::CloseFile(handle);
+ CRunningScript* pMissionScript = CTheScripts::StartNewScript(SIZE_MAIN_SCRIPT);
+ CTimer::Resume();
+ pMissionScript->m_bIsMissionScript = true;
+ pMissionScript->m_bMissionFlag = true;
return 0;
+ }
case COMMAND_SET_OBJECT_DRAW_LAST:
+ {
+ CollectParameters(&m_nIp, 2);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ assert(pObject);
+ pObject->bDrawLast = !!ScriptParams[1];
return 0;
+ }
case COMMAND_GET_AMMO_IN_PLAYER_WEAPON:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ assert(pPed);
+ CWeapon* pWeaponSlot = &pPed->m_weapons[ScriptParams[1]];
+ if (pWeaponSlot->m_eWeaponType == (eWeaponType)ScriptParams[1])
+ ScriptParams[0] = pWeaponSlot->m_nAmmoTotal;
+ else
+ ScriptParams[0] = 0;
+ StoreParameters(&m_nIp, 1);
return 0;
+ }
case COMMAND_GET_AMMO_IN_CHAR_WEAPON:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pPed);
+ CWeapon* pWeaponSlot = &pPed->m_weapons[ScriptParams[1]];
+ if (pWeaponSlot->m_eWeaponType == (eWeaponType)ScriptParams[1])
+ ScriptParams[0] = pWeaponSlot->m_nAmmoTotal;
+ else
+ ScriptParams[0] = 0;
+ StoreParameters(&m_nIp, 1);
return 0;
+ }
case COMMAND_REGISTER_KILL_FRENZY_PASSED:
+ CStats::AnotherKillFrenzyPassed();
return 0;
case COMMAND_SET_CHAR_SAY:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ switch (ScriptParams[1]) {
+ case SCRIPT_SOUND_CHUNKY_RUN_SHOUT:
+ pPed->Say(SOUND_PED_FLEE_RUN);
+ break;
+ case SCRIPT_SOUND_SECURITY_GUARD_AWAY_SHOUT:
+ pPed->Say(SOUND_PED_FLEE_RUN);
+ break;
+ case SCRIPT_SOUND_SWAT_PED_SHOUT:
+ pPed->Say(SOUND_PED_PURSUIT_SWAT);
+ break;
+ case SCRIPT_SOUND_AMMUNATION_CHAT_1:
+ pPed->Say(SOUND_AMMUNATION_WELCOME_1);
+ break;
+ case SCRIPT_SOUND_AMMUNATION_CHAT_2:
+ pPed->Say(SOUND_AMMUNATION_WELCOME_2);
+ break;
+ case SCRIPT_SOUND_AMMUNATION_CHAT_3:
+ pPed->Say(SOUND_AMMUNATION_WELCOME_3);
+ break;
+ default:
+ break;
+ }
return 0;
+ }
case COMMAND_SET_NEAR_CLIP:
+ CollectParameters(&m_nIp, 1);
+ TheCamera.SetNearClipScript(*(float*)&ScriptParams[0]);
return 0;
case COMMAND_SET_RADIO_CHANNEL:
+ CollectParameters(&m_nIp, 2);
+ DMAudio.SetRadioChannel(ScriptParams[0], ScriptParams[1]);
return 0;
case COMMAND_OVERRIDE_HOSPITAL_LEVEL:
+ CollectParameters(&m_nIp, 1);
+ CRestart::OverrideHospitalLevel = ScriptParams[0];
return 0;
case COMMAND_OVERRIDE_POLICE_STATION_LEVEL:
+ CollectParameters(&m_nIp, 1);
+ CRestart::OverridePoliceStationLevel = ScriptParams[0];
return 0;
case COMMAND_FORCE_RAIN:
+ CollectParameters(&m_nIp, 1);
+ CWeather::bScriptsForceRain = !!ScriptParams[0];
return 0;
case COMMAND_DOES_GARAGE_CONTAIN_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ assert(pVehicle);
+ UpdateCompareFlag(CGarages::IsThisCarWithinGarageArea(ScriptParams[0], pVehicle));
return 0;
+ }
case COMMAND_SET_CAR_TRACTION:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ float fTraction = *(float*)&ScriptParams[1];
+ assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR || pVehicle->m_vehType == VEHICLE_TYPE_BIKE);
+ if (pVehicle->m_vehType == VEHICLE_TYPE_CAR)
+ ((CAutomobile*)pVehicle)->m_fTraction = fTraction;
+ else
+ // this is certainly not a boat, trane, heli or plane field
+ //((CBike*)pVehicle)->m_fTraction = fTraction;
+ *(float*)(((char*)pVehicle) + 1088) = fTraction;
return 0;
+ }
case COMMAND_ARE_MEASUREMENTS_IN_METRES:
+#ifdef USE_MEASUREMENTS_IN_METERS
+ UpdateCompareFlag(true);
+#else
+ UpdateCompareFlag(false)
+#endif
return 0;
case COMMAND_CONVERT_METRES_TO_FEET:
+ {
+ CollectParameters(&m_nIp, 1);
+ float fMeterValue = *(float*)&ScriptParams[0];
+ float fFeetValue = fMeterValue / METERS_IN_FEET;
+ *(float*)&ScriptParams[0] = fFeetValue;
+ StoreParameters(&m_nIp, 1);
return 0;
+ }
case COMMAND_MARK_ROADS_BETWEEN_LEVELS:
+ {
+ CollectParameters(&m_nIp, 6);
+ float infX = *(float*)&ScriptParams[0];
+ float infY = *(float*)&ScriptParams[1];
+ float infZ = *(float*)&ScriptParams[2];
+ float supX = *(float*)&ScriptParams[3];
+ float supY = *(float*)&ScriptParams[4];
+ float supZ = *(float*)&ScriptParams[5];
+ if (infX > supX) {
+ infX = *(float*)&ScriptParams[3];
+ supX = *(float*)&ScriptParams[0];
+ }
+ if (infY > supY) {
+ infY = *(float*)&ScriptParams[4];
+ supY = *(float*)&ScriptParams[1];
+ }
+ if (infZ > supZ) {
+ infZ = *(float*)&ScriptParams[5];
+ supZ = *(float*)&ScriptParams[2];
+ }
+ ThePaths.MarkRoadsBetweenLevelsInArea(infX, supX, infY, supY, infZ, supZ);
return 0;
+ }
case COMMAND_MARK_PED_ROADS_BETWEEN_LEVELS:
+ {
+ CollectParameters(&m_nIp, 6);
+ float infX = *(float*)&ScriptParams[0];
+ float infY = *(float*)&ScriptParams[1];
+ float infZ = *(float*)&ScriptParams[2];
+ float supX = *(float*)&ScriptParams[3];
+ float supY = *(float*)&ScriptParams[4];
+ float supZ = *(float*)&ScriptParams[5];
+ if (infX > supX) {
+ infX = *(float*)&ScriptParams[3];
+ supX = *(float*)&ScriptParams[0];
+ }
+ if (infY > supY) {
+ infY = *(float*)&ScriptParams[4];
+ supY = *(float*)&ScriptParams[1];
+ }
+ if (infZ > supZ) {
+ infZ = *(float*)&ScriptParams[5];
+ supZ = *(float*)&ScriptParams[2];
+ }
+ ThePaths.PedMarkRoadsBetweenLevelsInArea(infX, supX, infY, supY, infZ, supZ);
return 0;
+ }
case COMMAND_SET_CAR_AVOID_LEVEL_TRANSITIONS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ pVehicle->AutoPilot.m_bStayInCurrentLevel = !!ScriptParams[1];
return 0;
+ }
case COMMAND_SET_CHAR_AVOID_LEVEL_TRANSITIONS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ assert(pPed);
+ // not implemented
return 0;
+ }
case COMMAND_IS_THREAT_FOR_PED_TYPE:
+ CollectParameters(&m_nIp, 2);
+ UpdateCompareFlag(CPedType::IsThreat(ScriptParams[0], ScriptParams[1]));
return 0;
case COMMAND_CLEAR_AREA_OF_CHARS:
+ {
+ CollectParameters(&m_nIp, 6);
+ float infX = *(float*)&ScriptParams[0];
+ float infY = *(float*)&ScriptParams[1];
+ float infZ = *(float*)&ScriptParams[2];
+ float supX = *(float*)&ScriptParams[3];
+ float supY = *(float*)&ScriptParams[4];
+ float supZ = *(float*)&ScriptParams[5];
+ if (infX > supX) {
+ infX = *(float*)&ScriptParams[3];
+ supX = *(float*)&ScriptParams[0];
+ }
+ if (infY > supY) {
+ infY = *(float*)&ScriptParams[4];
+ supY = *(float*)&ScriptParams[1];
+ }
+ if (infZ > supZ) {
+ infZ = *(float*)&ScriptParams[5];
+ supZ = *(float*)&ScriptParams[2];
+ }
+ CWorld::ClearPedsFromArea(infX, infY, infZ, supX, supY, supZ);
return 0;
+ }
case COMMAND_SET_TOTAL_NUMBER_OF_MISSIONS:
+ CollectParameters(&m_nIp, 1);
+ CStats::SetTotalNumberMissions(ScriptParams[0]);
return 0;
case COMMAND_CONVERT_METRES_TO_FEET_INT:
+ CollectParameters(&m_nIp, 1);
+ ScriptParams[0] *= FEET_IN_METER;
+ StoreParameters(&m_nIp, 1);
return 0;
case COMMAND_REGISTER_FASTEST_TIME:
+ CollectParameters(&m_nIp, 2);
+ CStats::RegisterFastestTime(ScriptParams[0], ScriptParams[1]);
return 0;
case COMMAND_REGISTER_HIGHEST_SCORE:
+ CollectParameters(&m_nIp, 2);
+ CStats::RegisterHighestScore(ScriptParams[0], ScriptParams[1]);
return 0;
- case COMMAND_WARP_CHAR_INTO_CAR_AS_PASSENGER:
- return 0;
- case COMMAND_IS_CAR_PASSENGER_SEAT_FREE:
- return 0;
+ //case COMMAND_WARP_CHAR_INTO_CAR_AS_PASSENGER:
+ //case COMMAND_IS_CAR_PASSENGER_SEAT_FREE:
case COMMAND_GET_CHAR_IN_CAR_PASSENGER_SEAT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ assert(ScriptParams[1] >= 0 && ScriptParams[1] < 8);
+ CPed* pPassenger = pVehicle->pPassengers[ScriptParams[1]];
+ ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPassenger);
+ StoreParameters(&m_nIp, 1);
return 0;
+ }
case COMMAND_SET_CHAR_IS_CHRIS_CRIMINAL:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pPed);
+ pPed->bChrisCriminal = !!ScriptParams[1];
return 0;
+ }
case COMMAND_START_CREDITS:
+ CCredits::Start();
return 0;
case COMMAND_STOP_CREDITS:
+ CCredits::Stop();
return 0;
case COMMAND_ARE_CREDITS_FINISHED:
+ UpdateCompareFlag(CCredits::AreCreditsDone());
return 0;
case COMMAND_CREATE_SINGLE_PARTICLE:
+ CParticle::AddParticle((tParticleType)ScriptParams[0], *(CVector*)&ScriptParams[1],
+ *(CVector*)&ScriptParams[4], nil, *(float*)&ScriptParams[7], 0, 0, 0, 0);
return 0;
case COMMAND_SET_CHAR_IGNORE_LEVEL_TRANSITIONS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pPed);
+ if (ScriptParams[1])
+ pPed->m_nZoneLevel = -1;
+ else
+ pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(pPed->GetPosition());
return 0;
+ }
case COMMAND_GET_CHASE_CAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CRecordDataForChase::TurnChaseCarIntoScriptCar(ScriptParams[0]);
+ ScriptParams[0] = CPools::GetVehiclePool()->GetIndex(pVehicle);
+ StoreParameters(&m_nIp, 1);
+ if (m_bIsMissionScript)
+ CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CAR);
return 0;
+ }
case COMMAND_START_BOAT_FOAM_ANIMATION:
+ CSpecialParticleStuff::StartBoatFoamAnimation();
return 0;
case COMMAND_UPDATE_BOAT_FOAM_ANIMATION:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle->m_vehType == VEHICLE_TYPE_BOAT);
+ CSpecialParticleStuff::UpdateBoatFoamAnimation(&pVehicle->GetMatrix());
return 0;
+ }
case COMMAND_SET_MUSIC_DOES_FADE:
+ CollectParameters(&m_nIp, 1);
+ TheCamera.m_bMusicFading = (ScriptParams[0] == 0);
return 0;
case COMMAND_SET_INTRO_IS_PLAYING:
+ CollectParameters(&m_nIp, 1);
+ if (ScriptParams[0]) {
+ CGame::playingIntro = true;
+ CStreaming::RemoveCurrentZonesModels();
+ } else {
+ CGame::playingIntro = false;
+ DMAudio.ChangeMusicMode(MUSICMODE_GAME);
+ int mi;
+ CModelInfo::GetModelInfo("bridgefukb", &mi);
+ CStreaming::RequestModel(mi, STREAMFLAGS_DEPENDENCY);
+ CStreaming::LoadAllRequestedModels(false);
+ }
return 0;
case COMMAND_SET_PLAYER_HOOKER:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ if (ScriptParams[1] < 0) {
+ pPlayerInfo->m_pHooker = nil;
+ pPlayerInfo->m_nNextSexFrequencyUpdateTime = 0;
+ pPlayerInfo->m_nNextSexMoneyUpdateTime = 0;
+ } else {
+ CPed* pHooker = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ assert(pHooker);
+ pPlayerInfo->m_pHooker = (CCivilianPed*)pHooker;
+ pPlayerInfo->m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 1000;
+ pPlayerInfo->m_nNextSexMoneyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000;
+ }
return 0;
+ }
case COMMAND_PLAY_END_OF_GAME_TUNE:
+ DMAudio.PlayPreloadedCutSceneMusic();
return 0;
case COMMAND_STOP_END_OF_GAME_TUNE:
+ DMAudio.StopCutSceneMusic();
+ DMAudio.ChangeMusicMode(MUSICMODE_GAME);
return 0;
case COMMAND_GET_CAR_MODEL:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ ScriptParams[0] = pVehicle->GetModelIndex();
+ StoreParameters(&m_nIp, 1);
return 0;
+ }
case COMMAND_IS_PLAYER_SITTING_IN_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ assert(pPed);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ assert(pVehicle);
+ UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_pMyVehicle == pVehicle);
return 0;
+ }
case COMMAND_IS_PLAYER_SITTING_IN_ANY_CAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ assert(pPed);
+ UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING);
return 0;
+ }
case COMMAND_SET_SCRIPT_FIRE_AUDIO:
+ CollectParameters(&m_nIp, 2);
+ gFireManager.SetScriptFireAudio(ScriptParams[0], !!ScriptParams[1]);
return 0;
case COMMAND_ARE_ANY_CAR_CHEATS_ACTIVATED:
+ UpdateCompareFlag(CVehicle::bAllDodosCheat || CVehicle::bCheat3);
return 0;
case COMMAND_SET_CHAR_SUFFERS_CRITICAL_HITS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pPed);
+ pPed->bNoCriticalHits = (ScriptParams[0] == 0);
return 0;
+ }
case COMMAND_IS_PLAYER_LIFTING_A_PHONE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ assert(pPed);
+ UpdateCompareFlag(pPed->GetPedState() == PED_MAKE_CALL);
return 0;
+ }
case COMMAND_IS_CHAR_SITTING_IN_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pPed);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ assert(pVehicle);
+ UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_pMyVehicle == pVehicle);
return 0;
+ }
case COMMAND_IS_CHAR_SITTING_IN_ANY_CAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pPed);
+ UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING);
return 0;
+ }
case COMMAND_IS_PLAYER_ON_FOOT:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ assert(pPed);
+ UpdateCompareFlag(!pPed->bInVehicle && pPed->m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER &&
+ pPed->m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER);
return 0;
+ }
case COMMAND_IS_CHAR_ON_FOOT:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pPed);
+ UpdateCompareFlag(!pPed->bInVehicle && pPed->m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER &&
+ pPed->m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER);
return 0;
+ }
+#ifndef GTA_PS2
default:
assert(0);
}
return -1;
}
-#endif
-#if 1
-WRAPPER int8 CRunningScript::ProcessCommands1100To1199(int32 command) { EAXJMP(0x589D00); }
-#else
int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
+ char tmp[48];
switch (command) {
+#endif
case COMMAND_LOAD_COLLISION_WITH_SCREEN:
+ CollectParameters(&m_nIp, 1);
+ CTimer::Stop();
+ CGame::currLevel = (eLevelName)ScriptParams[0];
+ if (CGame::currLevel != CCollision::ms_collisionInMemory) {
+ DMAudio.SetEffectsFadeVol(0);
+ CPad::StopPadsShaking();
+ CCollision::LoadCollisionScreen(CGame::currLevel);
+ DMAudio.Service();
+ CPopulation::DealWithZoneChange(CCollision::ms_collisionInMemory, CGame::currLevel, false);
+ CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
+ CStreaming::RemoveIslandsNotUsed(CGame::currLevel);
+ CCollision::SortOutCollisionAfterLoad();
+ CStreaming::RequestIslands(CGame::currLevel);
+ CStreaming::RequestBigBuildings(CGame::currLevel);
+ CStreaming::LoadAllRequestedModels(true);
+ DMAudio.SetEffectsFadeVol(127);
+ }
+ CTimer::Update();
return 0;
case COMMAND_LOAD_SPLASH_SCREEN:
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, tmp);
+ for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
+ tmp[i] = tolower(tmp[i]);
+ m_nIp += 8;
+ LoadSplash(tmp);
return 0;
case COMMAND_SET_CAR_IGNORE_LEVEL_TRANSITIONS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ if (ScriptParams[1])
+ pVehicle->m_nZoneLevel = -1;
+ else
+ pVehicle->m_nZoneLevel = CTheZones::GetLevelFromPosition(pVehicle->GetPosition());
return 0;
+ }
case COMMAND_MAKE_CRAIGS_CAR_A_BIT_STRONGER:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR);
+ CAutomobile* pCar = (CAutomobile*)pVehicle;
+ pCar->bTakeLessDamage = ScriptParams[1];
return 0;
+ }
case COMMAND_SET_JAMES_CAR_ON_PATH_TO_PLAYER:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ CCarCtrl::JoinCarWithRoadSystemGotoCoors(pVehicle, FindPlayerCoors(), false);
return 0;
+ }
case COMMAND_LOAD_END_OF_GAME_TUNE:
+ printf("Start preload end of game audio\n");
+ DMAudio.PreloadCutSceneMusic(STREAMED_SOUND_GAME_COMPLETED);
+ printf("End preload end of game audio\n");
return 0;
case COMMAND_ENABLE_PLAYER_CONTROL_CAMERA:
+ CPad::GetPad(0)->DisablePlayerControls &= PLAYERCONTROL_DISABLED_1;
return 0;
+#ifndef GTA_PS2
+ // To be precise, on PS2 previous handlers were in 1000-1099 function
+ // These are "beta" VC commands (with bugs)
case COMMAND_SET_OBJECT_ROTATION:
+ {
+ CollectParameters(&m_nIp, 4);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ assert(pObject);
+ CWorld::Remove(pObject);
+ pObject->SetOrientation(
+ DEGTORAD(*(float*)&ScriptParams[1]),
+ DEGTORAD(*(float*)&ScriptParams[2]),
+ DEGTORAD(*(float*)&ScriptParams[3]));
+ pObject->GetMatrix().UpdateRW();
+ pObject->UpdateRwFrame();
+ CWorld::Add(pObject);
return 0;
+ }
case COMMAND_GET_DEBUG_CAMERA_COORDINATES:
+ *(CVector*)&ScriptParams[0] = TheCamera.Cams[2].Source;
+ StoreParameters(&m_nIp, 3);
return 0;
case COMMAND_GET_DEBUG_CAMERA_FRONT_VECTOR:
+ *(CVector*)&ScriptParams[0] = TheCamera.Cams[2].Front;
+ StoreParameters(&m_nIp, 3);
return 0;
case COMMAND_IS_PLAYER_TARGETTING_ANY_CHAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ assert(pPed);
+ CEntity* pTarget = pPed->m_pPointGunAt;
+ UpdateCompareFlag(pTarget && pTarget->IsPed());
return 0;
+ }
case COMMAND_IS_PLAYER_TARGETTING_CHAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ assert(pPed);
+ CPed* pTestedPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ assert(pTestedPed);
+ CEntity* pTarget = pPed->m_pPointGunAt;
+ UpdateCompareFlag(pTarget && pTarget->IsPed() && pTarget == pTestedPed);
return 0;
+ }
case COMMAND_IS_PLAYER_TARGETTING_OBJECT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ assert(pPed);
+ CObject* pTestedObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+ assert(pTestedObject);
+ CEntity* pTarget = pPed->m_pPointGunAt;
+ UpdateCompareFlag(pTarget && pTarget->IsObject() && pTarget == pTestedObject);
return 0;
+ }
case COMMAND_TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME:
+ {
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, tmp);
+ for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
+ tmp[i] = tolower(tmp[i]);
+ m_nIp += 8;
+ CRunningScript* pScript = CTheScripts::pActiveScripts;
+ while (pScript) {
+ CRunningScript* pNext = pScript->next;
+ if (strcmp(pScript->m_abScriptName, tmp) == 0) {
+ pScript->RemoveScriptFromList(&CTheScripts::pActiveScripts);
+ pScript->AddScriptToList(&CTheScripts::pIdleScripts);
+ }
+ pScript = pNext;
+ }
return 0;
+ }
case COMMAND_DISPLAY_TEXT_WITH_NUMBER:
+ {
+ CollectParameters(&m_nIp, 2);
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtX = *(float*)&ScriptParams[0];
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtY = *(float*)&ScriptParams[1];
+ CollectParameters(&m_nIp, 1);
+ CMessages::InsertNumberInString(text, ScriptParams[0], -1, -1, -1, -1, -1,
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame++].m_Text);
return 0;
+ }
case COMMAND_DISPLAY_TEXT_WITH_2_NUMBERS:
+ {
+ CollectParameters(&m_nIp, 2);
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtX = *(float*)&ScriptParams[0];
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtY = *(float*)&ScriptParams[1];
+ CollectParameters(&m_nIp, 2);
+ CMessages::InsertNumberInString(text, ScriptParams[0], ScriptParams[1], -1, -1, -1, -1,
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame++].m_Text);
return 0;
+ }
case COMMAND_FAIL_CURRENT_MISSION:
+ CTheScripts::FailCurrentMission = 2;
return 0;
case COMMAND_GET_CLOSEST_OBJECT_OF_TYPE:
+ {
+ CollectParameters(&m_nIp, 5);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= -100.0f)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ float range = *(float*)&ScriptParams[3];
+ int mi = ScriptParams[4] < 0 ? CTheScripts::UsedObjectArray[-ScriptParams[4]].index : ScriptParams[4];
+ int16 total;
+ CEntity* apEntities[16];
+ CWorld::FindObjectsOfTypeInRange(mi, pos, range, true, &total, 16, apEntities, false, false, false, true, true);
+ CEntity* pClosestEntity = nil;
+ float min_dist = 2.0f * range;
+ for (int i = 0; i < total; i++) {
+ float dist = (apEntities[i]->GetPosition() - pos).Magnitude();
+ if (dist < min_dist) {
+ min_dist = dist;
+ pClosestEntity = apEntities[i];
+ }
+ }
+ if (pClosestEntity && pClosestEntity->IsDummy()) {
+ CPopulation::ConvertToRealObject((CDummyObject*)pClosestEntity);
+ CWorld::FindObjectsOfTypeInRange(mi, pos, range, true, &total, 16, apEntities, false, false, false, true, true);
+ pClosestEntity = nil;
+ float min_dist = 2.0f * range;
+ for (int i = 0; i < total; i++) {
+ float dist = (apEntities[i]->GetPosition() - pos).Magnitude();
+ if (dist < min_dist) {
+ min_dist = dist;
+ pClosestEntity = apEntities[i];
+ }
+ }
+ if (pClosestEntity->IsDummy())
+ pClosestEntity = nil;
+ }
+ if (pClosestEntity) {
+ assert(pClosestEntity->IsObject());
+ CObject* pObject = (CObject*)pClosestEntity;
+ pObject->ObjectCreatedBy = MISSION_OBJECT;
+ ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pObject);
+ } else {
+ ScriptParams[0] = -1;
+ }
+ StoreParameters(&m_nIp, 1);
return 0;
+ }
case COMMAND_PLACE_OBJECT_RELATIVE_TO_OBJECT:
+ {
+ CollectParameters(&m_nIp, 5);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ assert(pObject);
+ CObject* pTarget = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+ assert(pTarget);
+ CVector offset = *(CVector*)&ScriptParams[2];
+ CPhysical::PlacePhysicalRelativeToOtherPhysical(pTarget, pObject, offset);
return 0;
+ }
case COMMAND_SET_ALL_OCCUPANTS_OF_CAR_LEAVE_CAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ if (pVehicle->pDriver) {
+ pVehicle->pDriver->bScriptObjectiveCompleted = false;
+ pVehicle->pDriver->SetObjective(OBJECTIVE_LEAVE_VEHICLE, pVehicle);
+ }
+ for (int i = 0; i < 8; i++)
+ {
+ if (pVehicle->pPassengers[i]) {
+ pVehicle->pPassengers[i]->bScriptObjectiveCompleted = false;
+ pVehicle->pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_VEHICLE, pVehicle);
+ }
+ }
return 0;
+ }
case COMMAND_SET_INTERPOLATION_PARAMETERS:
+ CollectParameters(&m_nIp, 2);
+ TheCamera.SetParametersForScriptInterpolation(*(float*)&ScriptParams[0], 50.0f - *(float*)&ScriptParams[0], ScriptParams[1]);
return 0;
case COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_TOWARDS_POINT:
+ {
+ CollectParameters(&m_nIp, 5);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= -100.0f)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ float destX = *(float*)&ScriptParams[3];
+ float destY = *(float*)&ScriptParams[4];
+ int32 nid = ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f, true, true);
+ CPathNode* pNode = &ThePaths.m_pathNodes[nid];
+ *(CVector*)&ScriptParams[0] = pNode->pos;
+ *(float*)&ScriptParams[3] = ThePaths.FindNodeOrientationForCarPlacementFacingDestination(nid, destX, destY, true);
+ StoreParameters(&m_nIp, 4);
return 0;
+ }
case COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_AWAY_POINT:
+ {
+ CollectParameters(&m_nIp, 5);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= -100.0f)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ float destX = *(float*)&ScriptParams[3];
+ float destY = *(float*)&ScriptParams[4];
+ int32 nid = ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f, true, true);
+ CPathNode* pNode = &ThePaths.m_pathNodes[nid];
+ *(CVector*)&ScriptParams[0] = pNode->pos;
+ *(float*)&ScriptParams[3] = ThePaths.FindNodeOrientationForCarPlacementFacingDestination(nid, destX, destY, false);
+ StoreParameters(&m_nIp, 4);
return 0;
+ }
case COMMAND_GET_DEBUG_CAMERA_POINT_AT:
+ *(CVector*)&ScriptParams[0] = TheCamera.Cams[2].Source + TheCamera.Cams[2].Front;
+ StoreParameters(&m_nIp, 3);
return 0;
case COMMAND_ATTACH_CHAR_TO_CAR:
+ // empty implementation
return 0;
case COMMAND_DETACH_CHAR_FROM_CAR:
+ // empty implementation
return 0;
- case COMMAND_SET_CAR_STAY_IN_FAST_LANE:
+ case COMMAND_SET_CAR_CHANGE_LANE: // for some reason changed in SA
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ pVehicle->AutoPilot.m_bStayInFastLane = !ScriptParams[1];
return 0;
+ }
case COMMAND_CLEAR_CHAR_LAST_WEAPON_DAMAGE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pPed);
+ pPed->m_lastWepDam = -1;
return 0;
+ }
case COMMAND_CLEAR_CAR_LAST_WEAPON_DAMAGE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ pVehicle->m_nLastWeaponDamage = -1;
return 0;
+ }
case COMMAND_GET_RANDOM_COP_IN_AREA:
+ {
+ CollectParameters(&m_nIp, 4);
+ int ped_handle = -1;
+ CVector pos = FindPlayerCoors();
+ float x1 = *(float*)&ScriptParams[0];
+ float y1 = *(float*)&ScriptParams[1];
+ float x2 = *(float*)&ScriptParams[2];
+ float y2 = *(float*)&ScriptParams[3];
+ int i = CPools::GetPedPool()->GetSize();
+ while (--i && ped_handle == -1) {
+ CPed* pPed = CPools::GetPedPool()->GetSlot(i);
+ if (!pPed)
+ continue;
+ if (CTheScripts::LastRandomPedId == CPools::GetPedPool()->GetIndex(pPed))
+ continue;
+ if (pPed->m_nPedType != PEDTYPE_COP)
+ continue;
+ if (pPed->CharCreatedBy != RANDOM_CHAR)
+ continue;
+ if (!pPed->IsPedInControl() && pPed->GetPedState() != PED_DRIVING)
+ continue;
+ if (pPed->bRemoveFromWorld)
+ continue;
+ if (pPed->bFadeOut)
+ continue;
+ if (pPed->bIsLeader || pPed->m_leader)
+ continue;
+ if (!pPed->IsWithinArea(x1, y1, x2, y2))
+ continue;
+ if (pos.z - PED_FIND_Z_OFFSET > pPed->GetPosition().z)
+ continue;
+ if (pos.z + PED_FIND_Z_OFFSET < pPed->GetPosition().z)
+ continue;
+ ped_handle = CPools::GetPedPool()->GetIndex(pPed);
+ CTheScripts::LastRandomPedId = ped_handle;
+ pPed->CharCreatedBy = MISSION_CHAR;
+ pPed->bRespondsToThreats = false;
+ ++CPopulation::ms_nTotalMissionPeds;
+ if (m_bIsMissionScript)
+ CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR);
+ }
+ ScriptParams[0] = ped_handle;
+ StoreParameters(&m_nIp, 1);
return 0;
+ }
case COMMAND_GET_RANDOM_COP_IN_ZONE:
+ {
+ char zone[KEY_LENGTH_IN_SCRIPT];
+ strncpy(zone, (const char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
+ int nZone = CTheZones::FindZoneByLabelAndReturnIndex(zone);
+ if (nZone != -1)
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ CZone* pZone = CTheZones::GetZone(nZone);
+ int ped_handle = -1;
+ CVector pos = FindPlayerCoors();
+ int i = CPools::GetPedPool()->GetSize();
+ while (--i && ped_handle == -1) {
+ CPed* pPed = CPools::GetPedPool()->GetSlot(i);
+ if (!pPed)
+ continue;
+ if (CTheScripts::LastRandomPedId == CPools::GetPedPool()->GetIndex(pPed))
+ continue;
+ if (pPed->m_nPedType != PEDTYPE_COP)
+ continue;
+ if (pPed->CharCreatedBy != RANDOM_CHAR)
+ continue;
+ if (!pPed->IsPedInControl() && pPed->GetPedState() != PED_DRIVING)
+ continue;
+ if (pPed->bRemoveFromWorld)
+ continue;
+ if (pPed->bFadeOut)
+ continue;
+ if (pPed->bIsLeader || pPed->m_leader)
+ continue;
+ if (!CTheZones::PointLiesWithinZone(pPed->GetPosition(), pZone))
+ continue;
+ if (pos.z - PED_FIND_Z_OFFSET > pPed->GetPosition().z)
+ continue;
+ if (pos.z + PED_FIND_Z_OFFSET < pPed->GetPosition().z)
+ continue;
+ ped_handle = CPools::GetPedPool()->GetIndex(pPed);
+ CTheScripts::LastRandomPedId = ped_handle;
+ pPed->CharCreatedBy = MISSION_CHAR;
+ pPed->bRespondsToThreats = false;
+ ++CPopulation::ms_nTotalMissionPeds;
+ if (m_bIsMissionScript)
+ CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR);
+ }
+ ScriptParams[0] = ped_handle;
+ StoreParameters(&m_nIp, 1);
return 0;
+ }
case COMMAND_SET_CHAR_OBJ_FLEE_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pPed);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ assert(pVehicle);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_FLEE_CAR, pVehicle);
return 0;
+ }
case COMMAND_GET_DRIVER_OF_CAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ CPed* pDriver = pVehicle->pDriver;
+ if (pDriver)
+ ScriptParams[0] = CPools::GetPedPool()->GetIndex(pDriver);
+ else
+ ScriptParams[0] = -1;
+ StoreParameters(&m_nIp, 1);
return 0;
+ }
case COMMAND_GET_NUMBER_OF_FOLLOWERS:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pLeader = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pLeader);
+ int total = 0;
+ int i = CPools::GetPedPool()->GetSize();
+ while (--i) {
+ CPed* pPed = CPools::GetPedPool()->GetSlot(i);
+ if (!pPed)
+ continue;
+ if (pPed->m_leader == pLeader)
+ total++;
+ }
+ ScriptParams[0] = total;
+ StoreParameters(&m_nIp, 1);
return 0;
+ }
case COMMAND_GIVE_REMOTE_CONTROLLED_MODEL_TO_PLAYER:
+ {
+ CollectParameters(&m_nIp, 6);
+ CVector pos = *(CVector*)&ScriptParams[1];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ CRemote::GivePlayerRemoteControlledCar(pos.x, pos.y, pos.z, DEGTORAD(*(float*)&ScriptParams[4]), ScriptParams[5]);
return 0;
+ }
case COMMAND_GET_CURRENT_PLAYER_WEAPON:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ assert(pPed);
+ ScriptParams[0] = pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType;
+ StoreParameters(&m_nIp, 1);
return 0;
+ }
case COMMAND_GET_CURRENT_CHAR_WEAPON:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pPed);
+ ScriptParams[0] = pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType;
+ StoreParameters(&m_nIp, 1);
return 0;
+ }
case COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_2D:
- return 0;
case COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_2D:
- return 0;
case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_2D:
- return 0;
case COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_3D:
- return 0;
case COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_3D:
- return 0;
case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_3D:
+ LocateCharObjectCommand(command, &m_nIp);
return 0;
- case COMMAND_SET_CAR_TEMP_ACTION:
+ case COMMAND_SET_CAR_HANDBRAKE_TURN_LEFT: // this will be changed in final VC version to a more general SET_TEMP_ACTION
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ pVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKETURNLEFT;
+ pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + ScriptParams[1];
return 0;
+ }
case COMMAND_SET_CAR_HANDBRAKE_TURN_RIGHT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ pVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKETURNRIGHT;
+ pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + ScriptParams[1];
return 0;
+ }
case COMMAND_SET_CAR_HANDBRAKE_STOP:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ assert(pVehicle);
+ pVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKESTRAIGHT;
+ pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + ScriptParams[1];
return 0;
+ }
case COMMAND_IS_CHAR_ON_ANY_BIKE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pPed);
+ UpdateCompareFlag(pPed->bInVehicle&& pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_BIKE);
return 0;
+ }
case COMMAND_LOCATE_SNIPER_BULLET_2D:
- return 0;
case COMMAND_LOCATE_SNIPER_BULLET_3D:
+ LocateSniperBulletCommand(command, &m_nIp);
return 0;
case COMMAND_GET_NUMBER_OF_SEATS_IN_MODEL:
+ CollectParameters(&m_nIp, 1);
+ ScriptParams[0] = CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(ScriptParams[0]) + 1;
+ StoreParameters(&m_nIp, 1);
return 0;
case COMMAND_IS_PLAYER_ON_ANY_BIKE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ assert(pPed);
+ UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_BIKE);
return 0;
+ }
case COMMAND_IS_CHAR_LYING_DOWN:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pPed);
+ UpdateCompareFlag(pPed->bFallenDown);
return 0;
+ }
case COMMAND_CAN_CHAR_SEE_DEAD_CHAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ assert(pPed);
+ int pedtype = ScriptParams[1];
+ bool can = false;
+ for (int i = 0; i < pPed->m_numNearPeds; i++) {
+ CPed* pTestPed = pPed->m_nearPeds[i];
+ if (pTestPed->m_fHealth <= 0.0f && pTestPed->m_nPedType == pedtype && pPed->OurPedCanSeeThisOne(pTestPed))
+ can = true;
+ }
+ UpdateCompareFlag(can);
return 0;
+ }
case COMMAND_SET_ENTER_CAR_RANGE_MULTIPLIER:
+ CollectParameters(&m_nIp, 1);
+#ifdef FIX_BUGS
+ CPed::nEnterCarRangeMultiplier = *(float*)&ScriptParams[0];
+#else
+ CPed::nEnterCarRangeMultiplier = (float)ScriptParams[0];
+#endif
return 0;
+#endif
default:
assert(0);
}
return -1;
}
-#endif
int16 CRunningScript::GetPadState(uint16 pad, uint16 button)
{
diff --git a/src/control/Script.h b/src/control/Script.h
index a1b35dcc..aa6f7e58 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -139,7 +139,9 @@ public:
int8 ProcessCommands800To899(int32);
int8 ProcessCommands900To999(int32);
int8 ProcessCommands1000To1099(int32);
+#ifndef GTA_PS2
int8 ProcessCommands1100To1199(int32);
+#endif
void UpdateCompareFlag(bool);
int16 GetPadState(uint16, uint16);
void LocatePlayerCommand(int32, uint32*);
diff --git a/src/control/ScriptCommands.h b/src/control/ScriptCommands.h
index 539a0bd2..dafe2418 100644
--- a/src/control/ScriptCommands.h
+++ b/src/control/ScriptCommands.h
@@ -1108,6 +1108,7 @@ enum {
COMMAND_SET_JAMES_CAR_ON_PATH_TO_PLAYER,
COMMAND_LOAD_END_OF_GAME_TUNE,
COMMAND_ENABLE_PLAYER_CONTROL_CAMERA,
+#ifndef GTA_PS2
COMMAND_SET_OBJECT_ROTATION,
COMMAND_GET_DEBUG_CAMERA_COORDINATES,
COMMAND_GET_DEBUG_CAMERA_FRONT_VECTOR,
@@ -1127,7 +1128,7 @@ enum {
COMMAND_GET_DEBUG_CAMERA_POINT_AT,
COMMAND_ATTACH_CHAR_TO_CAR,
COMMAND_DETACH_CHAR_FROM_CAR,
- COMMAND_SET_CAR_STAY_IN_FAST_LANE,
+ COMMAND_SET_CAR_CHANGE_LANE,
COMMAND_CLEAR_CHAR_LAST_WEAPON_DAMAGE,
COMMAND_CLEAR_CAR_LAST_WEAPON_DAMAGE,
COMMAND_GET_RANDOM_COP_IN_AREA,
@@ -1144,7 +1145,7 @@ enum {
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_LEFT,
COMMAND_SET_CAR_HANDBRAKE_TURN_RIGHT,
COMMAND_SET_CAR_HANDBRAKE_STOP,
COMMAND_IS_CHAR_ON_ANY_BIKE,
@@ -1155,4 +1156,5 @@ enum {
COMMAND_IS_CHAR_LYING_DOWN,
COMMAND_CAN_CHAR_SEE_DEAD_CHAR,
COMMAND_SET_ENTER_CAR_RANGE_MULTIPLIER,
+#endif
}; \ No newline at end of file
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index 64a52bdc..88c87c95 100644
--- a/src/core/Camera.cpp
+++ b/src/core/Camera.cpp
@@ -30,6 +30,7 @@ WRAPPER void CCamera::Process(void) { EAXJMP(0x46D3F0); }
WRAPPER void CCamera::LoadPathSplines(int file) { EAXJMP(0x46D1D0); }
WRAPPER void CCamera::RestoreWithJumpCut(void) { EAXJMP(0x46FAE0); };
WRAPPER void CCamera::SetPercentAlongCutScene(float) { EAXJMP(0x46FE20); };
+WRAPPER void CCamera::SetParametersForScriptInterpolation(float, float, int32) { EAXJMP(0x46FDE0); }
bool
CCamera::GetFading()
@@ -155,6 +156,13 @@ CCamera::SetMotionBlurAlpha(int a)
}
void
+CCamera::SetNearClipScript(float clip)
+{
+ m_fNearClipScript = clip;
+ m_bUseNearClipScript = true;
+}
+
+void
CCamera::RenderMotionBlur(void)
{
if(m_BlurType == 0)
diff --git a/src/core/Camera.h b/src/core/Camera.h
index 6b631ee2..980af5c1 100644
--- a/src/core/Camera.h
+++ b/src/core/Camera.h
@@ -485,6 +485,7 @@ int m_iModeObbeCamIsInForCar;
void Restore(void);
void SetWideScreenOn(void);
void SetWideScreenOff(void);
+ void SetNearClipScript(float);
float Find3rdPersonQuickAimPitch(void);
@@ -512,6 +513,7 @@ int m_iModeObbeCamIsInForCar;
void UpdateAimingCoors(CVector const &);
void SetPercentAlongCutScene(float);
+ void SetParametersForScriptInterpolation(float, float, int32);
void dtor(void) { this->CCamera::~CCamera(); }
};
diff --git a/src/core/CutsceneMgr.h b/src/core/CutsceneMgr.h
index e95a2a04..381c71c9 100644
--- a/src/core/CutsceneMgr.h
+++ b/src/core/CutsceneMgr.h
@@ -26,6 +26,7 @@ public:
static CDirectory *&ms_pCutsceneDir;
static uint32 &ms_cutsceneLoadStatus;
+ static void SetRunning(bool running) { ms_running = running; }
static bool IsRunning(void) { return ms_running; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
static CCutsceneObject* GetCutsceneObject(int id) { return ms_pCutsceneObjects[id]; }
diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp
index cd5bee06..2c27ba70 100644
--- a/src/core/Stats.cpp
+++ b/src/core/Stats.cpp
@@ -33,13 +33,102 @@ int32 &CStats::MissionsPassed = *(int32*)0x940768;
char(&CStats::LastMissionPassedName)[8] = *(char(*)[8])*(uintptr*)0x70D828;
int32 &CStats::TotalLegitimateKills = *(int32*)0x8F6004;
int32 &CStats::ElBurroTime = *(int32*)0x8E2A6C;
+int32& CStats::Record4x4One = *(int32*)0x940570;
+int32& CStats::Record4x4Two = *(int32*)0x94058C;
+int32& CStats::Record4x4Three = *(int32*)0x880FA8;
+int32& CStats::Record4x4Mayhem = *(int32*)0x885B70;
+int32& CStats::LivesSavedWithAmbulance = *(int32*)0x8F57E0;
+int32& CStats::CriminalsCaught = *(int32*)0x8F2518;
+int32& CStats::HighestLevelAmbulanceMission = *(int32*)0x8F2A04;
+int32& CStats::FiresExtinguished = *(int32*)0x8F5FEC;
+int32& CStats::LongestFlightInDodo = *(int32*)0x8F5FE4;
+int32& CStats::TimeTakenDefuseMission = *(int32*)0x880E24;
+int32& CStats::TotalNumberKillFrenzies = *(int32*)0x8E2884;
+int32& CStats::TotalNumberMissions = *(int32*)0x8E2820;
+int32(&CStats::FastestTimes)[CStats::TOTAL_FASTEST_TIMES] = *(int32(*)[CStats::TOTAL_FASTEST_TIMES])*(uintptr*)0x6E9128;
+int32(&CStats::HighestScores)[CStats::TOTAL_HIGHEST_SCORES] = *(int32(*)[CStats::TOTAL_HIGHEST_SCORES]) * (uintptr*)0x8622B0;
-void CStats::AnotherKillFrenzyPassed()
+void CStats::RegisterFastestTime(int32 index, int32 time)
{
- ++NumberKillFrenziesPassed;
+ assert(index >= 0 && index < TOTAL_FASTEST_TIMES);
+ if (FastestTimes[index] == 0)
+ FastestTimes[index] = time;
+ else
+ FastestTimes[index] = min(FastestTimes[index], time);
+}
+
+void CStats::RegisterHighestScore(int32 index, int32 score)
+{
+ assert(index >= 0 && index < TOTAL_HIGHEST_SCORES);
+ HighestScores[index] = max(HighestScores[index], score);
}
void CStats::RegisterElBurroTime(int32 time)
{
ElBurroTime = (ElBurroTime && ElBurroTime < time) ? ElBurroTime : time;
}
+
+void CStats::Register4x4OneTime(int32 time)
+{
+ Record4x4One = (Record4x4One && Record4x4One < time) ? Record4x4One : time;
+}
+
+void CStats::Register4x4TwoTime(int32 time)
+{
+ Record4x4Two = (Record4x4Two && Record4x4Two < time) ? Record4x4Two : time;
+}
+
+void CStats::Register4x4ThreeTime(int32 time)
+{
+ Record4x4Three = (Record4x4Three && Record4x4Three < time) ? Record4x4Three : time;
+}
+
+void CStats::Register4x4MayhemTime(int32 time)
+{
+ Record4x4Mayhem = (Record4x4Mayhem && Record4x4Mayhem < time) ? Record4x4Mayhem : time;
+}
+
+void CStats::AnotherLifeSavedWithAmbulance()
+{
+ ++LivesSavedWithAmbulance;
+}
+
+void CStats::AnotherCriminalCaught()
+{
+ ++CriminalsCaught;
+}
+
+void CStats::RegisterLevelAmbulanceMission(int32 level)
+{
+ HighestLevelAmbulanceMission = max(HighestLevelAmbulanceMission, level);
+}
+
+void CStats::AnotherFireExtinguished()
+{
+ ++FiresExtinguished;
+}
+
+void CStats::RegisterLongestFlightInDodo(int32 time)
+{
+ LongestFlightInDodo = max(LongestFlightInDodo, time);
+}
+
+void CStats::RegisterTimeTakenDefuseMission(int32 time)
+{
+ TimeTakenDefuseMission = (TimeTakenDefuseMission && TimeTakenDefuseMission < time) ? TimeTakenDefuseMission : time;
+}
+
+void CStats::AnotherKillFrenzyPassed()
+{
+ ++NumberKillFrenziesPassed;
+}
+
+void CStats::SetTotalNumberKillFrenzies(int32 total)
+{
+ TotalNumberKillFrenzies = total;
+}
+
+void CStats::SetTotalNumberMissions(int32 total)
+{
+ TotalNumberMissions = total;
+}
diff --git a/src/core/Stats.h b/src/core/Stats.h
index e1ef3749..4b558c32 100644
--- a/src/core/Stats.h
+++ b/src/core/Stats.h
@@ -3,6 +3,10 @@
class CStats
{
public:
+ enum {
+ TOTAL_FASTEST_TIMES = 16,
+ TOTAL_HIGHEST_SCORES = 16
+ };
static int32 &DaysPassed;
static int32 &HeadsPopped;
static bool& CommercialPassed;
@@ -35,9 +39,37 @@ public:
static char (&LastMissionPassedName)[8];
static int32 &TotalLegitimateKills;
static int32 &ElBurroTime;
+ static int32 &Record4x4One;
+ static int32 &Record4x4Two;
+ static int32 &Record4x4Three;
+ static int32 &Record4x4Mayhem;
+ static int32 &LivesSavedWithAmbulance;
+ static int32 &CriminalsCaught;
+ static int32 &HighestLevelAmbulanceMission;
+ static int32 &FiresExtinguished;
+ static int32 &LongestFlightInDodo;
+ static int32 &TimeTakenDefuseMission;
+ static int32 &TotalNumberKillFrenzies;
+ static int32 &TotalNumberMissions;
+ static int32(&FastestTimes)[TOTAL_FASTEST_TIMES];
+ static int32(&HighestScores)[TOTAL_HIGHEST_SCORES];
public:
+ static void RegisterFastestTime(int32, int32);
+ static void RegisterHighestScore(int32, int32);
static void AnotherKillFrenzyPassed();
+ static void AnotherLifeSavedWithAmbulance();
+ static void AnotherCriminalCaught();
+ static void RegisterLevelAmbulanceMission(int32);
+ static void AnotherFireExtinguished();
+ static void Register4x4OneTime(int32);
+ static void Register4x4TwoTime(int32);
+ static void Register4x4ThreeTime(int32);
+ static void Register4x4MayhemTime(int32);
+ static void RegisterLongestFlightInDodo(int32);
+ static void RegisterTimeTakenDefuseMission(int32);
+ static void SetTotalNumberKillFrenzies(int32);
+ static void SetTotalNumberMissions(int32);
static void CheckPointReachedUnsuccessfully() { KillsSinceLastCheckpoint = 0; };
static void CheckPointReachedSuccessfully() { TotalLegitimateKills += KillsSinceLastCheckpoint; KillsSinceLastCheckpoint = 0; };
static void RegisterElBurroTime(int32);
diff --git a/src/core/World.cpp b/src/core/World.cpp
index 70e526e8..c6236f42 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -50,6 +50,7 @@ WRAPPER void CWorld::FindObjectsOfTypeInRange(uint32, CVector&, float, bool, sho
WRAPPER void CWorld::FindObjectsOfTypeInRangeSectorList(uint32, CPtrList&, CVector&, float, bool, short*, short, CEntity**) { EAXJMP(0x4B2960); }
WRAPPER void CWorld::FindMissionEntitiesIntersectingCube(const CVector&, const CVector&, int16*, int16, CEntity**, bool, bool, bool) { EAXJMP(0x4B3680); }
WRAPPER void CWorld::ClearCarsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B50E0); }
+WRAPPER void CWorld::ClearPedsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B52B0); }
void
CWorld::Initialise()
diff --git a/src/core/World.h b/src/core/World.h
index 68af156c..12582d49 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -116,6 +116,7 @@ public:
static void FindObjectsIntersectingAngledCollisionBox(const CColBox &, const CMatrix &, const CVector &, float, float, float, float, int16*, int16, CEntity **, bool, bool, bool, bool, bool);
static void FindMissionEntitiesIntersectingCube(const CVector&, const CVector&, int16*, int16, CEntity**, bool, bool, bool);
static void ClearCarsFromArea(float, float, float, float, float, float);
+ static void ClearPedsFromArea(float, float, float, float, float, float);
static float GetSectorX(float f) { return ((f - WORLD_MIN_X)/SECTOR_SIZE_X); }
static float GetSectorY(float f) { return ((f - WORLD_MIN_Y)/SECTOR_SIZE_Y); }
diff --git a/src/core/config.h b/src/core/config.h
index de96ad1b..770b51e6 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -163,6 +163,8 @@ enum Config {
// Script
#define USE_DEBUG_SCRIPT_LOADER // makes game load main_freeroam.scm by default
+#define USE_MEASUREMENTS_IN_METERS // makes game use meters instead of feet in script
+#define USE_PRECISE_MEASUREMENT_CONVERTION // makes game convert feet to meeters more precisely
// Vehicles
#define EXPLODING_AIRTRAIN // can blow up jumbo jet with rocket launcher
diff --git a/src/peds/PedType.h b/src/peds/PedType.h
index 9d284318..797344ab 100644
--- a/src/peds/PedType.h
+++ b/src/peds/PedType.h
@@ -85,6 +85,9 @@ public:
static uint32 GetFlag(int type) { return ms_apPedType[type]->m_flag; }
static uint32 GetAvoid(int type) { return ms_apPedType[type]->m_avoid; }
static uint32 GetThreats(int type) { return ms_apPedType[type]->m_threats; }
+ static void AddThreat(int type, int threat) { ms_apPedType[type]->m_threats |= threat; }
+ static void RemoveThreat(int type, int threat) { ms_apPedType[type]->m_threats &= ~threat; }
+ static bool IsThreat(int type, int threat) { return ms_apPedType[type]->m_threats & threat; }
};
static_assert(sizeof(CPedType) == 0x20, "CPedType: error");
diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp
index f1fd3f09..39b22671 100644
--- a/src/render/SpecialFX.cpp
+++ b/src/render/SpecialFX.cpp
@@ -11,6 +11,9 @@
#include "Lights.h"
#include "VisibilityPlugins.h"
#include "World.h"
+#include "Particle.h"
+#include "General.h"
+#include "Camera.h"
WRAPPER void CSpecialFX::Render(void) { EAXJMP(0x518DC0); }
WRAPPER void CSpecialFX::Update(void) { EAXJMP(0x518D40); }
@@ -383,6 +386,77 @@ CMoneyMessages::RegisterOne(CVector vecPos, const char *pText, uint8 bRed, uint8
aMoneyMessages[nIndex].m_fOpacity = fOpacity;
}
+void CSpecialParticleStuff::CreateFoamAroundObject(CMatrix* pMatrix, float innerFw, float innerRg, float innerUp, int32 particles)
+{
+ int attempts = 0;
+ float outerFw = innerFw + 5.0f;
+ float outerRg = innerRg + 5.0f;
+ float outerUp = innerUp + 5.0f;
+ while (particles > 0 && attempts < 1000) {
+ CVector pos;
+ int rnd = CGeneral::GetRandomNumber();
+ pos.x = (int8)(rnd - 128) / 110.0f;
+ pos.y = (int8)((rnd >> 8) - 128) / 110.0f;
+ pos.z = 0.0f;
+ if (DotProduct2D(pos, TheCamera.GetForward()) >= 0)
+ continue;
+ pos += pMatrix->GetPosition();
+ pos.z = 2.0f;
+ // was there any point in adding it here?
+ float fw = DotProduct(pMatrix->GetForward(), pos - pMatrix->GetPosition());
+ if (fw >= outerFw)
+ continue;
+ float rg = DotProduct(pMatrix->GetRight(), pos - pMatrix->GetPosition());
+ if (rg >= outerRg)
+ continue;
+ float up = DotProduct(pMatrix->GetUp(), pos - pMatrix->GetPosition());
+ if (up >= outerUp)
+ continue;
+ if (fw > innerFw || rg > innerRg || up > innerUp) {
+ CParticle::AddParticle(PARTICLE_STEAM2, pos, CVector(0.0f, 0.0f, 0.0f), nil, 4.0f, 1, 0, 0, 0);
+ particles--;
+ }
+ }
+}
+
+void CSpecialParticleStuff::StartBoatFoamAnimation()
+{
+ BoatFromStart = CTimer::GetTimeInMilliseconds();
+}
+
+CRGBA FoamColour(255, 255, 255, 255);
+unsigned int CSpecialParticleStuff::BoatFromStart;
+
+void CSpecialParticleStuff::UpdateBoatFoamAnimation(CMatrix* pMatrix)
+{
+ static int32 FrameInAnimation = 0;
+ static float X, Y, Z, dX, dY, dZ;
+ CreateFoamAroundObject(pMatrix, 107.0f, 24.1f, 30.5f, 2);
+ uint32 prev = CTimer::GetPreviousTimeInMilliseconds();
+ uint32 cur = CTimer::GetTimeInMilliseconds();
+ if (FrameInAnimation != 0) {
+ X += dX;
+ Y += dY;
+ Z += dZ;
+ CVector pos = *pMatrix * CVector(X, Y, Z);
+ CParticle::AddParticle(PARTICLE_STEAM_NY, pos, CVector(0.0f, 0.0f, 0.0f),
+ nil, FrameInAnimation * 0.5f + 2.0f, FoamColour, 1, 0, 0, 0);
+ if (++FrameInAnimation)
+ FrameInAnimation = 0;
+ }
+ if ((cur & 0x3FF) < (prev & 0x3FF)) {
+ FrameInAnimation = 1;
+ int rnd = CGeneral::GetRandomNumber();
+ X = (int8)(rnd - 128) * 0.2f;
+ Y = (int8)((rnd >> 8) - 128) * 0.2f;
+ Z = 10.0f;
+ rnd = CGeneral::GetRandomNumber();
+ dX = (int8)(rnd - 128) * 0.02f;
+ dY = (int8)((rnd >> 8) - 128) * 0.02f;
+ dZ = 2.0f;
+ }
+}
+
STARTPATCHES
InjectHook(0x51B070, &C3dMarker::AddMarker, PATCH_JUMP);
InjectHook(0x51B170, &C3dMarker::DeleteMarkerObject, PATCH_JUMP);
diff --git a/src/render/SpecialFX.h b/src/render/SpecialFX.h
index 10b22a77..7b77280b 100644
--- a/src/render/SpecialFX.h
+++ b/src/render/SpecialFX.h
@@ -1,5 +1,7 @@
#pragma once
+#include "rwplcore.h"
+
class CSpecialFX
{
public:
@@ -109,4 +111,13 @@ public:
static void Init();
static void Render();
static void RegisterOne(CVector vecPos, const char *pText, uint8 bRed, uint8 bGreen, uint8 bBlue, float fSize, float fOpacity);
-}; \ No newline at end of file
+};
+
+class CSpecialParticleStuff
+{
+ static uint32 BoatFromStart;
+public:
+ static void CreateFoamAroundObject(CMatrix*, float, float, float, int32);
+ static void StartBoatFoamAnimation();
+ static void UpdateBoatFoamAnimation(CMatrix*);
+};