From a5b84eb9fe32689f0aee10077854a3652c986c08 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Sun, 17 May 2020 21:43:11 +0300 Subject: [PATCH] full script basic support --- src/animation/AnimBlendAssocGroup.cpp | 4 +- src/control/CarAI.cpp | 16 +- src/control/CarCtrl.cpp | 4 +- src/control/Garages.cpp | 2 +- src/control/Pickups.cpp | 10 + src/control/Pickups.h | 2 + src/control/Script.cpp | 626 +++++++++++++++++++++++--- src/control/Script.h | 6 +- src/core/Camera.cpp | 2 + src/core/Camera.h | 4 +- src/modelinfo/ModelIndices.h | 3 +- src/peds/Ped.cpp | 68 +-- src/peds/Ped.h | 5 +- src/peds/Population.cpp | 4 +- src/vehicles/Automobile.cpp | 17 +- src/vehicles/Automobile.h | 3 + src/vehicles/Vehicle.cpp | 13 +- src/vehicles/Vehicle.h | 13 +- 18 files changed, 675 insertions(+), 127 deletions(-) diff --git a/src/animation/AnimBlendAssocGroup.cpp b/src/animation/AnimBlendAssocGroup.cpp index c5711fda..ef0161db 100644 --- a/src/animation/AnimBlendAssocGroup.cpp +++ b/src/animation/AnimBlendAssocGroup.cpp @@ -104,7 +104,7 @@ strcmpIgnoringDigits(const char *s1, const char *s2) c2 = toupper(c2); #endif - if(c1 != c2) + if(c1 && c2 && c1 != c2) return false; } } @@ -126,6 +126,8 @@ GetModelFromName(const char *name) for(i = 0; i < MODELINFOSIZE; i++){ mi = CModelInfo::GetModelInfo(i); + if (mi && strcmp("drink", mi->GetName()) == 0 && strcmp(name, "drink01") == 0) + debug("TEST"); if(mi && mi->GetRwObject() && RwObjectGetType(mi->GetRwObject()) == rpCLUMP && strcmpIgnoringDigits(mi->GetName(), name)) return mi; diff --git a/src/control/CarAI.cpp b/src/control/CarAI.cpp index 0f80954b..a4406da9 100644 --- a/src/control/CarAI.cpp +++ b/src/control/CarAI.cpp @@ -358,7 +358,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) pVehicle->AutoPilot.m_nCruiseSpeed = FindPoliceCarSpeedForWantedLevel(pVehicle); pVehicle->SetStatus(STATUS_PHYSICS); pVehicle->AutoPilot.m_nCarMission = - pVehicle->GetVehicleAppearance() == VEHICLE_BOAT ? FindPoliceBoatMissionForWantedLevel() : FindPoliceCarMissionForWantedLevel(); + pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT ? FindPoliceBoatMissionForWantedLevel() : FindPoliceCarMissionForWantedLevel(); pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE; pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; }else if (pVehicle->AutoPilot.m_nCarMission == MISSION_CRUISE){ @@ -432,7 +432,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) if (pVehicle->bIsLawEnforcer) { if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_FARAWAY || pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_CLOSE) { - if (FindPlayerVehicle() && FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_BIKE) + if (FindPlayerVehicle() && FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE) pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKPLAYER_FARAWAY; } } @@ -489,16 +489,16 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) if (pVehicle->bIsLawEnforcer && FindPlayerPed()->m_pWanted->m_nWantedLevel > 0) { if (!FindPlayerVehicle() || - FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_CAR || - FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_BIKE) { - if (pVehicle->GetVehicleAppearance() == VEHICLE_BOAT) { + FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_CAR || + FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE) { + if (pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT) { pVehicle->AutoPilot.m_nTempAction = TEMPACT_WAIT; pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 1000; } } - else if (FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_BOAT) { - if (pVehicle->GetVehicleAppearance() == VEHICLE_CAR || - pVehicle->GetVehicleAppearance() == VEHICLE_BIKE) { + else if (FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT) { + if (pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_CAR || + pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE) { pVehicle->AutoPilot.m_nTempAction = TEMPACT_WAIT; pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 1000; } diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp index 956bad28..920fba81 100644 --- a/src/control/CarCtrl.cpp +++ b/src/control/CarCtrl.cpp @@ -655,10 +655,10 @@ CCarCtrl::GenerateOneRandomCar() } int nMadDrivers; switch (pVehicle->GetVehicleAppearance()) { - case VEHICLE_BIKE: + case VEHICLE_APPEARANCE_BIKE: nMadDrivers = 30; break; - case VEHICLE_BOAT: + case VEHICLE_APPEARANCE_BOAT: nMadDrivers = 40; break; default: diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp index 82003561..a177343b 100644 --- a/src/control/Garages.cpp +++ b/src/control/Garages.cpp @@ -960,7 +960,7 @@ void CGarage::Update() if (m_pDoor1) { if (((CVector2D)FindPlayerVehicle()->GetPosition() - (CVector2D)m_pDoor1->GetPosition()).MagnitudeSqr() < SQR(DISTANCE_TO_SHOW_HIDEOUT_MESSAGE) && CTimer::GetTimeInMilliseconds() - CGarages::LastTimeHelpMessage > TIME_BETWEEN_HIDEOUT_MESSAGES) { - if (FindPlayerVehicle()->GetVehicleAppearance() != VEHICLE_HELI && FindPlayerVehicle()->GetVehicleAppearance() != VEHICLE_PLANE) { + if (FindPlayerVehicle()->GetVehicleAppearance() != VEHICLE_APPEARANCE_HELI && FindPlayerVehicle()->GetVehicleAppearance() != VEHICLE_APPEARANCE_PLANE) { CHud::SetHelpMessage(TheText.Get("GA_21"), false); // You cannot store any more cars in this garage. CGarages::LastTimeHelpMessage = CTimer::GetTimeInMilliseconds(); } diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index b2cd1e05..b764eac8 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -1436,3 +1436,13 @@ CPacManPickups::ResetPowerPillsCarriedByPlayer() FindPlayerVehicle()->m_fForceMultiplier = 1.0f; } } + +bool +CPickups::TestForPickupsInBubble(CVector pos, float radius) +{ + for (int i = 0; i < NUMPICKUPS; i++) { + if ((pos - aPickUps[i].m_vecPos).Magnitude() < radius) + return true; + } + return false; +} diff --git a/src/control/Pickups.h b/src/control/Pickups.h index fde3e134..d2d1657b 100644 --- a/src/control/Pickups.h +++ b/src/control/Pickups.h @@ -93,6 +93,8 @@ public: static void Load(uint8 *buf, uint32 size); static void Save(uint8 *buf, uint32 *size); + static bool TestForPickupsInBubble(CVector pos, float radius); + static CPickup aPickUps[NUMPICKUPS]; // unused diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 805d6469..cfa5be46 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -58,11 +58,14 @@ #include "Rubbish.h" #include "Shadows.h" #include "SpecialFX.h" +#include "Sprite.h" #include "Stats.h" #include "Streaming.h" #include "Text.h" +#include "Timecycle.h" #include "TxdStore.h" #include "User.h" +#include "VisibilityPlugins.h" #include "WaterLevel.h" #include "Weather.h" #include "World.h" @@ -70,7 +73,7 @@ #include "main.h" #define PICKUP_PLACEMENT_OFFSET 0.5f -#define PED_FIND_Z_OFFSET 5.0f +#define PED_FIND_Z_OFFSET 10.0f #define SPHERE_MARKER_R 0 #define SPHERE_MARKER_G 128 @@ -285,6 +288,9 @@ void CMissionCleanup::Process() CWorld::Players[0].m_pPed->m_pWanted->m_bIgnoredByCops = false; CWorld::Players[0].m_pPed->m_pWanted->m_bIgnoredByEveryone = false; CWorld::Players[0].MakePlayerSafe(false); + + CVehicle::bDisableRemoteDetonation = false; + CTheScripts::StoreVehicleIndex = -1; CTheScripts::StoreVehicleWasRandom = true; CTheScripts::UpsideDownCars.Init(); @@ -2084,8 +2090,10 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) } else { CVehicle* car; - if (!CModelInfo::IsBikeModel(ScriptParams[0])) - car = new CAutomobile(ScriptParams[0], MISSION_VEHICLE); + + // TODO(MIAMI) + //if (!CModelInfo::IsBikeModel(ScriptParams[0])) + car = new CAutomobile(ScriptParams[0], MISSION_VEHICLE); CVector pos = *(CVector*)&ScriptParams[1]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); @@ -8331,13 +8339,21 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) DMAudio.PreloadMissionAudio(str); return 0; case COMMAND_HAS_MISSION_AUDIO_LOADED: - UpdateCompareFlag(DMAudio.GetMissionAudioLoadingStatus() == 1); + CollectParameters(&m_nIp, 1); + debug("HAS_MISSION_AUDIO_LOADED doesn't support parameter yet, default to TRUE\n"); + UpdateCompareFlag(true); + //UpdateCompareFlag(DMAudio.GetMissionAudioLoadingStatus() == 1); return 0; case COMMAND_PLAY_MISSION_AUDIO: - DMAudio.PlayLoadedMissionAudio(); + CollectParameters(&m_nIp, 1); + debug("PLAY_MISSION_AUDIO doesn't support parameter yet, skipping\n"); + //DMAudio.PlayLoadedMissionAudio(); return 0; case COMMAND_HAS_MISSION_AUDIO_FINISHED: - UpdateCompareFlag(DMAudio.IsMissionAudioSampleFinished()); + CollectParameters(&m_nIp, 1); + debug("HAS_MISSION_AUDIO_FINISHED doesn't support parameter yet, default to TRUE\n"); + UpdateCompareFlag(true); + //UpdateCompareFlag(DMAudio.IsMissionAudioSampleFinished()); return 0; case COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING: { @@ -8650,8 +8666,15 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CStats::RegisterLongestFlightInDodo(ScriptParams[0]); return 0; case COMMAND_GET_OFFSET_FROM_CAR_IN_WORLD_COORDS: - assert(0 && "GET_OFFSET_FROM_CAR_IN_WORLD_COORDS not yet implemented"); + { + CollectParameters(&m_nIp, 4); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + CVector result = pVehicle->GetMatrix() * *(CVector*)&ScriptParams[1] + pVehicle->GetPosition(); + *(CVector*)&ScriptParams[0] = result; + StoreParameters(&m_nIp, 3); return 0; + } case COMMAND_SET_TOTAL_NUMBER_OF_KILL_FRENZIES: CollectParameters(&m_nIp, 1); CStats::SetTotalNumberKillFrenzies(ScriptParams[0]); @@ -9178,7 +9201,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) { char tmp[48]; switch (command) { - case COMMAND_LOAD_COLLISION_WITH_SCREEN: + case COMMAND_LOAD_COLLISION_WITH_SCREEN: // NB: not actually implemented CollectParameters(&m_nIp, 1); CTimer::Stop(); CGame::currLevel = (eLevelName)ScriptParams[0]; @@ -9205,7 +9228,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) m_nIp += 8; LoadSplash(tmp); return 0; - case COMMAND_SET_CAR_IGNORE_LEVEL_TRANSITIONS: + case COMMAND_SET_CAR_IGNORE_LEVEL_TRANSITIONS: // NB: not actually implemented { CollectParameters(&m_nIp, 2); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); @@ -9216,7 +9239,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) pVehicle->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pVehicle->GetPosition()); return 0; } - case COMMAND_MAKE_CRAIGS_CAR_A_BIT_STRONGER: + case COMMAND_MAKE_CRAIGS_CAR_A_BIT_STRONGER: // NB: not actually implemented { CollectParameters(&m_nIp, 2); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); @@ -9240,7 +9263,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) DMAudio.PreloadCutSceneMusic(STREAMED_SOUND_GAME_COMPLETED); printf("End preload end of game audio\n"); return 0; - case COMMAND_ENABLE_PLAYER_CONTROL_CAMERA: + case COMMAND_ENABLE_PLAYER_CONTROL_CAMERA: // NB: not actually implemented CPad::GetPad(0)->DisablePlayerControls &= PLAYERCONTROL_DISABLED_1; return 0; case COMMAND_SET_OBJECT_ROTATION: @@ -9262,11 +9285,11 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) *(CVector*)&ScriptParams[0] = TheCamera.Cams[2].Source; StoreParameters(&m_nIp, 3); return 0; - case COMMAND_GET_DEBUG_CAMERA_FRONT_VECTOR: + case COMMAND_GET_DEBUG_CAMERA_FRONT_VECTOR: // NB: not actually implemented *(CVector*)&ScriptParams[0] = TheCamera.Cams[2].Front; StoreParameters(&m_nIp, 3); return 0; - case COMMAND_IS_PLAYER_TARGETTING_ANY_CHAR: + case COMMAND_IS_PLAYER_TARGETTING_ANY_CHAR: // NB: not actually implemented { CollectParameters(&m_nIp, 1); CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; @@ -9283,10 +9306,38 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CPed* pTestedPed = CPools::GetPedPool()->GetAt(ScriptParams[1]); assert(pTestedPed); CEntity* pTarget = pPed->m_pPointGunAt; - UpdateCompareFlag(pTarget && pTarget->IsPed() && pTarget == pTestedPed); + bool bTargetting = pTarget && pTarget->IsPed() && pTarget == pTestedPed; + // PC shit + static int nCounter = 0; + nCounter = Max(0, nCounter - 1); + if (!pPed->GetWeapon()->IsTypeMelee() && !bTargetting) { + if ((pTarget->GetPosition() - TheCamera.GetPosition()).Magnitude() < 10.0f) { + CVector vTestedPos(pTarget->GetPosition().x, pTarget->GetPosition().y, pTarget->GetPosition().z + 0.4); + CVector vScreenPos; + float w, h; + if (CSprite::CalcScreenCoors(vTestedPos, vScreenPos, &w, &h, false)) { + CVector2D vCrosshairPosition(CCamera::m_f3rdPersonCHairMultX * RsGlobal.maximumWidth, CCamera::m_f3rdPersonCHairMultY * RsGlobal.maximumHeight); + float fScreenDistance = ((CVector2D)vScreenPos - vCrosshairPosition).Magnitude(); + if (SCREEN_STRETCH_X(0.45f) > fScreenDistance / w) { + CColPoint point; + CEntity* entity; + if (!CWorld::ProcessLineOfSight(TheCamera.GetPosition() + 2.0f * TheCamera.GetForward(), + vTestedPos, point, entity, true, true, true, true, true, false) || + entity == pTarget) { + nCounter += 2; + if (nCounter > 20) { + bTargetting = true; + nCounter = 20; + } + } + } + } + } + } + UpdateCompareFlag(bTargetting); return 0; } - case COMMAND_IS_PLAYER_TARGETTING_OBJECT: + case COMMAND_IS_PLAYER_TARGETTING_OBJECT: // NB: not actually implemented { CollectParameters(&m_nIp, 2); CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; @@ -9339,7 +9390,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) case COMMAND_FAIL_CURRENT_MISSION: CTheScripts::FailCurrentMission = 2; return 0; - case COMMAND_GET_CLOSEST_OBJECT_OF_TYPE: + case COMMAND_GET_CLOSEST_OBJECT_OF_TYPE: // NB: actually does nothing { CollectParameters(&m_nIp, 5); CVector pos = *(CVector*)&ScriptParams[0]; @@ -9385,7 +9436,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) StoreParameters(&m_nIp, 1); return 0; } - case COMMAND_PLACE_OBJECT_RELATIVE_TO_OBJECT: + case COMMAND_PLACE_OBJECT_RELATIVE_TO_OBJECT: // NB: not actually implemented { CollectParameters(&m_nIp, 5); CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); @@ -9401,24 +9452,14 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) 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 < ARRAY_SIZE(pVehicle->pPassengers); i++) - { - if (pVehicle->pPassengers[i]) { - pVehicle->pPassengers[i]->bScriptObjectiveCompleted = false; - pVehicle->pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_VEHICLE, pVehicle); - } - } + CCarAI::TellOccupantsToLeaveCar(pVehicle); return 0; } case COMMAND_SET_INTERPOLATION_PARAMETERS: CollectParameters(&m_nIp, 2); - TheCamera.SetParametersForScriptInterpolation(*(float*)&ScriptParams[0], 50.0f - *(float*)&ScriptParams[0], ScriptParams[1]); + TheCamera.SetParametersForScriptInterpolation(*(float*)&ScriptParams[0], 100.0f - *(float*)&ScriptParams[0], ScriptParams[1]); return 0; - case COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_TOWARDS_POINT: + case COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_TOWARDS_POINT: // NB: not actually implemented { CollectParameters(&m_nIp, 5); CVector pos = *(CVector*)&ScriptParams[0]; @@ -9433,7 +9474,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) StoreParameters(&m_nIp, 4); return 0; } - case COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_AWAY_POINT: + case COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_AWAY_POINT: // NB: not actually implemented { CollectParameters(&m_nIp, 5); CVector pos = *(CVector*)&ScriptParams[0]; @@ -9453,10 +9494,12 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) StoreParameters(&m_nIp, 3); return 0; case COMMAND_ATTACH_CHAR_TO_CAR: - // empty implementation + // TODO(MIAMI) + assert(0); return 0; case COMMAND_DETACH_CHAR_FROM_CAR: - // empty implementation + // TODO(MIAMI) + assert(0); return 0; case COMMAND_SET_CAR_CHANGE_LANE: // for some reason changed in SA { @@ -9470,15 +9513,20 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) { CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); - assert(pPed); - pPed->m_lastWepDam = -1; + if (pPed) + pPed->m_lastWepDam = -1; + else + debug("CLEAR_CHAR_LAST_WEAPON_DAMAGE - Character doesn't exist\n"); return 0; } case COMMAND_CLEAR_CAR_LAST_WEAPON_DAMAGE: { CollectParameters(&m_nIp, 1); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); - pVehicle->m_nLastWeaponDamage = -1; + if (pVehicle) + pVehicle->m_nLastWeaponDamage = -1; + else + debug("CLEAR_CAR_LAST_WEAPON_DAMAGE - Vehicle doesn't exist\n"); return 0; } case COMMAND_GET_RANDOM_COP_IN_AREA: @@ -9499,9 +9547,11 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) continue; if (pPed->m_nPedType != PEDTYPE_COP) continue; + if (!ThisIsAValidRandomCop(pPed->GetModelIndex(), ScriptParams[4], ScriptParams[5], ScriptParams[6], ScriptParams[7], ScriptParams[8])) + continue; if (pPed->CharCreatedBy != RANDOM_CHAR) continue; - if (!pPed->IsPedInControl() && pPed->GetPedState() != PED_DRIVING) + if (!pPed->IsPedInControl() && pPed->GetPedState() != PED_DRIVING /* && pPed->GetPedState() != PED_ONROPE */) // TODO(MIAMI)! continue; if (pPed->bRemoveFromWorld) continue; @@ -9527,7 +9577,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) StoreParameters(&m_nIp, 1); return 0; } - case COMMAND_GET_RANDOM_COP_IN_ZONE: + case COMMAND_GET_RANDOM_COP_IN_ZONE: // NB: not actually implemented { char zone[KEY_LENGTH_IN_SCRIPT]; strncpy(zone, (const char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT); @@ -9631,7 +9681,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CollectParameters(&m_nIp, 1); CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; assert(pPed); - ScriptParams[0] = pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType; + ScriptParams[0] = pPed->GetWeapon()->m_eWeaponType; StoreParameters(&m_nIp, 1); return 0; } @@ -9640,7 +9690,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); assert(pPed); - ScriptParams[0] = pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType; + ScriptParams[0] = pPed->GetWeapon()->m_eWeaponType; StoreParameters(&m_nIp, 1); return 0; } @@ -9661,7 +9711,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + ScriptParams[2]; return 0; } - case COMMAND_SET_CAR_HANDBRAKE_TURN_RIGHT: + case COMMAND_SET_CAR_HANDBRAKE_TURN_RIGHT: // NB: not actually implemented { CollectParameters(&m_nIp, 2); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); @@ -9670,7 +9720,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + ScriptParams[1]; return 0; } - case COMMAND_SET_CAR_HANDBRAKE_STOP: + case COMMAND_SET_CAR_HANDBRAKE_STOP: // NB: not actually implemented { CollectParameters(&m_nIp, 2); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); @@ -9684,11 +9734,11 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); assert(pPed); - UpdateCompareFlag(pPed->bInVehicle&& pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_BIKE); + UpdateCompareFlag(pPed->bInVehicle&& pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE); return 0; } - case COMMAND_LOCATE_SNIPER_BULLET_2D: - case COMMAND_LOCATE_SNIPER_BULLET_3D: + case COMMAND_LOCATE_SNIPER_BULLET_2D: // NB: not actually implemented + case COMMAND_LOCATE_SNIPER_BULLET_3D: // NB: not actually implemented LocateSniperBulletCommand(command, &m_nIp); return 0; case COMMAND_GET_NUMBER_OF_SEATS_IN_MODEL: @@ -9701,10 +9751,10 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) 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); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE); return 0; } - case COMMAND_IS_CHAR_LYING_DOWN: + case COMMAND_IS_CHAR_LYING_DOWN: // NB: not actually implemented { CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); @@ -9736,14 +9786,39 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CPed::nThreatReactionRangeMultiplier = *(float*)&ScriptParams[0]; return 0; case COMMAND_SET_CHAR_CEASE_ATTACK_TIMER: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + pPed->m_ceaseAttackTimer = ScriptParams[1]; + return 0; + } case COMMAND_GET_REMOTE_CONTROLLED_CAR: + { + CollectParameters(&m_nIp, 1); + CVehicle* pVehicle = CWorld::Players[ScriptParams[0]].m_pRemoteVehicle; + if (pVehicle) + ScriptParams[0] = CPools::GetVehiclePool()->GetIndex(pVehicle); + else + ScriptParams[0] = -1; + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_IS_PC_VERSION: - case COMMAND_REPLAY: - case COMMAND_IS_REPLAY_PLAYING: + UpdateCompareFlag(true); + return 0; + //case COMMAND_REPLAY: + //case COMMAND_IS_REPLAY_PLAYING: case COMMAND_IS_MODEL_AVAILABLE: + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(CModelInfo::GetModelInfo(ScriptParams[0]) != nil); + return 0; case COMMAND_SHUT_CHAR_UP: + assert("SHUT_CHAR_UP not implemented"); // TODO(MIAMI) case COMMAND_SET_ENABLE_RC_DETONATE: - assert(0); + CollectParameters(&m_nIp, 1); + CVehicle::bDisableRemoteDetonation = ScriptParams[0]; + return 0; case COMMAND_SET_CAR_RANDOM_ROUTE_SEED: { CollectParameters(&m_nIp, 2); @@ -9753,40 +9828,232 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) return 0; } case COMMAND_IS_ANY_PICKUP_AT_COORDS: - case COMMAND_GET_FIRST_PICKUP_COORDS: - case COMMAND_GET_NEXT_PICKUP_COORDS: + { + CollectParameters(&m_nIp, 3); + CVector pos = *(CVector*)&ScriptParams[0]; + bool bFound = false; + for (int i = 0; i < NUMPICKUPS; i++) { + if ((CPickups::aPickUps[i].m_vecPos - pos).Magnitude() < 0.5f) + bFound = true; + } + UpdateCompareFlag(bFound); + return 0; + } + //case COMMAND_GET_FIRST_PICKUP_COORDS: + //case COMMAND_GET_NEXT_PICKUP_COORDS: case COMMAND_REMOVE_ALL_CHAR_WEAPONS: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + pPed->ClearWeapons(); + return 0; + } case COMMAND_HAS_PLAYER_GOT_WEAPON: - case COMMAND_HAS_CHAR_GOT_WEAPON: - case COMMAND_IS_PLAYER_FACING_CHAR: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + bool bFound = false; + for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) { + if (pPed->GetWeapon(i).m_eWeaponType == ScriptParams[1]) { + bFound = true; + break; + } + } + UpdateCompareFlag(bFound); + return 0; + } + //case COMMAND_HAS_CHAR_GOT_WEAPON: + //case COMMAND_IS_PLAYER_FACING_CHAR: case COMMAND_SET_TANK_DETONATE_CARS: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle && pVehicle->m_vehType == VEHICLE_TYPE_CAR); + ((CAutomobile*)pVehicle)->bTankDetonateCars = ScriptParams[1]; + return 0; + } case COMMAND_GET_POSITION_OF_ANALOGUE_STICKS: + { + CollectParameters(&m_nIp, 1); + CPad* pPad = CPad::GetPad(ScriptParams[0]); + ScriptParams[0] = pPad->NewState.LeftStickX; + ScriptParams[1] = pPad->NewState.LeftStickY; + ScriptParams[2] = pPad->NewState.RightStickX; + ScriptParams[3] = pPad->NewState.RightStickY; + StoreParameters(&m_nIp, 4); + return 0; + } case COMMAND_IS_CAR_ON_FIRE: + { + CollectParameters(&m_nIp, 1); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + bool bOnFire = false; + if (pVehicle->m_pCarFire) + bOnFire = true; + if (pVehicle->m_vehType == VEHICLE_TYPE_CAR && ((CAutomobile*)pVehicle)->Damage.GetEngineStatus() >= ENGINE_STATUS_ON_FIRE) + bOnFire = true; + if (pVehicle->m_fHealth < 250.0f) + bOnFire = true; + UpdateCompareFlag(bOnFire); + return 0; + } case COMMAND_IS_CAR_TYRE_BURST: - case COMMAND_SET_CAR_DRIVE_STRAIGHT_AHEAD: - case COMMAND_SET_CAR_WAIT: - case COMMAND_IS_PLAYER_STANDING_ON_A_VEHICLE: - case COMMAND_IS_PLAYER_FOOT_DOWN: - case COMMAND_IS_CHAR_FOOT_DOWN: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + bool bIsBurst = false; + if (pVehicle->m_vehType == VEHICLE_APPEARANCE_BIKE) { + assert("IS_CAR_TYPE_BURST not yet implemented for bikes"); + } + else { + CAutomobile* pCar = (CAutomobile*)pVehicle; + if (ScriptParams[1] == 4) { + for (int i = 0; i < 4; i++) { + if (pCar->Damage.GetWheelStatus(i) == WHEEL_STATUS_BURST) + bIsBurst = true; + } + } + else + bIsBurst = pCar->Damage.GetWheelStatus(ScriptParams[1] == WHEEL_STATUS_BURST); + } + UpdateCompareFlag(bIsBurst); + } + //case COMMAND_SET_CAR_DRIVE_STRAIGHT_AHEAD: + //case COMMAND_SET_CAR_WAIT: + //case COMMAND_IS_PLAYER_STANDING_ON_A_VEHICLE: + //case COMMAND_IS_PLAYER_FOOT_DOWN: + //case COMMAND_IS_CHAR_FOOT_DOWN: case COMMAND_INITIALISE_OBJECT_PATH: + // TODO(MIAMI): script path + CollectParameters(&m_nIp, 2); + debug("INITALISE_OBJECT_PATH not yet implemented, skipping\n"); + ScriptParams[0] = 0; + StoreParameters(&m_nIp, 1); + return 0; case COMMAND_START_OBJECT_ON_PATH: + { + CollectParameters(&m_nIp, 2); + debug("START_OBJECT_ON_PATH not yet implemented, skipping\n"); + return 0; + } case COMMAND_SET_OBJECT_PATH_SPEED: + { + CollectParameters(&m_nIp, 2); + debug("SET_OBJECT_PATH_SPEED not yet implemented, skipping\n"); + return 0; + } case COMMAND_SET_OBJECT_PATH_POSITION: - case COMMAND_GET_OBJECT_DISTANCE_ALONG_PATH: + { + CollectParameters(&m_nIp, 2); + debug("SET_OBJECT_PATH_POSITION not yet implemented, skipping\n"); + return 0; + } + //case COMMAND_GET_OBJECT_DISTANCE_ALONG_PATH: case COMMAND_CLEAR_OBJECT_PATH: + { + CollectParameters(&m_nIp, 1); + debug("CLEAR_OBJECT_PATH not yet implemented, skipping\n"); + return 0; + } case COMMAND_HELI_GOTO_COORDS: + { + CollectParameters(&m_nIp, 5); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle && pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI); + ((CAutomobile*)pVehicle)->TellHeliToGoToCoors(*(float*)&ScriptParams[1], *(float*)&ScriptParams[2], *(float*)&ScriptParams[3], ScriptParams[4]); + return 0; + } case COMMAND_IS_INT_VAR_EQUAL_TO_CONSTANT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr = ScriptParams[0]); + return 0; + } case COMMAND_IS_INT_LVAR_EQUAL_TO_CONSTANT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr = ScriptParams[0]); + return 0; + } case COMMAND_GET_DEAD_CHAR_PICKUP_COORDS: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + pPed->CreateDeadPedPickupCoors((float*)&ScriptParams[0], (float*)&ScriptParams[1], (float*)&ScriptParams[2]); + StoreParameters(&m_nIp, 3); + return 0; + } case COMMAND_CREATE_PROTECTION_PICKUP: + { + CollectParameters(&m_nIp, 5); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= MAP_Z_LOW_LIMIT) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y) + PICKUP_PLACEMENT_OFFSET; + ScriptParams[0] = CPickups::GenerateNewOne(pos, MI_PICKUP_REVENUE, PICKUP_ASSET_REVENUE, ScriptParams[3], ScriptParams[4]); + StoreParameters(&m_nIp, 1); + return 0; + } case COMMAND_IS_CHAR_IN_ANY_BOAT: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT); + return 0; + } case COMMAND_IS_PLAYER_IN_ANY_BOAT: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE); + return 0; + } case COMMAND_IS_CHAR_IN_ANY_HELI: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI); + return 0; + } case COMMAND_IS_PLAYER_IN_ANY_HELI: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI); + return 0; + } case COMMAND_IS_CHAR_IN_ANY_PLANE: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE); + return 0; + } case COMMAND_IS_PLAYER_IN_ANY_PLANE: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI); + return 0; + } case COMMAND_IS_CHAR_IN_WATER: - assert(0); + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + UpdateCompareFlag(pPed && pPed->bIsInWater); + return 0; + } case COMMAND_SET_VAR_INT_TO_CONSTANT: { int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); @@ -9812,17 +10079,74 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) { switch (command) { case COMMAND_IS_INT_VAR_GREATER_THAN_CONSTANT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr > ScriptParams[0]); + return 0; + } case COMMAND_IS_INT_LVAR_GREATER_THAN_CONSTANT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr > ScriptParams[0]); + return 0; + } case COMMAND_IS_CONSTANT_GREATER_THAN_INT_VAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + UpdateCompareFlag(ScriptParams[0] > *ptr); + return 0; + } case COMMAND_IS_CONSTANT_GREATER_THAN_INT_LVAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(ScriptParams[0] > *ptr); + return 0; + } case COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_CONSTANT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr >= ScriptParams[0]); + return 0; + } case COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_CONSTANT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(*ptr >= ScriptParams[0]); + return 0; + } case COMMAND_IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_VAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(ScriptParams[0] >= *ptr); + return 0; + } case COMMAND_IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_LVAR: + { + CollectParameters(&m_nIp, 1); + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + UpdateCompareFlag(ScriptParams[0] >= *ptr); + return 0; + } case COMMAND_GET_CHAR_WEAPON_IN_SLOT: case COMMAND_GET_CLOSEST_STRAIGHT_ROAD: - case COMMAND_SET_CAR_FORWARD_SPEED: assert(0); + case COMMAND_SET_CAR_FORWARD_SPEED: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + float speed = *(float*)&ScriptParams[1] / GAME_SPEED_TO_CARAI_SPEED; + pVehicle->SetMoveSpeed(pVehicle->GetForward() * speed); + // TODO(MIAMI): heli hack! + return 0; + } case COMMAND_SET_AREA_VISIBLE: CollectParameters(&m_nIp, 1); CGame::currArea = ScriptParams[0]; @@ -9850,7 +10174,15 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) case COMMAND_SET_CHAR_OBJ_AIM_GUN_AT_CHAR: case COMMAND_SWITCH_SECURITY_CAMERA: case COMMAND_IS_CHAR_IN_FLYING_VEHICLE: + assert(0); case COMMAND_IS_PLAYER_IN_FLYING_VEHICLE: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + UpdateCompareFlag(pPed->bInVehicle && (pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI || pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE)); + return 0; + } case COMMAND_HAS_SONY_CD_BEEN_READ: case COMMAND_GET_NUMBER_OF_SONY_CDS_READ: case COMMAND_ADD_SHORT_RANGE_BLIP_FOR_COORD_OLD: @@ -9948,11 +10280,36 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) case COMMAND_SET_CHAR_AS_PLAYER_FRIEND: case COMMAND_DISPLAY_NTH_ONSCREEN_COUNTER: case COMMAND_DISPLAY_NTH_ONSCREEN_COUNTER_WITH_STRING: + assert(0); case COMMAND_ADD_SET_PIECE: + { + CollectParameters(&m_nIp, 13); + debug("ADD_SET_PIECE not implemented, skipping\n"); + return 0; + } case COMMAND_SET_EXTRA_COLOURS: + { + CollectParameters(&m_nIp, 2); + debug("SET_EXTRA_COLOURS not implemented, skipping\n"); + return 0; + } case COMMAND_CLEAR_EXTRA_COLOURS: + { + CollectParameters(&m_nIp, 1); + debug("CLEAR_EXTRA_COLOURS not implemented, skipping\n"); + return 0; + } case COMMAND_CLOSE_CAR_BOOT: + assert(0); case COMMAND_GET_WHEELIE_STATS: + { + CollectParameters(&m_nIp, 1); + debug("GET_WHEELIE_STATS not implemented, skipping\n"); + for (int i = 0; i < 6; i++) + ScriptParams[i] = 0; + StoreParameters(&m_nIp, 6); + return 0; + } case COMMAND_DISARM_CHAR: case COMMAND_BURST_CAR_TYRE: case COMMAND_IS_CHAR_OBJ_NO_OBJ: @@ -10023,7 +10380,12 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) case COMMAND_DISPLAY_TEXT_WITH_3_NUMBERS: case COMMAND_IS_CAR_DROWNING_IN_WATER: case COMMAND_IS_CHAR_DROWNING_IN_WATER: + assert(0); case COMMAND_DISABLE_CUTSCENE_SHADOWS: + { + debug("DISABLE_CUTSCENE_SHADOWS not implemented, skipping\n"); + return 0; + } case COMMAND_HAS_GLASS_BEEN_SHATTERED_NEARBY: case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_BONE: case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_COMPONENT: @@ -10065,7 +10427,15 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) case COMMAND_CLEAR_CHAR_FOLLOW_PATH: case COMMAND_SET_CHAR_CAN_BE_SHOT_IN_VEHICLE: case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_VEHICLE: + assert(0); case COMMAND_LOAD_MISSION_TEXT: + { + char key[8]; + CTheScripts::ReadTextLabelFromScript(&m_nIp, key); + m_nIp += KEY_LENGTH_IN_SCRIPT; + debug("skipping LOAD_MISSION_TEXT\n"); + return 0; + } case COMMAND_SET_TONIGHTS_EVENT: case COMMAND_CLEAR_CHAR_LAST_DAMAGE_ENTITY: case COMMAND_CLEAR_CAR_LAST_DAMAGE_ENTITY: @@ -10080,6 +10450,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) case COMMAND_SET_CHAR_OBJ_GOTO_CAR_ON_FOOT: case COMMAND_GET_CLOSEST_WATER_NODE: case COMMAND_ADD_PORN_LEAFLET_TO_RUBBISH: + assert(0); case COMMAND_CREATE_CLOTHES_PICKUP: { CollectParameters(&m_nIp, 4); @@ -10117,7 +10488,64 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) return 0; } case COMMAND_CREATE_RANDOM_CHAR_AS_DRIVER: + { + CollectParameters(&m_nIp, 1); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + CPed* pPed = CPopulation::AddPedInCar(pVehicle, true); + pPed->CharCreatedBy = MISSION_CHAR; + pPed->bRespondsToThreats = false; + pPed->bAllowMedicsToReviveMe = false; + // TODO(MIAMI): two more flags and more stuff + pPed->SetPosition(pVehicle->GetPosition()); + pPed->SetOrientation(0.0f, 0.0f, 0.0f); + pPed->SetPedState(PED_DRIVING); + pPed->m_pMyVehicle = pVehicle; + pPed->m_pMyVehicle->RegisterReference((CEntity**)&pPed->m_pMyVehicle); + pVehicle->pDriver = pPed; + pVehicle->pDriver->RegisterReference((CEntity**)&pVehicle->pDriver); + pPed->bInVehicle = true; + pVehicle->SetStatus(STATUS_PHYSICS); + if (pVehicle->m_vehType == VEHICLE_TYPE_BOAT) + pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE; + pVehicle->bEngineOn = true; + pVehicle->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pVehicle->GetPosition()); + CPopulation::ms_nTotalMissionPeds++; + ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); + StoreParameters(&m_nIp, 1); + if (m_bIsMissionScript) + CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + return 0; + } case COMMAND_CREATE_RANDOM_CHAR_AS_PASSENGER: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + CPed* pPed = CPopulation::AddPedInCar(pVehicle, false); + pPed->CharCreatedBy = MISSION_CHAR; + pPed->bRespondsToThreats = false; + pPed->bAllowMedicsToReviveMe = false; + // TODO(MIAMI): two more flags and more stuff (ClearFollowPath) + pPed->SetPosition(pVehicle->GetPosition()); + pPed->SetOrientation(0.0f, 0.0f, 0.0f); + CPopulation::ms_nTotalMissionPeds++; + pVehicle->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pVehicle->GetPosition()); + if (ScriptParams[1] >= 0) + pVehicle->AddPassenger(pPed, ScriptParams[1]); + else + pVehicle->AddPassenger(pPed); + + pPed->m_pMyVehicle = pVehicle; + pPed->m_pMyVehicle->RegisterReference((CEntity**)&pPed->m_pMyVehicle); + pPed->bInVehicle = true; + // TODO + pPed->SetPedState(PED_DRIVING); + + ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); + StoreParameters(&m_nIp, 1); + if (m_bIsMissionScript) + CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + return 0; + } case COMMAND_SET_CHAR_IGNORE_THREATS_BEHIND_OBJECTS: case COMMAND_ENSURE_PLAYER_HAS_DRIVE_BY_WEAPON: case COMMAND_MAKE_HELI_COME_CRASHING_DOWN: @@ -10134,12 +10562,31 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) case COMMAND_WAS_VEHICLE_EVER_POLICE: case COMMAND_SET_CHAR_NEVER_TARGETTED: case COMMAND_LOAD_UNCOMPRESSED_ANIM: + assert(0); case COMMAND_WAS_CUTSCENE_SKIPPED: + { + debug("WAS_CUTSCENE_SKIPPED is not implemented, defaulted to TRUE\n"); + UpdateCompareFlag(true); + return 0; + } case COMMAND_SET_CHAR_CROUCH_WHEN_THREATENED: + { + CollectParameters(&m_nIp, 2); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + debug("SET_CHAR_CROUCH_WHEN_THREATENED not implemented, skipping\n"); + return 0; + } case COMMAND_IS_CHAR_IN_ANY_POLICE_VEHICLE: + { + CollectParameters(&m_nIp, 1); + debug("IS_CHAR_IN_ANY_POLICE_VEHICLE is not implemented, defaulted to FALSE\n"); + UpdateCompareFlag(false); + return 0; + } case COMMAND_DOES_CHAR_EXIST: case COMMAND_DOES_VEHICLE_EXIST: case COMMAND_ADD_SHORT_RANGE_BLIP_FOR_CONTACT_POINT: + assert(0); case COMMAND_ADD_SHORT_RANGE_SPRITE_BLIP_FOR_CONTACT_POINT: { CollectParameters(&m_nIp, 4); @@ -10177,14 +10624,37 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) CGarages::SetMaxNumStoredCarsForGarage(ScriptParams[0], ScriptParams[1]); break; case COMMAND_WANTED_STARS_ARE_FLASHING: + { + debug("WANTED_STARS_ARE_FLASHING not implemented, default to FALSE\n"); + UpdateCompareFlag(false); + return 0; + } case COMMAND_SET_ALLOW_HURRICANES: + CollectParameters(&m_nIp, 1); + CStats::NoMoreHurricanes = ScriptParams[0]; + return 0; case COMMAND_PLAY_ANNOUNCEMENT: + { + CollectParameters(&m_nIp, 1); + debug("PLAY_ANNOUNCEMENT not implemented, skipping\n"); + return 0; + } case COMMAND_SET_PLAYER_IS_IN_STADIUM: case COMMAND_GET_BUS_FARES_COLLECTED_BY_PLAYER: case COMMAND_SET_CHAR_OBJ_BUY_ICE_CREAM: case COMMAND_DISPLAY_RADAR: case COMMAND_REGISTER_BEST_POSITION: + assert(0); case COMMAND_IS_PLAYER_IN_INFO_ZONE: + { + CollectParameters(&m_nIp, 1); + char key[KEY_LENGTH_IN_SCRIPT]; + CTheScripts::ReadTextLabelFromScript(&m_nIp, key); + m_nIp += KEY_LENGTH_IN_SCRIPT; + debug("IS_PLAYER_IN_INFO_ZONE not implemented, default to FALSE\n"); + UpdateCompareFlag(false); + return 0; + } case COMMAND_CLEAR_CHAR_ICE_CREAM_PURCHASE: case COMMAND_IS_IN_CAR_FIRE_BUTTON_PRESSED: case COMMAND_HAS_CHAR_ATTEMPTED_ATTRACTOR: @@ -10199,6 +10669,11 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) StoreParameters(&m_nIp, 1); return 0; case COMMAND_SET_SHORTCUT_PICKUP_POINT: + { + CollectParameters(&m_nIp, 4); + debug("SET_SHORTCUT_PICKUP_POINT not implemented, skipping\n"); + return 0; + } case COMMAND_SET_SHORTCUT_DROPOFF_POINT_FOR_MISSION: case COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_AREA: case COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_ZONE: @@ -10209,9 +10684,23 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) CGangs::SetWillAttackPlayerWithCops((ePedType)((int)PEDTYPE_GANG1 + ScriptParams[0]), !!ScriptParams[1]); return 0; case COMMAND_SET_CHAR_FRIGHTENED_IN_JACKED_CAR: + assert(0); case COMMAND_SET_VEHICLE_TO_FADE_IN: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), ScriptParams[1]); + return 0; + } case COMMAND_REGISTER_ODDJOB_MISSION_PASSED: + assert(0); case COMMAND_IS_PLAYER_IN_SHORTCUT_TAXI: + { + CollectParameters(&m_nIp, 1); + debug("IS_PLAYER_IN_SHORTCUT_TAXI not implemented, default to FALSE\n"); + return 0; + } case COMMAND_IS_CHAR_DUCKING: case COMMAND_CREATE_DUST_EFFECT_FOR_CUTSCENE_HELI: case COMMAND_REGISTER_FIRE_LEVEL: @@ -10223,6 +10712,19 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) return -1; } +bool CRunningScript::ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami) +{ + switch (mi) + { + case MI_COP: if (cop) return true; + case MI_SWAT: if (swat) return true; + case MI_FBI: if (fbi) return true; + case MI_ARMY: if (army) return true; + default: + return miami && (mi >= MI_VICE1 && mi <= MI_VICE8); + } +} + int32 CTheScripts::GetNewUniqueScriptSphereIndex(int32 index) { if (ScriptSphereArray[index].m_Index >= UINT16_MAX - 1) diff --git a/src/control/Script.h b/src/control/Script.h index 9931f13e..c7a6e1e6 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -221,8 +221,8 @@ enum { }; enum { - SIZE_MAIN_SCRIPT = 128 * 1024, - SIZE_MISSION_SCRIPT = 32 * 1024, + SIZE_MAIN_SCRIPT = 225512, + SIZE_MISSION_SCRIPT = 35000, SIZE_SCRIPT_SPACE = SIZE_MAIN_SCRIPT + SIZE_MISSION_SCRIPT }; @@ -507,4 +507,6 @@ private: return false; } } + + static bool ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami); }; diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 623b2ea9..1efe6bae 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -61,6 +61,8 @@ enum CCamera TheCamera; bool CCamera::m_bUseMouse3rdPerson = true; bool bDidWeProcessAnyCinemaCam; +float CCamera::m_f3rdPersonCHairMultX; +float CCamera::m_f3rdPersonCHairMultY; #ifdef IMPROVED_CAMERA #define KEYJUSTDOWN(k) ControlsManager.GetIsKeyboardKeyJustDown((RsKeyCodes)k) diff --git a/src/core/Camera.h b/src/core/Camera.h index 80fc878e..8f2b6c51 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -472,8 +472,8 @@ public: // not static yet float m_fMouseAccelHorzntl;// acceleration multiplier for 1st person controls float m_fMouseAccelVertical;// acceleration multiplier for 1st person controls - float m_f3rdPersonCHairMultX; - float m_f3rdPersonCHairMultY; + static float m_f3rdPersonCHairMultX; + static float m_f3rdPersonCHairMultY; CCam Cams[3]; diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h index 3a53074d..5a3bee9f 100644 --- a/src/modelinfo/ModelIndices.h +++ b/src/modelinfo/ModelIndices.h @@ -161,7 +161,8 @@ X("files", MI_FILES, 0x5F5BC4) \ X("property_locked", MI_PICKUP_PROPERTY, 0x0) \ X("property_fsale", MI_PICKUP_PROPERTY_FORSALE, 0x0) \ - X("clothesp", MI_PICKUP_CLOTHES, 0x0) + X("clothesp", MI_PICKUP_CLOTHES, 0x0) \ + X("bigdollar", MI_PICKUP_REVENUE, 0x0) #define X(name, var, addr) extern int16 var; MODELINDICES diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 8da8249e..1d872b9c 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -534,6 +534,8 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_fAirResistance = 0.4f / m_fMass; m_fElasticity = 0.05f; + m_ceaseAttackTimer = 0; + bIsStanding = false; bWasStanding = false; bIsAttacking = false; @@ -6326,8 +6328,6 @@ CPed::CreateDeadPedMoney(void) void CPed::CreateDeadPedWeaponPickups(void) { - bool found = false; - float angleToPed; CVector pickupPos; if (bInVehicle) @@ -6340,34 +6340,10 @@ CPed::CreateDeadPedWeaponPickups(void) if (weapon == WEAPONTYPE_UNARMED || weapon == WEAPONTYPE_DETONATOR || (weaponAmmo == 0 && !GetWeapon(i).IsTypeMelee())) continue; - angleToPed = i * 1.75f; - pickupPos = GetPosition(); - pickupPos.x += 1.5f * Sin(angleToPed); - pickupPos.y += 1.5f * Cos(angleToPed); - pickupPos.z = CWorld::FindGroundZFor3DCoord(pickupPos.x, pickupPos.y, pickupPos.z, &found) + 0.5f; - - CVector pedPos = GetPosition(); - pedPos.z += 0.3f; - - CVector pedToPickup = pickupPos - pedPos; - float distance = pedToPickup.Magnitude(); - - // outer edge of pickup - distance = (distance + 0.3f) / distance; - CVector pickupPos2 = pedPos; - pickupPos2 += distance * pedToPickup; - - // pickup must be on ground and line to its edge must be clear - if (!found || CWorld::GetIsLineOfSightClear(pickupPos2, pedPos, true, false, false, false, false, false, false)) { - // otherwise try another position (but disregard second check apparently) - angleToPed += 3.14f; - pickupPos = GetPosition(); - pickupPos.x += 1.5f * Sin(angleToPed); - pickupPos.y += 1.5f * Cos(angleToPed); - pickupPos.z = CWorld::FindGroundZFor3DCoord(pickupPos.x, pickupPos.y, pickupPos.z, &found) + 0.5f; - } - if (found) - CPickups::GenerateNewOne_WeaponType(pickupPos, weapon, PICKUP_ONCE_TIMEOUT, Min(weaponAmmo, AmmoForWeapon_OnStreet[weapon])); + CreateDeadPedPickupCoors(&pickupPos.x, &pickupPos.y, &pickupPos.z); + pickupPos.z += 0.4f; + // TODO(MIAMI): there is more stuff it seems + CPickups::GenerateNewOne_WeaponType(pickupPos, weapon, PICKUP_ONCE_TIMEOUT, Min(weaponAmmo, AmmoForWeapon_OnStreet[weapon])); } ClearWeapons(); } @@ -18466,4 +18442,36 @@ CPed::ClearFollowPath() } m_nPathNodes = 0; m_nCurPathNode = 0; +} + +void +CPed::CreateDeadPedPickupCoors(float* x, float* y, float* z) +{ + for (int i = 0; i < 32; i++) { + CVector pickupPos = GetPosition(); + pickupPos.x += 1.5f * Sin(CGeneral::GetRandomNumberInRange(0.0f, TWOPI)); + pickupPos.y += 1.5f * Cos(CGeneral::GetRandomNumberInRange(0.0f, TWOPI)); + bool found; + pickupPos.z = CWorld::FindGroundZFor3DCoord(pickupPos.x, pickupPos.y, pickupPos.z, &found) + 0.5f; + if (!found) + continue; + CVector vPedPos = GetPosition(); + vPedPos.z += 0.3f; + CVector vTestPos = vPedPos + (pickupPos - vPedPos) * (((pickupPos - vPedPos).Magnitude() + 0.4f) / (pickupPos - vPedPos).Magnitude()); + if ((vTestPos - FindPlayerCoors()).Magnitude2D() > 2.0f || i > 16) { + if (i > 16 || CPickups::TestForPickupsInBubble(pickupPos, 1.3f)) { + if (CWorld::GetIsLineOfSightClear(vTestPos, vPedPos, true, i < 16, false, i < 16, false, false)) { + if (i > 16 || !CWorld::TestSphereAgainstWorld(pickupPos, 1.2f, nil, false, true, false, false, false, false)) { + *x = pickupPos.x; + *y = pickupPos.y; + *z = pickupPos.z; + return; + } + } + } + } + } + *x = GetPosition().x; + *y = GetPosition().y; + *z = GetPosition().z + 0.4f; } \ No newline at end of file diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 32557cb6..63e60991 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -209,7 +209,7 @@ enum eObjective : uint32 { OBJECTIVE_LEAVE_CAR_AND_DIE, OBJECTIVE_USE_SEAT_ATTRACTOR, OBJECTIVE_USE_ATM_ATTRACTOR, - OBJECTIVE_FLEE_CAR, // is it 41? + OBJECTIVE_FLEE_CAR, OBJ_42, OBJECTIVE_USE_STOP_ATTRACTOR, OBJECTIVE_USE_PIZZA_ATTRACTOR, @@ -550,7 +550,7 @@ public: uint32 m_duckAndCoverTimer; uint32 m_bloodyFootprintCountOrDeathTime; // Death time when bDoBloodyFootprints is false. Weird decision uint32 m_shotTime; - uint32 m_shotTimeAdd; + uint32 m_ceaseAttackTimer; uint8 m_panicCounter; bool m_deadBleeding; int8 m_bodyPartBleeding; // PedNode, but -1 if there isn't @@ -865,6 +865,7 @@ public: void SetNewAttraction(CPedAttractor* pAttractor, const CVector& pos, float, float, int); void ClearWaitState(void); + void CreateDeadPedPickupCoors(float* x, float* y, float* z); bool HasWeaponSlot(uint8 slot) { return m_weapons[slot].m_eWeaponType != WEAPONTYPE_UNARMED; } CWeapon& GetWeapon(uint8 slot) { return m_weapons[slot]; } diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp index 1c613acc..9d8d65dd 100644 --- a/src/peds/Population.cpp +++ b/src/peds/Population.cpp @@ -722,7 +722,7 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree } CPed* -CPopulation::AddPedInCar(CVehicle* car, bool isPassenger) +CPopulation::AddPedInCar(CVehicle* car, bool isDriver) { int defaultModel = MI_MALE01; int miamiViceIndex = 0; @@ -765,7 +765,7 @@ CPopulation::AddPedInCar(CVehicle* car, bool isPassenger) case MI_VICECHEE: // TODO(MIAMI): figure out new structure of the function preferredModel = COP_MIAMIVICE; pedType = PEDTYPE_COP; - miamiViceIndex = (isPassenger ? 2 * CCarCtrl::MiamiViceCycle : 2 * CCarCtrl::MiamiViceCycle + 1); + miamiViceIndex = (isDriver ? 2 * CCarCtrl::MiamiViceCycle : 2 * CCarCtrl::MiamiViceCycle + 1); break; case MI_TAXI: case MI_CABBIE: diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index d1f2faaa..8486d9e1 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -72,6 +72,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy) bFixedColour = false; bBigWheels = false; bWaterTight = false; + bTankDetonateCars = true; SetModelIndex(id); @@ -332,7 +333,7 @@ CAutomobile::ProcessControl(void) bool playerRemote = false; switch(GetStatus()){ case STATUS_PLAYER_REMOTE: - if(CPad::GetPad(0)->WeaponJustDown()){ + if(CPad::GetPad(0)->WeaponJustDown() && !bDisableRemoteDetonation){ BlowUpCar(FindPlayerPed()); CRemote::TakeRemoteControlledCarFromPlayer(); } @@ -4139,7 +4140,7 @@ CAutomobile::BlowUpCarsInPath(void) { int i; - if(m_vecMoveSpeed.Magnitude() > 0.1f) + if(m_vecMoveSpeed.Magnitude() > 0.1f && bTankDetonateCars) for(i = 0; i < m_nCollisionRecords; i++) if(m_aCollisionRecords[i] && m_aCollisionRecords[i]->IsVehicle() && @@ -4601,6 +4602,18 @@ CAutomobile::SetAllTaxiLights(bool set) m_sAllTaxiLights = set; } +void +CAutomobile::TellHeliToGoToCoors(float x, float y, float z, uint8 speed) +{ + AutoPilot.m_nCarMission = MISSION_HELI_FLYTOCOORS; + AutoPilot.m_vecDestinationCoors.x = x; + AutoPilot.m_vecDestinationCoors.y = y; + AutoPilot.m_vecDestinationCoors.z = z; + AutoPilot.m_nCruiseSpeed = speed; + SetStatus(STATUS_PHYSICS); + assert(0); // TODO(MIAMI) +} + #ifdef COMPATIBLE_SAVES void CAutomobile::Save(uint8*& buf) diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index 8c5c8f8e..e096465e 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -91,6 +91,7 @@ public: uint8 bWaterTight : 1; // no damage for non-player peds uint8 bNotDamagedUpsideDown : 1; uint8 bMoreResistantToDamage : 1; + uint8 bTankDetonateCars : 1; int16 field_4E0; uint16 m_hydraulicState; uint32 m_nBusDoorTimerEnd; @@ -178,6 +179,8 @@ public: void SetBumperDamage(int32 component, ePanels panel, bool noFlyingComponents = false); void SetDoorDamage(int32 component, eDoors door, bool noFlyingComponents = false); + void TellHeliToGoToCoors(float x, float y, float z, uint8 speed); + void Fix(void); void SetComponentVisibility(RwFrame *frame, uint32 flags); void SetupModelNodes(void); diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index df8c71b0..2fdc298f 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -29,6 +29,7 @@ bool CVehicle::bCheat5; bool CVehicle::bAltDodoCheat; #endif bool CVehicle::m_bDisableMouseSteering = true; +bool CVehicle::bDisableRemoteDetonation; void *CVehicle::operator new(size_t sz) { return CPools::GetVehiclePool()->New(); } void *CVehicle::operator new(size_t sz, int handle) { return CPools::GetVehiclePool()->New(handle); } @@ -1353,14 +1354,14 @@ eVehicleAppearance CVehicle::GetVehicleAppearance(void) { if (IsCar()) - return VEHICLE_CAR; + return VEHICLE_APPEARANCE_CAR; if (IsBoat()) - return VEHICLE_BOAT; + return VEHICLE_APPEARANCE_BOAT; if (IsBike()) - return VEHICLE_BIKE; + return VEHICLE_APPEARANCE_BIKE; if (IsPlane()) - return VEHICLE_PLANE; + return VEHICLE_APPEARANCE_PLANE; if (IsHeli()) - return VEHICLE_HELI; - return VEHICLE_NONE; + return VEHICLE_APPEARANCE_HELI; + return VEHICLE_APPEARANCE_NONE; } diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index c9e6bf93..fc138f45 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -112,12 +112,12 @@ enum eFlightModel enum eVehicleAppearance { - VEHICLE_NONE, - VEHICLE_CAR, - VEHICLE_BIKE, - VEHICLE_HELI, - VEHICLE_BOAT, - VEHICLE_PLANE, + VEHICLE_APPEARANCE_NONE, + VEHICLE_APPEARANCE_CAR, + VEHICLE_APPEARANCE_BIKE, + VEHICLE_APPEARANCE_HELI, + VEHICLE_APPEARANCE_BOAT, + VEHICLE_APPEARANCE_PLANE, }; // Or Weapon.h? @@ -311,6 +311,7 @@ public: static bool bAltDodoCheat; #endif static bool m_bDisableMouseSteering; + static bool bDisableRemoteDetonation; }; void DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle);