re3/src/control/RoadBlocks.cpp

200 lines
7.4 KiB
C++
Raw Normal View History

2019-08-11 17:11:54 +00:00
#include "common.h"
2020-04-17 13:31:11 +00:00
2019-08-11 17:11:54 +00:00
#include "RoadBlocks.h"
2020-03-25 14:13:06 +00:00
#include "PathFind.h"
2020-04-11 16:45:49 +00:00
#include "ModelIndices.h"
#include "Streaming.h"
#include "World.h"
#include "PedPlacement.h"
#include "Automobile.h"
#include "CopPed.h"
#include "VisibilityPlugins.h"
#include "PlayerPed.h"
#include "Wanted.h"
#include "Camera.h"
#include "CarCtrl.h"
#include "General.h"
2020-03-25 14:13:06 +00:00
#define ROADBLOCKDIST (80.0f)
2020-04-17 05:54:14 +00:00
int16 CRoadBlocks::NumRoadBlocks;
int16 CRoadBlocks::RoadBlockObjects[NUMROADBLOCKS];
bool CRoadBlocks::InOrOut[NUMROADBLOCKS];
2019-08-11 17:11:54 +00:00
2020-03-25 14:13:06 +00:00
void
CRoadBlocks::Init(void)
{
int i;
2020-04-11 16:45:49 +00:00
NumRoadBlocks = 0;
for (i = 0; i < ThePaths.m_numMapObjects; i++) {
if (ThePaths.m_objectFlags[i] & UseInRoadBlock) {
if (NumRoadBlocks < NUMROADBLOCKS) {
2020-04-11 16:45:49 +00:00
InOrOut[NumRoadBlocks] = true;
RoadBlockObjects[NumRoadBlocks] = i;
2020-04-11 16:45:49 +00:00
NumRoadBlocks++;
} else {
2020-03-25 14:13:06 +00:00
#ifndef MASTER
2020-04-11 16:45:49 +00:00
printf("Not enough room for the potential roadblocks\n");
2020-03-25 14:13:06 +00:00
#endif
2020-04-11 16:45:49 +00:00
// FIX: Don't iterate loop after NUMROADBLOCKS
return;
}
}
}
}
void
CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType, int16 roadBlockNode)
{
static const CVector vecRoadBlockOffets[6] = { CVector(-1.5, 1.8f, 0.0f), CVector(-1.5f, -1.8f, 0.0f), CVector(1.5f, 1.8f, 0.0f),
CVector(1.5f, -1.8f, 0.0f), CVector(-1.5f, 0.0f, 0.0f), CVector(1.5, 0.0, 0.0) };
2020-04-11 16:45:49 +00:00
CEntity* pEntityToAttack = (CEntity*)FindPlayerVehicle();
if (!pEntityToAttack)
pEntityToAttack = (CEntity*)FindPlayerPed();
CColModel* pPoliceColModel = CModelInfo::GetModelInfo(MI_POLICE)->GetColModel();
float fRadius = pVehicle->GetBoundRadius() / pPoliceColModel->boundingSphere.radius;
for (int32 i = 0; i < 2; i++) {
const int32 roadBlockIndex = i + 2 * roadBlockType;
CVector posForZ = pVehicle->m_matrix * (fRadius * vecRoadBlockOffets[roadBlockIndex]);
2020-04-11 21:08:16 +00:00
int32 modelInfoId = MI_COP;
2020-04-11 16:45:49 +00:00
eCopType copType = COP_STREET;
switch (pVehicle->GetModelIndex())
{
case MI_FBICAR:
modelInfoId = MI_FBI;
copType = COP_FBI;
break;
case MI_ENFORCER:
modelInfoId = MI_SWAT;
copType = COP_SWAT;
break;
case MI_BARRACKS:
modelInfoId = MI_ARMY;
copType = COP_ARMY;
break;
}
if (!CStreaming::HasModelLoaded(modelInfoId))
copType = COP_STREET;
CCopPed* pCopPed = new CCopPed(copType);
if (copType == COP_STREET)
pCopPed->SetCurrentWeapon(WEAPONTYPE_COLT45);
CPedPlacement::FindZCoorForPed(&posForZ);
pCopPed->SetPosition(posForZ);
CVector vecSavedPos = pCopPed->GetPosition();
2020-04-11 16:45:49 +00:00
pCopPed->m_matrix.SetRotate(0.0f, 0.0f, -HALFPI);
pCopPed->m_matrix.GetPosition() += vecSavedPos;
pCopPed->m_bIsDisabledCop = true;
pCopPed->SetIdle();
pCopPed->bKindaStayInSamePlace = true;
pCopPed->bNotAllowedToDuck = false;
pCopPed->m_nRoadblockNode = roadBlockNode;
2020-04-11 16:45:49 +00:00
pCopPed->bCrouchWhenShooting = roadBlockType != 2;
if (pEntityToAttack) {
2020-12-14 07:47:07 +00:00
pCopPed->SetWeaponLockOnTarget(pEntityToAttack);
2020-04-11 16:45:49 +00:00
pCopPed->SetAttack(pEntityToAttack);
}
pCopPed->m_pMyVehicle = pVehicle;
pVehicle->RegisterReference((CEntity**)&pCopPed->m_pMyVehicle);
pCopPed->bCullExtraFarAway = true;
CVisibilityPlugins::SetClumpAlpha(pCopPed->GetClump(), 0);
CWorld::Add(pCopPed);
}
}
2020-03-25 14:13:06 +00:00
2020-04-11 16:45:49 +00:00
void
CRoadBlocks::GenerateRoadBlocks(void)
{
#ifdef SQUEEZE_PERFORMANCE
if (FindPlayerPed()->m_pWanted->m_RoadblockDensity == 0)
return;
#endif
2020-04-11 16:45:49 +00:00
CMatrix offsetMatrix;
2020-04-11 21:08:16 +00:00
uint32 frame = CTimer::GetFrameCounter() & 0xF;
int16 nRoadblockNode = (int16)(NUMROADBLOCKS * frame) / 16;
const int16 maxRoadBlocks = (int16)(NUMROADBLOCKS * (frame + 1)) / 16;
for (; nRoadblockNode < Min(NumRoadBlocks, maxRoadBlocks); nRoadblockNode++) {
CTreadable *mapObject = ThePaths.m_mapObjects[RoadBlockObjects[nRoadblockNode]];
CVector2D vecDistance = FindPlayerCoors() - mapObject->GetPosition();
if (vecDistance.x > -ROADBLOCKDIST && vecDistance.x < ROADBLOCKDIST &&
vecDistance.y > -ROADBLOCKDIST && vecDistance.y < ROADBLOCKDIST &&
vecDistance.Magnitude() < ROADBLOCKDIST) {
if (!InOrOut[nRoadblockNode]) {
InOrOut[nRoadblockNode] = true;
if (FindPlayerVehicle() && (CGeneral::GetRandomNumber() & 0x7F) < FindPlayerPed()->m_pWanted->m_RoadblockDensity) {
CWanted *pPlayerWanted = FindPlayerPed()->m_pWanted;
float fMapObjectRadius = 2.0f * mapObject->GetColModel()->boundingBox.max.x;
int32 vehicleId = MI_POLICE;
if (pPlayerWanted->AreArmyRequired())
vehicleId = MI_BARRACKS;
else if (pPlayerWanted->AreFbiRequired())
vehicleId = MI_FBICAR;
else if (pPlayerWanted->AreSwatRequired())
vehicleId = MI_ENFORCER;
if (!CStreaming::HasModelLoaded(vehicleId))
vehicleId = MI_POLICE;
CColModel *pVehicleColModel = CModelInfo::GetModelInfo(vehicleId)->GetColModel();
float fModelRadius = 2.0f * pVehicleColModel->boundingSphere.radius + 0.25f;
int16 radius = (int16)(fMapObjectRadius / fModelRadius);
2020-06-01 09:45:03 +00:00
if (radius >= 6)
continue;
CVector2D vecDistanceToCamera = TheCamera.GetPosition() - mapObject->GetPosition();
float fDotProduct = DotProduct2D(vecDistanceToCamera, mapObject->GetForward());
float fOffset = 0.5f * fModelRadius * (float)(radius - 1);
for (int16 i = 0; i < radius; i++) {
uint8 nRoadblockType = fDotProduct < 0.0f;
if (CGeneral::GetRandomNumber() & 1) {
offsetMatrix.SetRotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f + HALFPI);
}
else {
nRoadblockType = !nRoadblockType;
offsetMatrix.SetRotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f - HALFPI);
}
if (ThePaths.m_objectFlags[RoadBlockObjects[nRoadblockNode]] & ObjectEastWest)
offsetMatrix.GetPosition() = CVector(0.0f, i * fModelRadius - fOffset, 0.6f);
else
offsetMatrix.GetPosition() = CVector(i * fModelRadius - fOffset, 0.0f, 0.6f);
CMatrix vehicleMatrix = mapObject->m_matrix * offsetMatrix;
float fModelRadius = CModelInfo::GetModelInfo(vehicleId)->GetColModel()->boundingSphere.radius - 0.25f;
int16 colliding = 0;
CWorld::FindObjectsKindaColliding(vehicleMatrix.GetPosition(), fModelRadius, 0, &colliding, 2, nil, false, true, true, false, false);
if (!colliding) {
CAutomobile *pVehicle = new CAutomobile(vehicleId, RANDOM_VEHICLE);
pVehicle->SetStatus(STATUS_ABANDONED);
// pVehicle->GetHeightAboveRoad(); // called but return value is ignored?
vehicleMatrix.GetPosition().z += fModelRadius - 0.6f;
pVehicle->m_matrix = vehicleMatrix;
pVehicle->PlaceOnRoadProperly();
pVehicle->SetIsStatic(false);
2020-06-01 09:45:03 +00:00
pVehicle->m_matrix.UpdateRW();
pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
CCarCtrl::JoinCarWithRoadSystem(pVehicle);
pVehicle->bIsLocked = false;
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
pVehicle->AutoPilot.m_nCurrentLane = 0;
pVehicle->AutoPilot.m_nNextLane = 0;
pVehicle->AutoPilot.m_fMaxTrafficSpeed = 0.0f;
pVehicle->AutoPilot.m_nCruiseSpeed = 0.0f;
pVehicle->bExtendedRange = true;
if (pVehicle->UsesSiren(pVehicle->GetModelIndex()) && CGeneral::GetRandomNumber() & 1)
pVehicle->m_bSirenOrAlarm = true;
if (pVehicle->GetUp().z > 0.94f) {
CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), 0);
CWorld::Add(pVehicle);
pVehicle->bCreateRoadBlockPeds = true;
pVehicle->m_nRoadblockType = nRoadblockType;
pVehicle->m_nRoadblockNode = nRoadblockNode;
}
else {
2020-06-01 09:45:03 +00:00
delete pVehicle;
}
}
}
}
2020-04-11 16:45:49 +00:00
}
} else {
InOrOut[nRoadblockNode] = false;
2020-04-11 16:45:49 +00:00
}
}
2020-03-25 14:13:06 +00:00
}