#include "common.h"
#include "patcher.h"
#include "Entity.h"
#include "Ped.h"
#include "PlayerPed.h"
#include "Vehicle.h"
#include "Object.h"
#include "Camera.h"
#include "DMAudio.h"
#include "CarCtrl.h"
#include "Garages.h"
#include "TempColModels.h"
#include "World.h"
CPtrList *CWorld::ms_bigBuildingsList = (CPtrList*)0x6FAB60;
CPtrList &CWorld::ms_listMovingEntityPtrs = *(CPtrList*)0x8F433C;
CSector (*CWorld::ms_aSectors)[NUMSECTORS_X] = (CSector (*)[NUMSECTORS_Y])0x665608;
uint16 &CWorld::ms_nCurrentScanCode = *(uint16*)0x95CC64;
uint8 &CWorld::PlayerInFocus = *(uint8 *)0x95CD61;
CPlayerInfo *CWorld::Players = (CPlayerInfo *)0x9412F0;
bool &CWorld::bNoMoreCollisionTorque = *(bool*)0x95CDCC;
CEntity *&CWorld::pIgnoreEntity = *(CEntity**)0x8F6494;
bool &CWorld::bIncludeDeadPeds = *(bool*)0x95CD8F;
bool &CWorld::bSecondShift = *(bool*)0x95CD54;
bool &CWorld::bForceProcessControl = *(bool*)0x95CD6C;
bool &CWorld::bProcessCutsceneOnly = *(bool*)0x95CD8B;
WRAPPER void CWorld::RemoveReferencesToDeletedObject(CEntity*) { EAXJMP(0x4B3BF0); }
void
CWorld::Add(CEntity *ent)
{
if(ent->IsVehicle() || ent->IsPed())
DMAudio.SetEntityStatus(((CPhysical*)ent)->m_audioEntityId, true);
if(ent->bIsBIGBuilding)
ms_bigBuildingsList[ent->m_level].InsertItem(ent);
else
ent->Add();
if(ent->IsBuilding() || ent->IsDummy())
return;
if(!ent->bIsStatic)
((CPhysical*)ent)->AddToMovingList();
}
void
CWorld::Remove(CEntity *ent)
{
if(ent->IsVehicle() || ent->IsPed())
DMAudio.SetEntityStatus(((CPhysical*)ent)->m_audioEntityId, false);
if(ent->bIsBIGBuilding)
ms_bigBuildingsList[ent->m_level].RemoveItem(ent);
else
ent->Remove();
if(ent->IsBuilding() || ent->IsDummy())
return;
if(!ent->bIsStatic)
((CPhysical*)ent)->RemoveFromMovingList();
}
void
CWorld::ClearScanCodes(void)
{
CPtrNode *node;
for(int i = 0; i < NUMSECTORS_Y; i++)
for(int j = 0; j < NUMSECTORS_X; j++){
CSector *s = &ms_aSectors[i][j];
for(node = s->m_lists[ENTITYLIST_BUILDINGS].first; node; node = node->next)
((CEntity*)node->item)->m_scanCode = 0;
for(node = s->m_lists[ENTITYLIST_VEHICLES].first; node; node = node->next)
((CEntity*)node->item)->m_scanCode = 0;
for(node = s->m_lists[ENTITYLIST_PEDS].first; node; node = node->next)
((CEntity*)node->item)->m_scanCode = 0;
for(node = s->m_lists[ENTITYLIST_OBJECTS].first; node; node = node->next)
((CEntity*)node->item)->m_scanCode = 0;
for(node = s->m_lists[ENTITYLIST_DUMMIES].first; node; node = node->next)
((CEntity*)node->item)->m_scanCode = 0;
}
}
bool
CWorld::CameraToIgnoreThisObject(CEntity *ent)
{
if(CGarages::IsModelIndexADoor(ent->GetModelIndex()))
return false;
return ((CObject*)ent)->m_bCameraToAvoidThisObject != 1;
}
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)
{
int x, xstart, xend;
int y, ystart, yend;
int y1, y2;
float dist;
AdvanceCurrentScanCode();
entity = nil;
dist = 1.0f;
xstart = GetSectorIndexX(point1.x);
ystart = GetSectorIndexX(point1.y);
xend = GetSectorIndexX(point2.x);
yend = GetSectorIndexX(point2.y);
#define LOSARGS CColLine(point1, point2), point, dist, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, ignoreSomeObjects
if(xstart == xend && ystart == yend){
// Only one sector
return ProcessLineOfSightSector(*GetSector(xstart, ystart), LOSARGS);
}else if(xstart == xend){
// Only step in y
if(ystart < yend)
for(y = ystart; y <= yend; y++)
ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
else
for(y = ystart; y >= yend; y--)
ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
return dist < 1.0f;
}else if(ystart == yend){
// Only step in x
if(xstart < xend)
for(x = xstart; x <= xend; x++)
ProcessLineOfSightSector(*GetSector(x, ystart), LOSARGS);
else
for(x = xstart; x >= xend; x--)
ProcessLineOfSightSector(*GetSector(x, ystart), LOSARGS);
return dist < 1.0f;
}else{
if(point1.x < point2.x){
// Step from left to right
float m = (point2.y - point1.y) / (point2.x - point1.x);
y1 = ystart;
y2 = GetSectorIndexY((GetWorldX(xstart+1) - point1.x)*m + point1.y);
if(y1 < y2)
for(y = y1; y <= y2; y++)
ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
else
for(y = y1; y >= y2; y--)
ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
for(x = xstart+1; x < xend; x++){
y1 = y2;
y2 = GetSectorIndexY((GetWorldX(x+1) - point1.x)*m + point1.y);
if(y1 < y2)
for(y = y1; y <= y2; y++)
ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
else
for(y = y1; y >= y2; y--)
ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
}
y1 = y2;
y2 = yend;
if(y1 < y2)
for(y = y1; y <= y2; y++)
ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
else
for(y = y1; y >= y2; y--)
ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
}else{
// Step from right to left
float m = (point2.y - point1.y) / (point2.x - point1.x);
y1 = ystart;
y2 = GetSectorIndexY((GetWorldX(xstart) - point1.x)*m + point1.y);
if(y1 < y2)
for(y = y1; y <= y2; y++)
ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
else
for(y = y1; y >= y2; y--)
ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
for(x = xstart-1; x > xend; x--){
y1 = y2;
y2 = GetSectorIndexY((GetWorldX(x) - point1.x)*m + point1.y);
if(y1 < y2)
for(y = y1; y <= y2; y++)
ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
else
for(y = y1; y >= y2; y--)
ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
}
y1 = y2;
y2 = yend;
if(y1 < y2)
for(y = y1; y <= y2; y++)
ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
else
for(y = y1; y >= y2; y--)
ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
}
return dist < 1.0f;
}
#undef LOSARGS
}
bool
CWorld::ProcessLineOfSightSector(CSector §or, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
{
float mindist = dist;
bool deadPeds = !!bIncludeDeadPeds;
bIncludeDeadPeds = false;
if(checkBuildings){
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS], line, point, mindist, entity, ignoreSeeThrough);
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough);
}
if(checkVehicles){
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_VEHICLES], line, point, mindist, entity, ignoreSeeThrough);
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_VEHICLES_OVERLAP], line, point, mindist, entity, ignoreSeeThrough);
}
if(checkPeds){
if(deadPeds)
bIncludeDeadPeds = true;
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS], line, point, mindist, entity, ignoreSeeThrough);
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough);
bIncludeDeadPeds = false;
}
if(checkObjects){
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_OBJECTS], line, point, mindist, entity, ignoreSeeThrough, ignoreSomeObjects);
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_OBJECTS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, ignoreSomeObjects);
}
if(checkDummies){
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_DUMMIES], line, point, mindist, entity, ignoreSeeThrough);
ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_DUMMIES_OVERLAP], line, point, mindist, entity, ignoreSeeThrough);
}
bIncludeDeadPeds = deadPeds;
if(mindist < dist){
dist = mindist;
return true;
}else
return false;
}
bool
CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects)
{
bool deadPeds = false;
float mindist = dist;
CPtrNode *node;
CEntity *e;
CColModel *colmodel;
if(list.first && bIncludeDeadPeds && ((CEntity*)list.first->item)->IsPed())
deadPeds = true;
for(node = list.first; node; node = node->next){
e = (CEntity*)node->item;
if(e->m_scanCode != GetCurrentScanCode() &&
e != pIgnoreEntity &&
(e->bUsesCollision || deadPeds) &&
!(ignoreSomeObjects && CameraToIgnoreThisObject(e))){
colmodel = nil;
e->m_scanCode = GetCurrentScanCode();
if(e->IsPed()){
if(e->bUsesCollision ||
deadPeds && ((CPed*)e)->m_nPedState == PED_DEAD){
if(((CPed*)e)->UseGroundColModel())
colmodel = &CTempColModels::ms_colModelPedGroundHit;
else
colmodel = ((CPedModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex()))->GetHitColModel();
}else
colmodel = nil;
}else if(e->bUsesCollision)
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
if(colmodel &&
CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, dist, ignoreSeeThrough))
entity = e;
}
}
if(mindist < dist){
dist = mindist;
return true;
}else
return false;
}
bool
CWorld::ProcessVerticalLine(const CVector &point1, float z2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, CStoredCollPoly *poly)
{
AdvanceCurrentScanCode();
CVector point2(point1.x, point1.y, z2);
return CWorld::ProcessVerticalLineSector(*GetSector(GetSectorIndexX(point1.x), GetSectorIndexX(point1.y)),
CColLine(point1, point2), point, entity,
checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, poly);
}
bool
CWorld::ProcessVerticalLineSector(CSector §or, const CColLine &line, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, CStoredCollPoly *poly)
{
float mindist = 1.0f;
if(checkBuildings){
ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_BUILDINGS], line, point, mindist, entity, ignoreSeeThrough, poly);
ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_BUILDINGS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, poly);
}
if(checkVehicles){
ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_VEHICLES], line, point, mindist, entity, ignoreSeeThrough, poly);
ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_VEHICLES_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, poly);
}
if(checkPeds){
ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_PEDS], line, point, mindist, entity, ignoreSeeThrough, poly);
ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, poly);
}
if(checkObjects){
ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_OBJECTS], line, point, mindist, entity, ignoreSeeThrough, poly);
ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_OBJECTS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, poly);
}
if(checkDummies){
ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_DUMMIES], line, point, mindist, entity, ignoreSeeThrough, poly);
ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_DUMMIES_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, poly);
}
return mindist < 1.0f;
}
bool
CWorld::ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, CStoredCollPoly *poly)
{
float mindist = dist;
CPtrNode *node;
CEntity *e;
CColModel *colmodel;
for(node = list.first; node; node = node->next){
e = (CEntity*)node->item;
if(e->m_scanCode != GetCurrentScanCode() &&
e->bUsesCollision){
e->m_scanCode = GetCurrentScanCode();
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, dist, ignoreSeeThrough, poly))
entity = e;
}
}
if(mindist < dist){
dist = mindist;
return true;
}else
return false;
}
bool
CWorld::GetIsLineOfSightClear(const CVector &point1, const CVector &point2, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
{
int x, xstart, xend;
int y, ystart, yend;
int y1, y2;
AdvanceCurrentScanCode();
xstart = GetSectorIndexX(point1.x);
ystart = GetSectorIndexX(point1.y);
xend = GetSectorIndexX(point2.x);
yend = GetSectorIndexX(point2.y);
#define LOSARGS CColLine(point1, point2), checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, ignoreSomeObjects
if(xstart == xend && ystart == yend){
// Only one sector
return GetIsLineOfSightSectorClear(*GetSector(xstart, ystart), LOSARGS);
}else if(xstart == xend){
// Only step in y
if(ystart < yend){
for(y = ystart; y <= yend; y++)
if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
return false;
}else{
for(y = ystart; y >= yend; y--)
if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
return false;
}
}else if(ystart == yend){
// Only step in x
if(xstart < xend){
for(x = xstart; x <= xend; x++)
if(!GetIsLineOfSightSectorClear(*GetSector(x, ystart), LOSARGS))
return false;
}else{
for(x = xstart; x >= xend; x--)
if(!GetIsLineOfSightSectorClear(*GetSector(x, ystart), LOSARGS))
return false;
}
}else{
if(point1.x < point2.x){
// Step from left to right
float m = (point2.y - point1.y) / (point2.x - point1.x);
y1 = ystart;
y2 = GetSectorIndexY((GetWorldX(xstart+1) - point1.x)*m + point1.y);
if(y1 < y2){
for(y = y1; y <= y2; y++)
if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
return false;
}else{
for(y = y1; y >= y2; y--)
if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
return false;
}
for(x = xstart+1; x < xend; x++){
y1 = y2;
y2 = GetSectorIndexY((GetWorldX(x+1) - point1.x)*m + point1.y);
if(y1 < y2){
for(y = y1; y <= y2; y++)
if(!GetIsLineOfSightSectorClear(*GetSector(x, y), LOSARGS))
return false;
}else{
for(y = y1; y >= y2; y--)
if(!GetIsLineOfSightSectorClear(*GetSector(x, y), LOSARGS))
return false;
}
}
y1 = y2;
y2 = yend;
if(y1 < y2){
for(y = y1; y <= y2; y++)
if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS))
return false;
}else{
for(y = y1; y >= y2; y--)
if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS))
return false;
}
}else{
// Step from right to left
float m = (point2.y - point1.y) / (point2.x - point1.x);
y1 = ystart;
y2 = GetSectorIndexY((GetWorldX(xstart) - point1.x)*m + point1.y);
if(y1 < y2){
for(y = y1; y <= y2; y++)
if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
return false;
}else{
for(y = y1; y >= y2; y--)
if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
return false;
}
for(x = xstart-1; x > xend; x--){
y1 = y2;
y2 = GetSectorIndexY((GetWorldX(x) - point1.x)*m + point1.y);
if(y1 < y2){
for(y = y1; y <= y2; y++)
if(!GetIsLineOfSightSectorClear(*GetSector(x, y), LOSARGS))
return false;
}else{
for(y = y1; y >= y2; y--)
if(!GetIsLineOfSightSectorClear(*GetSector(x, y), LOSARGS))
return false;
}
}
y1 = y2;
y2 = yend;
if(y1 < y2){
for(y = y1; y <= y2; y++)
if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS))
return false;
}else{
for(y = y1; y >= y2; y--)
if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS))
return false;
}
}
}
return true;
#undef LOSARGS
}
bool
CWorld::GetIsLineOfSightSectorClear(CSector §or, const CColLine &line, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
{
if(checkBuildings){
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_BUILDINGS], line, ignoreSeeThrough))
return false;
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_BUILDINGS_OVERLAP], line, ignoreSeeThrough))
return false;
}
if(checkVehicles){
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_VEHICLES], line, ignoreSeeThrough))
return false;
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_VEHICLES_OVERLAP], line, ignoreSeeThrough))
return false;
}
if(checkPeds){
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_PEDS], line, ignoreSeeThrough))
return false;
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, ignoreSeeThrough))
return false;
}
if(checkObjects){
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_OBJECTS], line, ignoreSeeThrough, ignoreSomeObjects))
return false;
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_OBJECTS_OVERLAP], line, ignoreSeeThrough, ignoreSomeObjects))
return false;
}
if(checkDummies){
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_DUMMIES], line, ignoreSeeThrough))
return false;
if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_DUMMIES_OVERLAP], line, ignoreSeeThrough))
return false;
}
return true;
}
bool
CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bool ignoreSeeThrough, bool ignoreSomeObjects)
{
CPtrNode *node;
CEntity *e;
CColModel *colmodel;
for(node = list.first; node; node = node->next){
e = (CEntity*)node->item;
if(e->m_scanCode != GetCurrentScanCode() &&
e->bUsesCollision){
e->m_scanCode = GetCurrentScanCode();
if(e != pIgnoreEntity &&
!(ignoreSomeObjects && CameraToIgnoreThisObject(e))){
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
if(CCollision::TestLineOfSight(line, e->GetMatrix(), *colmodel, ignoreSeeThrough))
return false;
}
}
}
return true;
}
void
CWorld::FindObjectsInRangeSectorList(CPtrList &list, CVector ¢re, float distance, bool ignoreZ, short *nextObject, short lastObject, CEntity **objects)
{
float distSqr = distance * distance;
float objDistSqr;
for (CPtrNode *node = list.first; node; node = node->next) {
CEntity *object = (CEntity*)node->item;
if (object->m_scanCode != CWorld::GetCurrentScanCode()) {
object->m_scanCode = CWorld::GetCurrentScanCode();
CVector diff = centre - object->GetPosition();
if (ignoreZ)
objDistSqr = diff.MagnitudeSqr2D();
else
objDistSqr = diff.MagnitudeSqr();
if (objDistSqr < distSqr && *nextObject < lastObject) {
if (objects) {
objects[*nextObject] = object;
}
(*nextObject)++;
}
}
}
}
void
CWorld::FindObjectsInRange(CVector ¢re, float distance, bool ignoreZ, short *nextObject, short lastObject, CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies)
{
int minX = GetSectorIndexX(centre.x - distance);
if (minX <= 0)
minX = 0;
int minY = GetSectorIndexY(centre.y - distance);
if (minY <= 0)
minY = 0;
int maxX = GetSectorIndexX(centre.x + distance);
if (maxX >= 100)
maxX = 100;
int maxY = GetSectorIndexY(centre.y + distance);
if (maxY >= 100)
maxY = 100;
AdvanceCurrentScanCode();
*nextObject = 0;
for(int curY = minY; curY <= maxY; curY++) {
for(int curX = minX; curX <= maxX; curX++) {
CSector *sector = GetSector(curX, curY);
if (checkBuildings) {
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], centre, distance, ignoreZ, nextObject, lastObject, objects);
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects);
}
if (checkVehicles) {
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES], centre, distance, ignoreZ, nextObject, lastObject, objects);
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects);
}
if (checkPeds) {
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS], centre, distance, ignoreZ, nextObject, lastObject, objects);
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects);
}
if (checkObjects) {
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS], centre, distance, ignoreZ, nextObject, lastObject, objects);
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects);
}
if (checkDummies) {
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES], centre, distance, ignoreZ, nextObject, lastObject, objects);
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects);
}
}
}
}
float
CWorld::FindGroundZForCoord(float x, float y)
{
CColPoint point;
CEntity *ent;
if(ProcessVerticalLine(CVector(x, y, 1000.0f), -1000.0f, point, ent, true, false, false, false, true, false, nil))
return point.point.z;
else
return 20.0f;
}
float
CWorld::FindGroundZFor3DCoord(float x, float y, float z, bool *found)
{
CColPoint point;
CEntity *ent;
if(ProcessVerticalLine(CVector(x, y, z), -1000.0f, point, ent, true, false, false, false, false, false, nil)){
if(found)
*found = true;
return point.point.z;
}else{
if(found)
*found = false;
return 0.0f;
}
}
float
CWorld::FindRoofZFor3DCoord(float x, float y, float z, bool *found)
{
CColPoint point;
CEntity *ent;
if(ProcessVerticalLine(CVector(x, y, z), 1000.0f, point, ent, true, false, false, false, true, false, nil)){
if(found)
*found = true;
return point.point.z;
}else{
if(found == nil)
printf("THERE IS NO MAP BELOW THE FOLLOWING COORS:%f %f %f. (FindGroundZFor3DCoord)\n", x, y, z);
if(found)
*found = false;
return 20.0f;
}
}
CPlayerPed*
FindPlayerPed(void)
{
return CWorld::Players[CWorld::PlayerInFocus].m_pPed;
}
CVehicle*
FindPlayerVehicle(void)
{
CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
if(ped->bInVehicle && ped->m_pMyVehicle)
return ped->m_pMyVehicle;
else
return nil;
}
CVehicle*
FindPlayerTrain(void)
{
if(FindPlayerVehicle() && FindPlayerVehicle()->IsTrain())
return FindPlayerVehicle();
else
return nil;
}
CEntity*
FindPlayerEntity(void)
{
CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
if(ped->bInVehicle && ped->m_pMyVehicle)
return ped->m_pMyVehicle;
else
return ped;
}
CVector
FindPlayerCoors(void)
{
CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
if(ped->bInVehicle && ped->m_pMyVehicle)
return ped->m_pMyVehicle->GetPosition();
else
return ped->GetPosition();
}
CVector&
FindPlayerSpeed(void)
{
CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
if(ped->bInVehicle && ped->m_pMyVehicle)
return ped->m_pMyVehicle->m_vecMoveSpeed;
else
return ped->m_vecMoveSpeed;
}
CVector&
FindPlayerCentreOfWorld(int32 player)
{
if(CCarCtrl::bCarsGeneratedAroundCamera)
return TheCamera.GetPosition();
if(CWorld::Players[player].m_pRemoteVehicle)
return CWorld::Players[player].m_pRemoteVehicle->GetPosition();
if(FindPlayerVehicle())
return FindPlayerVehicle()->GetPosition();
return CWorld::Players[player].m_pPed->GetPosition();
}
CVector&
FindPlayerCentreOfWorld_NoSniperShift(void)
{
if(CCarCtrl::bCarsGeneratedAroundCamera)
return TheCamera.GetPosition();
if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition();
if(FindPlayerVehicle())
return FindPlayerVehicle()->GetPosition();
return CWorld::Players[CWorld::PlayerInFocus].m_pPed->GetPosition();
}
float
FindPlayerHeading(void)
{
if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading();
if(FindPlayerVehicle())
return FindPlayerVehicle()->GetForward().Heading();
return CWorld::Players[CWorld::PlayerInFocus].m_pPed->GetForward().Heading();
}
STARTPATCHES
InjectHook(0x4AE930, CWorld::Add, PATCH_JUMP);
InjectHook(0x4AE9D0, CWorld::Remove, PATCH_JUMP);
InjectHook(0x4B1F60, CWorld::ClearScanCodes, PATCH_JUMP);
InjectHook(0x4AF970, CWorld::ProcessLineOfSight, PATCH_JUMP);
InjectHook(0x4B0A80, CWorld::ProcessLineOfSightSector, PATCH_JUMP);
InjectHook(0x4B0C70, CWorld::ProcessLineOfSightSectorList, PATCH_JUMP);
InjectHook(0x4B0DE0, CWorld::ProcessVerticalLine, PATCH_JUMP);
InjectHook(0x4B0EF0, CWorld::ProcessVerticalLineSector, PATCH_JUMP);
InjectHook(0x4B1090, CWorld::ProcessVerticalLineSectorList, PATCH_JUMP);
InjectHook(0x4AEAA0, CWorld::GetIsLineOfSightClear, PATCH_JUMP);
InjectHook(0x4B2000, CWorld::GetIsLineOfSightSectorClear, PATCH_JUMP);
InjectHook(0x4B2160, CWorld::GetIsLineOfSightSectorListClear, PATCH_JUMP);
InjectHook(0x4B2200, CWorld::FindObjectsInRange, PATCH_JUMP);
InjectHook(0x4B2540, CWorld::FindObjectsInRangeSectorList, PATCH_JUMP);
InjectHook(0x4B3A80, CWorld::FindGroundZForCoord, PATCH_JUMP);
InjectHook(0x4B3AE0, CWorld::FindGroundZFor3DCoord, PATCH_JUMP);
InjectHook(0x4B3B50, CWorld::FindRoofZFor3DCoord, PATCH_JUMP);
ENDPATCHES