2020-07-26 21:41:01 +00:00
|
|
|
#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();
|
2020-07-27 13:04:05 +00:00
|
|
|
m_pos[i].z -= 0.05f*CTimer::GetTimeStep();
|
2020-07-26 21:41:01 +00:00
|
|
|
CVector dist = m_pos[i] - m_pos[i-1];
|
2020-07-27 13:04:05 +00:00
|
|
|
m_pos[i] = m_pos[i-1] + (0.625f/dist.Magnitude())*dist;
|
2020-07-26 21:41:01 +00:00
|
|
|
m_speed[i] = (m_pos[i] - prevPos)/CTimer::GetTimeStep();
|
|
|
|
}
|
|
|
|
if(!m_bWasRegistered && m_pos[0].z < 0.0f)
|
|
|
|
m_bActive = false;
|
2020-07-27 13:04:05 +00:00
|
|
|
m_bWasRegistered = false;
|
2020-07-26 21:41:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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)){
|
2020-07-27 13:04:05 +00:00
|
|
|
#ifdef FIX_BUGS
|
2020-07-26 21:41:01 +00:00
|
|
|
RwIm3DRenderIndexedPrimitive(rwPRIMTYPELINELIST, RopeIndices, 2*(ARRAY_SIZE(m_pos)-1));
|
2020-07-27 13:04:05 +00:00
|
|
|
#else
|
|
|
|
RwIm3DRenderIndexedPrimitive(rwPRIMTYPEPOLYLINE, RopeIndices, 2*(ARRAY_SIZE(m_pos)-1));
|
|
|
|
#endif
|
2020-07-26 21:41:01 +00:00
|
|
|
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;
|
2020-07-27 13:04:05 +00:00
|
|
|
CCopPed *swat = (CCopPed*)CPopulation::AddPed(PEDTYPE_COP, COP_HELI_SWAT, pos);
|
2020-07-26 21:41:01 +00:00
|
|
|
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;
|
|
|
|
}
|