mirror of
https://git.rip/DMCA_FUCKER/re3.git
synced 2024-11-18 05:17:45 +00:00
340 lines
8.9 KiB
C++
340 lines
8.9 KiB
C++
#include "common.h"
|
|
|
|
#include "WaterCannon.h"
|
|
#include "Vector.h"
|
|
#include "General.h"
|
|
#include "main.h"
|
|
#include "Timer.h"
|
|
#include "Pools.h"
|
|
#include "Ped.h"
|
|
#include "AnimManager.h"
|
|
#include "Fire.h"
|
|
#include "WaterLevel.h"
|
|
#include "Camera.h"
|
|
#include "Particle.h"
|
|
|
|
// --LCS: file done
|
|
|
|
#if 0
|
|
//PSP:
|
|
#define WATER_COLOR 255
|
|
#else
|
|
//PS2:
|
|
#define WATER_COLOR 127
|
|
#endif
|
|
|
|
#define WATERCANNONVERTS 4
|
|
#define WATERCANNONINDEXES 12
|
|
|
|
RwIm3DVertex WaterCannonVertices[WATERCANNONVERTS];
|
|
RwImVertexIndex WaterCannonIndexList[WATERCANNONINDEXES];
|
|
|
|
CWaterCannon CWaterCannons::aCannons[NUM_WATERCANNONS];
|
|
|
|
void CWaterCannon::Init(void)
|
|
{
|
|
m_nId = 0;
|
|
m_nCur = 0;
|
|
m_nTimeCreated = CTimer::GetTimeInMilliseconds();
|
|
|
|
for ( int32 i = 0; i < NUM_SEGMENTPOINTS; i++ )
|
|
m_abUsed[i] = false;
|
|
|
|
RwIm3DVertexSetU(&WaterCannonVertices[0], 0.0f);
|
|
RwIm3DVertexSetV(&WaterCannonVertices[0], 0.0f);
|
|
|
|
RwIm3DVertexSetU(&WaterCannonVertices[1], 1.0f);
|
|
RwIm3DVertexSetV(&WaterCannonVertices[1], 0.0f);
|
|
|
|
RwIm3DVertexSetU(&WaterCannonVertices[2], 0.0f);
|
|
RwIm3DVertexSetV(&WaterCannonVertices[2], 0.0f);
|
|
|
|
RwIm3DVertexSetU(&WaterCannonVertices[3], 1.0f);
|
|
RwIm3DVertexSetV(&WaterCannonVertices[3], 0.0f);
|
|
|
|
WaterCannonIndexList[0] = 0;
|
|
WaterCannonIndexList[1] = 1;
|
|
WaterCannonIndexList[2] = 2;
|
|
|
|
WaterCannonIndexList[3] = 1;
|
|
WaterCannonIndexList[4] = 3;
|
|
WaterCannonIndexList[5] = 2;
|
|
|
|
WaterCannonIndexList[6] = 0;
|
|
WaterCannonIndexList[7] = 2;
|
|
WaterCannonIndexList[8] = 1;
|
|
|
|
WaterCannonIndexList[9] = 1;
|
|
WaterCannonIndexList[10] = 2;
|
|
WaterCannonIndexList[11] = 3;
|
|
}
|
|
|
|
void CWaterCannon::Update_OncePerFrame(int16 index)
|
|
{
|
|
ASSERT(index < NUM_WATERCANNONS);
|
|
|
|
if (CTimer::GetTimeInMilliseconds() > m_nTimeCreated + WATERCANNON_LIFETIME )
|
|
{
|
|
m_nCur = (m_nCur + 1) % NUM_SEGMENTPOINTS;
|
|
m_abUsed[m_nCur] = false;
|
|
}
|
|
|
|
for ( int32 i = 0; i < NUM_SEGMENTPOINTS; i++ )
|
|
{
|
|
if ( m_abUsed[i] )
|
|
{
|
|
m_avecVelocity[i].z += -WATERCANNON_GRAVITY * CTimer::GetTimeStep();
|
|
m_avecPos[i] += m_avecVelocity[i] * CTimer::GetTimeStep();
|
|
}
|
|
}
|
|
|
|
for ( int32 i = 0; i < NUM_SEGMENTPOINTS; i++ )
|
|
{
|
|
if ( m_abUsed[i] && gFireManager.ExtinguishPointWithWater(m_avecPos[i], 4.0f) )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( ((index + CTimer::GetFrameCounter()) & 3) == 0 )
|
|
PushPeds();
|
|
|
|
// free if unused
|
|
|
|
int32 i = 0;
|
|
while ( 1 )
|
|
{
|
|
if ( m_abUsed[i] )
|
|
break;
|
|
|
|
if ( ++i >= NUM_SEGMENTPOINTS )
|
|
{
|
|
m_nId = 0;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CWaterCannon::Update_NewInput(CVector *pos, CVector *dir)
|
|
{
|
|
ASSERT(pos != NULL);
|
|
ASSERT(dir != NULL);
|
|
|
|
m_avecPos[m_nCur] = *pos;
|
|
m_avecVelocity[m_nCur] = *dir;
|
|
m_abUsed[m_nCur] = true;
|
|
}
|
|
|
|
static float fWaterCannonU = 0.0f;
|
|
void CWaterCannon::Render(void)
|
|
{
|
|
extern RwRaster *gpFireHoseRaster;
|
|
|
|
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE);
|
|
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
|
|
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE);
|
|
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpFireHoseRaster);
|
|
|
|
fWaterCannonU += CTimer::GetTimeStepInSeconds() * 6.0f;
|
|
|
|
while ( fWaterCannonU >= 1.0f )
|
|
fWaterCannonU -= 1.0f;
|
|
|
|
RwIm3DVertexSetU(&WaterCannonVertices[0], -fWaterCannonU);
|
|
RwIm3DVertexSetV(&WaterCannonVertices[0], 0.0f);
|
|
RwIm3DVertexSetU(&WaterCannonVertices[1], -fWaterCannonU);
|
|
RwIm3DVertexSetV(&WaterCannonVertices[1], 1.0f);
|
|
RwIm3DVertexSetU(&WaterCannonVertices[2], 1.0f - fWaterCannonU);
|
|
RwIm3DVertexSetV(&WaterCannonVertices[2], 0.0f);
|
|
RwIm3DVertexSetU(&WaterCannonVertices[3], 1.0f - fWaterCannonU);
|
|
RwIm3DVertexSetV(&WaterCannonVertices[3], 1.0f);
|
|
|
|
int16 pointA = m_nCur % NUM_SEGMENTPOINTS;
|
|
int16 pointB = pointA - 1;
|
|
int16 pointC = pointA;
|
|
if ( pointB < 0 )
|
|
pointB += NUM_SEGMENTPOINTS;
|
|
|
|
bool bInit = false;
|
|
CVector norm;
|
|
|
|
for ( int32 i = 0; i < NUM_SEGMENTPOINTS - 1; i++ )
|
|
{
|
|
if ( m_abUsed[pointA] && m_abUsed[pointB] )
|
|
{
|
|
bool bFirst = false;
|
|
if ( i == 0 || m_abUsed[pointA] && !m_abUsed[pointC] )
|
|
bFirst = true;
|
|
|
|
if ( !bInit )
|
|
{
|
|
CVector cp = CrossProduct(m_avecPos[pointB] - m_avecPos[pointA], TheCamera.GetForward());
|
|
norm = cp * (0.05f / cp.Magnitude());
|
|
bInit = true;
|
|
}
|
|
|
|
float brightness = float(i) / NUM_SEGMENTPOINTS;
|
|
int32 color = (int32)((1.0f - brightness*brightness) * 255.0f);
|
|
|
|
CVector offset = (float(i)+1.0f) * norm;
|
|
|
|
RwIm3DVertexSetRGBA(&WaterCannonVertices[0], WATER_COLOR, WATER_COLOR, WATER_COLOR, bFirst ? 0 : color);
|
|
RwIm3DVertexSetPos (&WaterCannonVertices[0], m_avecPos[pointA].x - offset.x, m_avecPos[pointA].y - offset.y, m_avecPos[pointA].z - offset.z);
|
|
|
|
RwIm3DVertexSetRGBA(&WaterCannonVertices[1], WATER_COLOR, WATER_COLOR, WATER_COLOR, bFirst ? 0 : color);
|
|
RwIm3DVertexSetPos (&WaterCannonVertices[1], m_avecPos[pointA].x + offset.x, m_avecPos[pointA].y + offset.y, m_avecPos[pointA].z + offset.z);
|
|
|
|
offset = (float(i+1)+1.0f) * norm;
|
|
|
|
RwIm3DVertexSetRGBA(&WaterCannonVertices[2], WATER_COLOR, WATER_COLOR, WATER_COLOR, color);
|
|
RwIm3DVertexSetPos (&WaterCannonVertices[2], m_avecPos[pointB].x - offset.x, m_avecPos[pointB].y - offset.y, m_avecPos[pointB].z - offset.z);
|
|
|
|
RwIm3DVertexSetRGBA(&WaterCannonVertices[3], WATER_COLOR, WATER_COLOR, WATER_COLOR, color);
|
|
RwIm3DVertexSetPos (&WaterCannonVertices[3], m_avecPos[pointB].x + offset.x, m_avecPos[pointB].y + offset.y, m_avecPos[pointB].z + offset.z);
|
|
|
|
if ( RwIm3DTransform(WaterCannonVertices, WATERCANNONVERTS, NULL, rwIM3D_VERTEXUV) )
|
|
{
|
|
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, WaterCannonIndexList, WATERCANNONINDEXES);
|
|
RwIm3DEnd();
|
|
}
|
|
}
|
|
|
|
pointC = pointA;
|
|
pointA = pointB--;
|
|
if ( pointB < 0 )
|
|
pointB += NUM_SEGMENTPOINTS;
|
|
}
|
|
|
|
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)TRUE);
|
|
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)FALSE);
|
|
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)FALSE);
|
|
}
|
|
|
|
void CWaterCannon::PushPeds(void)
|
|
{
|
|
float minx = 10000.0f;
|
|
float maxx = -10000.0f;
|
|
float miny = 10000.0f;
|
|
float maxy = -10000.0f;
|
|
float minz = 10000.0f;
|
|
float maxz = -10000.0f;
|
|
|
|
for ( int32 i = 0; i < NUM_SEGMENTPOINTS; i++ )
|
|
{
|
|
if ( m_abUsed[i] )
|
|
{
|
|
minx = Min(minx, m_avecPos[i].x);
|
|
maxx = Max(maxx, m_avecPos[i].x);
|
|
|
|
miny = Min(miny, m_avecPos[i].y);
|
|
maxy = Max(maxy, m_avecPos[i].y);
|
|
|
|
minz = Min(minz, m_avecPos[i].z);
|
|
maxz = Max(maxz, m_avecPos[i].z);
|
|
}
|
|
}
|
|
|
|
for ( int32 i = CPools::GetPedPool()->GetSize() - 1; i >= 0; i--)
|
|
{
|
|
CPed *ped = CPools::GetPedPool()->GetSlot(i);
|
|
if ( ped )
|
|
{
|
|
if ( ped->GetPosition().x > minx && ped->GetPosition().x < maxx
|
|
&& ped->GetPosition().y > miny && ped->GetPosition().y < maxy
|
|
&& ped->GetPosition().z > minz && ped->GetPosition().z < maxz )
|
|
{
|
|
for ( int32 j = 0; j < NUM_SEGMENTPOINTS; j++ )
|
|
{
|
|
if ( m_abUsed[j] )
|
|
{
|
|
CVector dist = m_avecPos[j] - ped->GetPosition();
|
|
|
|
if ( dist.MagnitudeSqr() < 5.0f )
|
|
{
|
|
int32 localDir = ped->GetLocalDirection(CVector2D(1.0f, 0.0f));
|
|
|
|
ped->bIsStanding = false;
|
|
|
|
ped->ApplyMoveForce(0.0f, 0.0f, 2.0f * CTimer::GetTimeStep());
|
|
|
|
ped->m_vecMoveSpeed.x = (0.6f * m_avecVelocity[j].x + ped->m_vecMoveSpeed.x) * 0.5f;
|
|
ped->m_vecMoveSpeed.y = (0.6f * m_avecVelocity[j].y + ped->m_vecMoveSpeed.y) * 0.5f;
|
|
|
|
float pedSpeed2D = ped->m_vecMoveSpeed.Magnitude2D();
|
|
|
|
if ( pedSpeed2D > 0.2f ) {
|
|
ped->m_vecMoveSpeed.x *= (0.2f / pedSpeed2D);
|
|
ped->m_vecMoveSpeed.y *= (0.2f / pedSpeed2D);
|
|
}
|
|
ped->SetFall(2000, (AnimationId)(localDir + ANIM_KO_SKID_FRONT), 0);
|
|
CParticle::AddParticle(PARTICLE_STEAM_NY_SLOWMOTION, ped->GetPosition(), ped->m_vecMoveSpeed * 0.3f, 0, 0.5f);
|
|
CParticle::AddParticle(PARTICLE_CAR_SPLASH, ped->GetPosition(), ped->m_vecMoveSpeed * -0.3f + CVector(0.f, 0.f, 0.5f), 0, 0.5f,
|
|
CGeneral::GetRandomNumberInRange(0.f, 10.f), CGeneral::GetRandomNumberInRange(0.f, 90.f), 1);
|
|
|
|
j = NUM_SEGMENTPOINTS;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CWaterCannons::Init(void)
|
|
{
|
|
for ( int32 i = 0; i < NUM_WATERCANNONS; i++ )
|
|
aCannons[i].Init();
|
|
}
|
|
|
|
void CWaterCannons::UpdateOne(uint32 id, CVector *pos, CVector *dir)
|
|
{
|
|
ASSERT(pos != NULL);
|
|
ASSERT(dir != NULL);
|
|
|
|
// find the one by id
|
|
{
|
|
int32 n = 0;
|
|
while ( n < NUM_WATERCANNONS && id != aCannons[n].m_nId )
|
|
n++;
|
|
|
|
if ( n < NUM_WATERCANNONS )
|
|
{
|
|
aCannons[n].Update_NewInput(pos, dir);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// if no luck then find a free one
|
|
{
|
|
int32 n = 0;
|
|
while ( n < NUM_WATERCANNONS && 0 != aCannons[n].m_nId )
|
|
n++;
|
|
|
|
if ( n < NUM_WATERCANNONS )
|
|
{
|
|
aCannons[n].Init();
|
|
aCannons[n].m_nId = id;
|
|
aCannons[n].Update_NewInput(pos, dir);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CWaterCannons::Update(void)
|
|
{
|
|
for ( int32 i = 0; i < NUM_WATERCANNONS; i++ )
|
|
{
|
|
if ( aCannons[i].m_nId != 0 )
|
|
aCannons[i].Update_OncePerFrame(i);
|
|
}
|
|
}
|
|
|
|
void CWaterCannons::Render(void)
|
|
{
|
|
for ( int32 i = 0; i < NUM_WATERCANNONS; i++ )
|
|
{
|
|
if ( aCannons[i].m_nId != 0 )
|
|
aCannons[i].Render();
|
|
}
|
|
}
|