From 80453d3f4ddc13f8458e14353c318a69cfe10518 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Wed, 1 Jan 2020 02:35:54 +0300 Subject: [PATCH] some not fully tested stuff --- src/control/Garages.cpp | 1 + src/control/Garages.h | 1 + src/control/Pickups.cpp | 15 +- src/control/Pickups.h | 16 +- src/control/Script.cpp | 788 ++++++++++++++++++++++++++++++++- src/control/Script.h | 22 + src/core/Fire.cpp | 17 +- src/core/Fire.h | 9 +- src/core/Stats.cpp | 15 + src/core/Stats.h | 16 + src/peds/Ped.cpp | 36 +- src/peds/Ped.h | 20 +- src/vehicles/Vehicle.h | 2 + src/weapons/ProjectileInfo.cpp | 3 +- src/weapons/ProjectileInfo.h | 1 + 15 files changed, 920 insertions(+), 42 deletions(-) diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp index d8e8df9f..ca1dae1b 100644 --- a/src/control/Garages.cpp +++ b/src/control/Garages.cpp @@ -87,6 +87,7 @@ int32 CGarages::QueryCarsCollected(int16 garage) } WRAPPER bool CGarages::HasThisCarBeenCollected(int16 garage, uint8 id) { EAXJMP(0x426D50); } +WRAPPER void CGarages::ChangeGarageType(int16 garage, int8 type) { EAXJMP(0x4222A0); } #if 0 WRAPPER void CGarages::PrintMessages(void) { EAXJMP(0x426310); } diff --git a/src/control/Garages.h b/src/control/Garages.h index 7960e619..f9421ae8 100644 --- a/src/control/Garages.h +++ b/src/control/Garages.h @@ -39,4 +39,5 @@ public: static void DeActivateGarage(int16); static int32 QueryCarsCollected(int16); static bool HasThisCarBeenCollected(int16, uint8); + static void ChangeGarageType(int16, int8); //TODO: eGarageType }; diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index 52861e99..67c59101 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -46,8 +46,21 @@ uint8 aWeaponGreens[] = { 0, 255, 128, 255, 0, 255, 128, 255, 0, 255, 255, 0, 25 uint8 aWeaponBlues[] = { 0, 0, 255, 0, 255, 255, 0, 128, 255, 0, 255, 0, 128, 255, 0, 0 }; float aWeaponScale[] = { 1.0f, 2.0f, 1.5f, 1.0f, 1.0f, 1.5f, 1.0f, 2.0f, 1.0f, 2.0f, 2.5f, 1.0f, 1.0f, 1.0f, 1.0f }; -WRAPPER void CPacManPickups::Render(void) { EAXJMP(0x432F60); } +WRAPPER void CPacManPickups::Init(void) { EAXJMP(0x432760); } WRAPPER void CPacManPickups::Update(void) { EAXJMP(0x432800); } +WRAPPER void CPacManPickups::GeneratePMPickUps(CVector, float, int16, uint8) { EAXJMP(0x432AE0); } +WRAPPER void CPacManPickups::GeneratePMPickUpsForRace(int32) { EAXJMP(0x432D50); } +WRAPPER void CPacManPickups::GenerateOnePMPickUp(CVector) { EAXJMP(0x432F20); } +WRAPPER void CPacManPickups::Render(void) { EAXJMP(0x432F60); } +WRAPPER void CPacManPickups::DoCleanUpPacManStuff(void) { EAXJMP(0x433150); } +WRAPPER void CPacManPickups::StartPacManRace(int32) { EAXJMP(0x433340); } +WRAPPER void CPacManPickups::StartPacManRecord(void) { EAXJMP(0x433360); } +WRAPPER uint32 CPacManPickups::QueryPowerPillsEatenInRace(void) { EAXJMP(0x4333A0); } +WRAPPER void CPacManPickups::ResetPowerPillsEatenInRace(void) { EAXJMP(0x4333B0); } +WRAPPER void CPacManPickups::CleanUpPacManStuff(void) { EAXJMP(0x4333C0); } +WRAPPER void CPacManPickups::StartPacManScramble(CVector, float, int16) { EAXJMP(0x4333D0); } +WRAPPER uint32 CPacManPickups::QueryPowerPillsCarriedByPlayer(void) { EAXJMP(0x4333F0); } +WRAPPER void CPacManPickups::ResetPowerPillsCarriedByPlayer(void) { EAXJMP(0x433410); } void diff --git a/src/control/Pickups.h b/src/control/Pickups.h index 5f9814c3..4bb0ddff 100644 --- a/src/control/Pickups.h +++ b/src/control/Pickups.h @@ -105,6 +105,20 @@ extern uint16 CostOfWeapon[20]; class CPacManPickups { public: - static void Render(void); + static void Init(void); static void Update(void); + static void GeneratePMPickUps(CVector, float, int16, uint8); + static void GeneratePMPickUpsForRace(int32); + static void GenerateOnePMPickUp(CVector); + static void Render(void); + static void DoCleanUpPacManStuff(void); + static void StartPacManRace(int32); + static void StartPacManRecord(void); + static uint32 QueryPowerPillsEatenInRace(void); + static void ResetPowerPillsEatenInRace(void); + static void CleanUpPacManStuff(void); + static void StartPacManScramble(CVector, float, int16); + static uint32 QueryPowerPillsCarriedByPlayer(void); + static void ResetPowerPillsCarriedByPlayer(void); + }; diff --git a/src/control/Script.cpp b/src/control/Script.cpp index d361045c..6d0c596d 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -37,13 +37,16 @@ #include "PointLights.h" #include "Pools.h" #include "Population.h" +#include "ProjectileInfo.h" #include "Remote.h" #include "Restart.h" #include "Replay.h" #include "Shadows.h" +#include "Stats.h" #include "Streaming.h" #include "Text.h" #include "User.h" +#include "WaterLevel.h" #include "Weather.h" #include "World.h" #include "Zones.h" @@ -1661,13 +1664,23 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) CGeneral::GetRandomNumber(); CGeneral::GetRandomNumber(); CGeneral::GetRandomNumber(); /* To make it EXTRA random! */ +#ifdef FIX_BUGS + *ptr = CGeneral::GetRandomNumberInRange(0.0f, 1.0f); +#else *ptr = CGeneral::GetRandomNumber() / 65536.0f; /* Between 0 and 0.5 on PC (oh well...), never used in original script. */ +#endif + return 0; } case COMMAND_GENERATE_RANDOM_INT: +#ifdef FIX_BUGS + // Not a very good fix but before switching to PS2 rand, it sort of works + *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) = CGeneral::GetRandomNumberInRange(0, 65535); +#else /* On PC between 0 and 32767, even though script expects values between 0 and 65536 */ *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) = CGeneral::GetRandomNumber(); +#endif return 0; case COMMAND_CREATE_CHAR: { @@ -1709,7 +1722,7 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) ped = new CCivilianPed(ScriptParams[0], ScriptParams[1]); ped->CharCreatedBy = MISSION_CHAR; ped->bRespondsToThreats = false; - ped->m_ped_flagG2 = false; + ped->bAllowMedicsToReviveMe = false; CVector pos = *(CVector*)&ScriptParams[2]; if (pos.z <= -100.0f) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); @@ -2740,7 +2753,7 @@ int8 CRunningScript::ProcessCommandsFrom200To299(int32 command) pPed = new CCivilianPed(ScriptParams[1], ScriptParams[2]); pPed->CharCreatedBy = MISSION_CHAR; pPed->bRespondsToThreats = false; - pPed->m_ped_flagG2 = false; + pPed->bAllowMedicsToReviveMe = false; pPed->GetPosition() = pVehicle->GetPosition(); pPed->SetOrientation(0.0f, 0.0f, 0.0f); pPed->SetPedState(PED_DRIVING); @@ -3875,6 +3888,7 @@ int8 CRunningScript::ProcessCommandsFrom400To499(int32 command) { CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); return 0; } @@ -3882,6 +3896,7 @@ int8 CRunningScript::ProcessCommandsFrom400To499(int32 command) { CollectParameters(&m_nIp, 1); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); return 0; } @@ -3889,6 +3904,7 @@ int8 CRunningScript::ProcessCommandsFrom400To499(int32 command) { CollectParameters(&m_nIp, 1); CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + assert(pObject); CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); return 0; } @@ -3934,7 +3950,7 @@ int8 CRunningScript::ProcessCommandsFrom400To499(int32 command) pPed = new CCivilianPed(ScriptParams[1], ScriptParams[2]); pPed->CharCreatedBy = MISSION_CHAR; pPed->bRespondsToThreats = false; - pPed->m_ped_flagG2 = false; + pPed->bAllowMedicsToReviveMe = false; pPed->GetPosition() = pVehicle->GetPosition(); pPed->SetOrientation(0.0f, 0.0f, 0.0f); pPed->SetPedState(PED_DRIVING); @@ -4944,10 +4960,8 @@ int8 CRunningScript::ProcessCommandsFrom500To599(int32 command) CollectParameters(&m_nIp, 1); char name[16]; strncpy(name, (char*)&CTheScripts::ScriptSpace[m_nIp], 8); - for (int i = 0; i < 8; i++) { - if (name[i] >= 'A' && name[i] <= 'Z') - name[i] += 'a' - 'A'; - } + for (int i = 0; i < 8; i++) + name[i] = tolower(name[i]); CStreaming::RequestSpecialChar(ScriptParams[0] - 1, name, STREAMFLAGS_DEPENDENCY | STREAMFLAGS_SCRIPTOWNED); m_nIp += 8; return 0; @@ -5499,112 +5513,870 @@ int8 CRunningScript::ProcessCommandsFrom600To699(int32 command) } #endif -#if 1 +#if 0 WRAPPER int8 CRunningScript::ProcessCommandsFrom700To799(int32 command) { EAXJMP(0x4458A0); } #else int8 CRunningScript::ProcessCommandsFrom700To799(int32 command) { switch (command){ case COMMAND_SET_SWAT_REQUIRED: + CollectParameters(&m_nIp, 1); + FindPlayerPed()->m_pWanted->m_bSwatRequired = (ScriptParams[0] != 0); + return 0; case COMMAND_SET_FBI_REQUIRED: + CollectParameters(&m_nIp, 1); + FindPlayerPed()->m_pWanted->m_bFbiRequired = (ScriptParams[0] != 0); + return 0; case COMMAND_SET_ARMY_REQUIRED: + CollectParameters(&m_nIp, 1); + FindPlayerPed()->m_pWanted->m_bArmyRequired = (ScriptParams[0] != 0); + return 0; case COMMAND_IS_CAR_IN_WATER: + { + CollectParameters(&m_nIp, 1); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + UpdateCompareFlag(pVehicle->bIsInWater); + return 0; + } case COMMAND_GET_CLOSEST_CHAR_NODE: + { + CollectParameters(&m_nIp, 3); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + CPathNode* pNode = &ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, 1, 999999.9f)]; + *(CVector*)&ScriptParams[0] = pNode->pos; + StoreParameters(&m_nIp, 3); + return 0; + } case COMMAND_GET_CLOSEST_CAR_NODE: + { + CollectParameters(&m_nIp, 3); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + CPathNode* pNode = &ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f)]; + *(CVector*)&ScriptParams[0] = pNode->pos; + StoreParameters(&m_nIp, 3); + return 0; + } case COMMAND_CAR_GOTO_COORDINATES_ACCURATE: + { + CollectParameters(&m_nIp, 4); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + CVector pos = *(CVector*)&ScriptParams[1]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + pos.z += pVehicle->GetDistanceFromCentreOfMassToBaseOfModel(); + if (CCarCtrl::JoinCarWithRoadSystemGotoCoors(pVehicle, pos, false)) + pVehicle->AutoPilot.m_nCarMission = MISSION_GOTO_COORDS_STRAIGHT_ACCURATE; + else + pVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ACCURATE; + pVehicle->m_status = STATUS_PHYSICS; + pVehicle->bEngineOn = true; + pVehicle->AutoPilot.m_nCruiseSpeed = min(6, pVehicle->AutoPilot.m_nCruiseSpeed); + pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds(); + return 0; + } case COMMAND_START_PACMAN_RACE: + CollectParameters(&m_nIp, 1); + CPacManPickups::StartPacManRace(ScriptParams[0]); + return 0; case COMMAND_START_PACMAN_RECORD: + CPacManPickups::StartPacManRecord(); + return 0; case COMMAND_GET_NUMBER_OF_POWER_PILLS_EATEN: + ScriptParams[0] = CPacManPickups::QueryPowerPillsEatenInRace(); + StoreParameters(&m_nIp, 1); + return 0; case COMMAND_CLEAR_PACMAN: + CPacManPickups::CleanUpPacManStuff(); + return 0; case COMMAND_START_PACMAN_SCRAMBLE: + { + CollectParameters(&m_nIp, 5); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + CPacManPickups::StartPacManScramble(pos, *(float*)&ScriptParams[3], ScriptParams[4]); + return 0; + } case COMMAND_GET_NUMBER_OF_POWER_PILLS_CARRIED: + ScriptParams[0] = CPacManPickups::QueryPowerPillsCarriedByPlayer(); + return 0; case COMMAND_CLEAR_NUMBER_OF_POWER_PILLS_CARRIED: + CPacManPickups::ResetPowerPillsCarriedByPlayer(); + return 0; case COMMAND_IS_CAR_ON_SCREEN: + { + CollectParameters(&m_nIp, 1); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + UpdateCompareFlag(TheCamera.IsSphereVisible(pVehicle->GetBoundCentre(), pVehicle->GetBoundRadius())); + return 0; + } case COMMAND_IS_CHAR_ON_SCREEN: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(TheCamera.IsSphereVisible(pPed->GetBoundCentre(), pPed->GetBoundRadius())); + return 0; + } case COMMAND_IS_OBJECT_ON_SCREEN: + { + CollectParameters(&m_nIp, 1); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + assert(pObject); + UpdateCompareFlag(TheCamera.IsSphereVisible(pObject->GetBoundCentre(), pObject->GetBoundRadius())); + return 0; + } case COMMAND_GOSUB_FILE: + { + CollectParameters(&m_nIp, 2); + assert(m_nStackPointer < MAX_STACK_DEPTH); + m_anStack[m_nStackPointer++] = m_nIp; + m_nIp = ScriptParams[0]; + // ScriptParams[1] == filename + return 0; + } case COMMAND_GET_GROUND_Z_FOR_3D_COORD: + { + CollectParameters(&m_nIp, 3); + CVector pos = *(CVector*)&ScriptParams[0]; + bool success; + *(float*)&ScriptParams[0] = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, &success); + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_START_SCRIPT_FIRE: + { + CollectParameters(&m_nIp, 3); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + ScriptParams[0] = gFireManager.StartScriptFire(pos, nil, 0.8f, 1); + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_IS_SCRIPT_FIRE_EXTINGUISHED: + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(gFireManager.IsScriptFireExtinguish(ScriptParams[0])); + return 0; case COMMAND_REMOVE_SCRIPT_FIRE: + CollectParameters(&m_nIp, 1); + gFireManager.RemoveScriptFire(ScriptParams[0]); + return 0; case COMMAND_SET_COMEDY_CONTROLS: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + pVehicle->bComedyControls = (ScriptParams[1] != 0); + return 0; + } case COMMAND_BOAT_GOTO_COORDS: + { + CollectParameters(&m_nIp, 4); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + assert(pVehicle->m_vehType == VEHICLE_TYPE_BOAT); + CBoat* pBoat = (CBoat*)pVehicle; + CVector pos = *(CVector*)&ScriptParams[1]; + if (pos.z <= -100.0f) + CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &pos.z, false); + pBoat->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ASTHECROWSWIMS; + pBoat->AutoPilot.m_vecDestinationCoors = pos; + pBoat->m_status = STATUS_PHYSICS; + pBoat->AutoPilot.m_nCruiseSpeed = max(6, pBoat->AutoPilot.m_nCruiseSpeed); + pBoat->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds(); + return 0; + } case COMMAND_BOAT_STOP: + { + CollectParameters(&m_nIp, 4); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + assert(pVehicle->m_vehType == VEHICLE_TYPE_BOAT); + CBoat* pBoat = (CBoat*)pVehicle; + pBoat->AutoPilot.m_nCarMission = MISSION_NONE; + pBoat->m_status = STATUS_PHYSICS; + pBoat->bEngineOn = false; + pBoat->AutoPilot.m_nCruiseSpeed = 0; + return 0; + } case COMMAND_IS_PLAYER_SHOOTING_IN_AREA: + { + CollectParameters(&m_nIp, 6); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + float x1, y1, x2, y2; + x1 = *(float*)&ScriptParams[1]; + y1 = *(float*)&ScriptParams[2]; + x2 = *(float*)&ScriptParams[3]; + y2 = *(float*)&ScriptParams[4]; + UpdateCompareFlag(pPed->bIsShooting && pPed->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_CHAR_SHOOTING_IN_AREA: + { + CollectParameters(&m_nIp, 6); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + float x1, y1, x2, y2; + x1 = *(float*)&ScriptParams[1]; + y1 = *(float*)&ScriptParams[2]; + x2 = *(float*)&ScriptParams[3]; + y2 = *(float*)&ScriptParams[4]; + UpdateCompareFlag(pPed->bIsShooting && pPed->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_CURRENT_PLAYER_WEAPON: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + UpdateCompareFlag(ScriptParams[1] == pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType); + return 0; + } case COMMAND_IS_CURRENT_CHAR_WEAPON: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(ScriptParams[1] == pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType); + return 0; + } case COMMAND_CLEAR_NUMBER_OF_POWER_PILLS_EATEN: + CPacManPickups::ResetPowerPillsEatenInRace(); + return 0; case COMMAND_ADD_POWER_PILL: + { + CollectParameters(&m_nIp, 3); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + CPacManPickups::GenerateOnePMPickUp(pos); + return 0; + } case COMMAND_SET_BOAT_CRUISE_SPEED: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + assert(pVehicle->m_vehType == VEHICLE_TYPE_BOAT); + CBoat* pBoat = (CBoat*)pVehicle; + pBoat->AutoPilot.m_nCruiseSpeed = ScriptParams[1]; + } case COMMAND_GET_RANDOM_CHAR_IN_AREA: + { + CollectParameters(&m_nIp, 4); + int ped_handle = -1; + CVector pos = FindPlayerCoors(); + float x1, y1, x2, y2; + x1 = *(float*)&ScriptParams[1]; + y1 = *(float*)&ScriptParams[2]; + x2 = *(float*)&ScriptParams[3]; + y2 = *(float*)&ScriptParams[4]; + 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->CharCreatedBy != RANDOM_CHAR) + continue; + if (!pPed->IsPedInControl()) + continue; + if (pPed->bRemoveFromWorld) + continue; + if (pPed->bFadeOut) + continue; + if (pPed->GetModelIndex() == MI_SCUM_WOM || pPed->GetModelIndex() == MI_SCUM_MAN) + continue; + if (!ThisIsAValidRandomPed(pPed->m_nPedType)) + continue; + if (pPed->bIsLeader || pPed->m_leader) + continue; + if (!pPed->IsWithinArea(x1, y1, x2, y2)) + continue; + if (pos.z - 5.0f > pPed->GetPosition().z) + continue; + if (pos.z + 5.0f < 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_CHAR_IN_ZONE: + { + char zone[8]; + strncpy(zone, (const char*)&CTheScripts::ScriptSpace[m_nIp], 8); + int nZone = CTheZones::FindZoneByLabelAndReturnIndex(zone); + if (nZone != -1) + m_nIp += 8; + 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->CharCreatedBy != RANDOM_CHAR) + continue; + if (!pPed->IsPedInControl()) + continue; + if (pPed->bRemoveFromWorld) + continue; + if (pPed->bFadeOut) + continue; + if (pPed->GetModelIndex() == MI_SCUM_WOM || pPed->GetModelIndex() == MI_SCUM_MAN) + continue; + if (!ThisIsAValidRandomPed(pPed->m_nPedType)) + continue; + if (pPed->bIsLeader || pPed->m_leader) + continue; + if (!CTheZones::PointLiesWithinZone(pPed->GetPosition(), pZone)) + continue; + if (pos.z - 5.0f > pPed->GetPosition().z) + continue; + if (pos.z + 5.0f < 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_IS_PLAYER_IN_TAXI: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->IsTaxi()); + return 0; + } case COMMAND_IS_PLAYER_SHOOTING: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + UpdateCompareFlag(pPed->bIsShooting); + return 0; + } case COMMAND_IS_CHAR_SHOOTING: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(pPed->bIsShooting); + return 0; + } case COMMAND_CREATE_MONEY_PICKUP: + { + CollectParameters(&m_nIp, 4); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y) + 0.5f; + CPickups::GetActualPickupIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); + ScriptParams[0] = CPickups::GenerateNewOne(pos, MI_MONEY, PICKUP_MONEY, ScriptParams[3]); + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_SET_CHAR_ACCURACY: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + pPed->m_wepAccuracy = ScriptParams[1]; + return 0; + } case COMMAND_GET_CAR_SPEED: + { + CollectParameters(&m_nIp, 1); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + *(float*)&ScriptParams[0] = pVehicle->GetSpeed().Magnitude() * GAME_SPEED_TO_METERS_PER_SECOND; + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_LOAD_CUTSCENE: + { + char name[8]; + strncpy(name, (const char*)&CTheScripts::ScriptSpace[m_nIp], 8); + m_nIp += 8; + CCutsceneMgr::LoadCutsceneData(name); + return 0; + } case COMMAND_CREATE_CUTSCENE_OBJECT: + { + CollectParameters(&m_nIp, 1); + CCutsceneObject* pCutObj = CCutsceneMgr::CreateCutsceneObject(ScriptParams[0]); + ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pCutObj); + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_SET_CUTSCENE_ANIM: + { + CollectParameters(&m_nIp, 1); + char name[8]; + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + assert(pObject); + strncpy(name, (const char*)&CTheScripts::ScriptSpace[m_nIp], 8); + m_nIp += 8; + CCutsceneMgr::SetCutsceneAnim(name, pObject); + return 0; + } case COMMAND_START_CUTSCENE: + CCutsceneMgr::ms_cutsceneLoadStatus = 1; + return 0; case COMMAND_GET_CUTSCENE_TIME: + ScriptParams[0] = CCutsceneMgr::GetCutsceneTimeInMilleseconds(); + StoreParameters(&m_nIp, 1); + return 0; case COMMAND_HAS_CUTSCENE_FINISHED: + UpdateCompareFlag(CCutsceneMgr::HasCutsceneFinished()); + return 0; case COMMAND_CLEAR_CUTSCENE: + CCutsceneMgr::DeleteCutsceneData(); + return 0; case COMMAND_RESTORE_CAMERA_JUMPCUT: + TheCamera.RestoreWithJumpCut(); + return 0; case COMMAND_CREATE_COLLECTABLE1: + { + CollectParameters(&m_nIp, 3); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y) + 0.5f; + CPickups::GenerateNewOne(pos, MI_COLLECTABLE1, PICKUP_COLLECTABLE1, 0); + return 0; + } case COMMAND_SET_COLLECTABLE1_TOTAL: + CollectParameters(&m_nIp, 1); + CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages = ScriptParams[0]; + return 0; case COMMAND_IS_PROJECTILE_IN_AREA: + { + 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]; + } + UpdateCompareFlag(CProjectileInfo::IsProjectileInRange(infX, supX, infY, supY, infZ, supZ, false)); + if (CTheScripts::DbgFlag) + CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ); + return 0; + } case COMMAND_DESTROY_PROJECTILES_IN_AREA: + { + 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]; + } + UpdateCompareFlag(CProjectileInfo::IsProjectileInRange(infX, supX, infY, supY, infZ, supZ, true)); + if (CTheScripts::DbgFlag) + CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ); + return 0; + } case COMMAND_DROP_MINE: + { + CollectParameters(&m_nIp, 3); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y) + 0.5f; + CPickups::GenerateNewOne(pos, MI_CARMINE, PICKUP_MINE_INACTIVE, 0); + return 0; + } case COMMAND_DROP_NAUTICAL_MINE: + { + CollectParameters(&m_nIp, 3); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y) + 0.5f; + CPickups::GenerateNewOne(pos, MI_NAUTICALMINE, PICKUP_MINE_INACTIVE, 0); + return 0; + } case COMMAND_IS_CHAR_MODEL: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(ScriptParams[1] == pPed->GetModelIndex()); + return 0; + } case COMMAND_LOAD_SPECIAL_MODEL: + { + CollectParameters(&m_nIp, 1); + char name[8]; + strncpy(name, (const char*)&CTheScripts::ScriptSpace[m_nIp], 8); + for (int i = 0; i < 8; i++) + name[i] = tolower(name[i]); + CStreaming::RequestSpecialModel(ScriptParams[0], name, STREAMFLAGS_DEPENDENCY | STREAMFLAGS_SCRIPTOWNED); + m_nIp += 8; + return 0; + } case COMMAND_CREATE_CUTSCENE_HEAD: + { + CollectParameters(&m_nIp, 2); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + assert(pObject); + CCutsceneHead* pCutHead = CCutsceneMgr::AddCutsceneHead(pObject, ScriptParams[1]); + ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pCutHead); + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_SET_CUTSCENE_HEAD_ANIM: + { + CollectParameters(&m_nIp, 1); + CObject* pCutHead = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + assert(pCutHead); + char name[8]; + strncpy(name, (const char*)&CTheScripts::ScriptSpace[m_nIp], 8); + m_nIp += 8; + CTimer::Stop(); + CCutsceneMgr::SetHeadAnim(name, pCutHead); + CTimer::Update(); + return 0; + } case COMMAND_SIN: + CollectParameters(&m_nIp, 1); + *(float*)&ScriptParams[0] = Sin(DEGTORAD(*(float*)&ScriptParams[0])); + StoreParameters(&m_nIp, 1); + return 0; case COMMAND_COS: + CollectParameters(&m_nIp, 1); + *(float*)&ScriptParams[0] = Cos(DEGTORAD(*(float*)&ScriptParams[0])); + StoreParameters(&m_nIp, 1); + return 0; case COMMAND_GET_CAR_FORWARD_X: + { + CollectParameters(&m_nIp, 1); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + float forwardX = pVehicle->GetForward().x / pVehicle->GetForward().Magnitude2D(); + *(float*)&ScriptParams[0] = forwardX; + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_GET_CAR_FORWARD_Y: + { + CollectParameters(&m_nIp, 1); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + float forwardY = pVehicle->GetForward().y / pVehicle->GetForward().Magnitude2D(); + *(float*)&ScriptParams[0] = forwardY; + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_CHANGE_GARAGE_TYPE: + CollectParameters(&m_nIp, 2); + CGarages::ChangeGarageType(ScriptParams[0], ScriptParams[1]); + return 0; case COMMAND_ACTIVATE_CRUSHER_CRANE: + { + CollectParameters(&m_nIp, 10); + float infX = *(float*)&ScriptParams[2]; + float infY = *(float*)&ScriptParams[3]; + float supX = *(float*)&ScriptParams[4]; + float supY = *(float*)&ScriptParams[5]; + if (infX > supX) { + infX = *(float*)&ScriptParams[4]; + supX = *(float*)&ScriptParams[2]; + } + if (infY > supY) { + infY = *(float*)&ScriptParams[5]; + supY = *(float*)&ScriptParams[3]; + } + CCranes::ActivateCrane(infX, supX, infY, supY, + *(float*)&ScriptParams[6], *(float*)&ScriptParams[7], *(float*)&ScriptParams[8], + DEGTORAD(*(float*)&ScriptParams[8]), true, false, + *(float*)&ScriptParams[0], *(float*)&ScriptParams[1]); + return 0; + } case COMMAND_PRINT_WITH_2_NUMBERS: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CollectParameters(&m_nIp, 4); + CMessages::AddMessageWithNumber(text, ScriptParams[2], ScriptParams[3], ScriptParams[0], ScriptParams[1], -1, -1, -1, -1); + return 0; + } case COMMAND_PRINT_WITH_2_NUMBERS_NOW: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CollectParameters(&m_nIp, 4); + CMessages::AddMessageJumpQWithNumber(text, ScriptParams[2], ScriptParams[3], ScriptParams[0], ScriptParams[1], -1, -1, -1, -1); + return 0; + } case COMMAND_PRINT_WITH_2_NUMBERS_SOON: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CollectParameters(&m_nIp, 4); + CMessages::AddMessageSoonWithNumber(text, ScriptParams[2], ScriptParams[3], ScriptParams[0], ScriptParams[1], -1, -1, -1, -1); + return 0; + } case COMMAND_PRINT_WITH_3_NUMBERS: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CollectParameters(&m_nIp, 5); + CMessages::AddMessageWithNumber(text, ScriptParams[3], ScriptParams[4], ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1); + return 0; + } case COMMAND_PRINT_WITH_3_NUMBERS_NOW: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CollectParameters(&m_nIp, 5); + CMessages::AddMessageJumpQWithNumber(text, ScriptParams[3], ScriptParams[4], ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1); + return 0; + } case COMMAND_PRINT_WITH_3_NUMBERS_SOON: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CollectParameters(&m_nIp, 5); + CMessages::AddMessageSoonWithNumber(text, ScriptParams[3], ScriptParams[4], ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1); + return 0; + } case COMMAND_PRINT_WITH_4_NUMBERS: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CollectParameters(&m_nIp, 6); + CMessages::AddMessageWithNumber(text, ScriptParams[4], ScriptParams[5], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1); + return 0; + } case COMMAND_PRINT_WITH_4_NUMBERS_NOW: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CollectParameters(&m_nIp, 6); + CMessages::AddMessageJumpQWithNumber(text, ScriptParams[4], ScriptParams[5], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1); + return 0; + } case COMMAND_PRINT_WITH_4_NUMBERS_SOON: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CollectParameters(&m_nIp, 6); + CMessages::AddMessageSoonWithNumber(text, ScriptParams[4], ScriptParams[5], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1); + return 0; + } case COMMAND_PRINT_WITH_5_NUMBERS: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CollectParameters(&m_nIp, 7); + CMessages::AddMessageWithNumber(text, ScriptParams[5], ScriptParams[6], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1); + return 0; + } case COMMAND_PRINT_WITH_5_NUMBERS_NOW: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CollectParameters(&m_nIp, 7); + CMessages::AddMessageJumpQWithNumber(text, ScriptParams[5], ScriptParams[6], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1); + return 0; + } case COMMAND_PRINT_WITH_5_NUMBERS_SOON: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CollectParameters(&m_nIp, 7); + CMessages::AddMessageSoonWithNumber(text, ScriptParams[5], ScriptParams[6], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1); + return 0; + } case COMMAND_PRINT_WITH_6_NUMBERS: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CollectParameters(&m_nIp, 8); + CMessages::AddMessageWithNumber(text, ScriptParams[6], ScriptParams[7], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], ScriptParams[5]); + return 0; + } case COMMAND_PRINT_WITH_6_NUMBERS_NOW: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CollectParameters(&m_nIp, 8); + CMessages::AddMessageJumpQWithNumber(text, ScriptParams[6], ScriptParams[7], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], ScriptParams[5]); + return 0; + } case COMMAND_PRINT_WITH_6_NUMBERS_SOON: + { + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CollectParameters(&m_nIp, 8); + CMessages::AddMessageSoonWithNumber(text, ScriptParams[6], ScriptParams[7], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], ScriptParams[5]); + return 0; + } case COMMAND_SET_CHAR_OBJ_FOLLOW_CHAR_IN_FORMATION: + { + CollectParameters(&m_nIp, 3); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]); + pPed->bScriptObjectiveCompleted = false; + pPed->SetObjective(OBJECTIVE_FOLLOW_PED_IN_FORMATION, pTargetPed); + pPed->SetFormation((eFormation)ScriptParams[2]); + return 0; + } case COMMAND_PLAYER_MADE_PROGRESS: + CollectParameters(&m_nIp, 1); + CStats::ProgressMade += ScriptParams[0]; + return 0; case COMMAND_SET_PROGRESS_TOTAL: + CollectParameters(&m_nIp, 1); + CStats::TotalProgressInGame = ScriptParams[0]; + return 0; case COMMAND_REGISTER_JUMP_DISTANCE: + CollectParameters(&m_nIp, 1); + CStats::MaximumJumpDistance = max(CStats::MaximumJumpDistance, *(float*)&ScriptParams[0]); + return 0; case COMMAND_REGISTER_JUMP_HEIGHT: + CollectParameters(&m_nIp, 1); + CStats::MaximumJumpHeight = max(CStats::MaximumJumpHeight, *(float*)&ScriptParams[0]); + return 0; case COMMAND_REGISTER_JUMP_FLIPS: + CollectParameters(&m_nIp, 1); + CStats::MaximumJumpFlips = max(CStats::MaximumJumpFlips, ScriptParams[0]); + return 0; case COMMAND_REGISTER_JUMP_SPINS: + CollectParameters(&m_nIp, 1); + CStats::MaximumJumpSpins = max(CStats::MaximumJumpSpins, ScriptParams[0]); + return 0; case COMMAND_REGISTER_JUMP_STUNT: + CollectParameters(&m_nIp, 1); + CStats::BestStuntJump = max(CStats::BestStuntJump, ScriptParams[0]); + return 0; case COMMAND_REGISTER_UNIQUE_JUMP_FOUND: + ++CStats::NumberOfUniqueJumpsFound; + return 0; case COMMAND_SET_UNIQUE_JUMPS_TOTAL: + CollectParameters(&m_nIp, 1); + CStats::TotalNumberOfUniqueJumps = ScriptParams[0]; + return 0; case COMMAND_REGISTER_PASSENGER_DROPPED_OFF_TAXI: + ++CStats::PassengersDroppedOffWithTaxi; + return 0; case COMMAND_REGISTER_MONEY_MADE_TAXI: + CollectParameters(&m_nIp, 1); + CStats::MoneyMadeWithTaxi += ScriptParams[0]; + return 0; case COMMAND_REGISTER_MISSION_GIVEN: + ++CStats::MissionsGiven; + return 0; case COMMAND_REGISTER_MISSION_PASSED: + { + char name[8]; + strncpy(name, (const char*)&CTheScripts::ScriptSpace[m_nIp], 8); + m_nIp += 8; + strncpy(CStats::LastMissionPassedName, name, 8); + ++CStats::MissionsPassed; + CStats::CheckPointReachedSuccessfully(); + return 0; + } case COMMAND_SET_CHAR_RUNNING: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + pPed->bIsRunning = (ScriptParams[1] != 0); + return 0; + } case COMMAND_REMOVE_ALL_SCRIPT_FIRES: + gFireManager.RemoveAllScriptFires(); + return 0; case COMMAND_IS_FIRST_CAR_COLOUR: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + UpdateCompareFlag(pVehicle->m_currentColour1 == ScriptParams[1]); + return 0; + } case COMMAND_IS_SECOND_CAR_COLOUR: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + UpdateCompareFlag(pVehicle->m_currentColour2 == ScriptParams[1]); + return 0; + } case COMMAND_HAS_CHAR_BEEN_DAMAGED_BY_WEAPON: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + if (!pPed) + printf("HAS_CHAR_BEEN_DAMAGED_BY_WEAPON - Character doesn't exist\n"); + UpdateCompareFlag(pPed && pPed->m_lastWepDam == ScriptParams[1]); + return 0; + } case COMMAND_HAS_CAR_BEEN_DAMAGED_BY_WEAPON: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + if (!pVehicle) + printf("HAS_CAR_BEEN_DAMAGED_BY_WEAPON - Vehicle doesn't exist\n"); + UpdateCompareFlag(pVehicle && pVehicle->m_nLastWeaponDamage == ScriptParams[1]); + return 0; + } case COMMAND_IS_CHAR_IN_CHARS_GROUP: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + CPed* pLeader = CPools::GetPedPool()->GetAt(ScriptParams[1]); + assert(pPed); + assert(pLeader); + UpdateCompareFlag(pPed->m_leader == pLeader); + return 0; + } default: assert(0); } diff --git a/src/control/Script.h b/src/control/Script.h index 751ad9d5..fa8344ae 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -1,5 +1,6 @@ #pragma once #include "common.h" +#include "PedType.h" #include "Text.h" #include "Sprite2d.h" @@ -92,6 +93,27 @@ public: m_anLocalVariables[NUM_LOCAL_VARS + 1] += timeStep; } + bool ThisIsAValidRandomPed(uint32 pedtype){ + switch (pedtype){ + case PEDTYPE_CIVMALE: + case PEDTYPE_CIVFEMALE: + case PEDTYPE_GANG1: + case PEDTYPE_GANG2: + case PEDTYPE_GANG3: + case PEDTYPE_GANG4: + case PEDTYPE_GANG5: + case PEDTYPE_GANG6: + case PEDTYPE_GANG7: + case PEDTYPE_GANG8: + case PEDTYPE_GANG9: + case PEDTYPE_CRIMINAL: + case PEDTYPE_PROSTITUTE: + return true; + default: + return false; + } + } + void CollectParameters(uint32*, int16); int32 CollectNextParameterWithoutIncreasingPC(uint32); int32* GetPointerToScriptVariable(uint32*, int16); diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp index 0317ccbe..274c06a5 100644 --- a/src/core/Fire.cpp +++ b/src/core/Fire.cpp @@ -6,6 +6,13 @@ CFireManager &gFireManager = *(CFireManager*)0x8F31D0; WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); } +uint32 CFireManager::GetTotalActiveFires() const +{ + return m_nTotalFires; +} + +WRAPPER void CFireManager::Update(void) { EAXJMP(0x479310); } + CFire* CFireManager::FindNearestFire(CVector vecPos, float* pDistance) { for (int i = 0; i < MAX_FIREMEN_ATTENDING; i++) { @@ -31,6 +38,12 @@ CFire* CFireManager::FindNearestFire(CVector vecPos, float* pDistance) return nil; } -WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); } -WRAPPER void CFireManager::Update(void) { EAXJMP(0x479310); } WRAPPER CFire *CFireManager::FindFurthestFire_NeverMindFireMen(CVector coors, float, float) { EAXJMP(0x479430); } +WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); } +WRAPPER void CFireManager::StartFire(CVector, float, uint8) { EAXJMP(0x479500); } +WRAPPER void CFireManager::ExtinguishPoint(CVector, float) { EAXJMP(0x479DB0); } +WRAPPER int32 CFireManager::StartScriptFire(const CVector& pos, CEntity* culprit, float, uint8) { EAXJMP(0x479E60); } +WRAPPER bool CFireManager::IsScriptFireExtinguish(int16) { EAXJMP(0x479FC0); } +WRAPPER void CFireManager::RemoveScriptFire(int16) { EAXJMP(0x479FE0); } +WRAPPER void CFireManager::RemoveAllScriptFires(void) { EAXJMP(0x47A000); } +WRAPPER void CFireManager::SetScriptFireAudio(int16, bool) { EAXJMP(0x47A040); } diff --git a/src/core/Fire.h b/src/core/Fire.h index c752b2a6..9d72179e 100644 --- a/src/core/Fire.h +++ b/src/core/Fire.h @@ -31,9 +31,16 @@ class CFireManager CFire m_aFires[NUM_FIRES]; public: void StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32); + void StartFire(CVector, float, uint8); void Update(void); CFire *FindFurthestFire_NeverMindFireMen(CVector coors, float, float); CFire *FindNearestFire(CVector, float*); - uint32 GetTotalActiveFires() const { return m_nTotalFires; } + uint32 GetTotalActiveFires() const; + void ExtinguishPoint(CVector, float); + int32 StartScriptFire(const CVector& pos, CEntity* culprit, float, uint8); + bool IsScriptFireExtinguish(int16); + void RemoveScriptFire(int16); + void RemoveAllScriptFires(void); + void SetScriptFireAudio(int16, bool); }; extern CFireManager &gFireManager; diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp index 9641e8f0..5d2401ed 100644 --- a/src/core/Stats.cpp +++ b/src/core/Stats.cpp @@ -12,6 +12,21 @@ int32 *CStats::PedsKilledOfThisType = (int32*)0x880DBC; int32 &CStats::TimesDied = *(int32*)0x8E2BDC; int32 &CStats::TimesArrested = *(int32*)0x8E2BEC; int32 &CStats::KillsSinceLastCheckpoint = *(int32*)0x8F2C8C; +int32 &CStats::ProgressMade = *(int32*)0x8F6224; +int32 &CStats::TotalProgressInGame = *(int32*)0x885B2C; +float &CStats::MaximumJumpDistance = *(float*)0x8F2BDC; +float &CStats::MaximumJumpHeight = *(float*)0x940564; +int32 &CStats::MaximumJumpFlips = *(int32*)0x8F2524; +int32 &CStats::MaximumJumpSpins = *(int32*)0x8F29B0; +int32 &CStats::BestStuntJump = *(int32*)0x885B50; +int32 &CStats::NumberOfUniqueJumpsFound = *(int32*)0x885B74; +int32 &CStats::TotalNumberOfUniqueJumps = *(int32*)0x8E2DC0; +int32 &CStats::PassengersDroppedOffWithTaxi = *(int32*)0x940724; +int32 &CStats::MoneyMadeWithTaxi = *(int32*)0x941544; +int32 &CStats::MissionsGiven = *(int32*)0x9430E8; +int32 &CStats::MissionsPassed = *(int32*)0x940768; +char(&CStats::LastMissionPassedName)[8] = *(char(*)[8])*(uintptr*)0x70D828; +int32 &CStats::TotalLegitimateKills = *(int32*)0x8F6004; void CStats::AnotherKillFrenzyPassed() { diff --git a/src/core/Stats.h b/src/core/Stats.h index 7bae8c51..22f0c68a 100644 --- a/src/core/Stats.h +++ b/src/core/Stats.h @@ -14,8 +14,24 @@ public: static int32 &TimesDied; static int32 &TimesArrested; static int32 &KillsSinceLastCheckpoint; + static int32 &ProgressMade; + static int32 &TotalProgressInGame; + static float &MaximumJumpDistance; + static float &MaximumJumpHeight; + static int32 &MaximumJumpFlips; + static int32 &MaximumJumpSpins; + static int32 &BestStuntJump; + static int32 &NumberOfUniqueJumpsFound; + static int32 &TotalNumberOfUniqueJumps; + static int32 &PassengersDroppedOffWithTaxi; + static int32 &MoneyMadeWithTaxi; + static int32 &MissionsGiven; + static int32 &MissionsPassed; + static char (&LastMissionPassedName)[8]; + static int32 &TotalLegitimateKills; public: static void AnotherKillFrenzyPassed(); static void CheckPointReachedUnsuccessfully() { KillsSinceLastCheckpoint = 0; }; + static void CheckPointReachedSuccessfully() { TotalLegitimateKills += KillsSinceLastCheckpoint; KillsSinceLastCheckpoint = 0; }; }; \ No newline at end of file diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 4e64c1db..11aa480b 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -502,7 +502,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) bChangedSeat = false; bUpdateAnimHeading = false; bBodyPartJustCameOff = false; - m_ped_flagC40 = false; + bIsShooting = false; bFindNewNodeAfterStateRestore = false; bHasACamera = false; @@ -524,8 +524,8 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) bFleeAfterExitingCar = false; bWanderPathAfterExitingCar = false; - m_ped_flagF2 = false; - m_ped_flagF4 = false; + bIsLeader = false; + bDontDragMeOutCar = false; m_ped_flagF8 = false; bWillBeQuickJacked = false; bCancelEnteringCar = false; @@ -533,8 +533,8 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) bDuckAndCover = false; bStillOnValidPoly = false; - m_ped_flagG2 = true; - m_ped_flagG4 = false; + bAllowMedicsToReviveMe = true; + bResetWalkAnims = false; bStartWanderPathOnFoot = false; bOnBoat = false; bBusJacked = false; @@ -543,12 +543,12 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_ped_flagH1 = false; bHitSteepSlope = false; - m_ped_flagH4 = false; + bCullExtraFarAway = false; bClearObjective = false; - m_ped_flagH10 = false; + bTryingToReachDryLand = false; bCollidedWithMyVehicle = false; bRichFromMugging = false; - m_ped_flagH80 = false; + bChrisCriminal = false; bShakeFist = false; bNoCriticalHits = false; @@ -6821,7 +6821,7 @@ CPed::FinishJumpCB(CAnimBlendAssociation *animAssoc, void *arg) { CPed *ped = (CPed*)arg; - ped->m_ped_flagG4 = true; + ped->bResetWalkAnims = true; ped->bIsLanding = false; animAssoc->blendDelta = -1000.0f; @@ -7696,7 +7696,7 @@ CPed::GetNearestDoor(CVehicle *veh, CVector &posToOpen) CPed *rfPassenger = veh->pPassengers[0]; if (!rfPassenger - || rfPassenger->m_leader != this && !rfPassenger->m_ped_flagF4 && (veh->VehicleCreatedBy != MISSION_VEHICLE || m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) + || rfPassenger->m_leader != this && !rfPassenger->bDontDragMeOutCar && (veh->VehicleCreatedBy != MISSION_VEHICLE || m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) || veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, enterOffset) == 0) { if ((veh->m_nGettingInFlags & CAR_DOOR_FLAG_RF) == 0 @@ -9184,7 +9184,7 @@ CPed::ProcessControl(void) } CVisibilityPlugins::SetClumpAlpha(GetClump(), alpha); - m_ped_flagC40 = false; + bIsShooting = false; BuildPedLists(); bIsInWater = false; ProcessBuoyancy(); @@ -10709,7 +10709,7 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg) } if (ped->m_vehEnterType != CAR_DOOR_LF && ped->m_vehEnterType != CAR_DOOR_LR) { - if (pedToDragOut && !pedToDragOut->m_ped_flagF4) { + if (pedToDragOut && !pedToDragOut->bDontDragMeOutCar) { if (pedToDragOut->m_nPedState != PED_DRIVING) { ped->QuitEnteringCar(); pedToDragOut = nil; @@ -10740,9 +10740,9 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg) } } else { if (pedToDragOut) { - if (pedToDragOut->m_nPedState != PED_DRIVING || pedToDragOut->m_ped_flagF4) { + if (pedToDragOut->m_nPedState != PED_DRIVING || pedToDragOut->bDontDragMeOutCar) { - // BUG: Player freezes in that condition due to it's objective isn't restored. It's an unfinished feature, used in VC. + // BUG: Player freezes in that condition due to its objective isn't restored. It's an unfinished feature, used in VC. ped->QuitEnteringCar(); pedToDragOut = nil; } else { @@ -14310,7 +14310,7 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints) if (!collidingEnt->IsVehicle() && !collidingEnt->IsObject()) { m_pCurSurface = collidingEnt; collidingEnt->RegisterReference((CEntity**)&m_pCurSurface); - m_ped_flagH10 = false; + bTryingToReachDryLand = false; bOnBoat = false; } else { m_pCurrentPhysSurface = (CPhysical*)collidingEnt; @@ -14809,9 +14809,9 @@ CPed::ProcessBuoyancy(void) bIsInWater = true; ApplyMoveForce(buoyancyImpulse); if (!DyingOrDead()) { - if (m_ped_flagH10) { + if (bTryingToReachDryLand) { if (buoyancyImpulse.z / m_fMass > 0.0032f * CTimer::GetTimeStep()) { - m_ped_flagH10 = false; + bTryingToReachDryLand = false; CVector pos = GetPosition(); if (PlacePedOnDryLand()) { if (m_fHealth > 20.0f) @@ -15749,7 +15749,7 @@ CPed::SeekCar(void) break; case STATUS_ABANDONED: if (m_vehEnterType == CAR_DOOR_RF && vehToSeek->pPassengers[0]) { - if (vehToSeek->pPassengers[0]->m_ped_flagF4) { + if (vehToSeek->pPassengers[0]->bDontDragMeOutCar) { if (IsPlayer()) CPed::SetEnterCar(vehToSeek, m_vehEnterType); } else { diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 50a8bfec..446aab4b 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -313,7 +313,7 @@ public: uint8 bChangedSeat : 1; uint8 bUpdateAnimHeading : 1; uint8 bBodyPartJustCameOff : 1; - uint8 m_ped_flagC40 : 1; + uint8 bIsShooting : 1; uint8 bFindNewNodeAfterStateRestore : 1; uint8 bHasACamera : 1; // does ped possess a camera to document accidents involves fire/explosion @@ -335,17 +335,17 @@ public: uint8 bFleeAfterExitingCar : 1; uint8 bWanderPathAfterExitingCar : 1; - uint8 m_ped_flagF2 : 1; - uint8 m_ped_flagF4 : 1; // Unfinished feature from VC, probably bDontDragMeOutCar + uint8 bIsLeader : 1; + uint8 bDontDragMeOutCar : 1; uint8 m_ped_flagF8 : 1; uint8 bWillBeQuickJacked : 1; uint8 bCancelEnteringCar : 1; // after door is opened or couldn't be opened due to it's locked uint8 bObstacleShowedUpDuringKillObjective : 1; uint8 bDuckAndCover : 1; - uint8 bStillOnValidPoly : 1; - uint8 m_ped_flagG2 : 1; - uint8 m_ped_flagG4 : 1; // bResetWalkAnims? + uint8 bStillOnValidPoly : 1; // set if the polygon the ped is on is still valid for collision + uint8 bAllowMedicsToReviveMe : 1; + uint8 bResetWalkAnims : 1; uint8 bStartWanderPathOnFoot : 1; // exits the car if he's in it, reset after path found uint8 bOnBoat : 1; // not just driver, may be just standing uint8 bBusJacked : 1; @@ -354,12 +354,12 @@ public: uint8 m_ped_flagH1 : 1; uint8 bHitSteepSlope : 1; // has ped collided/is standing on a steep slope (surface type) - uint8 m_ped_flagH4 : 1; + uint8 bCullExtraFarAway : 1; // special ped only gets culled if it's extra far away (for roadblocks) uint8 bClearObjective : 1; - uint8 m_ped_flagH10 : 1; // bTryingToReachDryLand? reset when we landed on something not vehicle and object + uint8 bTryingToReachDryLand : 1; // has ped just exited boat and trying to get to dry land uint8 bCollidedWithMyVehicle : 1; - uint8 bRichFromMugging : 1; // ped has lots of cash from mugging people - will drop money if someone points gun to him - uint8 m_ped_flagH80 : 1; + uint8 bRichFromMugging : 1; // ped has lots of cash cause they've been mugging people + uint8 bChrisCriminal : 1; // Is a criminal as killed during Chris' police mission (should be counted as such) uint8 bShakeFist : 1; // test shake hand at look entity uint8 bNoCriticalHits : 1; // if set, limbs won't came off diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index 3046a58f..de05a738 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -2,6 +2,7 @@ #include "Physical.h" #include "AutoPilot.h" +#include "ModelIndices.h" class CPed; class CFire; @@ -267,6 +268,7 @@ public: bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1; } CVehicleModelInfo* GetModelInfo() { return (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); } + bool IsTaxi(void) { return GetModelIndex() == MI_TAXI || GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_BORGNINE; } static bool &bWheelsOnlyCheat; static bool &bAllDodosCheat; diff --git a/src/weapons/ProjectileInfo.cpp b/src/weapons/ProjectileInfo.cpp index 50d75516..a915504d 100644 --- a/src/weapons/ProjectileInfo.cpp +++ b/src/weapons/ProjectileInfo.cpp @@ -4,4 +4,5 @@ #include "Projectile.h" -WRAPPER bool CProjectileInfo::RemoveIfThisIsAProjectile(CObject *pObject) { EAXJMP(0x55BBD0); } \ No newline at end of file +WRAPPER bool CProjectileInfo::RemoveIfThisIsAProjectile(CObject *pObject) { EAXJMP(0x55BBD0); } +WRAPPER bool CProjectileInfo::IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove) { EAXJMP(0x55BA50); } diff --git a/src/weapons/ProjectileInfo.h b/src/weapons/ProjectileInfo.h index f4753b28..06ead482 100644 --- a/src/weapons/ProjectileInfo.h +++ b/src/weapons/ProjectileInfo.h @@ -6,4 +6,5 @@ class CProjectileInfo { public: static bool RemoveIfThisIsAProjectile(CObject *pObject); + static bool IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove); }; \ No newline at end of file