From 043efaf082a8ce5010e6ff974afea05d8d66e9d1 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Sat, 15 Feb 2020 14:53:42 +0300 Subject: script 900-999 --- src/control/Script.cpp | 559 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 547 insertions(+), 12 deletions(-) (limited to 'src/control/Script.cpp') diff --git a/src/control/Script.cpp b/src/control/Script.cpp index e5d4ba95..dfb16b0f 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -21,6 +21,7 @@ #include "EmergencyPed.h" #include "Explosion.h" #include "FileMgr.h" +#include "Frontend.h" #include "Gangs.h" #include "Garages.h" #include "General.h" @@ -47,7 +48,9 @@ #include "Restart.h" #include "Replay.h" #include "RpAnimBlend.h" +#include "Rubbish.h" #include "Shadows.h" +#include "SpecialFX.h" #include "Stats.h" #include "Streaming.h" #include "Text.h" @@ -61,6 +64,13 @@ #define PICKUP_PLACEMENT_OFFSET 0.5f #define PED_FIND_Z_OFFSET 5.0f +#define SPHERE_MARKER_R 0 +#define SPHERE_MARKER_G 128 +#define SPHERE_MARKER_B 255 +#define SPHERE_MARKER_A 128 +#define SPHERE_MARKER_PULSE_PERIOD 2048 +#define SPHERE_MARKER_PULSE_FRACTION 0.1f + uint8 (&CTheScripts::ScriptSpace)[SIZE_SCRIPT_SPACE] = *(uint8(*)[SIZE_SCRIPT_SPACE])*(uintptr*)0x74B248; CRunningScript(&CTheScripts::ScriptsArray)[MAX_NUM_SCRIPTS] = *(CRunningScript(*)[MAX_NUM_SCRIPTS])*(uintptr*)0x6F5C08; int32(&CTheScripts::BaseBriefIdForContact)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x880200; @@ -6178,7 +6188,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) } case COMMAND_CHANGE_GARAGE_TYPE: CollectParameters(&m_nIp, 2); - CGarages::ChangeGarageType(ScriptParams[0], (eGarageType)ScriptParams[1]); + CGarages::ChangeGarageType(ScriptParams[0], (eGarageType)ScriptParams[1], 0); return 0; case COMMAND_ACTIVATE_CRUSHER_CRANE: { @@ -7508,7 +7518,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) assert(pVehicle); // Adding this check to correspond to command name. // All original game scripts always assume that the vehicle is actually Mr. Whoopee, - // but maybe there are mods that use it as "is horn activated"? + // but maybe there are mods that use it as "is alarm activated"? assert(pVehicle->GetModelIndex() == MI_MRWHOOP); UpdateCompareFlag(pVehicle->m_bSirenOrAlarm); return 0; @@ -7520,12 +7530,13 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) } #endif -#if 1 +#if 0 WRAPPER int8 CRunningScript::ProcessCommands900To999(int32 command) { EAXJMP(0x44CB80); } #else int8 CRunningScript::ProcessCommands900To999(int32 command) { - char txd[52]; + char str[52]; + char onscreen_str[8]; switch (command) { case COMMAND_PRINT_STRING_IN_STRING_NOW: { @@ -7614,7 +7625,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) case COMMAND_LOAD_ALL_MODELS_NOW: CTimer::Stop(); CStreaming::LoadAllRequestedModels(false); - CTimer::Resume(); + CTimer::Update(); return 0; case COMMAND_ADD_TO_OBJECT_VELOCITY: { @@ -7649,27 +7660,27 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) case COMMAND_LOAD_SPRITE: { CollectParameters(&m_nIp, 1); - strncpy(txd, (char*)&CTheScripts::ScriptSpace[m_nIp], 8); + strncpy(str, (char*)&CTheScripts::ScriptSpace[m_nIp], 8); for (int i = 0; i < 8; i++) - txd[i] = tolower(txd[i]); + str[i] = tolower(str[i]); m_nIp += 8; int slot = CTxdStore::FindTxdSlot("script"); CTxdStore::PushCurrentTxd(); CTxdStore::SetCurrentTxd(slot); - CTheScripts::ScriptSprites[ScriptParams[0] - 1].SetTexture(txd); + CTheScripts::ScriptSprites[ScriptParams[0] - 1].SetTexture(str); CTxdStore::PopCurrentTxd(); return 0; } case COMMAND_LOAD_TEXTURE_DICTIONARY: { - strcpy(txd, "models\\"); - strncpy(txd + sizeof("models\\"), (char*)&CTheScripts::ScriptSpace[m_nIp], 8); - strcat(txd, ".txd"); + strcpy(str, "models\\"); + strncpy(str + sizeof("models\\"), (char*)&CTheScripts::ScriptSpace[m_nIp], 8); + strcat(str, ".txd"); m_nIp += 8; int slot = CTxdStore::FindTxdSlot("script"); if (slot == -1) slot = CTxdStore::AddTxdSlot("script"); - CTxdStore::LoadTxd(slot, txd); + CTxdStore::LoadTxd(slot, str); CTxdStore::AddRef(slot); return 0; } @@ -7818,146 +7829,590 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) return 0; } case COMMAND_DRAW_SPHERE: + { + CollectParameters(&m_nIp, 4); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= MAP_Z_LOW_LIMIT) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + C3dMarkers::PlaceMarkerSet((uint32)this + m_nIp, 4, pos, *(float*)&ScriptParams[3], + SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, SPHERE_MARKER_A, + SPHERE_MARKER_PULSE_PERIOD, SPHERE_MARKER_PULSE_FRACTION, 0); return 0; + } case COMMAND_SET_CAR_STATUS: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + pVehicle->m_status = ScriptParams[1]; return 0; + } case COMMAND_IS_CHAR_MALE: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + UpdateCompareFlag(pPed->m_nPedType != PEDTYPE_CIVFEMALE && pPed->m_nPedType != PEDTYPE_PROSTITUTE); return 0; + } case COMMAND_SCRIPT_NAME: + { + strncpy(str, (char*)&CTheScripts::ScriptSpace[m_nIp], 8); + for (int i = 0; i < 8; i++) + str[i] = tolower(str[i]); + m_nIp += 8; + strncpy(m_abScriptName, str, 8); return 0; + } case COMMAND_CHANGE_GARAGE_TYPE_WITH_CAR_MODEL: + { + CollectParameters(&m_nIp, 3); + CGarages::ChangeGarageType(ScriptParams[0], (eGarageType)ScriptParams[1], ScriptParams[2]); return 0; + } case COMMAND_FIND_DRUG_PLANE_COORDINATES: + *(CVector*)&ScriptParams[0] = CPlane::FindDrugPlaneCoordinates(); + StoreParameters(&m_nIp, 3); return 0; case COMMAND_SAVE_INT_TO_DEBUG_FILE: + // TODO: implement something here + CollectParameters(&m_nIp, 1); return 0; case COMMAND_SAVE_FLOAT_TO_DEBUG_FILE: + CollectParameters(&m_nIp, 1); return 0; case COMMAND_SAVE_NEWLINE_TO_DEBUG_FILE: return 0; case COMMAND_POLICE_RADIO_MESSAGE: + CollectParameters(&m_nIp, 3); + DMAudio.PlaySuspectLastSeen(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2]); return 0; case COMMAND_SET_CAR_STRONG: + { + CollectParameters(&m_nIp, 2); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + pVehicle->bTakeLessDamage = ScriptParams[1] != 0; return 0; + } case COMMAND_REMOVE_ROUTE: + CollectParameters(&m_nIp, 1); + CRouteNode::RemoveRoute(ScriptParams[0]); return 0; case COMMAND_SWITCH_RUBBISH: + CollectParameters(&m_nIp, 1); + CRubbish::SetVisibility(ScriptParams[0] != 0);; return 0; case COMMAND_REMOVE_PARTICLE_EFFECTS_IN_AREA: + { + CollectParameters(&m_nIp, 6); + float x1 = *(float*)&ScriptParams[1]; + float y1 = *(float*)&ScriptParams[2]; + float z1 = *(float*)&ScriptParams[3]; + float x2 = *(float*)&ScriptParams[4]; + float y2 = *(float*)&ScriptParams[5]; + float z2 = *(float*)&ScriptParams[6]; + CParticleObject* tmp = CParticleObject::pCloseListHead; + while (tmp) { + CParticleObject* next = tmp->m_pNext; + if (tmp->IsWithinArea(x1, y1, z1, x2, y2, z2)) + tmp->RemoveObject(); + tmp = next; + } + tmp = CParticleObject::pFarListHead; + while (tmp) { + CParticleObject* next = tmp->m_pNext; + if (tmp->IsWithinArea(x1, y1, z1, x2, y2, z2)) + tmp->RemoveObject(); + tmp = next; + } return 0; + } case COMMAND_SWITCH_STREAMING: + CollectParameters(&m_nIp, 1); + CStreaming::ms_disableStreaming = ScriptParams[0] == 0; return 0; case COMMAND_IS_GARAGE_OPEN: + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(CGarages::IsGarageOpen(ScriptParams[0])); return 0; case COMMAND_IS_GARAGE_CLOSED: + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(CGarages::IsGarageClosed(ScriptParams[0])); return 0; case COMMAND_START_CATALINA_HELI: + CHeli::StartCatalinaFlyBy(); return 0; case COMMAND_CATALINA_HELI_TAKE_OFF: + CHeli::CatalinaTakeOff(); return 0; case COMMAND_REMOVE_CATALINA_HELI: + CHeli::RemoveCatalinaHeli(); return 0; case COMMAND_HAS_CATALINA_HELI_BEEN_SHOT_DOWN: + UpdateCompareFlag(CHeli::HasCatalinaBeenShotDown()); return 0; case COMMAND_SWAP_NEAREST_BUILDING_MODEL: + { + CollectParameters(&m_nIp, 6); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= MAP_Z_LOW_LIMIT) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + float radius = *(float*)&ScriptParams[3]; + int mi1 = ScriptParams[4] >= 0 ? ScriptParams[4] : CTheScripts::UsedObjectArray[-ScriptParams[4]].index; + int mi2 = ScriptParams[5] >= 0 ? ScriptParams[5] : CTheScripts::UsedObjectArray[-ScriptParams[5]].index; + int16 total; + CEntity* apEntities[16]; + CWorld::FindObjectsOfTypeInRange(mi1, pos, radius, true, &total, 16, apEntities, true, false, false, false, false); + if (total == 0) + CWorld::FindObjectsOfTypeInRangeSectorList(mi1, CWorld::GetBigBuildingList(LEVEL_NONE), pos, radius, true, &total, 16, apEntities); + if (total == 0) + CWorld::FindObjectsOfTypeInRangeSectorList(mi1, CWorld::GetBigBuildingList(CTheZones::FindZoneForPoint(pos)), pos, radius, true, &total, 16, apEntities); + CEntity* pClosestEntity = nil; + float min_dist = 2.0f * radius; + for (int i = 0; i < total; i++) { + float dist = (apEntities[i]->GetPosition() - pos).Magnitude(); + if (dist < min_dist) { + min_dist = dist; + pClosestEntity = apEntities[i]; + } + } + if (!pClosestEntity) { + printf("Failed to find building\n"); + return 0; + } + CBuilding* pReplacedBuilding = ((CBuilding*)pClosestEntity); + pReplacedBuilding->ReplaceWithNewModel(mi2); + CTheScripts::AddToBuildingSwapArray(pReplacedBuilding, mi1, mi2); return 0; + } case COMMAND_SWITCH_WORLD_PROCESSING: + CollectParameters(&m_nIp, 1); + CWorld::bProcessCutsceneOnly = ScriptParams[0] == 0; return 0; case COMMAND_REMOVE_ALL_PLAYER_WEAPONS: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + pPed->ClearWeapons(); return 0; + } case COMMAND_GRAB_CATALINA_HELI: + CHeli* pHeli = CHeli::FindPointerToCatalinasHeli(); + ScriptParams[0] = pHeli ? CPools::GetVehiclePool()->GetIndex(pHeli) : -1; + StoreParameters(&m_nIp, 1); return 0; case COMMAND_CLEAR_AREA_OF_CARS: + { + CollectParameters(&m_nIp, 6); + float infX = *(float*)&ScriptParams[0]; + float infY = *(float*)&ScriptParams[1]; + float infZ = *(float*)&ScriptParams[2]; + float supX = *(float*)&ScriptParams[3]; + float supY = *(float*)&ScriptParams[4]; + float supZ = *(float*)&ScriptParams[5]; + if (infX > supX) { + infX = *(float*)&ScriptParams[3]; + supX = *(float*)&ScriptParams[0]; + } + if (infY > supY) { + infY = *(float*)&ScriptParams[4]; + supY = *(float*)&ScriptParams[1]; + } + if (infZ > supZ) { + infZ = *(float*)&ScriptParams[5]; + supZ = *(float*)&ScriptParams[2]; + } + CWorld::ClearCarsFromArea(infX, infY, infZ, supX, supY, supZ); return 0; + } case COMMAND_SET_ROTATING_GARAGE_DOOR: + CollectParameters(&m_nIp, 1); + CGarages::SetGarageDoorToRotate(ScriptParams[0]); return 0; case COMMAND_ADD_SPHERE: + { + CollectParameters(&m_nIp, 4); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= MAP_Z_LOW_LIMIT) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + float radius = *(float*)&ScriptParams[3]; + CTheScripts::GetActualScriptSphereIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); + ScriptParams[0] = CTheScripts::AddScriptSphere((uint32)this + m_nIp, pos, radius); + StoreParameters(&m_nIp, 1); return 0; + } case COMMAND_REMOVE_SPHERE: + CollectParameters(&m_nIp, 1); + CTheScripts::RemoveScriptSphere(ScriptParams[0]); return 0; case COMMAND_CATALINA_HELI_FLY_AWAY: + CHeli::MakeCatalinaHeliFlyAway(); return 0; case COMMAND_SET_EVERYONE_IGNORE_PLAYER: + { + CollectParameters(&m_nIp, 2); + CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + if (ScriptParams[1]) { + pPed->m_pWanted->m_bIgnoredByEveryone = true; + CWorld::StopAllLawEnforcersInTheirTracks(); + } + else { + pPed->m_pWanted->m_bIgnoredByEveryone = false; + } return 0; + } case COMMAND_STORE_CAR_CHAR_IS_IN_NO_SAVE: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(pPed); + CVehicle* pVehicle = pPed->bInVehicle ? pPed->m_pMyVehicle : nil; + ScriptParams[0] = CPools::GetVehiclePool()->GetIndex(pVehicle); + StoreParameters(&m_nIp, 1); return 0; + } case COMMAND_STORE_CAR_PLAYER_IS_IN_NO_SAVE: + { + CollectParameters(&m_nIp, 1); + CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; + assert(pPed); + CVehicle* pVehicle = pPed->bInVehicle ? pPed->m_pMyVehicle : nil; + ScriptParams[0] = CPools::GetVehiclePool()->GetIndex(pVehicle); + StoreParameters(&m_nIp, 1); return 0; + } case COMMAND_IS_PHONE_DISPLAYING_MESSAGE: + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(gPhoneInfo.IsMessageBeingDisplayed(ScriptParams[0])); return 0; case COMMAND_DISPLAY_ONSCREEN_TIMER_WITH_STRING: + assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR); + int16 var = CTheScripts::Read2BytesFromScript(&m_nIp); + wchar* text = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); // ??? + strncpy(onscreen_str, (char*)&CTheScripts::ScriptSpace[m_nIp], 8); + m_nIp += 8; + CUserDisplay::OnscnTimer.AddClock(var, onscreen_str); return 0; case COMMAND_DISPLAY_ONSCREEN_COUNTER_WITH_STRING: + assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR); + int16 var = CTheScripts::Read2BytesFromScript(&m_nIp); + CollectParameters(&m_nIp, 1); + wchar* text = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); // ??? + strncpy(onscreen_str, (char*)&CTheScripts::ScriptSpace[m_nIp], 8); + m_nIp += 8; + CUserDisplay::OnscnTimer.AddCounter(var, ScriptParams[0], onscreen_str); return 0; case COMMAND_CREATE_RANDOM_CAR_FOR_CAR_PARK: + { + CollectParameters(&m_nIp, 4); + if (CCarCtrl::NumRandomCars >= 30) + return 0; + int attempts; + int model = -1; + int index = CGeneral::GetRandomNumberInRange(0, 50); + for (attempts = 0; attempts < 50; attempts++) { + if (model != -1) + break; + model = CStreaming::ms_vehiclesLoaded[index]; + // desperatly want to believe this was inlined :| + CBaseModelInfo* pInfo = CModelInfo::GetModelInfo(model); + assert(pInfo->m_type == MITYPE_VEHICLE); + CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)pInfo; + if (pVehicleInfo->m_vehicleType != VEHICLE_TYPE_CAR) { + switch (model) { + case MI_LANDSTAL: + case MI_LINERUN: + case MI_FIRETRUCK: + case MI_TRASH: + case MI_STRETCH: + case MI_MULE: + case MI_AMBULAN: + case MI_FBICAR: + case MI_MRWHOOP: + case MI_BFINJECT: + case MI_CORPSE: + case MI_POLICE: + case MI_ENFORCER: + case MI_SECURICA: + case MI_PREDATOR: + case MI_BUS: + case MI_RHINO: + case MI_BARRACKS: + case MI_TRAIN: + case MI_CHOPPER: + case MI_DODO: + case MI_COACH: + case MI_RCBANDIT: + case MI_BELLYUP: + case MI_MRWONGS: + case MI_MAFIA: + case MI_YARDIE: + case MI_YAKUZA: + case MI_DIABLOS: + case MI_COLUMB: + case MI_HOODS: + case MI_AIRTRAIN: + case MI_DEADDODO: + case MI_SPEEDER: + case MI_REEFER: + case MI_PANLANT: + case MI_FLATBED: + case MI_YANKEE: + case MI_ESCAPE: + case MI_BORGNINE: + case MI_TOYZ: + case MI_GHOST: + case MI_MIAMI_RCBARON: + case MI_MIAMI_RCRAIDER: + model = -1; + break; + case MI_IDAHO: + case MI_STINGER: + case MI_PEREN: + case MI_SENTINEL: + case MI_PATRIOT: + case MI_MANANA: + case MI_INFERNUS: + case MI_BLISTA: + case MI_PONY: + case MI_CHEETAH: + case MI_MOONBEAM: + case MI_ESPERANT: + case MI_TAXI: + case MI_KURUMA: + case MI_BOBCAT: + case MI_BANSHEE: + case MI_CABBIE: + case MI_STALLION: + case MI_RUMPO: + case 151: + case 152: + case 153: + break; + default: + printf("CREATE_RANDOM_CAR_FOR_CAR_PARK - Unknown car model %d\n", CStreaming::ms_vehiclesLoaded[index]); + model = -1; + break; + } + } + else + model = -1; + if (++index >= 50) + index = 0; + } + if (model == -1) + return 0; + CVehicle* car; + if (!CModelInfo::IsBikeModel(model)) + car = new CAutomobile(model, MISSION_VEHICLE); + CVector pos = *(CVector*)&ScriptParams[0]; + pos.z += car->GetDistanceFromCentreOfMassToBaseOfModel(); + car->GetPosition() = pos; + car->SetHeading(DEGTORAD(*(float*)&ScriptParams[3])); + CTheScripts::ClearSpaceForMissionEntity(pos, car); + car->m_status = STATUS_ABANDONED; + car->bIsLocked = true; + car->bIsCarParkVehicle = true; + CCarCtrl::JoinCarWithRoadSystem(car); + car->AutoPilot.m_nCarMission = MISSION_NONE; + car->AutoPilot.m_nTempAction = TEMPACT_NONE; + car->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS; + car->AutoPilot.m_nCruiseSpeed = car->AutoPilot.m_fMaxTrafficSpeed = 9.0f; + car->AutoPilot.m_nCurrentLane = car->AutoPilot.m_nNextLane = 0; + car->bEngineOn = false; + car->m_nZoneLevel = CTheZones::GetLevelFromPosition(pos); + CWorld::Add(car); return 0; + } case COMMAND_IS_COLLISION_IN_MEMORY: + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(CCollision::ms_collisionInMemory == ScriptParams[0]); return 0; case COMMAND_SET_WANTED_MULTIPLIER: + CollectParameters(&m_nIp, 1); + FindPlayerPed()->m_pWanted->m_fCrimeSensitivity = *(float*)&ScriptParams[0]; return 0; case COMMAND_SET_CAMERA_IN_FRONT_OF_PLAYER: + TheCamera.SetCameraDirectlyInFrontForFollowPed_CamOnAString(); return 0; case COMMAND_IS_CAR_VISIBLY_DAMAGED: + { + CollectParameters(&m_nIp, 1); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + UpdateCompareFlag(pVehicle->bIsDamaged); return 0; + } case COMMAND_DOES_OBJECT_EXIST: + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(CPools::GetObjectPool()->GetAt(ScriptParams[0])); return 0; case COMMAND_LOAD_SCENE: + { + CollectParameters(&m_nIp, 3); + CVector pos = *(CVector*)&ScriptParams[0]; + CTimer::Stop(); + CStreaming::LoadScene(pos); + CTimer::Update(); return 0; + } case COMMAND_ADD_STUCK_CAR_CHECK: + { + CollectParameters(&m_nIp, 3); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(pVehicle); + CTheScripts::StuckCars.AddCarToCheck(ScriptParams[0], *(float*)&ScriptParams[1], ScriptParams[2]); return 0; + } case COMMAND_REMOVE_STUCK_CAR_CHECK: + { + CollectParameters(&m_nIp, 1); + CTheScripts::StuckCars.RemoveCarFromCheck(ScriptParams[0]); return 0; + } case COMMAND_IS_CAR_STUCK: + CollectParameters(&m_nIp, 1); + UpdateCompareFlag(CTheScripts::StuckCars.HasCarBeenStuckForAWhile(ScriptParams[0])); return 0; case COMMAND_LOAD_MISSION_AUDIO: + strncpy(str, (char*)&CTheScripts::ScriptSpace[m_nIp], 8); + for (int i = 0; i < 8; i++) + str[i] = tolower(str[i]); + m_nIp += 8; + DMAudio.PreloadMissionAudio(str); return 0; case COMMAND_HAS_MISSION_AUDIO_LOADED: + UpdateCompareFlag(DMAudio.GetMissionAudioLoadingStatus() == 1); return 0; case COMMAND_PLAY_MISSION_AUDIO: + DMAudio.PlayLoadedMissionAudio(); return 0; case COMMAND_HAS_MISSION_AUDIO_FINISHED: + UpdateCompareFlag(DMAudio.IsMissionAudioSampleFinished()); return 0; case COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING: + { + CollectParameters(&m_nIp, 3); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= MAP_Z_LOW_LIMIT) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + int node = ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f, true, true); + *(CVector*)&ScriptParams[0] = ThePaths.m_pathNodes[node].pos; + *(float*)&ScriptParams[3] = ThePaths.FindNodeOrientationForCarPlacement(node); + StoreParameters(&m_nIp, 4); return 0; + } case COMMAND_HAS_IMPORT_GARAGE_SLOT_BEEN_FILLED: + { + CollectParameters(&m_nIp, 2); + UpdateCompareFlag(CGarages::HasImportExportGarageCollectedThisCar(ScriptParams[0], ScriptParams[1] - 1)); return 0; + } case COMMAND_CLEAR_THIS_PRINT: + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CMessages::ClearThisPrint(text); return 0; case COMMAND_CLEAR_THIS_BIG_PRINT: + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CMessages::ClearThisBigPrint(text); return 0; case COMMAND_SET_MISSION_AUDIO_POSITION: + { + CollectParameters(&m_nIp, 3); + CVector pos = *(CVector*)&ScriptParams[0]; + DMAudio.SetMissionAudioLocation(pos.x, pos.y, pos.z); return 0; + } case COMMAND_ACTIVATE_SAVE_MENU: + FrontEndMenuManager.m_bSaveMenuActive = true; return 0; case COMMAND_HAS_SAVE_GAME_FINISHED: + UpdateCompareFlag(!FrontEndMenuManager.m_bMenuActive); return 0; case COMMAND_NO_SPECIAL_CAMERA_FOR_THIS_GARAGE: + CollectParameters(&m_nIp, 1); + CGarages::SetLeaveCameraForThisGarage(ScriptParams[0]); return 0; case COMMAND_ADD_BLIP_FOR_PICKUP_OLD: + { + CollectParameters(&m_nIp, 3); + CObject* pObject = CPickups::aPickUps[CPickups::GetActualPickupIndex(ScriptParams[0])].m_pObject; + CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); + ScriptParams[0] = CRadar::SetEntityBlip(BLIP_OBJECT, CPools::GetObjectPool()->GetIndex(pObject), ScriptParams[1], (eBlipDisplay)ScriptParams[2]); + StoreParameters(&m_nIp, 1); return 0; + } case COMMAND_ADD_BLIP_FOR_PICKUP: + { + CollectParameters(&m_nIp, 1); + CObject* pObject = CPickups::aPickUps[CPickups::GetActualPickupIndex(ScriptParams[0])].m_pObject; + CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); + int handle = CRadar::SetEntityBlip(BLIP_OBJECT, CPools::GetObjectPool()->GetIndex(pObject), 6, BLIP_DISPLAY_BOTH); + CRadar::ChangeBlipScale(handle, 3); + ScriptParams[0] = handle; + StoreParameters(&m_nIp, 1); return 0; + } case COMMAND_ADD_SPRITE_BLIP_FOR_PICKUP: + { + CollectParameters(&m_nIp, 2); + CObject* pObject = CPickups::aPickUps[CPickups::GetActualPickupIndex(ScriptParams[0])].m_pObject; + CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); + int handle = CRadar::SetEntityBlip(BLIP_OBJECT, CPools::GetObjectPool()->GetIndex(pObject), 6, BLIP_DISPLAY_BOTH); + CRadar::SetBlipSprite(handle, ScriptParams[1]); + ScriptParams[0] = handle; + StoreParameters(&m_nIp, 1); return 0; + } case COMMAND_SET_PED_DENSITY_MULTIPLIER: + CollectParameters(&m_nIp, 1); + CPopulation::PedDensityMultiplier = *(float*)&ScriptParams[0]; return 0; case COMMAND_FORCE_RANDOM_PED_TYPE: + CollectParameters(&m_nIp, 1); + CPopulation::m_AllRandomPedsThisType = ScriptParams[0]; return 0; case COMMAND_SET_TEXT_DRAW_BEFORE_FADE: + CollectParameters(&m_nIp, 1); + CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_bTextBeforeFade = ScriptParams[0] != 0; return 0; case COMMAND_GET_COLLECTABLE1S_COLLECTED: + ScriptParams[0] = CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages; + StoreParameters(&m_nIp, 1); return 0; case COMMAND_REGISTER_EL_BURRO_TIME: + CollectParameters(&m_nIp, 1); + CStats::RegisterElBurroTime(ScriptParams[0]); return 0; case COMMAND_SET_SPRITES_DRAW_BEFORE_FADE: + CollectParameters(&m_nIp, 1); + CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_bBeforeFade = ScriptParams[0] != 0; return 0; case COMMAND_SET_TEXT_RIGHT_JUSTIFY: + CollectParameters(&m_nIp, 1); + CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_bRightJustify = ScriptParams[0] != 0; return 0; case COMMAND_PRINT_HELP: + if (CCamera::m_bUseMouse3rdPerson && ( + strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "HELP15", 7) == 0 || + strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2A", 7) == 0 || + strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_3A", 7) == 0 || + strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_4A", 7) == 0)){ + m_nIp += 8; + return 0; + } + wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); + CHud::SetHelpMessage(text, false); return 0; case COMMAND_CLEAR_HELP: + CHud::SetHelpMessage(nil, false); return 0; case COMMAND_FLASH_HUD_OBJECT: + CollectParameters(&m_nIp, 1); + CHud::m_ItemToFlash = ScriptParams[0]; return 0; default: assert(0); @@ -8329,6 +8784,53 @@ int16 CRunningScript::GetPadState(uint16 pad, uint16 button) return 0; } +int32 CTheScripts::GetActualScriptSphereIndex(int32 index) +{ + if (index == -1) + return -1; + uint16 check = (uint32)index >> 16; + uint16 array_idx = (uint32)index & (0xFFFF); + if (check != ScriptSphereArray[array_idx].m_Index) + return -1; + return index; +} + +int32 CTheScripts::AddScriptSphere(int32 id, CVector pos, float radius) +{ + int16 i = 0; + for (i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++) { + if (!ScriptSphereArray[i].m_bInUse) + break; + } +#ifdef FIX_BUGS + if (i == MAX_NUM_SCRIPT_SPHERES) + return -1; +#endif + ScriptSphereArray[i].m_bInUse = true; + ScriptSphereArray[i].m_Id = id; + ScriptSphereArray[i].m_vecCenter = pos; + ScriptSphereArray[i].m_fRadius = radius; + return GetNewUniqueScriptSphereIndex(i); +} + +int32 CTheScripts::GetNewUniqueScriptSphereIndex(int32 index) +{ + if (ScriptSphereArray[index].m_Index >= 0xFFFE) + ScriptSphereArray[index].m_Index = 1; + else + ScriptSphereArray[index].m_Index = 1; + return index | ScriptSphereArray[index].m_Index << 16; +} + +void CTheScripts::RemoveScriptSphere(int32 index) +{ + index = GetActualScriptSphereIndex(index); + if (index == -1) + return; + ScriptSphereArray[index].m_bInUse = false; + ScriptSphereArray[index].m_Id = 0; +} + bool CTheScripts::IsVehicleStopped(CVehicle* pVehicle) { return 0.01f * CTimer::GetTimeStep() >= pVehicle->m_fDistanceTravelled; @@ -8359,7 +8861,40 @@ void CTheScripts::AddToInvisibilitySwapArray(CEntity* pEntity, bool remove) if (found) InvisibilitySettingArray[i] = pEntity; } +} +void CTheScripts::AddToBuildingSwapArray(CBuilding* pBuilding, int32 old_model, int32 new_model) +{ + int i = 0; + bool found = false; + while (i < MAX_NUM_BUILDING_SWAPS && !found) { + if (BuildingSwapArray[i].m_pBuilding == pBuilding) + found = true; + else + i++; + } + if (found) { + if (BuildingSwapArray[i].m_nOldModel == new_model) { + BuildingSwapArray[i].m_pBuilding = nil; + BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1; + }else{ + BuildingSwapArray[i].m_nNewModel = new_model; + } + } + else { + i = 0; + while (i < MAX_NUM_BUILDING_SWAPS && !found) { + if (BuildingSwapArray[i].m_pBuilding == nil) + found = true; + else + i++; + } + if (found) { + BuildingSwapArray[i].m_pBuilding = pBuilding; + BuildingSwapArray[i].m_nNewModel = new_model; + BuildingSwapArray[i].m_nOldModel = old_model; + } + } } WRAPPER void CRunningScript::LocatePlayerCommand(int32, uint32*) { EAXJMP(0x44FE10); } -- cgit v1.2.3