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.cpp360
1 files changed, 255 insertions, 105 deletions
diff --git a/src/core/World.cpp b/src/core/World.cpp
index 6e8314f4..841aab40 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -12,6 +12,7 @@
#include "Messages.h"
#include "ModelIndices.h"
#include "ParticleObject.h"
+#include "Pickups.h"
#include "Population.h"
#include "ProjectileInfo.h"
#include "Record.h"
@@ -23,7 +24,6 @@
#include "WaterLevel.h"
#include "World.h"
-
#define OBJECT_REPOSITION_OFFSET_Z 2.0f
CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS];
@@ -44,13 +44,13 @@ bool CWorld::bProcessCutsceneOnly;
bool CWorld::bDoingCarCollisions;
bool CWorld::bIncludeCarTyres;
+bool CWorld::bIncludeBikers;
+
+CColPoint CWorld::m_aTempColPts[MAX_COLLISION_POINTS];
void
CWorld::Initialise()
{
-#if GTA_VERSION <= GTA3_PS2_160
- CPools::Initialise();
-#endif
pIgnoreEntity = nil;
bDoingCarCollisions = false;
bSecondShift = false;
@@ -59,6 +59,7 @@ CWorld::Initialise()
bIncludeDeadPeds = false;
bForceProcessControl = false;
bIncludeCarTyres = false;
+ bIncludeBikers = false;
}
void
@@ -151,6 +152,7 @@ CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, bool bRemov
CProjectileInfo::RemoveAllProjectiles();
CShadows::TidyUpShadows();
}
+ CPickups::RemoveUnnecessaryPickups(pos, radius);
}
bool
@@ -163,7 +165,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;
@@ -182,7 +184,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
@@ -264,50 +266,55 @@ 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;
+ bool bikers = !!bIncludeBikers;
bIncludeDeadPeds = false;
+ bIncludeBikers = false;
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;
+ if(bikers) bIncludeBikers = 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;
+ bIncludeBikers = 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;
+ bIncludeBikers = bikers;
if(mindist < dist) {
dist = mindist;
@@ -318,53 +325,63 @@ 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;
+ bool bikers = false;
+ bool carTyres = false;
float mindist = dist;
CPtrNode *node;
CEntity *e;
CColModel *colmodel;
-
+ CColModel tyreCol;
+ CColSphere tyreSpheres[6];
+ CColPoint tyreColPoint;
+ float tyreDist;
+
+ if(bIncludeCarTyres && list.first && ((CEntity*)list.first->item)->IsVehicle()){
+ carTyres = true;
+ tyreCol.numTriangles = 0;
+ tyreCol.numBoxes = 0;
+ tyreCol.numLines = 0;
+ tyreCol.spheres = tyreSpheres;
+ tyreCol.numSpheres = ARRAY_SIZE(tyreSpheres);
+ }
if(list.first && bIncludeDeadPeds && ((CEntity *)list.first->item)->IsPed()) deadPeds = true;
+ if(list.first && bIncludeBikers && ((CEntity *)list.first->item)->IsPed()) bikers = true;
for(node = list.first; node; node = node->next) {
e = (CEntity *)node->item;
- if(e->m_scanCode != GetCurrentScanCode() && e != pIgnoreEntity && (e->bUsesCollision || deadPeds) &&
+ if(e->m_scanCode != GetCurrentScanCode() && e != pIgnoreEntity && (e->bUsesCollision || deadPeds || bikers) &&
!(ignoreSomeObjects && CameraToIgnoreThisObject(e))) {
colmodel = nil;
+ tyreDist = mindist;
e->m_scanCode = GetCurrentScanCode();
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
+ if(e->bUsesCollision || deadPeds && ((CPed *)e)->m_nPedState == PED_DEAD || bikers && ((CPed*)e)->InVehicle() && (((CPed*)e)->m_pMyVehicle->IsBike() || ((CPed*)e)->m_pMyVehicle->IsBoat())) {
+ 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, mindist,
- ignoreSeeThrough))
+ ignoreSeeThrough, ignoreShootThrough))
entity = e;
+ if(carTyres && ((CVehicle*)e)->SetUpWheelColModel(&tyreCol) && CCollision::ProcessLineOfSight(line, e->GetMatrix(), tyreCol, tyreColPoint, tyreDist, false, ignoreShootThrough)){
+ float dp1 = DotProduct(line.p1 - line.p0, e->GetRight());
+ float dp2 = DotProduct(point.point - e->GetPosition(), e->GetRight());
+ if(tyreDist < mindist || dp1 < -0.85f && dp2 > 0.0f || dp1 > 0.85f && dp2 < 0.0f){
+ mindist = tyreDist;
+ point = tyreColPoint;
+ entity = e;
+ }
+ }
}
}
+ tyreCol.spheres = nil;
if(mindist < dist) {
dist = mindist;
@@ -380,7 +397,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);
}
@@ -446,7 +467,7 @@ CWorld::ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CCol
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, mindist,
- ignoreSeeThrough, poly))
+ ignoreSeeThrough, false, poly))
entity = e;
}
}
@@ -647,7 +668,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;
}
}
@@ -694,18 +715,10 @@ CWorld::FindObjectsInRange(Const CVector &centre, float radius, bool ignoreZ, in
if(minY <= 0) minY = 0;
int maxX = GetSectorIndexX(centre.x + radius);
-#ifdef FIX_BUGS
if(maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
-#else
- if(maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
-#endif
int maxY = GetSectorIndexY(centre.y + radius);
-#ifdef FIX_BUGS
if(maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
-#else
- if(maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y;
-#endif
AdvanceCurrentScanCode();
@@ -782,8 +795,13 @@ CWorld::FindObjectsOfTypeInRange(uint32 modelId, const CVector &position, float
const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
const int32 nStartX = Max(GetSectorIndexX(vecSectorStartPos.x), 0);
const int32 nStartY = Max(GetSectorIndexY(vecSectorStartPos.y), 0);
+#ifdef FIX_BUGS
const int32 nEndX = Min(GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1);
const int32 nEndY = Min(GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1);
+#else
+ const int32 nEndX = Min(GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X);
+ const int32 nEndY = Min(GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y);
+#endif
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
@@ -918,6 +936,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
bool ignoreSomeObjects)
{
static CColModel OurColModel;
+ CColSphere sphere;
OurColModel.boundingSphere.center.x = 0.0f;
OurColModel.boundingSphere.center.y = 0.0f;
@@ -930,7 +949,8 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
OurColModel.boundingBox.max.y = radius;
OurColModel.boundingBox.max.z = radius;
OurColModel.numSpheres = 1;
- OurColModel.spheres = &OurColModel.boundingSphere;
+ sphere.Set(radius, CVector(0.0f, 0.0f, 0.0f));
+ OurColModel.spheres = &sphere;
OurColModel.numLines = 0;
OurColModel.numBoxes = 0;
OurColModel.numTriangles = 0;
@@ -947,11 +967,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
if(e != entityToIgnore && e->bUsesCollision &&
!(ignoreSomeObjects && CameraToIgnoreThisObject(e))) {
-#ifdef FIX_BUGS
CVector diff = spherePos - e->GetBoundCentre();
-#else
- CVector diff = spherePos - e->GetPosition();
-#endif
float distance = diff.Magnitude();
if(e->GetBoundRadius() + radius > distance) {
@@ -1053,8 +1069,13 @@ CWorld::FindObjectsKindaColliding(const CVector &position, float radius, bool bC
const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
const int32 nStartX = Max(GetSectorIndexX(vecSectorStartPos.x), 0);
const int32 nStartY = Max(GetSectorIndexY(vecSectorStartPos.y), 0);
+#ifdef FIX_BUGS
const int32 nEndX = Min(GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1);
const int32 nEndY = Min(GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1);
+#else
+ const int32 nEndX = Min(GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X);
+ const int32 nEndY = Min(GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y);
+#endif
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
@@ -1132,8 +1153,13 @@ CWorld::FindObjectsIntersectingCube(const CVector &vecStartPos, const CVector &v
*nIntersecting = 0;
const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0);
const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0);
- const int32 nEndX = Min(GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
- const int32 nEndY = Min(GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+#ifdef FIX_BUGS
+ const int32 nEndX = Min(GetSectorIndexX(vecStartPos.x), NUMSECTORS_X - 1);
+ const int32 nEndY = Min(GetSectorIndexY(vecStartPos.y), NUMSECTORS_Y - 1);
+#else
+ const int32 nEndX = Min(GetSectorIndexX(vecStartPos.x), NUMSECTORS_X);
+ const int32 nEndY = Min(GetSectorIndexY(vecStartPos.y), NUMSECTORS_Y);
+#endif
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
@@ -1203,7 +1229,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,
@@ -1213,8 +1239,13 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &boundingBox, co
*nEntitiesFound = 0;
const int32 nStartX = Max(GetSectorIndexX(fStartX), 0);
const int32 nStartY = Max(GetSectorIndexY(fStartY), 0);
+#ifdef FIX_BUGS
const int32 nEndX = Min(GetSectorIndexX(fEndX), NUMSECTORS_X - 1);
const int32 nEndY = Min(GetSectorIndexY(fEndY), NUMSECTORS_Y - 1);
+#else
+ const int32 nEndX = Min(GetSectorIndexX(fEndX), NUMSECTORS_X);
+ const int32 nEndY = Min(GetSectorIndexY(fEndY), NUMSECTORS_Y);
+#endif
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
@@ -1263,7 +1294,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)
@@ -1293,8 +1324,13 @@ CWorld::FindMissionEntitiesIntersectingCube(const CVector &vecStartPos, const CV
*nIntersecting = 0;
const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0);
const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0);
+#ifdef FIX_BUGS
const int32 nEndX = Min(GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
const int32 nEndY = Min(GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+#else
+ const int32 nEndX = Min(GetSectorIndexX(vecEndPos.x), NUMSECTORS_X);
+ const int32 nEndY = Min(GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y);
+#endif
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
@@ -1411,8 +1447,13 @@ CWorld::CallOffChaseForArea(float x1, float y1, float x2, float y2)
float fEndY = y2 + 10.0f;
const int32 nStartX = Max(GetSectorIndexX(fStartX), 0);
const int32 nStartY = Max(GetSectorIndexY(fStartY), 0);
+#ifdef FIX_BUGS
const int32 nEndX = Min(GetSectorIndexX(fEndX), NUMSECTORS_X - 1);
const int32 nEndY = Min(GetSectorIndexY(fEndY), NUMSECTORS_Y - 1);
+#else
+ const int32 nEndX = Min(GetSectorIndexX(fEndX), NUMSECTORS_X);
+ const int32 nEndY = Min(GetSectorIndexY(fEndY), NUMSECTORS_Y);
+#endif
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
@@ -1543,7 +1584,7 @@ CWorld::RemoveFallenCars(void)
CVehicle *veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
if(veh) {
if(veh->GetPosition().z < MAP_Z_LOW_LIMIT) {
- if(veh->VehicleCreatedBy == MISSION_VEHICLE || veh == FindPlayerVehicle() ||
+ if(veh->VehicleCreatedBy == MISSION_VEHICLE && !veh->bRenderScorched || veh == FindPlayerVehicle() ||
(veh->pDriver && veh->pDriver->IsPlayer())) {
int closestNode = ThePaths.FindNodeClosestToCoors(veh->GetPosition(), PATH_CAR,
999999.9f, false, false);
@@ -1595,10 +1636,10 @@ CWorld::ExtinguishAllCarFiresInArea(CVector point, float range)
}
}
-inline void
-AddSteamsFromGround(CPtrList& list)
+inline void
+AddSteamsFromGround(CPtrList& list)
{
- CPtrNode *pNode = list.first;
+ CPtrNode* pNode = list.first;
while (pNode) {
((CEntity*)pNode->item)->AddSteamsFromGround(nil);
pNode = pNode->next;
@@ -1700,9 +1741,6 @@ CWorld::ShutDown(void)
}
}
ms_listMovingEntityPtrs.Flush();
-#if GTA_VERSION <= GTA3_PS2_160
- CPools::Shutdown();
-#endif
}
void
@@ -1750,35 +1788,56 @@ 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) {
- CVector &position = pEntity->GetMatrix().GetPosition();
- float fBoundingBoxMinZ = pEntity->GetColModel()->boundingBox.min.z;
+ 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)
+ ) {
+ CVector& position = pEntity->GetMatrix().GetPosition();
+ 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 = FindGroundZFor3DCoord(position.x, position.y,
- position.z + OBJECT_REPOSITION_OFFSET_Z, nil) -
- fBoundingBoxMinZ;
+ position.z + fHeight, nil) -
+ fBoundingBoxMinZ;
+ pEntity->GetMatrix().UpdateRW();
+ pEntity->UpdateRwFrame();
+ } else if(IsLightThatNeedsRepositioning(modelId)) {
+ CVector position = pEntity->GetMatrix().GetPosition();
+ 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;
+ if (pColModel->numBoxes == 1)
+ position = pEntity->GetMatrix() * CVector(
+ (pColModel->boxes[0].min.x + pColModel->boxes[0].max.x) / 2,
+ (pColModel->boxes[0].min.y + pColModel->boxes[0].max.y) / 2,
+ pColModel->boxes[0].min.z);
+ else if (pColModel->numSpheres > 0) {
+ position.z = 1000.0f;
+ for (int i = 0; i < pColModel->numSpheres; i++) {
+ if (pColModel->spheres[i].center.z < position.z)
+ position = pColModel->spheres[i].center;
+ }
+ if (position.z < 1000.0f)
+ position = pEntity->GetMatrix() * position;
+ }
+ pEntity->GetMatrix().GetPosition().z = FindGroundZFor3DCoord(position.x, position.y, pEntity->GetMatrix().GetPosition().z + fHeight, nil) - fBoundingBoxMinZ;
pEntity->GetMatrix().UpdateRW();
pEntity->UpdateRwFrame();
- } else if(modelId == MI_BUOY) {
- float fWaterLevel = 0.0f;
+
+ }
+ if(modelId == MI_BUOY) {
bool bFound = true;
const CVector &position = pEntity->GetPosition();
float fGroundZ = FindGroundZFor3DCoord(position.x, position.y,
position.z + OBJECT_REPOSITION_OFFSET_Z, &bFound);
- if(CWaterLevel::GetWaterLevelNoWaves(position.x, position.y, position.z + OBJECT_REPOSITION_OFFSET_Z,
- &fWaterLevel)) {
- if(!bFound || fWaterLevel > fGroundZ) {
- CColModel *pColModel = pEntity->GetColModel();
- float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z;
- pEntity->GetMatrix().GetPosition().z = 0.2f * fHeight + fWaterLevel - 0.5f * fHeight;
- }
- }
+ CColModel *pColModel = pEntity->GetColModel();
+ float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z;
+ pEntity->GetMatrix().GetPosition().z = 0.2f * fHeight + 6.0f - 0.5f * fHeight;
}
}
@@ -1797,6 +1856,28 @@ CWorld::SetCarsOnFire(float x, float y, float z, float radius, CEntity *reason)
}
void
+CWorld::SetPedsChoking(float x, float y, float z, float radius, CEntity* reason)
+{
+ int32 poolSize = CPools::GetPedPool()->GetSize();
+ for (int32 i = poolSize - 1; i >= 0; i--) {
+ CPed* pPed = CPools::GetPedPool()->GetSlot(i);
+ // suspicious copypaste
+ if (pPed && pPed->m_nPedState != PED_DEAD && !pPed->bInVehicle && !pPed->m_pFire && !pPed->bFireProof && pPed->CharCreatedBy != MISSION_CHAR) {
+ if (Abs(pPed->GetPosition().z - z) < 5.0f && Abs(pPed->GetPosition().x - x) < radius &&
+ Abs(pPed->GetPosition().y - y) < radius) {
+ if (!pPed->IsPlayer())
+ pPed->SetFlee(CVector2D(x, y), 10000);
+#ifdef FIX_BUGS
+ pPed->InflictDamage(reason, WEAPONTYPE_TEARGAS, 1.0f, PEDPIECE_TORSO, 0);
+#else
+ pPed->InflictDamage(nil, WEAPONTYPE_TEARGAS, 1.0f, PEDPIECE_TORSO, 0);
+#endif
+ }
+ }
+ }
+}
+
+void
CWorld::SetPedsOnFire(float x, float y, float z, float radius, CEntity *reason)
{
int32 poolSize = CPools::GetPedPool()->GetSize();
@@ -1848,10 +1929,13 @@ CWorld::Process(void)
if(csObj && csObj->m_entryInfoList.first) {
if(csObj->m_rwObject && RwObjectGetType(csObj->m_rwObject) == rpCLUMP &&
RpAnimBlendClumpGetFirstAssociation(csObj->GetClump())) {
- RpAnimBlendClumpUpdateAnimations(csObj->GetClump(),
- csObj->IsObject()
- ? CTimer::GetTimeStepNonClippedInSeconds()
- : CTimer::GetTimeStepInSeconds());
+ if (csObj->IsObject())
+ RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), CTimer::GetTimeStepNonClippedInSeconds());
+ else {
+ if (!csObj->bOffscreen)
+ csObj->bOffscreen = !csObj->GetIsOnScreen();
+ RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), CTimer::GetTimeStepInSeconds(), !csObj->bOffscreen);
+ }
}
csObj->ProcessControl();
csObj->ProcessCollision();
@@ -1864,16 +1948,15 @@ CWorld::Process(void)
} else {
for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
CEntity *movingEnt = (CEntity *)node->item;
-#ifdef FIX_BUGS // from VC
if(!movingEnt->bRemoveFromWorld && movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP &&
-#else
- if(movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP &&
-#endif
RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) {
- RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(),
- movingEnt->IsObject()
- ? CTimer::GetTimeStepNonClippedInSeconds()
- : CTimer::GetTimeStepInSeconds());
+ if (movingEnt->IsObject())
+ RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), CTimer::GetTimeStepNonClippedInSeconds());
+ else {
+ if (!movingEnt->bOffscreen)
+ movingEnt->bOffscreen = !movingEnt->GetIsOnScreen();
+ RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), CTimer::GetTimeStepInSeconds(), !movingEnt->bOffscreen);
+ }
}
}
for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
@@ -1957,7 +2040,7 @@ CWorld::Process(void)
movingEnt->bIsStuck = true;
if(movingEnt->GetStatus() == STATUS_PLAYER) {
printf("STUCK: Final Step: Player Entity %d Is Stuck\n", movingEnt->GetModelIndex());
- movingEnt->m_vecMoveSpeed *= 0.3f;
+ movingEnt->m_vecMoveSpeed *= Pow(0.707f, CTimer::GetTimeStep());
movingEnt->ApplyMoveSpeed();
movingEnt->ApplyTurnSpeed();
}
@@ -1972,9 +2055,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;
@@ -1995,6 +2081,10 @@ CWorld::Process(void)
movingPed->bInVehicle = false;
movingPed->QuitEnteringCar();
}
+ } else if (movingPed->m_attachedTo) {
+ movingPed->PositionAttachedPed();
+ movingPed->GetMatrix().UpdateRW();
+ movingPed->UpdateRwFrame();
}
}
}
@@ -2059,7 +2149,7 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa
pObject->bHasBeenDamaged) {
if(pEntity->IsObject() &&
modelId != MI_EXPLODINGBARREL &&
- modelId != MI_PETROLPUMP)
+ modelId != MI_PETROLPUMP && modelId != MI_PETROLPUMP2)
pObject->bHasBeenDamaged = true;
} else {
CVector pos = pEntity->GetPosition();
@@ -2149,8 +2239,12 @@ CWorld::UseDetonator(CEntity *pEntity)
{
int32 i = CPools::GetVehiclePool()->GetSize();
while(--i >= 0) {
+#ifdef FIX_BUGS
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+#else
CAutomobile *pVehicle = (CAutomobile *)CPools::GetVehiclePool()->GetSlot(i);
- if(pVehicle && !pVehicle->m_vehType && pVehicle->m_bombType == CARBOMB_REMOTE &&
+#endif
+ if(pVehicle && pVehicle->m_bombType == CARBOMB_REMOTE &&
pVehicle->m_pBombRigger == pEntity) {
pVehicle->m_bombType = CARBOMB_NONE;
pVehicle->m_nBombTimer = 500;
@@ -2159,4 +2253,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;
}