summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/control/CarCtrl.h2
-rw-r--r--src/control/PathFind.h6
-rw-r--r--src/control/RoadBlocks.cpp242
-rw-r--r--src/control/RoadBlocks.h18
-rw-r--r--src/control/Script.cpp6
-rw-r--r--src/core/config.h1
-rw-r--r--src/math/Matrix.h8
7 files changed, 192 insertions, 91 deletions
diff --git a/src/control/CarCtrl.h b/src/control/CarCtrl.h
index ed63a0e2..6b4e94ee 100644
--- a/src/control/CarCtrl.h
+++ b/src/control/CarCtrl.h
@@ -16,8 +16,6 @@ enum{
MAX_CAR_MODELS_IN_ARRAY = 25,
};
-#define LANE_WIDTH 5.0f
-
#ifdef FIX_BUGS
#define FIX_PATHFIND_BUG
#endif
diff --git a/src/control/PathFind.h b/src/control/PathFind.h
index 7abc455a..171a79c5 100644
--- a/src/control/PathFind.h
+++ b/src/control/PathFind.h
@@ -5,6 +5,8 @@
class CVehicle;
class CPtrList;
+#define LANE_WIDTH 5.0f
+
enum
{
NodeTypeExtern = 1,
@@ -85,6 +87,8 @@ struct CPathNode
float GetX(void) { return x/8.0f; }
float GetY(void) { return y/8.0f; }
float GetZ(void) { return z/8.0f; }
+ bool HasDivider(void) { return width != 0; }
+ float GetDivider(void) { return width/(2*8.0f); }
CPathNode *GetPrev(void);
CPathNode *GetNext(void);
void SetPrev(CPathNode *node);
@@ -120,7 +124,7 @@ struct CCarPathLink
float GetY(void) { return y/8.0f; }
float GetDirX(void) { return dirX/100.0f; }
float GetDirY(void) { return dirY/100.0f; }
- float GetLaneOffset(void) { return width/80.0f; }
+ float GetLaneOffset(void) { return width/(2*8.0f*LANE_WIDTH); }
float OneWayLaneOffset()
{
diff --git a/src/control/RoadBlocks.cpp b/src/control/RoadBlocks.cpp
index a26e19f5..67847cf9 100644
--- a/src/control/RoadBlocks.cpp
+++ b/src/control/RoadBlocks.cpp
@@ -14,14 +14,18 @@
#include "Camera.h"
#include "CarCtrl.h"
#include "General.h"
+#include "Object.h"
+
+//--MIAMI: file done
#define ROADBLOCKDIST (90.0f)
+#define ROADBLOCK_OBJECT_WIDTH (4.0f)
int16 CRoadBlocks::NumRoadBlocks;
int16 CRoadBlocks::RoadBlockNodes[NUMROADBLOCKS];
bool CRoadBlocks::InOrOut[NUMROADBLOCKS];
+CScriptRoadblock CRoadBlocks::aScriptRoadBlocks[NUM_SCRIPT_ROADBLOCKS];
-//--MIAMI: TODO
void
CRoadBlocks::Init(void)
{
@@ -43,7 +47,7 @@ CRoadBlocks::Init(void)
}
}
- // TODO(MIAMI): script roadblocks
+ ClearScriptRoadBlocks();
}
void
@@ -83,14 +87,11 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType
pCopPed->SetCurrentWeapon(WEAPONTYPE_COLT45);
CPedPlacement::FindZCoorForPed(&posForZ);
pCopPed->SetPosition(posForZ);
- CVector vecSavedPos = pCopPed->GetPosition();
- pCopPed->m_matrix.SetRotate(0.0f, 0.0f, -HALFPI);
- pCopPed->m_matrix.GetPosition() += vecSavedPos;
+ pCopPed->SetOrientation(0.0f, 0.0f, -HALFPI);
pCopPed->m_bIsDisabledCop = true;
pCopPed->SetIdle();
pCopPed->bKindaStayInSamePlace = true;
pCopPed->bNotAllowedToDuck = false;
-// pCopPed->m_nRoadblockNode = roadBlockNode;
pCopPed->bCrouchWhenShooting = roadBlockType != 2;
if (pEntityToAttack) {
pCopPed->m_pPointGunAt = pEntityToAttack;
@@ -105,99 +106,178 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType
}
}
-//--MIAMI: TODO: implement this
void
CRoadBlocks::GenerateRoadBlocks(void)
{
- CMatrix offsetMatrix;
+ CMatrix tmp1, tmp2;
+ static int16 unk;
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++) {
- CVector2D vecDistance = FindPlayerCoors() - ThePaths.m_pathNodes[nRoadblockNode].GetPosition();
+ int16 node = RoadBlockNodes[nRoadblockNode];
+ CVector2D vecDistance = FindPlayerCoors() - ThePaths.m_pathNodes[node].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) {
-#ifndef MIAMI
- 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);
- if (radius > 0 && radius < 6) {
- 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, -fOffset, 0.6f);
- else
- offsetMatrix.GetPosition() = CVector(-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->bIsStatic = false;
- 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->GetForward().z > 0.94f) {
- CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), 0);
- CWorld::Add(pVehicle);
- pVehicle->bCreateRoadBlockPeds = true;
- pVehicle->m_nRoadblockType = nRoadblockType;
- pVehicle->m_nRoadblockNode = nRoadblockNode;
- }
- else {
- delete pVehicle;
- }
- }
- }
+ CCarPathLink* pLink1 = &ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[ThePaths.m_pathNodes[node].firstLink]];
+ CCarPathLink* pLink2 = &ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[ThePaths.m_pathNodes[node].firstLink + 1]];
+ int lanes = Min(pLink1->numRightLanes + pLink1->numLeftLanes, pLink2->numLeftLanes + pLink2->numRightLanes);
+ float length = LANE_WIDTH * (lanes + 1);
+ CVector forward(pLink2->GetY() - pLink1->GetY(), -(pLink2->GetX() - pLink1->GetX()), 0.0f);
+ forward.Normalise();
+ if (ThePaths.m_pathNodes[node].HasDivider()) {
+ CreateRoadBlockBetween2Points(
+ ThePaths.m_pathNodes[node].GetPosition() + (length * 0.5f + ThePaths.m_pathNodes[node].GetDivider()) * forward,
+ ThePaths.m_pathNodes[node].GetPosition() + ThePaths.m_pathNodes[node].GetDivider() * forward);
+ CreateRoadBlockBetween2Points(
+ ThePaths.m_pathNodes[node].GetPosition() - ThePaths.m_pathNodes[node].GetDivider() * forward,
+ ThePaths.m_pathNodes[node].GetPosition() - (length * 0.5f + ThePaths.m_pathNodes[node].GetDivider()) * forward);
+ }
+ else {
+ CreateRoadBlockBetween2Points(
+ ThePaths.m_pathNodes[node].GetPosition() + (length * 0.5f) * forward,
+ ThePaths.m_pathNodes[node].GetPosition() - (length * 0.5f) * forward);
}
-#endif
}
}
- } else {
+ }
+ else {
InOrOut[nRoadblockNode] = false;
}
}
+ int i = CTimer::GetFrameCounter() & 0xF;
+ if (!aScriptRoadBlocks[i].m_bInUse)
+ return;
+ if ((aScriptRoadBlocks[i].GetPosition() - FindPlayerCoors()).Magnitude() < 100.0f) {
+ CreateRoadBlockBetween2Points(aScriptRoadBlocks[i].m_vInf, aScriptRoadBlocks[i].m_vSup);
+ aScriptRoadBlocks[i].m_bInUse = false;
+ }
+}
- // TODO(MIAMI): script roadblocks
+void
+CRoadBlocks::ClearScriptRoadBlocks(void)
+{
+ for (int i = 0; i < NUM_SCRIPT_ROADBLOCKS; i++)
+ aScriptRoadBlocks[i].m_bInUse = false;
+}
+
+void
+CRoadBlocks::RegisterScriptRoadBlock(CVector vInf, CVector vSup)
+{
+ int32 i;
+ for (i = 0; i < NUM_SCRIPT_ROADBLOCKS; i++) {
+ if (!aScriptRoadBlocks[i].m_bInUse)
+ break;
+ }
+ if (i == NUM_SCRIPT_ROADBLOCKS)
+ return;
+ aScriptRoadBlocks[i].m_bInUse = true;
+ aScriptRoadBlocks[i].m_vInf = vInf;
+ aScriptRoadBlocks[i].m_vSup = vSup;
+}
+
+void
+CRoadBlocks::CreateRoadBlockBetween2Points(CVector point1, CVector point2)
+{
+ CMatrix tmp;
+ CVector forward = (point2 - point1);
+ float distBetween = forward.Magnitude();
+ CVector pos = (point1 + point2) / 2;
+ CVector right(forward.y, -forward.x, 0.0f);
+ forward.Normalise();
+ right.Normalise();
+ if (DotProduct(FindPlayerCoors() - pos, right) < 0.0f) {
+ right *= -1.0f;
+ }
+ int32 vehicleId = MI_POLICE;
+ if (FindPlayerPed()->m_pWanted->AreArmyRequired())
+ vehicleId = MI_BARRACKS;
+ else if (FindPlayerPed()->m_pWanted->AreFbiRequired())
+ vehicleId = MI_FBICAR;
+ else if (FindPlayerPed()->m_pWanted->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 numRoadblockVehicles = Min(6, (int16)(distBetween / fModelRadius));
+ for (int16 i = 0; i < numRoadblockVehicles; i++) {
+ float offset = fModelRadius * (i - numRoadblockVehicles / 2);
+ tmp.SetTranslate(0.0f, 0.0f, 0.0f);
+ tmp.GetRight() = CVector(forward.y, -forward.x, 0.0f);
+ tmp.GetForward() = forward;
+ tmp.GetUp() = CVector(0.0f, 0.0f, 1.0f);
+ tmp.RotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f);
+ if (CGeneral::GetRandomNumber() & 1)
+ tmp.RotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f + 3.1416f);
+ tmp.SetTranslateOnly(offset * forward + pos);
+ tmp.GetPosition().z += 0.6f;
+ float fModelRadius = CModelInfo::GetModelInfo(vehicleId)->GetColModel()->boundingSphere.radius - 0.25f;
+ int16 colliding = 0;
+ CWorld::FindObjectsKindaColliding(tmp.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?
+ tmp.GetPosition().z += fModelRadius - 0.6f;
+ pVehicle->m_matrix = tmp;
+ pVehicle->PlaceOnRoadProperly();
+ pVehicle->bIsStatic = false;
+ 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_nNextLane = pVehicle->AutoPilot.m_nCurrentLane = 0;
+ pVehicle->AutoPilot.m_nCruiseSpeed = pVehicle->AutoPilot.m_fMaxTrafficSpeed = 0;
+ 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 = DotProduct(pVehicle->GetRight(), pVehicle->GetPosition() - FindPlayerCoors()) >= 0.0f;
+ pVehicle->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 7000;
+ }
+ else {
+ delete pVehicle;
+ }
+ }
+ }
+ int numBarriers = distBetween / ROADBLOCK_OBJECT_WIDTH;
+ CStreaming::RequestModel(MI_ROADWORKBARRIER1, STREAMFLAGS_DONT_REMOVE);
+ if (!CStreaming::HasModelLoaded(MI_ROADWORKBARRIER1))
+ return;
+ for (int i = 0; i < numBarriers; i++) {
+ float offset = ROADBLOCK_OBJECT_WIDTH * (i - numBarriers / 2);
+ tmp.SetTranslate(0.0f, 0.0f, 0.0f);
+ tmp.GetRight() = CVector(forward.y, -forward.x, 0.0f);
+ tmp.GetForward() = forward;
+ tmp.GetUp() = CVector(0.0f, 0.0f, 1.0f);
+ tmp.RotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f);
+ tmp.SetTranslateOnly(5.0f * right + offset * forward + pos);
+ tmp.GetPosition().x += (CGeneral::GetRandomNumber() & 0xF) * 0.1f;
+ tmp.GetPosition().y += (CGeneral::GetRandomNumber() & 0xF) * 0.1f;
+ bool found;
+ tmp.GetPosition().z = CWorld::FindGroundZFor3DCoord(tmp.GetPosition().x, tmp.GetPosition().y, tmp.GetPosition().z + 2.0f, &found);
+ if (!found)
+ continue;
+ int16 colliding = 0;
+ CBaseModelInfo* pMI = CModelInfo::GetModelInfo(MI_ROADWORKBARRIER1);
+ tmp.GetPosition().z -= pMI->GetColModel()->boundingBox.min.z;
+ CWorld::FindObjectsKindaColliding(tmp.GetPosition(), pMI->GetColModel()->boundingSphere.radius, 0, &colliding, 2, nil, false, true, true, false, false);
+ if (colliding == 0) {
+ CObject* pObject = new CObject(MI_ROADWORKBARRIER1, true);
+ pObject->GetMatrix() = tmp;
+ pObject->ObjectCreatedBy = TEMP_OBJECT;
+ pObject->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 600000;
+ CWorld::Add(pObject);
+ }
+ }
}
diff --git a/src/control/RoadBlocks.h b/src/control/RoadBlocks.h
index c8469ba5..ef614950 100644
--- a/src/control/RoadBlocks.h
+++ b/src/control/RoadBlocks.h
@@ -3,18 +3,28 @@
class CVehicle;
+class CScriptRoadblock
+{
+public:
+ CVector m_vInf;
+ CVector m_vSup;
+ bool m_bInUse;
+ CVector GetPosition() { return (m_vInf + m_vSup) / 2; }
+};
+
class CRoadBlocks
{
public:
static int16 NumRoadBlocks;
-#ifndef MIAMI
- static int16 RoadBlockObjects[NUMROADBLOCKS];
-#else
static int16 RoadBlockNodes[NUMROADBLOCKS];
-#endif
static bool InOrOut[NUMROADBLOCKS];
+ static CScriptRoadblock aScriptRoadBlocks[NUM_SCRIPT_ROADBLOCKS];
static void Init(void);
static void GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType);
static void GenerateRoadBlocks(void);
+
+ static void CreateRoadBlockBetween2Points(CVector, CVector);
+ static void RegisterScriptRoadBlock(CVector, CVector);
+ static void ClearScriptRoadBlocks();
};
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index f3583cbe..46fdab73 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -272,7 +272,7 @@ void CMissionCleanup::Process()
CPed::nThreatReactionRangeMultiplier = 1;
CPed::nEnterCarRangeMultiplier = 1;
FindPlayerPed()->m_pWanted->m_fCrimeSensitivity = 1.0f;
- //CRoadBlocks::ClearScriptRoadblocks() // TODO(MIAMI)
+ CRoadBlocks::ClearScriptRoadBlocks();
CRouteNode::Initialise();
if (!CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
TheCamera.Restore();
@@ -10533,12 +10533,12 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
case COMMAND_CREATE_SCRIPT_ROADBLOCK:
{
CollectParameters(&m_nIp, 6);
- debug("CREATE_SCRIPT_ROADBLOCK not implemented\n"); // TODO(MIAMI)
+ CRoadBlocks::RegisterScriptRoadBlock(*(CVector*)&ScriptParams[0], *(CVector*)&ScriptParams[3]);
return 0;
}
case COMMAND_CLEAR_ALL_SCRIPT_ROADBLOCKS:
{
- debug("CLEAR_ALL_SCRIPT_ROADBLOCKS not implemented\n"); // TODO(MIAMI)
+ CRoadBlocks::ClearScriptRoadBlocks();
return 0;
}
case COMMAND_SET_CHAR_OBJ_WALK_TO_CHAR:
diff --git a/src/core/config.h b/src/core/config.h
index c90d3cbf..802925a0 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -115,6 +115,7 @@ enum Config {
NUMSHOTINFOS = 100,
NUMROADBLOCKS = 300,
+ NUM_SCRIPT_ROADBLOCKS = 16,
NUMVISIBLEENTITIES = 2000,
NUMINVISIBLEENTITIES = 150,
diff --git a/src/math/Matrix.h b/src/math/Matrix.h
index 1d26cc20..9979e701 100644
--- a/src/math/Matrix.h
+++ b/src/math/Matrix.h
@@ -255,6 +255,14 @@ public:
m_matrix.at.y = 0.0f;
m_matrix.at.z = 1.0f;
}
+ void SetTranslateOnly(float x, float y, float z) {
+ m_matrix.pos.x = x;
+ m_matrix.pos.y = y;
+ m_matrix.pos.z = z;
+ }
+ void SetTranslateOnly(const CVector& pos) {
+ SetTranslateOnly(pos.x, pos.y, pos.z);
+ }
};