diff --git a/src/Pools.cpp b/src/Pools.cpp index 106715e4..f7f93292 100644 --- a/src/Pools.cpp +++ b/src/Pools.cpp @@ -3,9 +3,12 @@ CCPtrNodePool *&CPools::ms_pPtrNodePool = *(CCPtrNodePool**)0x943044; CEntryInfoNodePool *&CPools::ms_pEntryInfoNodePool = *(CEntryInfoNodePool**)0x941448; +CPedPool *&CPools::ms_pPedPool = *(CPedPool**)0x8F2C60; +CVehiclePool *&CPools::ms_pVehiclePool = *(CVehiclePool**)0x9430DC; CBuildingPool *&CPools::ms_pBuildingPool = *(CBuildingPool**)0x8F2C04; CTreadablePool *&CPools::ms_pTreadablePool = *(CTreadablePool**)0x8F2568; CObjectPool *&CPools::ms_pObjectPool = *(CObjectPool**)0x880E28; +CDummyPool *&CPools::ms_pDummyPool = *(CDummyPool**)0x8F2C18; void CPools::Initialise(void) @@ -13,7 +16,10 @@ CPools::Initialise(void) // TODO: unused right now ms_pPtrNodePool = new CCPtrNodePool(NUMPTRNODES); ms_pEntryInfoNodePool = new CEntryInfoNodePool(NUMENTRYINFOS); + ms_pPedPool = new CPedPool(NUMPEDS); + ms_pVehiclePool = new CVehiclePool(NUMVEHICLES); ms_pBuildingPool = new CBuildingPool(NUMBUILDINGS); ms_pTreadablePool = new CTreadablePool(NUMTREADABLES); ms_pObjectPool = new CObjectPool(NUMOBJECTS); + ms_pDummyPool = new CDummyPool(NUMDUMMIES); } diff --git a/src/Pools.h b/src/Pools.h index aa804788..3496064c 100644 --- a/src/Pools.h +++ b/src/Pools.h @@ -5,30 +5,39 @@ #include "Treadable.h" #include "Object.h" #include "CutsceneHead.h" +#include "PlayerPed.h" +#include "Automobile.h" +#include "DummyPed.h" typedef CPool CCPtrNodePool; typedef CPool CEntryInfoNodePool; +typedef CPool CPedPool; +typedef CPool CVehiclePool; typedef CPool CBuildingPool; typedef CPool CTreadablePool; typedef CPool CObjectPool; +typedef CPool CDummyPool; class CPools { static CCPtrNodePool *&ms_pPtrNodePool; static CEntryInfoNodePool *&ms_pEntryInfoNodePool; - // ms_pPedPool - // ms_pVehiclePool + static CPedPool *&ms_pPedPool; + static CVehiclePool *&ms_pVehiclePool; static CBuildingPool *&ms_pBuildingPool; static CTreadablePool *&ms_pTreadablePool; static CObjectPool *&ms_pObjectPool; - // ms_pDummyPool + static CDummyPool *&ms_pDummyPool; // ms_pAudioScriptObjectPool public: static CCPtrNodePool *GetPtrNodePool(void) { return ms_pPtrNodePool; } static CEntryInfoNodePool *GetEntryInfoNodePool(void) { return ms_pEntryInfoNodePool; } + static CPedPool *GetPedPool(void) { return ms_pPedPool; } + static CVehiclePool *GetVehiclePool(void) { return ms_pVehiclePool; } static CBuildingPool *GetBuildingPool(void) { return ms_pBuildingPool; } static CTreadablePool *GetTreadablePool(void) { return ms_pTreadablePool; } static CObjectPool *GetObjectPool(void) { return ms_pObjectPool; } + static CDummyPool *GetDummyPool(void) { return ms_pDummyPool; } static void Initialise(void); }; diff --git a/src/Zones.cpp b/src/Zones.cpp index 741fff7d..0f9bedfb 100644 --- a/src/Zones.cpp +++ b/src/Zones.cpp @@ -629,6 +629,8 @@ STARTPATCHES InjectHook(0x4B6790, CTheZones::FindSmallestZonePositionType, PATCH_JUMP); InjectHook(0x4B6890, CTheZones::FindSmallestZonePositionILN, PATCH_JUMP); InjectHook(0x4B6800, CTheZones::FindZoneByLabelAndReturnIndex, PATCH_JUMP); + InjectHook(0x4B6FA0, CTheZones::GetZone, PATCH_JUMP); + InjectHook(0x4B84F0, CTheZones::GetPointerForZoneIndex, PATCH_JUMP); InjectHook(0x4B6A10, CTheZones::GetZoneInfo, PATCH_JUMP); InjectHook(0x4B6FB0, CTheZones::GetZoneInfoForTimeOfDay, PATCH_JUMP); InjectHook(0x4B6A50, CTheZones::SetZoneCarInfo, PATCH_JUMP); diff --git a/src/entities/Automobile.h b/src/entities/Automobile.h index 06c0e742..379124e6 100644 --- a/src/entities/Automobile.h +++ b/src/entities/Automobile.h @@ -5,7 +5,7 @@ class CAutomobile : public CVehicle { public: - // 0x228 + // 0x288 uint8 stuff1[484]; float m_afWheelSuspDist[4]; uint8 stuff2[300]; diff --git a/src/entities/Boat.h b/src/entities/Boat.h new file mode 100644 index 00000000..b66ab107 --- /dev/null +++ b/src/entities/Boat.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Vehicle.h" + +class CBoat : public CVehicle +{ +public: + // 0x288 + uint8 stuff[508]; +}; +static_assert(sizeof(CBoat) == 0x484, "CBoat: error"); diff --git a/src/entities/CivilianPed.h b/src/entities/CivilianPed.h new file mode 100644 index 00000000..7a592279 --- /dev/null +++ b/src/entities/CivilianPed.h @@ -0,0 +1,9 @@ +#pragma once + +#include "Ped.h" + +class CCivilianPed : public CPed +{ +public: +}; +static_assert(sizeof(CCivilianPed) == 0x53C, "CCivilianPed: error"); diff --git a/src/entities/CopPed.h b/src/entities/CopPed.h new file mode 100644 index 00000000..2658a386 --- /dev/null +++ b/src/entities/CopPed.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Ped.h" + +class CCopPed : public CPed +{ +public: + // 0x53C + uint8 stuff[28]; +}; +static_assert(sizeof(CCopPed) == 0x558, "CCopPed: error"); diff --git a/src/entities/Dummy.cpp b/src/entities/Dummy.cpp new file mode 100644 index 00000000..a4880175 --- /dev/null +++ b/src/entities/Dummy.cpp @@ -0,0 +1,7 @@ +#include "common.h" +#include "patcher.h" +#include "Dummy.h" +#include "Pools.h" + +void *CDummy::operator new(size_t sz) { return CPools::GetDummyPool()->New(); } +void CDummy::operator delete(void *p, size_t sz) { CPools::GetDummyPool()->Delete((CDummy*)p); } diff --git a/src/entities/Dummy.h b/src/entities/Dummy.h new file mode 100644 index 00000000..e7506617 --- /dev/null +++ b/src/entities/Dummy.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Lists.h" +#include "Entity.h" + +class CDummy : public CEntity +{ +public: + CEntryInfoList m_entryInfoList; + + static void *operator new(size_t); + static void operator delete(void*, size_t); +}; +static_assert(sizeof(CDummy) == 0x68, "CDummy: error"); diff --git a/src/entities/DummyObject.h b/src/entities/DummyObject.h new file mode 100644 index 00000000..7bfe3a57 --- /dev/null +++ b/src/entities/DummyObject.h @@ -0,0 +1,8 @@ +#pragma once + +#include "Dummy.h" + +class CDummyObject : CDummy +{ +}; +static_assert(sizeof(CDummyObject) == 0x68, "CDummyObject: error"); diff --git a/src/entities/DummyPed.h b/src/entities/DummyPed.h new file mode 100644 index 00000000..af633dc4 --- /dev/null +++ b/src/entities/DummyPed.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Dummy.h" + +// actually unused +class CDummyPed : CDummy +{ + int32 pedType; + int32 unknown; +}; +static_assert(sizeof(CDummyPed) == 0x70, "CDummyPed: error"); diff --git a/src/entities/EmergencyPed.h b/src/entities/EmergencyPed.h new file mode 100644 index 00000000..f21996e8 --- /dev/null +++ b/src/entities/EmergencyPed.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Ped.h" + +class CEmergencyPed : public CPed +{ +public: + // 0x53C + uint8 stuff[24]; +}; +static_assert(sizeof(CEmergencyPed) == 0x554, "CEmergencyPed: error"); diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index 439d1462..2338f627 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -12,6 +12,63 @@ int gBuildings; +CEntity::CEntity(void) +{ + m_type = ENTITY_TYPE_NOTHING; + m_status = STATUS_ABANDONED; + + bUsesCollision = false; + bCollisionProcessed = false; + bIsStatic = false; + bHasContacted = false; + bPedPhysics = false; + bIsStuck = false; + bIsInSafePosition = false; + bUseCollisionRecords = false; + + bWasPostponed = false; + m_flagB2 = false; + bIsVisible = true; + bHasCollided = false; + bRenderScorched = false; + m_flagB20 = false; + bIsBIGBuilding = false; + bRenderDamaged = false; + + m_flagC1 = false; + m_flagC2 = false; + m_flagC4 = false; + m_flagC8 = false; + m_flagC10 = false; + m_flagC20 = false; + m_bZoneCulled = false; + m_bZoneCulled2 = false; + + bRemoveFromWorld = false; + bHasHitWall = false; + bImBeingRendered = false; + m_flagD8 = false; + m_flagD10 = false; + bDrawLast = false; + m_flagD40 = false; + m_flagD80 = false; + + bDistanceFade = false; + m_flagE2 = false; + + m_scanCode = 0; + m_modelIndex = -1; + m_rwObject = nil; + m_randomSeed = rand(); + m_pFirstReference = nil; +} + +CEntity::~CEntity(void) +{ + DeleteRwObject(); + ResolveReferences(); +} + void CEntity::GetBoundCentre(CVector &out) { @@ -308,6 +365,28 @@ CEntity::SetupLighting(void) return false; } +void +CEntity::AttachToRwObject(RwObject *obj) +{ + m_rwObject = obj; + if(m_rwObject){ + if(RwObjectGetType(m_rwObject) == rpATOMIC) + m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame(m_rwObject)), false); + else if(RwObjectGetType(m_rwObject) == rpCLUMP) + m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame(m_rwObject)), false); + CModelInfo::GetModelInfo(m_modelIndex)->AddRef(); + } +} + +void +CEntity::DetachFromRwObject(void) +{ + if(m_rwObject) + CModelInfo::GetModelInfo(m_modelIndex)->RemoveRef(); + m_rwObject = nil; + m_matrix.Detach(); +} + void CEntity::RegisterReference(CEntity **pent) { @@ -381,6 +460,9 @@ STARTPATCHES InjectHook(0x4A74E0, &CEntity::ResolveReferences, PATCH_JUMP); InjectHook(0x4A7530, &CEntity::PruneReferences, PATCH_JUMP); + InjectHook(0x473F10, &CEntity::AttachToRwObject, PATCH_JUMP); + InjectHook(0x473F60, &CEntity::DetachFromRwObject, PATCH_JUMP); + InjectHook(0x475080, &CEntity::Add_, PATCH_JUMP); InjectHook(0x475310, &CEntity::Remove_, PATCH_JUMP); InjectHook(0x473EA0, &CEntity::CreateRwObject_, PATCH_JUMP); diff --git a/src/entities/Entity.h b/src/entities/Entity.h index 8bcd7348..c4a5c467 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -94,6 +94,9 @@ public: uint16 m_level; // int16 CReference *m_pFirstReference; + CEntity(void); + ~CEntity(void); + virtual void Add(void); virtual void Remove(void); virtual void SetModelIndex(uint32 i) { m_modelIndex = i; CreateRwObject(); } @@ -120,6 +123,7 @@ public: void GetBoundCentre(CVector &out); CVector GetBoundCentre(void) { CVector v; GetBoundCentre(v); return v; } float GetBoundRadius(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.radius; } + float GetDistanceFromCentreOfMassToBaseOfModel(void) { return -CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingBox.min.z; } bool GetIsTouching(CVector const ¢er, float r); bool GetIsOnScreen(void); bool GetIsOnScreenComplex(void); @@ -129,6 +133,9 @@ public: void UpdateRwFrame(void); void SetupBigBuilding(void); + void AttachToRwObject(RwObject *obj); + void DetachFromRwObject(void); + void RegisterReference(CEntity **pent); void ResolveReferences(void); void PruneReferences(void); diff --git a/src/entities/Ped.cpp b/src/entities/Ped.cpp index 0d83ed97..018979eb 100644 --- a/src/entities/Ped.cpp +++ b/src/entities/Ped.cpp @@ -3,8 +3,8 @@ #include "Ped.h" #include "Pools.h" -//void *CPed::operator new(size_t sz) { return CPools::GetPedPool()->New(); } -//void CPed::operator delete(void *p, size_t sz) { CPools::GetPedPool()->Delete((CPed*)p); } +void *CPed::operator new(size_t sz) { return CPools::GetPedPool()->New(); } +void CPed::operator delete(void *p, size_t sz) { CPools::GetPedPool()->Delete((CPed*)p); } WRAPPER void CPed::KillPedWithCar(CVehicle *veh, float impulse) { EAXJMP(0x4EC430); } diff --git a/src/entities/Ped.h b/src/entities/Ped.h index 04763cc1..366674d4 100644 --- a/src/entities/Ped.h +++ b/src/entities/Ped.h @@ -179,10 +179,10 @@ public: CWeapon m_weapons[PED_MAX_WEAPONS]; int32 stuff7; uint8 m_currentWeapon; - uint8 stuff[167]; + uint8 stuff[163]; -// static void *operator new(size_t); -// static void operator delete(void*, size_t); + static void *operator new(size_t); + static void operator delete(void*, size_t); bool IsPlayer(void) { return m_nPedType == 0 || m_nPedType== 1 || m_nPedType == 2 || m_nPedType == 3; } bool UseGroundColModel(void); @@ -196,4 +196,4 @@ static_assert(offsetof(CPed, m_nPedType) == 0x32C, "CPed: error"); static_assert(offsetof(CPed, m_pCollidingEntity) == 0x34C, "CPed: error"); static_assert(offsetof(CPed, m_weapons) == 0x35C, "CPed: error"); static_assert(offsetof(CPed, m_currentWeapon) == 0x498, "CPed: error"); -static_assert(sizeof(CPed) == 0x540, "CPed: error"); +static_assert(sizeof(CPed) == 0x53C, "CPed: error"); diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp index 55eab951..9cd36070 100644 --- a/src/entities/Physical.cpp +++ b/src/entities/Physical.cpp @@ -272,7 +272,7 @@ void CPhysical::ProcessControl(void) { if(!IsPed()) - m_phy_flagA8 = false; + bIsInWater = false; bHasContacted = false; bIsInSafePosition = false; bWasPostponed = false; @@ -438,7 +438,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl if(B->IsPed() && ((CPed*)B)->m_pCurrentPhysSurface == A) ispedcontactA = true; }else - timestepA = A->m_phy_flagA1 ? 2.0f : 1.0f; + timestepA = A->bIsHeavy ? 2.0f : 1.0f; float timestepB; if(A->bPedPhysics){ @@ -451,7 +451,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl if(A->IsPed() && ((CPed*)A)->m_pCurrentPhysSurface == B) ispedcontactB = true; }else - timestepB = B->m_phy_flagA1 ? 2.0f : 1.0f; + timestepB = B->bIsHeavy ? 2.0f : 1.0f; float speedA, speedB; if(B->bIsStatic){ @@ -1821,7 +1821,7 @@ CPhysical::ProcessCollision(void) m_phy_flagA80 = false; if(!m_vecMoveSpeed.IsZero() || !m_vecTurnSpeed.IsZero() || - m_phy_flagA40 || + bHitByTrain || m_status == STATUS_PLAYER || IsPed() && ped->IsPlayer()){ if(IsVehicle()) ((CVehicle*)this)->m_veh_flagD4 = true; @@ -1830,7 +1830,7 @@ CPhysical::ProcessCollision(void) return; } } - m_phy_flagA40 = false; + bHitByTrain = false; m_fDistanceTravelled = (GetPosition() - *savedMatrix.GetPosition()).Magnitude(); m_phy_flagA80 = false; diff --git a/src/entities/Physical.h b/src/entities/Physical.h index 514994f7..c6944b76 100644 --- a/src/entities/Physical.h +++ b/src/entities/Physical.h @@ -49,13 +49,13 @@ public: CVector m_vecDamageNormal; int16 m_nDamagePieceType; - uint8 m_phy_flagA1 : 1; + uint8 bIsHeavy : 1; uint8 bAffectedByGravity : 1; uint8 bInfiniteMass : 1; - uint8 m_phy_flagA8 : 1; + uint8 bIsInWater : 1; uint8 m_phy_flagA10 : 1; uint8 m_phy_flagA20 : 1; - uint8 m_phy_flagA40 : 1; + uint8 bHitByTrain : 1; // from nick uint8 m_phy_flagA80 : 1; uint8 m_nLastCollType; diff --git a/src/entities/Plane.h b/src/entities/Plane.h new file mode 100644 index 00000000..9acc24ec --- /dev/null +++ b/src/entities/Plane.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Vehicle.h" + +class CPlane : public CVehicle +{ +public: + // 0x288 + uint8 stuff[20]; +}; +static_assert(sizeof(CPlane) == 0x29C, "CPlane: error"); diff --git a/src/entities/PlayerPed.h b/src/entities/PlayerPed.h new file mode 100644 index 00000000..35128f46 --- /dev/null +++ b/src/entities/PlayerPed.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Ped.h" + +class CPlayerPed : public CPed +{ +public: + // 0x53C + uint8 stuff[180]; +}; +static_assert(sizeof(CPlayerPed) == 0x5F0, "CPlayerPed: error"); diff --git a/src/entities/Train.h b/src/entities/Train.h new file mode 100644 index 00000000..e591239b --- /dev/null +++ b/src/entities/Train.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Vehicle.h" + +class CTrain : public CVehicle +{ +public: + // 0x288 + uint8 stuff[92]; +}; +static_assert(sizeof(CTrain) == 0x2E4, "CTrain: error"); diff --git a/src/entities/Vehicle.cpp b/src/entities/Vehicle.cpp new file mode 100644 index 00000000..f18cb5a7 --- /dev/null +++ b/src/entities/Vehicle.cpp @@ -0,0 +1,7 @@ +#include "common.h" +#include "patcher.h" +#include "Vehicle.h" +#include "Pools.h" + +void *CVehicle::operator new(size_t sz) { return CPools::GetVehiclePool()->New(); } +void CVehicle::operator delete(void *p, size_t sz) { CPools::GetVehiclePool()->Delete((CVehicle*)p); } diff --git a/src/entities/Vehicle.h b/src/entities/Vehicle.h index 16f11763..46e1c57c 100644 --- a/src/entities/Vehicle.h +++ b/src/entities/Vehicle.h @@ -54,6 +54,9 @@ uint8 m_extra2; uint8 stuff4[139]; int32 m_vehType; + static void *operator new(size_t); + static void operator delete(void*, size_t); + bool IsCar(void) { return m_vehType == VEHICLE_TYPE_CAR; } bool IsBoat(void) { return m_vehType == VEHICLE_TYPE_BOAT; } bool IsTrain(void) { return m_vehType == VEHICLE_TYPE_TRAIN; } diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 6979bb19..c2b341dc 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1169,6 +1169,7 @@ STARTPATCHES InjectHook(0x4A9920, CRenderer::SetupBigBuildingVisibility, PATCH_JUMP); InjectHook(0x4A76B0, CRenderer::ConstructRenderList, PATCH_JUMP); + InjectHook(0x4A7840, CRenderer::PreRender, PATCH_JUMP); InjectHook(0x4A8970, CRenderer::ScanWorld, PATCH_JUMP); InjectHook(0x4AA240, CRenderer::RequestObjectsInFrustum, PATCH_JUMP); InjectHook(0x4A7F30, CRenderer::ScanSectorPoly, PATCH_JUMP);