diff options
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/Hud.cpp | 3 | ||||
-rw-r--r-- | src/render/Particle.cpp | 15 | ||||
-rw-r--r-- | src/render/Particle.h | 3 | ||||
-rw-r--r-- | src/render/SpecialFX.cpp | 298 | ||||
-rw-r--r-- | src/render/SpecialFX.h | 48 | ||||
-rw-r--r-- | src/render/VisibilityPlugins.cpp | 28 | ||||
-rw-r--r-- | src/render/WaterCannon.cpp | 2 | ||||
-rw-r--r-- | src/render/WaterCannon.h | 18 |
8 files changed, 397 insertions, 18 deletions
diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index ab635a39..7c8b157c 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -637,6 +637,7 @@ void CHud::Draw() /* DrawOnScreenTimer */ + wchar sTimer[16]; if (!CUserDisplay::OnscnTimer.m_sEntries[0].m_bTimerProcessed) @@ -697,7 +698,7 @@ void CHud::Draw() if (CTimer::GetFrameCounter() & 4 || !CounterFlashTimer) { if (CUserDisplay::OnscnTimer.m_sEntries[0].m_nType) { CSprite2d::DrawRect(CRect(SCREEN_SCALE_FROM_RIGHT(27.0f) - SCREEN_SCALE_X(100.0f) / 2 + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(8.0f), SCREEN_SCALE_FROM_RIGHT(27.0f) + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(11.0f) + SCREEN_SCALE_Y(8.0f)), CRGBA(0, 106, 164, 80)); - CSprite2d::DrawRect(CRect(SCREEN_SCALE_FROM_RIGHT(27.0f) - SCREEN_SCALE_X(100.0f) / 2 + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(8.0f), SCREEN_SCALE_X(atoi(CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterBuffer)) / 2 + SCREEN_SCALE_FROM_RIGHT(27.0f) - SCREEN_SCALE_X(100.0f) / 2 + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(11.0f) + SCREEN_SCALE_Y(8.0f)), CRGBA(0, 106, 164, 255)); + CSprite2d::DrawRect(CRect(SCREEN_SCALE_FROM_RIGHT(27.0f) - SCREEN_SCALE_X(100.0f) / 2 + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(8.0f), SCREEN_SCALE_X(atoi(CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterBuffer)) / 2 + SCREEN_SCALE_FROM_RIGHT(27.0f + 50.0f) + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(11.0f) + SCREEN_SCALE_Y(8.0f)), CRGBA(0, 106, 164, 255)); } else { AsciiToUnicode(CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterBuffer, sTimer); CFont::SetPropOn(); diff --git a/src/render/Particle.cpp b/src/render/Particle.cpp index e2db55c7..56ac9512 100644 --- a/src/render/Particle.cpp +++ b/src/render/Particle.cpp @@ -12,6 +12,10 @@ #include "ParticleObject.h" #include "Particle.h" +#ifndef MASTER +bool CParticle::bEnableBannedParticles = false; +#endif + #define MAX_PARTICLES_ON_SCREEN (1000) @@ -768,7 +772,9 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe { if ( CTimer::GetIsPaused() ) return NULL; - +#ifndef MASTER + if(!bEnableBannedParticles) +#endif if ( ( type == PARTICLE_ENGINE_SMOKE || type == PARTICLE_ENGINE_SMOKE2 || type == PARTICLE_ENGINE_STEAM @@ -781,7 +787,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe { return nil; } - + CParticle *pParticle = m_pUnusedListHead; if ( pParticle == nil ) @@ -1455,7 +1461,10 @@ void CParticle::Render() RwRaster **frames = psystem->m_ppRaster; tParticleType type = psystem->m_Type; - + +#ifndef MASTER + if (!bEnableBannedParticles) +#endif if ( type == PARTICLE_ENGINE_SMOKE || type == PARTICLE_ENGINE_SMOKE2 || type == PARTICLE_ENGINE_STEAM diff --git a/src/render/Particle.h b/src/render/Particle.h index 4e41ea2d..310ef0d4 100644 --- a/src/render/Particle.h +++ b/src/render/Particle.h @@ -97,6 +97,9 @@ public: static void AddJetExplosion(CVector const &vecPos, float fPower, float fSize); static void AddYardieDoorSmoke(CVector const &vecPos, CMatrix const &matMatrix); +#ifndef MASTER + static bool bEnableBannedParticles; +#endif }; VALIDATE_SIZE(CParticle, 0x68);
\ No newline at end of file diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp index 6f21e06c..f1fd3f09 100644 --- a/src/render/SpecialFX.cpp +++ b/src/render/SpecialFX.cpp @@ -5,6 +5,12 @@ #include "Sprite.h" #include "Font.h" #include "Text.h" +#include "TxdStore.h" +#include "FileMgr.h" +#include "FileLoader.h" +#include "Lights.h" +#include "VisibilityPlugins.h" +#include "World.h" WRAPPER void CSpecialFX::Render(void) { EAXJMP(0x518DC0); } WRAPPER void CSpecialFX::Update(void) { EAXJMP(0x518D40); } @@ -18,9 +24,290 @@ WRAPPER void CBulletTraces::Init(void) { EAXJMP(0x518DE0); } WRAPPER void CBrightLights::RegisterOne(CVector pos, CVector up, CVector right, CVector fwd, uint8 type, uint8 unk1, uint8 unk2, uint8 unk3) { EAXJMP(0x51A410); } -WRAPPER void C3dMarkers::PlaceMarkerSet(uint32 id, uint16 type, CVector& pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate) { EAXJMP(0x51BB80); } +RpAtomic *
+MarkerAtomicCB(RpAtomic *atomic, void *data)
+{
+ *(RpAtomic**)data = atomic;
+ return atomic;
+} + +bool
+C3dMarker::AddMarker(uint32 identifier, uint16 type, float fSize, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate)
+{
+ m_nIdentifier = identifier;
+
+ m_Matrix.SetUnity();
+
+ RpAtomic *origAtomic;
+ origAtomic = nil;
+ RpClumpForAllAtomics(C3dMarkers::m_pRpClumpArray[type], MarkerAtomicCB, &origAtomic);
+
+ RpAtomic *atomic = RpAtomicClone(origAtomic);
+ RwFrame *frame = RwFrameCreate();
+ RpAtomicSetFrame(atomic, frame);
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
+
+ RpGeometry *geometry = RpAtomicGetGeometry(atomic);
+ RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR);
+
+ m_pAtomic = atomic;
+ m_Matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame(m_pAtomic)));
+ m_pMaterial = RpGeometryGetMaterial(geometry, 0);
+ m_fSize = fSize;
+ m_fStdSize = m_fSize;
+ m_Color.red = r;
+ m_Color.green = g;
+ m_Color.blue = b;
+ m_Color.alpha = a;
+ m_nPulsePeriod = pulsePeriod;
+ m_fPulseFraction = pulseFraction;
+ m_nRotateRate = rotateRate;
+ m_nStartTime = CTimer::GetTimeInMilliseconds();
+ m_nType = type;
+ return m_pAtomic != nil;
+} + +void +C3dMarker::DeleteMarkerObject() +{ + RwFrame *frame; + + m_nIdentifier = 0;
+ m_nStartTime = 0;
+ m_bIsUsed = false;
+ m_nType = MARKERTYPE_INVALID;
+
+ frame = RpAtomicGetFrame(m_pAtomic);
+ RpAtomicDestroy(m_pAtomic);
+ RwFrameDestroy(frame);
+ m_pAtomic = nil; +} + +void
+C3dMarker::Render()
+{
+ if (m_pAtomic == nil) return;
+
+ RwRGBA *color = RpMaterialGetColor(m_pMaterial);
+ *color = m_Color;
+
+ m_Matrix.UpdateRW();
+
+ CMatrix matrix;
+ matrix.Attach(m_Matrix.m_attachment);
+ matrix.Scale(m_fSize);
+ matrix.UpdateRW();
+
+ RwFrameUpdateObjects(RpAtomicGetFrame(m_pAtomic));
+ SetBrightMarkerColours(m_fBrightness);
+ if (m_nType != MARKERTYPE_ARROW)
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RpAtomicRender(m_pAtomic);
+ if (m_nType != MARKERTYPE_ARROW)
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ ReSetAmbientAndDirectionalColours();
+} + +C3dMarker(&C3dMarkers::m_aMarkerArray)[NUM3DMARKERS] = *(C3dMarker(*)[NUM3DMARKERS])*(uintptr*)0x72D408; +int32 &C3dMarkers::NumActiveMarkers = *(int32*)0x8F2A08; +RpClump* (&C3dMarkers::m_pRpClumpArray)[NUMMARKERTYPES] = *(RpClump*(*)[NUMMARKERTYPES])*(uintptr*)0x8E2888; + +void
+C3dMarkers::Init()
+{
+ for (int i = 0; i < NUM3DMARKERS; i++) {
+ m_aMarkerArray[i].m_pAtomic = nil;
+ m_aMarkerArray[i].m_nType = MARKERTYPE_INVALID;
+ m_aMarkerArray[i].m_bIsUsed = false;
+ m_aMarkerArray[i].m_nIdentifier = 0;
+ m_aMarkerArray[i].m_Color.red = 255;
+ m_aMarkerArray[i].m_Color.green = 255;
+ m_aMarkerArray[i].m_Color.blue = 255;
+ m_aMarkerArray[i].m_Color.alpha = 255;
+ m_aMarkerArray[i].m_nPulsePeriod = 1024;
+ m_aMarkerArray[i].m_nRotateRate = 5;
+ m_aMarkerArray[i].m_nStartTime = 0;
+ m_aMarkerArray[i].m_fPulseFraction = 0.25f;
+ m_aMarkerArray[i].m_fStdSize = 1.0f;
+ m_aMarkerArray[i].m_fSize = 1.0f;
+ m_aMarkerArray[i].m_fBrightness = 1.0f;
+ m_aMarkerArray[i].m_fCameraRange = 0.0f;
+ }
+ NumActiveMarkers = 0;
+ int txdSlot = CTxdStore::FindTxdSlot("particle");
+ CTxdStore::PushCurrentTxd();
+ CTxdStore::SetCurrentTxd(txdSlot);
+ CFileMgr::ChangeDir("\\");
+ m_pRpClumpArray[MARKERTYPE_ARROW] = CFileLoader::LoadAtomicFile2Return("models/generic/arrow.dff");
+ m_pRpClumpArray[MARKERTYPE_CYLINDER] = CFileLoader::LoadAtomicFile2Return("models/generic/zonecylb.dff");
+ CTxdStore::PopCurrentTxd();
+} + +void
+C3dMarkers::Shutdown()
+{
+ for (int i = 0; i < NUM3DMARKERS; i++) {
+ if (m_aMarkerArray[i].m_pAtomic != nil)
+ m_aMarkerArray[i].DeleteMarkerObject();
+ }
+
+ for (int i = 0; i < NUMMARKERTYPES; i++) {
+ if (m_pRpClumpArray[i] != nil)
+ RpClumpDestroy(m_pRpClumpArray[i]);
+ }
+} +void
+C3dMarkers::Render()
+{
+ NumActiveMarkers = 0;
+ ActivateDirectional();
+ for (int i = 0; i < NUM3DMARKERS; i++) {
+ if (m_aMarkerArray[i].m_bIsUsed) {
+ if (m_aMarkerArray[i].m_fCameraRange < 120.0f)
+ m_aMarkerArray[i].Render();
+ NumActiveMarkers++;
+ m_aMarkerArray[i].m_bIsUsed = false;
+ } else if (m_aMarkerArray[i].m_pAtomic != nil) {
+ m_aMarkerArray[i].DeleteMarkerObject();
+ }
+ }
+} +C3dMarker *
+C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate) +{ + C3dMarker *pMarker;
+
+ pMarker = nil;
+ float dist = Sqrt((pos.x - FindPlayerCentreOfWorld(0).x) * (pos.x - FindPlayerCentreOfWorld(0).x) + (pos.y - FindPlayerCentreOfWorld(0).y) * (pos.y - FindPlayerCentreOfWorld(0).y));
+
+ if (type != MARKERTYPE_ARROW && type != MARKERTYPE_CYLINDER) return nil;
+
+ for (int i = 0; i < NUM3DMARKERS; i++) {
+ if (!m_aMarkerArray[i].m_bIsUsed && m_aMarkerArray[i].m_nIdentifier == identifier) {
+ pMarker = &m_aMarkerArray[i];
+ break;
+ }
+ }
+
+ if (pMarker == nil) {
+ for (int i = 0; i < NUM3DMARKERS; i++) {
+ if (m_aMarkerArray[i].m_nType == MARKERTYPE_INVALID) {
+ pMarker = &m_aMarkerArray[i];
+ break;
+ }
+ }
+ }
+
+ if (pMarker == nil && type == MARKERTYPE_ARROW) {
+ for (int i = 0; i < NUM3DMARKERS; i++) {
+ if (dist < m_aMarkerArray[i].m_fCameraRange && m_aMarkerArray[i].m_nType == MARKERTYPE_ARROW && (pMarker == nil || m_aMarkerArray[i].m_fCameraRange > pMarker->m_fCameraRange)) {
+ pMarker = &m_aMarkerArray[i];
+ break;
+ }
+ }
+
+ if (pMarker != nil)
+ pMarker->m_nType = MARKERTYPE_INVALID;
+ }
+
+ if (pMarker == nil) return pMarker;
+
+ pMarker->m_fCameraRange = dist;
+ if (pMarker->m_nIdentifier == identifier && pMarker->m_nType == type) {
+ if (type == MARKERTYPE_ARROW) {
+ if (dist < 25.0f) {
+ if (dist > 5.0f)
+ pMarker->m_fStdSize = size - (25.0f - dist) * (0.3f * size) / 20.0f;
+ else
+ pMarker->m_fStdSize = size - 0.3f * size;
+ } else {
+ pMarker->m_fStdSize = size;
+ }
+ } else if (type == MARKERTYPE_CYLINDER) {
+ if (dist < size + 12.0f) {
+ if (dist > size + 1.0f)
+ pMarker->m_Color.alpha = (1.0f - (size + 12.0f - dist) * 0.7f / 11.0f) * (float)a;
+ else
+ pMarker->m_Color.alpha = (float)a * 0.3f;
+ } else {
+ pMarker->m_Color.alpha = a;
+ }
+ }
+ float someSin = Sin(TWOPI * (float)((pMarker->m_nPulsePeriod - 1) & (CTimer::GetTimeInMilliseconds() - pMarker->m_nStartTime)) / (float)pMarker->m_nPulsePeriod);
+ pMarker->m_fSize = pMarker->m_fStdSize - pulseFraction * pMarker->m_fStdSize * someSin;
+
+ if (type == MARKERTYPE_ARROW) {
+ pos.z += 0.25f * pMarker->m_fStdSize * someSin;
+ } else if (type == MARKERTYPE_0) {
+ if (someSin > 0.0f)
+ pMarker->m_Color.alpha = (float)a * 0.7f * someSin + a;
+ else
+ pMarker->m_Color.alpha = (float)a * 0.4f * someSin + a;
+ }
+ if (pMarker->m_nRotateRate) {
+ RwV3d pos = pMarker->m_Matrix.m_matrix.pos;
+ pMarker->m_Matrix.RotateZ(DEGTORAD(pMarker->m_nRotateRate * CTimer::GetTimeStep()));
+ pMarker->m_Matrix.GetPosition() = pos;
+ }
+ if (type == MARKERTYPE_ARROW)
+ pMarker->m_Matrix.GetPosition() = pos;
+ pMarker->m_bIsUsed = true;
+ return pMarker;
+ }
+
+ if (pMarker->m_nIdentifier != 0)
+ pMarker->DeleteMarkerObject();
+
+ pMarker->AddMarker(identifier, type, size, r, g, b, a, pulsePeriod, pulseFraction, rotateRate);
+ if (type == MARKERTYPE_CYLINDER || type == MARKERTYPE_0 || type == MARKERTYPE_2) {
+ float z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 1.0f, nil);
+ if (z != 0.0f)
+ pos.z = z - 0.05f * size;
+ }
+ pMarker->m_Matrix.SetTranslate(pos.x, pos.y, pos.z);
+ if (type == MARKERTYPE_2) {
+ pMarker->m_Matrix.RotateX(PI);
+ pMarker->m_Matrix.GetPosition() = pos;
+ }
+ pMarker->m_Matrix.UpdateRW();
+ if (type == MARKERTYPE_ARROW) {
+ if (dist < 25.0f) {
+ if (dist > 5.0f)
+ pMarker->m_fStdSize = size - (25.0f - dist) * (0.3f * size) / 20.0f;
+ else
+ pMarker->m_fStdSize = size - 0.3f * size;
+ } else {
+ pMarker->m_fStdSize = size;
+ }
+ } else if (type == MARKERTYPE_CYLINDER) {
+ if (dist < size + 12.0f) {
+ if (dist > size + 1.0f)
+ pMarker->m_Color.alpha = (1.0f - (size + 12.0f - dist) * 0.7f / 11.0f) * (float)a;
+ else
+ pMarker->m_Color.alpha = (float)a * 0.3f;
+ } else {
+ pMarker->m_Color.alpha = a;
+ }
+ }
+ pMarker->m_bIsUsed = true;
+ return pMarker; +} + +void
+C3dMarkers::PlaceMarkerSet(uint32 id, uint16 type, CVector &pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate)
+{
+ PlaceMarker(id, type, pos, size, r, g, b, a, pulsePeriod, pulseFraction, 1);
+ PlaceMarker(id, type, pos, size * 0.93f, r, g, b, a, pulsePeriod, pulseFraction, 2);
+ PlaceMarker(id, type, pos, size * 0.86f, r, g, b, a, pulsePeriod, pulseFraction, -1);
+} + +
+void +C3dMarkers::Update() +{ +} #define MONEY_MESSAGE_LIFETIME_MS 2000 @@ -97,6 +384,15 @@ CMoneyMessages::RegisterOne(CVector vecPos, const char *pText, uint8 bRed, uint8 }
STARTPATCHES + InjectHook(0x51B070, &C3dMarker::AddMarker, PATCH_JUMP); + InjectHook(0x51B170, &C3dMarker::DeleteMarkerObject, PATCH_JUMP); + InjectHook(0x51B1B0, &C3dMarker::Render, PATCH_JUMP); + InjectHook(0x51B2B0, C3dMarkers::Init, PATCH_JUMP); + InjectHook(0x51B480, C3dMarkers::PlaceMarker, PATCH_JUMP); + InjectHook(0x51BB80, C3dMarkers::PlaceMarkerSet, PATCH_JUMP); + InjectHook(0x51B400, C3dMarkers::Render, PATCH_JUMP); + InjectHook(0x51B3B0, C3dMarkers::Shutdown, PATCH_JUMP); + InjectHook(0x51AF70, CMoneyMessages::Init, PATCH_JUMP); InjectHook(0x51B030, CMoneyMessages::Render, PATCH_JUMP); ENDPATCHES diff --git a/src/render/SpecialFX.h b/src/render/SpecialFX.h index 6f4e636f..10b22a77 100644 --- a/src/render/SpecialFX.h +++ b/src/render/SpecialFX.h @@ -36,10 +36,56 @@ public: static void RegisterOne(CVector pos, CVector up, CVector right, CVector fwd, uint8 type, uint8 unk1 = 0, uint8 unk2 = 0, uint8 unk3 = 0); }; +enum +{ + MARKERTYPE_0 = 0, + MARKERTYPE_ARROW, + MARKERTYPE_2, + MARKERTYPE_3, + MARKERTYPE_CYLINDER, + NUMMARKERTYPES, + + MARKERTYPE_INVALID = 0x101 +}; + + +class C3dMarker +{
+public:
+ CMatrix m_Matrix;
+ RpAtomic *m_pAtomic;
+ RpMaterial *m_pMaterial;
+ uint16 m_nType;
+ bool m_bIsUsed;
+ uint32 m_nIdentifier;
+ RwRGBA m_Color;
+ uint16 m_nPulsePeriod;
+ int16 m_nRotateRate;
+ uint32 m_nStartTime;
+ float m_fPulseFraction;
+ float m_fStdSize;
+ float m_fSize;
+ float m_fBrightness;
+ float m_fCameraRange;
+
+ bool AddMarker(uint32 identifier, uint16 type, float fSize, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate);
+ void DeleteMarkerObject();
+ void Render();
+}; + class C3dMarkers { public: - static void PlaceMarkerSet(uint32 id, uint16 type, CVector& pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate); + static void Init(); + static void Shutdown(); + static C3dMarker *PlaceMarker(uint32 id, uint16 type, CVector &pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate); + static void PlaceMarkerSet(uint32 id, uint16 type, CVector &pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate); + static void Render();
+ static void Update(); + + static C3dMarker(&m_aMarkerArray)[NUM3DMARKERS]; + static int32 &NumActiveMarkers; + static RpClump* (&m_pRpClumpArray)[NUMMARKERTYPES]; };
class CMoneyMessage
diff --git a/src/render/VisibilityPlugins.cpp b/src/render/VisibilityPlugins.cpp index ac5ac826..bbaa08ce 100644 --- a/src/render/VisibilityPlugins.cpp +++ b/src/render/VisibilityPlugins.cpp @@ -7,6 +7,7 @@ #include "Renderer.h" #include "Camera.h" #include "VisibilityPlugins.h" +#include "World.h" #define FADE_DISTANCE 20.0f @@ -498,14 +499,11 @@ CVisibilityPlugins::RenderTrainHiDetailAlphaCB(RpAtomic *atomic) return atomic; } -// TODO: this is part of a struct -static RwTexture *&playerskin = *(RwTexture**)0x941428; - RpAtomic* CVisibilityPlugins::RenderPlayerCB(RpAtomic *atomic) { - if(playerskin) - RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetTextureCB, playerskin); + if(CWorld::Players[0].m_pSkinTexture) + RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetTextureCB, CWorld::Players[0].m_pSkinTexture); AtomicDefaultRenderCallBack(atomic); return atomic; } @@ -607,22 +605,30 @@ CVisibilityPlugins::DefaultVisibilityCB(RpClump *clump) bool CVisibilityPlugins::FrustumSphereCB(RpClump *clump) { - // TODO, but unused - return true; + RwSphere sphere; + RwFrame *frame = RpClumpGetFrame(clump); + + CClumpModelInfo *modelInfo = (CClumpModelInfo*)GetFrameHierarchyId(frame); + sphere.radius = modelInfo->GetColModel()->boundingSphere.radius; + sphere.center.x = modelInfo->GetColModel()->boundingSphere.center.x; + sphere.center.y = modelInfo->GetColModel()->boundingSphere.center.y; + sphere.center.z = modelInfo->GetColModel()->boundingSphere.center.z; + RwV3dTransformPoints(&sphere.center, &sphere.center, 1, RwFrameGetLTM(frame)); + return RwCameraFrustumTestSphere(ms_pCamera, &sphere) != rwSPHEREOUTSIDE; } bool CVisibilityPlugins::VehicleVisibilityCB(RpClump *clump) { - // TODO, but unused - return true; + if (GetDistanceSquaredFromCamera(RpClumpGetFrame(clump)) <= ms_vehicleLod1Dist) + return FrustumSphereCB(clump); + return false; } bool CVisibilityPlugins::VehicleVisibilityCB_BigVehicle(RpClump *clump) { - // TODO, but unused - return true; + return FrustumSphereCB(clump); } diff --git a/src/render/WaterCannon.cpp b/src/render/WaterCannon.cpp index 7f44116b..c2af73f0 100644 --- a/src/render/WaterCannon.cpp +++ b/src/render/WaterCannon.cpp @@ -2,6 +2,8 @@ #include "patcher.h" #include "WaterCannon.h" +CWaterCannon* aCannons = (CWaterCannon*)0x8F2CA8; + WRAPPER void CWaterCannons::Update(void) { EAXJMP(0x522510); } WRAPPER void CWaterCannons::UpdateOne(uint32 id, CVector *pos, CVector *dir) { EAXJMP(0x522470); } WRAPPER void CWaterCannons::Render(void) { EAXJMP(0x522550); } diff --git a/src/render/WaterCannon.h b/src/render/WaterCannon.h index de9d0344..16df63db 100644 --- a/src/render/WaterCannon.h +++ b/src/render/WaterCannon.h @@ -1,9 +1,25 @@ #pragma once +class CWaterCannon +{ +public: + int32 m_nId; + int16 m_wIndex; + char gap_6[2]; + int32 m_nTimeCreated; + CVector m_avecPos[16]; + CVector m_avecVelocity[16]; + char m_abUsed[16]; +}; + +static_assert(sizeof(CWaterCannon) == 412, "CWaterCannon: error"); + class CWaterCannons { public: - static void Update(void); + static void Update(); static void UpdateOne(uint32 id, CVector *pos, CVector *dir); static void Render(void); }; + +extern CWaterCannon *aCannons; |