summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNikolay Korolev <nickvnuk@gmail.com>2020-11-10 22:08:32 +0100
committerNikolay Korolev <nickvnuk@gmail.com>2020-11-10 22:08:32 +0100
commitef2089cafbdbd37589d17a4af9e1989f04672777 (patch)
treeb4b1e77e277272a52de8fcca35496cec3f5e337f /src
parentfixes (diff)
downloadre3-ef2089cafbdbd37589d17a4af9e1989f04672777.tar
re3-ef2089cafbdbd37589d17a4af9e1989f04672777.tar.gz
re3-ef2089cafbdbd37589d17a4af9e1989f04672777.tar.bz2
re3-ef2089cafbdbd37589d17a4af9e1989f04672777.tar.lz
re3-ef2089cafbdbd37589d17a4af9e1989f04672777.tar.xz
re3-ef2089cafbdbd37589d17a4af9e1989f04672777.tar.zst
re3-ef2089cafbdbd37589d17a4af9e1989f04672777.zip
Diffstat (limited to 'src')
-rw-r--r--src/control/Pickups.cpp14
-rw-r--r--src/control/Pickups.h1
-rw-r--r--src/core/World.cpp250
-rw-r--r--src/core/World.h20
-rw-r--r--src/vehicles/Automobile.cpp12
-rw-r--r--src/weapons/ProjectileInfo.cpp4
6 files changed, 211 insertions, 90 deletions
diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp
index 2a5863f1..acfb1fbb 100644
--- a/src/control/Pickups.cpp
+++ b/src/control/Pickups.cpp
@@ -1411,6 +1411,20 @@ CPickups::DetonateMinesHitByGunShot(CVector *vec1, CVector *vec2)
}
void
+CPickups::RemoveUnnecessaryPickups(const CVector& center, float radius)
+{
+ for (int i = 0; i < NUMPICKUPS; i++) {
+ if (aPickUps[i].m_eType == PICKUP_ONCE_TIMEOUT || aPickUps[i].m_eType == PICKUP_MONEY) {
+ if ((aPickUps[i].m_vecPos - center).Magnitude() < radius) {
+ aPickUps[i].GetRidOfObjects();
+ aPickUps[i].m_bRemoved = true;
+ aPickUps[i].m_eType = PICKUP_NONE;
+ }
+ }
+ }
+}
+
+void
CPickups::Load(uint8 *buf, uint32 size)
{
INITSAVEBUF
diff --git a/src/control/Pickups.h b/src/control/Pickups.h
index e48ae3b7..36179f66 100644
--- a/src/control/Pickups.h
+++ b/src/control/Pickups.h
@@ -103,6 +103,7 @@ public:
static bool TryToMerge_WeaponType(CVector pos, eWeaponType weapon, uint8 type, uint32 quantity, bool unused);
static void CreateSomeMoney(CVector, int);
static void DetonateMinesHitByGunShot(CVector *vec1, CVector *vec2);
+ static void RemoveUnnecessaryPickups(const CVector& center, float radius);
static void Load(uint8 *buf, uint32 size);
static void Save(uint8 *buf, uint32 *size);
diff --git a/src/core/World.cpp b/src/core/World.cpp
index 14c06a81..e3b8837f 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -15,6 +15,7 @@
#include "Object.h"
#include "ParticleObject.h"
#include "Ped.h"
+#include "Pickups.h"
#include "PlayerPed.h"
#include "Population.h"
#include "ProjectileInfo.h"
@@ -28,6 +29,7 @@
#include "WaterLevel.h"
#include "World.h"
+// --MIAMI: file done
#define OBJECT_REPOSITION_OFFSET_Z 2.0f
@@ -157,6 +159,7 @@ CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, bool bRemov
CProjectileInfo::RemoveAllProjectiles();
CShadows::TidyUpShadows();
}
+ CPickups::RemoveUnnecessaryPickups(pos, radius);
}
bool
@@ -333,11 +336,24 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP
{
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;
@@ -346,10 +362,11 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP
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 || bikers) {
+ 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;
@@ -360,8 +377,18 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP
if(colmodel && CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, dist,
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;
@@ -695,18 +722,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();
@@ -781,13 +800,18 @@ CWorld::FindObjectsOfTypeInRange(uint32 modelId, const CVector &position, float
*nEntitiesFound = 0;
const CVector2D vecSectorStartPos(position.x - radius, position.y - radius);
const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
- const int32 nStartX = Max(CWorld::GetSectorIndexX(vecSectorStartPos.x), 0);
- const int32 nStartY = Max(CWorld::GetSectorIndexY(vecSectorStartPos.y), 0);
- const int32 nEndX = Min(CWorld::GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1);
- const int32 nEndY = Min(CWorld::GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1);
+ 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 = CWorld::GetSector(x, y);
+ CSector *pSector = GetSector(x, y);
if(bBuildings) {
CWorld::FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly,
@@ -1050,13 +1074,18 @@ CWorld::FindObjectsKindaColliding(const CVector &position, float radius, bool bC
*nCollidingEntities = 0;
const CVector2D vecSectorStartPos(position.x - radius, position.y - radius);
const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
- const int32 nStartX = Max(CWorld::GetSectorIndexX(vecSectorStartPos.x), 0);
- const int32 nStartY = Max(CWorld::GetSectorIndexY(vecSectorStartPos.y), 0);
- const int32 nEndX = Min(CWorld::GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1);
- const int32 nEndY = Min(CWorld::GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1);
+ 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 = CWorld::GetSector(x, y);
+ CSector *pSector = GetSector(x, y);
if(bBuildings) {
CWorld::FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly,
@@ -1129,13 +1158,18 @@ CWorld::FindObjectsIntersectingCube(const CVector &vecStartPos, const CVector &v
{
CWorld::AdvanceCurrentScanCode();
*nIntersecting = 0;
- const int32 nStartX = Max(CWorld::GetSectorIndexX(vecStartPos.x), 0);
- const int32 nStartY = Max(CWorld::GetSectorIndexY(vecStartPos.y), 0);
- const int32 nEndX = Min(CWorld::GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
- const int32 nEndY = Min(CWorld::GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+ const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0);
+ const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0);
+#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(vecSectorPos.x), NUMSECTORS_X);
+ const int32 nEndY = Min(GetSectorIndexY(vecSectorPos.y), NUMSECTORS_Y);
+#endif
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
- CSector *pSector = CWorld::GetSector(x, y);
+ CSector *pSector = GetSector(x, y);
if(bBuildings) {
CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS],
vecStartPos, vecEndPos, nIntersecting,
@@ -1210,13 +1244,18 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CBox &boundingBox, const
{
CWorld::AdvanceCurrentScanCode();
*nEntitiesFound = 0;
- const int32 nStartX = Max(CWorld::GetSectorIndexX(fStartX), 0);
- const int32 nStartY = Max(CWorld::GetSectorIndexY(fStartY), 0);
- const int32 nEndX = Min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X - 1);
- const int32 nEndY = Min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y - 1);
+ 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 = CWorld::GetSector(x, y);
+ CSector *pSector = GetSector(x, y);
if(bBuildings) {
CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_BUILDINGS], boundingBox, matrix, position,
@@ -1290,13 +1329,18 @@ CWorld::FindMissionEntitiesIntersectingCube(const CVector &vecStartPos, const CV
{
CWorld::AdvanceCurrentScanCode();
*nIntersecting = 0;
- const int32 nStartX = Max(CWorld::GetSectorIndexX(vecStartPos.x), 0);
- const int32 nStartY = Max(CWorld::GetSectorIndexY(vecStartPos.y), 0);
- const int32 nEndX = Min(CWorld::GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
- const int32 nEndY = Min(CWorld::GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+ 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 = CWorld::GetSector(x, y);
+ CSector *pSector = GetSector(x, y);
if(bVehicles) {
CWorld::FindMissionEntitiesIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES], vecStartPos, vecEndPos, nIntersecting,
@@ -1504,13 +1548,18 @@ CWorld::CallOffChaseForArea(float x1, float y1, float x2, float y2)
float fStartY = y1 - 10.0f;
float fEndX = x2 + 10.0f;
float fEndY = y2 + 10.0f;
- const int32 nStartX = Max(CWorld::GetSectorIndexX(fStartX), 0);
- const int32 nStartY = Max(CWorld::GetSectorIndexY(fStartY), 0);
- const int32 nEndX = Min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X - 1);
- const int32 nEndY = Min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y - 1);
+ 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 = CWorld::GetSector(x, y);
+ CSector *pSector = GetSector(x, y);
CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES], x1, y1, x2,
y2, fStartX, fStartY, fEndX, fEndY);
CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], x1,
@@ -1638,7 +1687,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);
@@ -1825,37 +1874,55 @@ CWorld::RepositionOneObject(CEntity *pEntity)
{
int16 modelId = pEntity->GetModelIndex();
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)
+ 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();
+ 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 (fHeight < OBJECT_REPOSITION_OFFSET_Z) fHeight = OBJECT_REPOSITION_OFFSET_Z;
position.z = CWorld::FindGroundZFor3DCoord(position.x, position.y,
- position.z + fHeight, nil) -
- fBoundingBoxMinZ;
+ position.z + fHeight, nil) -
+ fBoundingBoxMinZ;
pEntity->m_matrix.UpdateRW();
pEntity->UpdateRwFrame();
- } else if(modelId == MI_BUOY) {
- float fWaterLevel = 0.0f;
+ } 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();
+
+ }
+ if(modelId == MI_BUOY) {
bool bFound = true;
const CVector &position = pEntity->GetPosition();
float fGroundZ = CWorld::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;
}
}
@@ -1874,6 +1941,27 @@ 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);
+ 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();
@@ -1925,11 +2013,12 @@ 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()
- : CTimer::GetTimeStep()));
+ if (csObj->IsObject())
+ RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), 0.02f * CTimer::GetTimeStepNonClipped());
+ else {
+ csObj->bOffscreen = !csObj->GetIsOnScreen();
+ RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), 0.02f * CTimer::GetTimeStep(), !csObj->bOffscreen);
+ }
}
csObj->ProcessControl();
csObj->ProcessCollision();
@@ -1949,11 +2038,12 @@ CWorld::Process(void)
#endif
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()
- : CTimer::GetTimeStep()));
+ if (movingEnt->IsObject())
+ RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * CTimer::GetTimeStepNonClipped());
+ else {
+ movingEnt->bOffscreen = !movingEnt->GetIsOnScreen();
+ RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * CTimer::GetTimeStep(), !movingEnt->bOffscreen);
+ }
}
}
for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
@@ -2037,7 +2127,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();
}
@@ -2102,13 +2192,13 @@ CWorld::TriggerExplosion(const CVector &position, float fRadius, float fPower, C
{
CVector2D vecStartPos(position.x - fRadius, position.y - fRadius);
CVector2D vecEndPos(position.x + fRadius, position.y + fRadius);
- const int32 nStartX = Max(CWorld::GetSectorIndexX(vecStartPos.x), 0);
- const int32 nStartY = Max(CWorld::GetSectorIndexY(vecStartPos.y), 0);
- const int32 nEndX = Min(CWorld::GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
- const int32 nEndY = Min(CWorld::GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+ 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);
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
- CSector *pSector = CWorld::GetSector(x, y);
+ CSector *pSector = GetSector(x, y);
CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], position, fRadius,
fPower, pCreator, bProcessVehicleBombTimer);
CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, fRadius, fPower,
@@ -2146,7 +2236,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();
@@ -2171,7 +2261,7 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa
if(!pEntity->GetIsStatic()) {
float fDamageMultiplier = Min((fRadius - fMagnitude) * 2.0f / fRadius, 1.0f);
CVector vecForceDir =
- vecDistance * (fPower * pEntity->m_fMass * 0.00071429f * fDamageMultiplier /
+ vecDistance * (fPower * pEntity->m_fMass / 14000.0f * fDamageMultiplier /
Max(fMagnitude, 0.01f));
vecForceDir.z = Max(vecForceDir.z, 0.0f);
if(pEntity == FindPlayerPed()) vecForceDir.z = Min(vecForceDir.z, 1.0f);
diff --git a/src/core/World.h b/src/core/World.h
index 606a3466..cfdafedd 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -77,7 +77,7 @@ public:
static void Remove(CEntity *entity);
static void Add(CEntity *entity);
- static CSector *GetSector(int x, int y) { return &ms_aSectors[y][x]; }
+ static CSector *GetSector(int x, int y) { if (x > NUMSECTORS_X || y > NUMSECTORS_Y) return &ms_aSectors[0][0]; return &ms_aSectors[y][x]; }
static CPtrList &GetBigBuildingList(eLevelName i) { return ms_bigBuildingsList[i]; }
static CPtrList &GetMovingEntityList(void) { return ms_listMovingEntityPtrs; }
static uint16 GetCurrentScanCode(void) { return ms_nCurrentScanCode; }
@@ -144,6 +144,7 @@ public:
static void SetAllCarsCanBeDamaged(bool);
static void ExtinguishAllCarFiresInArea(CVector, float);
static void SetCarsOnFire(float x, float y, float z, float radius, CEntity* reason);
+ static void SetPedsChoking(float x, float y, float z, float radius, CEntity* reason);
static void SetPedsOnFire(float x, float y, float z, float radius, CEntity* reason);
static void Initialise();
@@ -157,6 +158,23 @@ public:
static void TriggerExplosion(const CVector& position, float fRadius, float fPower, CEntity* pCreator, bool bProcessVehicleBombTimer);
static void TriggerExplosionSectorList(CPtrList& list, const CVector& position, float fRadius, float fPower, CEntity* pCreator, bool bProcessVehicleBombTimer);
static void UseDetonator(CEntity *pEntity);
+
+ // NB: following functions are unused (TODO?)
+ static void CastShadow(float, float, float, float);
+ static void CastShadowSectorList(CPtrList&, float, float, float, float);
+ static void FindLowestZForCoord(float, float);
+ static void CheckBlockListIntegrity(void);
+ static void ProcessVerticalLineSectorList_FillGlobeColPoints(CPtrList&, const CColLine&, CEntity*&, bool, CStoredCollPoly*);
+ static void ProcessVerticalLineSector_FillGlobeColPoints(CSector&, const CColLine&, CEntity*&, bool, bool, bool, bool, bool, bool, CStoredCollPoly*);
+ static void ProcessVerticalLine_FillGlobeColPoints(const CVector&, float, CEntity*&, bool, bool, bool, bool, bool, bool, CStoredCollPoly*);
+ static void PrintCarChanges(void);
+ static void TestForBuildingsOnTopOfEachOther(CPtrList&);
+ static void TestForBuildingsOnTopOfEachOther(void);
+ static void TestForUnusedModels(CPtrList&, int*);
+ static void TestForUnusedModels(void);
+ static void HandleCollisionZoneChange(eLevelName, eLevelName);
+ static void DoZoneTestForChaser(class CPhysical*);
+ static void FindPlayerSlotWithPedPointer(void*);
};
extern CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS];
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index d1a7505e..881dbf4b 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -4834,19 +4834,19 @@ CAutomobile::SetUpWheelColModel(CColModel *colModel)
CMatrix mat;
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LF]));
- colModel->spheres[0].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_LF);
+ colModel->spheres[0].Set(mi->m_wheelScale / 2, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_LF);
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LB]));
- colModel->spheres[1].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_LR);
+ colModel->spheres[1].Set(mi->m_wheelScale / 2, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_LR);
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF]));
- colModel->spheres[2].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_RF);
+ colModel->spheres[2].Set(mi->m_wheelScale / 2, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_RF);
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RB]));
- colModel->spheres[3].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_RR);
+ colModel->spheres[3].Set(mi->m_wheelScale / 2, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_RR);
if(m_aCarNodes[CAR_WHEEL_LM] != nil && m_aCarNodes[CAR_WHEEL_RM] != nil){
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LM]));
- colModel->spheres[4].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_LR);
+ colModel->spheres[4].Set(mi->m_wheelScale / 2, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_LR);
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RM]));
- colModel->spheres[5].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_RR);
+ colModel->spheres[5].Set(mi->m_wheelScale / 2, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_RR);
colModel->numSpheres = 6;
}else
colModel->numSpheres = 4;
diff --git a/src/weapons/ProjectileInfo.cpp b/src/weapons/ProjectileInfo.cpp
index 71cd9cfb..754da5f7 100644
--- a/src/weapons/ProjectileInfo.cpp
+++ b/src/weapons/ProjectileInfo.cpp
@@ -296,10 +296,8 @@ CProjectileInfo::Update()
CParticle::AddParticle(PARTICLE_TEARGAS, projectilePos, CVector(-0.2f, tearGasOffset, 0.0f), 0, 0.0f, 0, 0, 0, 0);
CParticle::AddParticle(PARTICLE_TEARGAS, projectilePos, CVector(tearGasOffset, tearGasOffset, 0.0f), 0, 0.0f, 0, 0, 0, 0);
- // TODO(Miami): SetPedsChoking
- /*if ( CTimer::GetTimeInMilliseconds() & 0x200 )
+ if ( CTimer::GetTimeInMilliseconds() & 0x200 )
CWorld::SetPedsChoking(projectilePos.x, projectilePos.y, projectilePos.z, 6.0f, gaProjectileInfo[i].m_pSource);
- */
}
if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKET) {