summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/Ropes.cpp169
-rw-r--r--src/core/Ropes.h31
2 files changed, 200 insertions, 0 deletions
diff --git a/src/core/Ropes.cpp b/src/core/Ropes.cpp
new file mode 100644
index 00000000..4c57f190
--- /dev/null
+++ b/src/core/Ropes.cpp
@@ -0,0 +1,169 @@
+#include "common.h"
+
+#include "Timer.h"
+#include "ModelIndices.h"
+#include "Streaming.h"
+#include "CopPed.h"
+#include "Population.h"
+#include "RenderBuffer.h"
+#include "Camera.h"
+#include "Ropes.h"
+
+CRope CRopes::aRopes[8];
+
+RwImVertexIndex RopeIndices[64] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
+ 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15,
+ 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23,
+ 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31,
+ 31, 32 // unused
+};
+
+void
+CRope::Update(void)
+{
+ int i;
+ float step = Pow(0.85f, CTimer::GetTimeStep());
+ if(!m_bWasRegistered && CTimer::GetTimeInMilliseconds() > m_updateTimer){
+ m_speed[0].z -= 0.0015f*CTimer::GetTimeStep();
+ m_pos[0] += m_speed[0]*CTimer::GetTimeStep();
+ }
+ for(i = 1; i < ARRAY_SIZE(m_pos); i++){
+ CVector prevPos = m_pos[i];
+ m_pos[i] += m_speed[i]*step*CTimer::GetTimeStep();
+ m_pos[0].z -= 0.05f*CTimer::GetTimeStep();
+ CVector dist = m_pos[i] - m_pos[i-1];
+ m_pos[i] = m_pos[i-1] + dist/dist.Magnitude()*0.625f;
+ m_speed[i] = (m_pos[i] - prevPos)/CTimer::GetTimeStep();
+ }
+ if(!m_bWasRegistered && m_pos[0].z < 0.0f)
+ m_bActive = false;
+ m_bWasRegistered = true;
+}
+
+void
+CRope::Render(void)
+{
+ int i;
+ int numVerts = 0;
+ if(!TheCamera.IsSphereVisible(m_pos[16], 20.0f))
+ return;
+
+ for(i = 0; i < ARRAY_SIZE(m_pos); i++){
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[i], 128, 128, 128, 100);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[i], m_pos[i].x, m_pos[i].y, m_pos[i].z);
+ }
+
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+
+ if(RwIm3DTransform(TempBufferRenderVertices, ARRAY_SIZE(m_pos), nil, rwIM3D_VERTEXXYZ|rwIM3D_VERTEXRGBA)){
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPELINELIST, RopeIndices, 2*(ARRAY_SIZE(m_pos)-1));
+ RwIm3DEnd();
+ }
+}
+
+
+void
+CRopes::Init(void)
+{
+ int i;
+ for(i = 0; i < ARRAY_SIZE(aRopes); i++)
+ aRopes[i].m_bActive = false;
+}
+
+void
+CRopes::Update(void)
+{
+ int i;
+ for(i = 0; i < ARRAY_SIZE(aRopes); i++)
+ if(aRopes[i].m_bActive)
+ aRopes[i].Update();
+}
+
+void
+CRopes::Render(void)
+{
+ int i;
+ for(i = 0; i < ARRAY_SIZE(aRopes); i++)
+ if(aRopes[i].m_bActive)
+ aRopes[i].Render();
+}
+
+bool
+CRopes::RegisterRope(uintptr id, CVector pos, bool setUpdateTimer)
+{
+ int i, j;
+ for(i = 0; i < ARRAY_SIZE(aRopes); i++){
+ if(aRopes[i].m_bActive && aRopes[i].m_id == id){
+ aRopes[i].m_pos[0] = pos;
+ aRopes[i].m_speed[0] = CVector(0.0f, 0.0f, 0.0f);
+ aRopes[i].m_bWasRegistered = true;
+ return true;
+ }
+ }
+ for(i = 0; i < ARRAY_SIZE(aRopes); i++)
+ if(!aRopes[i].m_bActive){
+ aRopes[i].m_id = id;
+ aRopes[i].m_pos[0] = pos;
+ aRopes[i].m_speed[0] = CVector(0.0f, 0.0f, 0.0f);
+ aRopes[i].m_unk = false;
+ aRopes[i].m_bWasRegistered = true;
+ aRopes[i].m_updateTimer = setUpdateTimer ? CTimer::GetTimeInMilliseconds() + 20000 : 0;
+ for(j = 1; j < ARRAY_SIZE(CRope::m_pos); j++){
+ if(j & 1)
+ aRopes[i].m_pos[j] = aRopes[i].m_pos[j-1] + CVector(0.0f, 0.0f, 0.625f);
+ else
+ aRopes[i].m_pos[j] = aRopes[i].m_pos[j-1] - CVector(0.0f, 0.0f, 0.625f);
+ aRopes[i].m_speed[j] = CVector(0.0f, 0.0f, 0.0f);
+ }
+ aRopes[i].m_bActive = true;
+ return true;
+ }
+ return false;
+}
+
+void
+CRopes::SetSpeedOfTopNode(uintptr id, CVector speed)
+{
+ int i;
+ for(i = 0; i < ARRAY_SIZE(aRopes); i++)
+ if(aRopes[i].m_bActive && aRopes[i].m_id == id){
+ aRopes[i].m_speed[0] = speed;
+ return;
+ }
+}
+
+bool
+CRopes::FindCoorsAlongRope(uintptr id, float t, CVector *coors)
+{
+ int i, j;
+ float f;
+ for(i = 0; i < ARRAY_SIZE(aRopes); i++)
+ if(aRopes[i].m_bActive && aRopes[i].m_id == id){
+ t = (ARRAY_SIZE(CRope::m_pos)-1)*clamp(t, 0.0f, 0.999f);
+ j = t;
+ f = t - j;
+ *coors = (1.0f-f)*aRopes[i].m_pos[j] + f*aRopes[i].m_pos[j+1];
+ return true;
+ }
+ return false;
+}
+
+bool
+CRopes::CreateRopeWithSwatComingDown(CVector pos)
+{
+ static uint32 ropeId = 0;
+
+ if(!CStreaming::HasModelLoaded(MI_SWAT) || !RegisterRope(ropeId+100, pos, true))
+ return false;
+ CCopPed *swat = (CCopPed*)CPopulation::AddPed(PEDTYPE_COP, COP_ARMY, pos);
+ swat->bUsesCollision = false;
+ swat->m_pRopeEntity = (CEntity*)1;
+ swat->m_nRopeID = 100 + ropeId;
+ CAnimManager::BlendAnimation(swat->GetClump(), ASSOCGRP_STD, ANIM_ABSEIL, 4.0f);
+ ropeId++;
+ return true;
+}
diff --git a/src/core/Ropes.h b/src/core/Ropes.h
new file mode 100644
index 00000000..7930fa98
--- /dev/null
+++ b/src/core/Ropes.h
@@ -0,0 +1,31 @@
+#pragma once
+
+class CRope
+{
+public:
+ bool m_bActive;
+ bool m_bWasRegistered;
+ bool m_unk;
+ uintptr m_id;
+ uint32 m_updateTimer;
+ CVector m_pos[32];
+ CVector m_speed[32];
+
+ void Update(void);
+ void Render(void);
+};
+
+class CRopes
+{
+ static CRope aRopes[8];
+
+public:
+
+ static void Init(void);
+ static void Update(void);
+ static void Render(void);
+ static bool RegisterRope(uintptr id, CVector pos, bool setUpdateTimer);
+ static void SetSpeedOfTopNode(uintptr id, CVector speed);
+ static bool FindCoorsAlongRope(uintptr id, float t, CVector *coors);
+ static bool CreateRopeWithSwatComingDown(CVector pos);
+};