diff options
Diffstat (limited to 'src/control/Script5.cpp')
-rw-r--r-- | src/control/Script5.cpp | 307 |
1 files changed, 255 insertions, 52 deletions
diff --git a/src/control/Script5.cpp b/src/control/Script5.cpp index c7e190ac..ab3c5b7f 100644 --- a/src/control/Script5.cpp +++ b/src/control/Script5.cpp @@ -330,7 +330,7 @@ void CRunningScript::LocateCharCommand(int32 command, uint32* pIp) CollectParameters(pIp, b3D ? 8 : 6); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); script_assert(pPed); - CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition(); + CVector pos = pPed->InVehicle() ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition(); switch (command) { case COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_2D: case COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_3D: @@ -731,6 +731,64 @@ void CRunningScript::LocateCarCommand(int32 command, uint32* pIp) } } +void CRunningScript::LocateObjectCommand(int32 command, uint32* pIp) +{ + bool b3D, result, debug; + float X, Y, Z, dX, dY, dZ; + switch (command) { + case COMMAND_LOCATE_OBJECT_3D: + b3D = true; + break; + default: + b3D = false; + break; + } + CollectParameters(pIp, b3D ? 8 : 6); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + script_assert(pObject); + CVector pos = pObject->GetPosition(); + X = *(float*)&ScriptParams[1]; + Y = *(float*)&ScriptParams[2]; + if (b3D) { + Z = *(float*)&ScriptParams[3]; + dX = *(float*)&ScriptParams[4]; + dY = *(float*)&ScriptParams[5]; + dZ = *(float*)&ScriptParams[6]; + debug = ScriptParams[7]; + } + else { + dX = *(float*)&ScriptParams[3]; + dY = *(float*)&ScriptParams[4]; + debug = ScriptParams[5]; + } + result = false; + bool in_area; + if (b3D) { + in_area = X - dX <= pos.x && + X + dX >= pos.x && + Y - dY <= pos.y && + Y + dY >= pos.y && + Z - dZ <= pos.z && + Z + dZ >= pos.z; + } + else { + in_area = X - dX <= pos.x && + X + dX >= pos.x && + Y - dY <= pos.y && + Y + dY >= pos.y; + } + result = in_area; + UpdateCompareFlag(result); + if (debug) + CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT); + if (CTheScripts::DbgFlag) { + if (b3D) + CTheScripts::DrawDebugCube(X - dX, Y - dY, Z - dZ, X + dX, Y + dY, Z + dZ); + else + CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY); + } +} + void CRunningScript::LocateSniperBulletCommand(int32 command, uint32* pIp) { bool b3D, result, debug; @@ -1032,7 +1090,7 @@ void CRunningScript::CharInAreaCheckCommand(int32 command, uint32* pIp) CollectParameters(pIp, b3D ? 8 : 6); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); script_assert(pPed); - CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition(); + CVector pos = pPed->InVehicle() ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition(); switch (command) { case COMMAND_IS_CHAR_STOPPED_IN_AREA_3D: case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_3D: @@ -1228,6 +1286,88 @@ void CRunningScript::CarInAreaCheckCommand(int32 command, uint32* pIp) } } +void CRunningScript::ObjectInAreaCheckCommand(int32 command, uint32* pIp) +{ + bool b3D, result, debug; + float infX, infY, infZ, supX, supY, supZ; + switch (command) { + case COMMAND_IS_OBJECT_IN_AREA_3D: + b3D = true; + break; + default: + b3D = false; + break; + } + CollectParameters(pIp, b3D ? 8 : 6); + CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + script_assert(pObject); + CVector pos = pObject->GetPosition(); + infX = *(float*)&ScriptParams[1]; + infY = *(float*)&ScriptParams[2]; + if (b3D) { + infZ = *(float*)&ScriptParams[3]; + supX = *(float*)&ScriptParams[4]; + supY = *(float*)&ScriptParams[5]; + supZ = *(float*)&ScriptParams[6]; + if (infZ > supZ) { + infZ = *(float*)&ScriptParams[6]; + supZ = *(float*)&ScriptParams[3]; + } + debug = ScriptParams[7]; + } + else { + supX = *(float*)&ScriptParams[3]; + supY = *(float*)&ScriptParams[4]; + debug = ScriptParams[5]; + } + if (infX > supX) { + float tmp = infX; + infX = supX; + supX = tmp; + } + if (infY > supY) { + float tmp = infY; + infY = supY; + supY = tmp; + } + result = false; + bool in_area; + if (b3D) { + in_area = infX <= pos.x && + supX >= pos.x && + infY <= pos.y && + supY >= pos.y && + infZ <= pos.z && + supZ >= pos.z; + } + else { + in_area = infX <= pos.x && + supX >= pos.x && + infY <= pos.y && + supY >= pos.y; + } + if (in_area) { + switch (command) { + case COMMAND_IS_OBJECT_IN_AREA_2D: + case COMMAND_IS_OBJECT_IN_AREA_3D: + result = true; + break; + default: + script_assert(false); + break; + } + } + UpdateCompareFlag(result); + if (debug) + CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, infX, infY, supX, supY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT); + if (CTheScripts::DbgFlag) { + if (b3D) + CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ); + else + CTheScripts::DrawDebugSquare(infX, infY, supX, supY); + } +} + void CRunningScript::DoDeatharrestCheck() { if (!m_bDeatharrestEnabled) @@ -1235,7 +1375,7 @@ void CRunningScript::DoDeatharrestCheck() if (!CTheScripts::IsPlayerOnAMission()) return; CPlayerInfo* pPlayer = &CWorld::Players[CWorld::PlayerInFocus]; - if (!pPlayer->IsRestartingAfterDeath() && !pPlayer->IsRestartingAfterArrest() && !CTheScripts::UpsideDownCars.AreAnyCarsUpsideDown()) + if (!pPlayer->IsRestartingAfterDeath() && !pPlayer->IsRestartingAfterArrest()) return; #ifdef MISSION_REPLAY if (AllowMissionReplay != 0) @@ -1247,29 +1387,7 @@ void CRunningScript::DoDeatharrestCheck() while (m_nStackPointer > 1) --m_nStackPointer; m_nIp = m_anStack[--m_nStackPointer]; - int16 messageId; - if (pPlayer->IsRestartingAfterDeath()) - messageId = 0; - else if (pPlayer->IsRestartingAfterArrest()) - messageId = 5; - else - messageId = 10; - messageId += CGeneral::GetRandomNumberInRange(0, 5); - bool found = false; - for (int16 contact = 0; !found && contact < MAX_NUM_CONTACTS; contact++) { - int contactFlagOffset = CTheScripts::OnAMissionForContactFlag[contact]; - if (contactFlagOffset && CTheScripts::ScriptSpace[contactFlagOffset] == 1) { - messageId += CTheScripts::BaseBriefIdForContact[contact]; - found = true; - } - } - if (!found) - messageId = 8001; - char tmp[16]; - sprintf(tmp, "%d", messageId); CMessages::ClearSmallMessagesOnly(); - wchar* text = TheText.Get(tmp); - // ...and do nothing about it *(int32*)&CTheScripts::ScriptSpace[CTheScripts::OnAMissionFlag] = 0; m_bDeatharrestExecuted = true; m_nWakeTime = 0; @@ -1786,6 +1904,76 @@ void CRunningScript::CollectiveInAreaCheckCommand(int32 command, uint32* pIp) } #endif +bool CRunningScript::CheckDamagedWeaponType(int32 actual, int32 type) +{ + if (actual == -1) + return false; + + if (type == WEAPONTYPE_ANYMELEE) { + if (actual <= WEAPONTYPE_CHAINSAW) + return true; + if (actual - WEAPONTYPE_GRENADE <= WEAPONTYPE_MINIGUN) + return false; + return false; + } + + if (type != WEAPONTYPE_ANYWEAPON) + return false; + + switch (actual) { + case WEAPONTYPE_UNARMED: + case WEAPONTYPE_BRASSKNUCKLE: + case WEAPONTYPE_SCREWDRIVER: + case WEAPONTYPE_GOLFCLUB: + case WEAPONTYPE_NIGHTSTICK: + case WEAPONTYPE_KNIFE: + case WEAPONTYPE_BASEBALLBAT: + case WEAPONTYPE_HAMMER: + case WEAPONTYPE_CLEAVER: + case WEAPONTYPE_MACHETE: + case WEAPONTYPE_KATANA: + case WEAPONTYPE_CHAINSAW: + case WEAPONTYPE_GRENADE: + case WEAPONTYPE_DETONATOR_GRENADE: + case WEAPONTYPE_TEARGAS: + case WEAPONTYPE_MOLOTOV: + case WEAPONTYPE_ROCKET: + case WEAPONTYPE_COLT45: + case WEAPONTYPE_PYTHON: + case WEAPONTYPE_SHOTGUN: + case WEAPONTYPE_SPAS12_SHOTGUN: + case WEAPONTYPE_STUBBY_SHOTGUN: + case WEAPONTYPE_TEC9: + case WEAPONTYPE_UZI: + case WEAPONTYPE_SILENCED_INGRAM: + case WEAPONTYPE_MP5: + case WEAPONTYPE_M4: + case WEAPONTYPE_RUGER: + case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: + case WEAPONTYPE_ROCKETLAUNCHER: + case WEAPONTYPE_FLAMETHROWER: + case WEAPONTYPE_M60: + case WEAPONTYPE_MINIGUN: + case WEAPONTYPE_DETONATOR: + case WEAPONTYPE_HELICANNON: + case WEAPONTYPE_CAMERA: + case WEAPONTYPE_EXPLOSION: + case WEAPONTYPE_UZI_DRIVEBY: + return true; + case WEAPONTYPE_HEALTH: + case WEAPONTYPE_ARMOUR: + case WEAPONTYPE_RAMMEDBYCAR: + case WEAPONTYPE_RUNOVERBYCAR: + case WEAPONTYPE_DROWNING: + case WEAPONTYPE_FALL: + case WEAPONTYPE_UNIDENTIFIED: + return false; + } + + return false; +} + void CTheScripts::PrintListSizes() { int active = 0; @@ -1908,8 +2096,8 @@ void CTheScripts::RenderTheScriptDebugLines() RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)0); } -#define SCRIPT_DATA_SIZE sizeof(CTheScripts::OnAMissionFlag) + sizeof(CTheScripts::BaseBriefIdForContact) + sizeof(CTheScripts::OnAMissionForContactFlag) +\ - sizeof(CTheScripts::CollectiveArray) + 4 * sizeof(uint32) * MAX_NUM_BUILDING_SWAPS + 2 * sizeof(uint32) * MAX_NUM_INVISIBILITY_SETTINGS + 5 * sizeof(uint32) +#define SCRIPT_DATA_SIZE sizeof(CTheScripts::OnAMissionFlag) +\ + 4 * sizeof(uint32) * MAX_NUM_BUILDING_SWAPS + 2 * sizeof(uint32) * MAX_NUM_INVISIBILITY_SETTINGS + 5 * sizeof(uint32) void CTheScripts::SaveAllScripts(uint8* buf, uint32* size) { @@ -1929,13 +2117,7 @@ INITSAVEBUF uint32 script_data_size = SCRIPT_DATA_SIZE; WriteSaveBuf(buf, script_data_size); WriteSaveBuf(buf, OnAMissionFlag); - for (uint32 i = 0; i < MAX_NUM_CONTACTS; i++) { - WriteSaveBuf(buf, OnAMissionForContactFlag[i]); - WriteSaveBuf(buf, BaseBriefIdForContact[i]); - } - for (uint32 i = 0; i < MAX_NUM_COLLECTIVES; i++) - WriteSaveBuf(buf, CollectiveArray[i]); - WriteSaveBuf(buf, NextFreeCollectiveIndex); + WriteSaveBuf(buf, LastMissionPassedTime); for (uint32 i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) { CBuilding* pBuilding = BuildingSwapArray[i].m_pBuilding; uint32 type, handle; @@ -1985,12 +2167,12 @@ INITSAVEBUF WriteSaveBuf(buf, handle); } WriteSaveBuf(buf, bUsingAMultiScriptFile); - WriteSaveBuf(buf, (uint8)0); + WriteSaveBuf(buf, bPlayerHasMetDebbieHarry); WriteSaveBuf(buf, (uint16)0); WriteSaveBuf(buf, MainScriptSize); WriteSaveBuf(buf, LargestMissionScriptSize); WriteSaveBuf(buf, NumberOfMissionScripts); - WriteSaveBuf(buf, (uint16)0); + WriteSaveBuf(buf, NumberOfExclusiveMissionScripts); WriteSaveBuf(buf, runningScripts); for (CRunningScript* pScript = pActiveScripts; pScript; pScript = pScript->GetNext()) pScript->Save(buf); @@ -2007,13 +2189,7 @@ INITSAVEBUF ScriptSpace[i] = ReadSaveBuf<uint8>(buf); script_assert(ReadSaveBuf<uint32>(buf) == SCRIPT_DATA_SIZE); OnAMissionFlag = ReadSaveBuf<uint32>(buf); - for (uint32 i = 0; i < MAX_NUM_CONTACTS; i++) { - OnAMissionForContactFlag[i] = ReadSaveBuf<uint32>(buf); - BaseBriefIdForContact[i] = ReadSaveBuf<uint32>(buf); - } - for (uint32 i = 0; i < MAX_NUM_COLLECTIVES; i++) - CollectiveArray[i] = ReadSaveBuf<tCollectiveData>(buf); - NextFreeCollectiveIndex = ReadSaveBuf<uint32>(buf); + LastMissionPassedTime = ReadSaveBuf<uint32>(buf); for (uint32 i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) { uint32 type = ReadSaveBuf<uint32>(buf); uint32 handle = ReadSaveBuf<uint32>(buf); @@ -2061,12 +2237,12 @@ INITSAVEBUF InvisibilitySettingArray[i]->bIsVisible = false; } script_assert(ReadSaveBuf<bool>(buf) == bUsingAMultiScriptFile); - ReadSaveBuf<uint8>(buf); + bPlayerHasMetDebbieHarry = ReadSaveBuf<uint8>(buf); ReadSaveBuf<uint16>(buf); script_assert(ReadSaveBuf<uint32>(buf) == MainScriptSize); script_assert(ReadSaveBuf<uint32>(buf) == LargestMissionScriptSize); script_assert(ReadSaveBuf<uint16>(buf) == NumberOfMissionScripts); - ReadSaveBuf<uint16>(buf); + script_assert(ReadSaveBuf<uint16>(buf) == NumberOfExclusiveMissionScripts); uint32 runningScripts = ReadSaveBuf<uint32>(buf); for (uint32 i = 0; i < runningScripts; i++) StartNewScript(0)->Load(buf); @@ -2366,22 +2542,24 @@ void CTheScripts::SetObjectiveForAllPedsInCollective(int colIndex, eObjective ob bool CTheScripts::IsPedStopped(CPed* pPed) { - if (pPed->bInVehicle) + if (pPed->InVehicle()) return IsVehicleStopped(pPed->m_pMyVehicle); - return pPed->m_nMoveState == eMoveState::PEDMOVE_NONE || pPed->m_nMoveState == eMoveState::PEDMOVE_STILL; + return (pPed->m_nMoveState == eMoveState::PEDMOVE_NONE || pPed->m_nMoveState == eMoveState::PEDMOVE_STILL) && + !pPed->bIsInTheAir && !pPed->bIsLanding && pPed->bIsStanding && pPed->m_vecAnimMoveDelta.x == 0.0f && pPed->m_vecAnimMoveDelta.y == 0.0f; } bool CTheScripts::IsPlayerStopped(CPlayerInfo* pPlayer) { CPed* pPed = pPlayer->m_pPed; - if (pPed->bInVehicle) + if (pPed->InVehicle()) return IsVehicleStopped(pPed->m_pMyVehicle); if (RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_RUN_STOP) || RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_RUN_STOP_R) || RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_JUMP_LAUNCH) || RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_JUMP_GLIDE)) return false; - return pPed->m_nMoveState == eMoveState::PEDMOVE_NONE || pPed->m_nMoveState == eMoveState::PEDMOVE_STILL; + return (pPed->m_nMoveState == eMoveState::PEDMOVE_NONE || pPed->m_nMoveState == eMoveState::PEDMOVE_STILL) && + !pPed->bIsInTheAir && !pPed->bIsLanding && pPed->bIsStanding && pPed->m_vecAnimMoveDelta.x == 0.0f && pPed->m_vecAnimMoveDelta.y == 0.0f; } bool CTheScripts::IsVehicleStopped(CVehicle* pVehicle) @@ -2389,6 +2567,30 @@ bool CTheScripts::IsVehicleStopped(CVehicle* pVehicle) return 0.01f * CTimer::GetTimeStep() >= pVehicle->m_fDistanceTravelled; } +void CTheScripts::RemoveThisPed(CPed* pPed) +{ + if (pPed) { + bool bWasMissionPed = pPed->CharCreatedBy == MISSION_CHAR; + if (pPed->InVehicle() && pPed->m_pMyVehicle) { + if (pPed->m_pMyVehicle->pDriver == pPed) { + pPed->m_pMyVehicle->RemoveDriver(); + pPed->m_pMyVehicle->SetStatus(STATUS_ABANDONED); + if (pPed->m_pMyVehicle->m_nDoorLock == CARLOCK_LOCKED_INITIALLY) + pPed->m_pMyVehicle->m_nDoorLock = CARLOCK_UNLOCKED; + if (pPed->m_nPedType == PEDTYPE_COP && pPed->m_pMyVehicle->IsLawEnforcementVehicle()) + pPed->m_pMyVehicle->ChangeLawEnforcerState(0); + } + else { + pPed->m_pMyVehicle->RemovePassenger(pPed); + } + } + CWorld::RemoveReferencesToDeletedObject(pPed); + delete pPed; + if (bWasMissionPed) + --CPopulation::ms_nTotalMissionPeds; + } +} + void CTheScripts::CleanUpThisPed(CPed* pPed) { if (!pPed) @@ -2398,7 +2600,7 @@ void CTheScripts::CleanUpThisPed(CPed* pPed) pPed->CharCreatedBy = RANDOM_CHAR; if (pPed->m_nPedType == PEDTYPE_PROSTITUTE) pPed->m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 30000; - if (pPed->bInVehicle) { + if (pPed->InVehicle()) { if (pPed->m_pMyVehicle->pDriver == pPed) { if (pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_CAR) { CCarCtrl::JoinCarWithRoadSystem(pPed->m_pMyVehicle); @@ -2423,6 +2625,7 @@ void CTheScripts::CleanUpThisPed(CPed* pPed) pPed->ClearObjective(); pPed->bRespondsToThreats = true; pPed->bScriptObjectiveCompleted = false; + pPed->bKindaStayInSamePlace = false; pPed->ClearLeader(); if (pPed->IsPedInControl()) pPed->SetWanderPath(CGeneral::GetRandomNumber() & 7); @@ -2453,7 +2656,7 @@ void CTheScripts::CleanUpThisObject(CObject* pObject) if (pObject->ObjectCreatedBy != MISSION_OBJECT) return; pObject->ObjectCreatedBy = TEMP_OBJECT; - pObject->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 20000; + pObject->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 20000000; pObject->m_nRefModelIndex = -1; pObject->bUseVehicleColours = false; ++CObject::nNoTempObjects; @@ -2510,7 +2713,7 @@ void CTheScripts::ReadMultiScriptFileOffsetsFromScript() MainScriptSize = Read4BytesFromScript(&ip); LargestMissionScriptSize = Read4BytesFromScript(&ip); NumberOfMissionScripts = Read2BytesFromScript(&ip); - ip += 2; + NumberOfExclusiveMissionScripts = Read2BytesFromScript(&ip); for (int i = 0; i < NumberOfMissionScripts; i++) { MultiScriptArray[i] = Read4BytesFromScript(&ip); } |