summaryrefslogtreecommitdiffstats
path: root/src/core/World.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/World.cpp')
-rw-r--r--src/core/World.cpp160
1 files changed, 110 insertions, 50 deletions
diff --git a/src/core/World.cpp b/src/core/World.cpp
index c3633d77..ecf17575 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -50,6 +50,8 @@ bool CWorld::bProcessCutsceneOnly;
bool CWorld::bDoingCarCollisions;
bool CWorld::bIncludeCarTyres;
+CColPoint CWorld::m_aTempColPts[MAX_COLLISION_POINTS];
+
void
CWorld::Initialise()
{
@@ -165,7 +167,7 @@ CWorld::CameraToIgnoreThisObject(CEntity *ent)
bool
CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoint &point, CEntity *&entity,
bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects,
- bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
+ bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects, bool ignoreShootThrough)
{
int x, xstart, xend;
int y, ystart, yend;
@@ -184,7 +186,7 @@ CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoi
#define LOSARGS \
CColLine(point1, point2), point, dist, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, \
- checkDummies, ignoreSeeThrough, ignoreSomeObjects
+ checkDummies, ignoreSeeThrough, ignoreSomeObjects, ignoreShootThrough
if(xstart == xend && ystart == yend) {
// Only one sector
@@ -266,7 +268,7 @@ CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoi
bool
CWorld::ProcessLineOfSightSector(CSector &sector, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity,
bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects,
- bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
+ bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects, bool ignoreShootThrough)
{
float mindist = dist;
bool deadPeds = !!bIncludeDeadPeds;
@@ -274,39 +276,39 @@ CWorld::ProcessLineOfSightSector(CSector &sector, const CColLine &line, CColPoin
if(checkBuildings) {
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS], line, point, mindist, entity,
- ignoreSeeThrough);
+ ignoreSeeThrough, false, ignoreShootThrough);
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS_OVERLAP], line, point, mindist, entity,
- ignoreSeeThrough);
+ ignoreSeeThrough, false, ignoreShootThrough);
}
if(checkVehicles) {
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_VEHICLES], line, point, mindist, entity,
- ignoreSeeThrough);
+ ignoreSeeThrough, false, ignoreShootThrough);
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_VEHICLES_OVERLAP], line, point, mindist, entity,
- ignoreSeeThrough);
+ ignoreSeeThrough, false, ignoreShootThrough);
}
if(checkPeds) {
if(deadPeds) bIncludeDeadPeds = true;
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS], line, point, mindist, entity,
- ignoreSeeThrough);
+ ignoreSeeThrough, false, ignoreShootThrough);
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, point, mindist, entity,
- ignoreSeeThrough);
+ ignoreSeeThrough, false, ignoreShootThrough);
bIncludeDeadPeds = false;
}
if(checkObjects) {
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_OBJECTS], line, point, mindist, entity,
- ignoreSeeThrough, ignoreSomeObjects);
+ ignoreSeeThrough, ignoreSomeObjects, ignoreShootThrough);
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_OBJECTS_OVERLAP], line, point, mindist, entity,
- ignoreSeeThrough, ignoreSomeObjects);
+ ignoreSeeThrough, ignoreSomeObjects, ignoreShootThrough);
}
if(checkDummies) {
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_DUMMIES], line, point, mindist, entity,
- ignoreSeeThrough);
+ ignoreSeeThrough, false, ignoreShootThrough);
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_DUMMIES_OVERLAP], line, point, mindist, entity,
- ignoreSeeThrough);
+ ignoreSeeThrough, false, ignoreShootThrough);
}
bIncludeDeadPeds = deadPeds;
@@ -320,7 +322,7 @@ CWorld::ProcessLineOfSightSector(CSector &sector, const CColLine &line, CColPoin
bool
CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist,
- CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects)
+ CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects, bool ignoreShootThrough)
{
bool deadPeds = false;
float mindist = dist;
@@ -339,31 +341,15 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP
if(e->IsPed()) {
if(e->bUsesCollision || deadPeds && ((CPed *)e)->m_nPedState == PED_DEAD) {
-#ifdef PED_SKIN
- if(IsClumpSkinned(e->GetClump()))
- colmodel = ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))->AnimatePedColModelSkinned(e->GetClump());
- else
-#endif
- if(((CPed *)e)->UseGroundColModel())
- colmodel = &CTempColModels::ms_colModelPedGroundHit;
- else
-#ifdef ANIMATE_PED_COL_MODEL
- colmodel = CPedModelInfo::AnimatePedColModel(
- ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))
- ->GetHitColModel(),
- RpClumpGetFrame(e->GetClump()));
-#else
- colmodel =
- ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))
- ->GetHitColModel();
-#endif
+ colmodel = ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))->AnimatePedColModelSkinned(e->GetClump());
} else
colmodel = nil;
+
} else if(e->bUsesCollision)
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
if(colmodel && CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, dist,
- ignoreSeeThrough))
+ ignoreSeeThrough, ignoreShootThrough))
entity = e;
}
}
@@ -382,7 +368,11 @@ CWorld::ProcessVerticalLine(const CVector &point1, float z2, CColPoint &point, C
{
AdvanceCurrentScanCode();
CVector point2(point1.x, point1.y, z2);
- return ProcessVerticalLineSector(*GetSector(GetSectorIndexX(point1.x), GetSectorIndexY(point1.y)),
+ int secX = GetSectorIndexX(point1.x);
+ int secY = GetSectorIndexY(point1.y);
+ secX = clamp(secX, 0, NUMSECTORS_X-1);
+ secY = clamp(secY, 0, NUMSECTORS_Y-1);
+ return ProcessVerticalLineSector(*GetSector(secX, secY),
CColLine(point1, point2), point, entity, checkBuildings, checkVehicles,
checkPeds, checkObjects, checkDummies, ignoreSeeThrough, poly);
}
@@ -448,7 +438,7 @@ CWorld::ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CCol
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, dist,
- ignoreSeeThrough, poly))
+ ignoreSeeThrough, false, poly))
entity = e;
}
}
@@ -649,7 +639,7 @@ CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bo
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
- if(CCollision::TestLineOfSight(line, e->GetMatrix(), *colmodel, ignoreSeeThrough))
+ if(CCollision::TestLineOfSight(line, e->GetMatrix(), *colmodel, ignoreSeeThrough, false))
return false;
}
}
@@ -920,6 +910,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
bool ignoreSomeObjects)
{
static CColModel sphereCol;
+ CColSphere sphere;
sphereCol.boundingSphere.center.x = 0.0f;
sphereCol.boundingSphere.center.y = 0.0f;
@@ -932,7 +923,8 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
sphereCol.boundingBox.max.y = radius;
sphereCol.boundingBox.max.z = radius;
sphereCol.numSpheres = 1;
- sphereCol.spheres = &sphereCol.boundingSphere;
+ sphere.Set(radius, CVector(0.0f, 0.0f, 0.0f));
+ sphereCol.spheres = &sphere;
sphereCol.numLines = 0;
sphereCol.numBoxes = 0;
sphereCol.numTriangles = 0;
@@ -1201,7 +1193,7 @@ CWorld::FindObjectsIntersectingCubeSectorList(CPtrList &list, const CVector &vec
}
void
-CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &boundingBox, const CMatrix &matrix,
+CWorld::FindObjectsIntersectingAngledCollisionBox(const CBox &boundingBox, const CMatrix &matrix,
const CVector &position, float fStartX, float fStartY, float fEndX,
float fEndY, int16 *nEntitiesFound, int16 maxEntitiesToFind,
CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds,
@@ -1261,7 +1253,7 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &boundingBox, co
}
void
-CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList &list, const CColBox &boundingBox,
+CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList &list, const CBox &boundingBox,
const CMatrix &matrix, const CVector &position,
int16 *nEntitiesFound, int16 maxEntitiesToFind,
CEntity **aEntities)
@@ -1823,18 +1815,21 @@ void
CWorld::RepositionOneObject(CEntity *pEntity)
{
int16 modelId = pEntity->GetModelIndex();
- if (IsStreetLight(modelId) || IsTreeModel(modelId) || modelId == MI_PARKINGMETER ||
- modelId == MI_PHONEBOOTH1 || modelId == MI_WASTEBIN || modelId == MI_BIN || modelId == MI_POSTBOX1 ||
- modelId == MI_NEWSSTAND || modelId == MI_TRAFFICCONE || modelId == MI_DUMP1 ||
- modelId == MI_ROADWORKBARRIER1 || modelId == MI_BUSSIGN1 || modelId == MI_NOPARKINGSIGN1 ||
- modelId == MI_PHONESIGN || modelId == MI_TAXISIGN || modelId == MI_FISHSTALL01 ||
- modelId == MI_FISHSTALL02 || modelId == MI_FISHSTALL03 || modelId == MI_FISHSTALL04 ||
- modelId == MI_BAGELSTAND2 || modelId == MI_FIRE_HYDRANT || modelId == MI_BOLLARDLIGHT ||
- modelId == MI_PARKTABLE) {
+ if (modelId == MI_PARKINGMETER || modelId == MI_PHONEBOOTH1 || modelId == MI_WASTEBIN ||
+ modelId == MI_BIN || modelId == MI_POSTBOX1 || modelId == MI_NEWSSTAND || modelId == MI_TRAFFICCONE ||
+ modelId == MI_DUMP1 || modelId == MI_ROADWORKBARRIER1 || modelId == MI_BUSSIGN1 || modelId == MI_NOPARKINGSIGN1 ||
+ modelId == MI_PHONESIGN || modelId == MI_FIRE_HYDRANT || modelId == MI_BOLLARDLIGHT ||
+ modelId == MI_PARKTABLE || modelId == MI_PARKINGMETER2 || modelId == MI_TELPOLE02 ||
+ modelId == MI_PARKBENCH || modelId == MI_BARRIER1 || IsTreeModel(modelId) ||
+ IsLightThatNeedsRepositioning(modelId)
+ ) {
CVector &position = pEntity->GetMatrix().GetPosition();
- float fBoundingBoxMinZ = pEntity->GetColModel()->boundingBox.min.z;
+ CColModel *pColModel = pEntity->GetColModel();
+ float fBoundingBoxMinZ = pColModel->boundingBox.min.z;
+ float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z;
+ if(fHeight < OBJECT_REPOSITION_OFFSET_Z) fHeight = OBJECT_REPOSITION_OFFSET_Z;
position.z = CWorld::FindGroundZFor3DCoord(position.x, position.y,
- position.z + OBJECT_REPOSITION_OFFSET_Z, nil) -
+ position.z + fHeight, nil) -
fBoundingBoxMinZ;
pEntity->m_matrix.UpdateRW();
pEntity->UpdateRwFrame();
@@ -1921,6 +1916,7 @@ CWorld::Process(void)
if(csObj && csObj->m_entryInfoList.first) {
if(csObj->m_rwObject && RwObjectGetType(csObj->m_rwObject) == rpCLUMP &&
RpAnimBlendClumpGetFirstAssociation(csObj->GetClump())) {
+// TODO(MIAMI): doRender argument
RpAnimBlendClumpUpdateAnimations(csObj->GetClump(),
0.02f * (csObj->IsObject()
? CTimer::GetTimeStepNonClipped()
@@ -1939,6 +1935,7 @@ CWorld::Process(void)
CEntity *movingEnt = (CEntity *)node->item;
if(movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP &&
RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) {
+// TODO(MIAMI): doRender argument
RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(),
0.02f * (movingEnt->IsObject()
? CTimer::GetTimeStepNonClipped()
@@ -2041,9 +2038,12 @@ CWorld::Process(void)
movingPed->EnteringCar()) {
CVehicle *movingCar = movingPed->m_pMyVehicle;
if(movingCar) {
+#ifdef GTA_TRAIN
if(movingCar->IsTrain()) {
movingPed->SetPedPositionInTrain();
- } else {
+ } else
+#endif
+ {
switch(movingPed->m_nPedState) {
case PED_ENTER_CAR:
case PED_CARJACK: movingPed->EnterCar(); break;
@@ -2064,6 +2064,10 @@ CWorld::Process(void)
movingPed->bInVehicle = false;
movingPed->QuitEnteringCar();
}
+ } else if (movingPed->m_attachedTo) {
+ movingPed->PositionAttachedPed();
+ movingPed->GetMatrix().UpdateRW();
+ movingPed->UpdateRwFrame();
}
}
}
@@ -2228,4 +2232,60 @@ CWorld::UseDetonator(CEntity *pEntity)
pVehicle->m_pBlowUpEntity->RegisterReference(&pVehicle->m_pBlowUpEntity);
}
}
+ CProjectileInfo::RemoveDetonatorProjectiles();
+}
+
+bool
+CWorld::IsWanderPathClear(CVector const& point1, CVector const& point2, float distance, int maxSteps)
+{
+ if (Abs(point1.z - point2.z) > distance)
+ return false;
+ if (!GetIsLineOfSightClear(point1, point2, true, false, false, false, false, false, false))
+ return false;
+ CVector vecBetween = point2 - point1;
+ uint32 nSteps = Max(vecBetween.Magnitude(), maxSteps);
+ if (nSteps == 0)
+ return true;
+ vecBetween.Normalise();
+ uint32 step = 1;
+ for (step = 1; step < nSteps; step++) {
+ CVector posThisStep = point1 + vecBetween * step;
+ float level;
+ if (!CWaterLevel::GetWaterLevel(posThisStep, &level, false))
+ continue;
+ posThisStep.z = level;
+ AdvanceCurrentScanCode();
+
+ CVector vecCheckedPos(posThisStep.x, posThisStep.y, Max(point1.z, point2.z));
+ CColPoint colpoint;
+ CEntity* entity;
+ if (!ProcessVerticalLineSector(*GetSector(GetSectorIndexX(posThisStep.x), GetSectorIndexY(posThisStep.y)),
+ CColLine(posThisStep, vecCheckedPos), colpoint, entity, true, false, false, false, false, false, nil))
+ return false;
+ }
+
+ CVector posThisStep = point1;
+ AdvanceCurrentScanCode();
+ CVector vecCheckedPos(posThisStep.x, posThisStep.y, point1.z - 5.0f);
+
+ CColPoint colpoint;
+ CEntity* entity;
+ if (!ProcessVerticalLineSector(*GetSector(GetSectorIndexX(posThisStep.x), GetSectorIndexY(posThisStep.y)),
+ CColLine(posThisStep, vecCheckedPos), colpoint, entity, true, false, false, false, false, false, nil))
+ return false;
+
+ float heightNextStep = colpoint.point.z + 0.5f;
+ for (step = 1; step < nSteps; step++) {
+ CVector posThisStep = point1 + vecBetween * step;
+ posThisStep.z = heightNextStep;
+ AdvanceCurrentScanCode();
+ CVector vecCheckedPos(posThisStep.x, posThisStep.y, heightNextStep - 2.0f);
+ if (!ProcessVerticalLineSector(*GetSector(GetSectorIndexX(posThisStep.x), GetSectorIndexY(posThisStep.y)),
+ CColLine(posThisStep, vecCheckedPos), colpoint, entity, true, false, false, false, false, false, nil))
+ return false;
+ if (Abs(colpoint.point.z - heightNextStep) > 1.0f)
+ return false;
+ heightNextStep = colpoint.point.z + 0.5f;
+ }
+ return true;
}