mirror of
https://git.rip/DMCA_FUCKER/re3.git
synced 2024-11-05 10:35:54 +00:00
CHeli and CRopes done
This commit is contained in:
parent
7fea567eb2
commit
90fdc4328b
169
src/core/Ropes.cpp
Normal file
169
src/core/Ropes.cpp
Normal file
|
@ -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;
|
||||||
|
}
|
31
src/core/Ropes.h
Normal file
31
src/core/Ropes.h
Normal file
|
@ -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);
|
||||||
|
};
|
|
@ -84,6 +84,7 @@ CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
|
||||||
m_nRoadblockNode = -1; // TODO(Miami): this will be nil
|
m_nRoadblockNode = -1; // TODO(Miami): this will be nil
|
||||||
m_bThrowsSpikeTrap = false;
|
m_bThrowsSpikeTrap = false;
|
||||||
field_5FF = 0;
|
field_5FF = 0;
|
||||||
|
m_pRopeEntity = nil;
|
||||||
m_fAbseilPos = 0.0f;
|
m_fAbseilPos = 0.0f;
|
||||||
m_bBeatingSuspect = false;
|
m_bBeatingSuspect = false;
|
||||||
m_pPointGunAt = nil;
|
m_pPointGunAt = nil;
|
||||||
|
|
|
@ -26,6 +26,8 @@ public:
|
||||||
float m_fAbseilPos;
|
float m_fAbseilPos;
|
||||||
eCopType m_nCopType;
|
eCopType m_nCopType;
|
||||||
bool m_bThrowsSpikeTrap;
|
bool m_bThrowsSpikeTrap;
|
||||||
|
CEntity *m_pRopeEntity; // CHeli or 1
|
||||||
|
uintptr m_nRopeID;
|
||||||
int32 field_624;
|
int32 field_624;
|
||||||
int8 field_628;
|
int8 field_628;
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ CPlaneTrail::Render(float visibility)
|
||||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
|
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
|
||||||
|
|
||||||
if(RwIm3DTransform(TempBufferRenderVertices, numVerts, nil, rwIM3D_VERTEXXYZ|rwIM3D_VERTEXUV)){
|
if(RwIm3DTransform(TempBufferRenderVertices, numVerts, nil, rwIM3D_VERTEXXYZ|rwIM3D_VERTEXRGBA)){
|
||||||
RwIm3DRenderIndexedPrimitive(rwPRIMTYPELINELIST, TrailIndices, (numVerts-1)*2);
|
RwIm3DRenderIndexedPrimitive(rwPRIMTYPELINELIST, TrailIndices, (numVerts-1)*2);
|
||||||
RwIm3DEnd();
|
RwIm3DEnd();
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ CPlaneBanner::Render(void)
|
||||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRubbishTexture[2]));
|
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRubbishTexture[2]));
|
||||||
|
|
||||||
#ifdef FIX_BUGS
|
#ifdef FIX_BUGS
|
||||||
if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXXYZ|rwIM3D_VERTEXUV)){
|
if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXXYZ|rwIM3D_VERTEXUV|rwIM3D_VERTEXRGBA)){
|
||||||
#else
|
#else
|
||||||
if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, 0)){
|
if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, 0)){
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -14,20 +14,26 @@
|
||||||
#include "Shadows.h"
|
#include "Shadows.h"
|
||||||
#include "Coronas.h"
|
#include "Coronas.h"
|
||||||
#include "Explosion.h"
|
#include "Explosion.h"
|
||||||
|
#include "WindModifiers.h"
|
||||||
#include "Timecycle.h"
|
#include "Timecycle.h"
|
||||||
#include "TempColModels.h"
|
#include "TempColModels.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "WaterLevel.h"
|
#include "WaterLevel.h"
|
||||||
|
#include "Population.h"
|
||||||
#include "PlayerPed.h"
|
#include "PlayerPed.h"
|
||||||
|
#include "CopPed.h"
|
||||||
#include "Wanted.h"
|
#include "Wanted.h"
|
||||||
#include "DMAudio.h"
|
#include "DMAudio.h"
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "HandlingMgr.h"
|
#include "HandlingMgr.h"
|
||||||
|
#include "Ropes.h"
|
||||||
#include "Heli.h"
|
#include "Heli.h"
|
||||||
#ifdef FIX_BUGS
|
#ifdef FIX_BUGS
|
||||||
#include "Replay.h"
|
#include "Replay.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//--MIAMI: done
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
HELI_STATUS_HOVER,
|
HELI_STATUS_HOVER,
|
||||||
|
@ -40,7 +46,6 @@ enum
|
||||||
CHeli *CHeli::pHelis[NUM_HELIS];
|
CHeli *CHeli::pHelis[NUM_HELIS];
|
||||||
int16 CHeli::NumRandomHelis;
|
int16 CHeli::NumRandomHelis;
|
||||||
uint32 CHeli::TestForNewRandomHelisTimer;
|
uint32 CHeli::TestForNewRandomHelisTimer;
|
||||||
int16 CHeli::NumScriptHelis; // unused
|
|
||||||
bool CHeli::CatalinaHeliOn;
|
bool CHeli::CatalinaHeliOn;
|
||||||
bool CHeli::CatalinaHasBeenShotDown;
|
bool CHeli::CatalinaHasBeenShotDown;
|
||||||
bool CHeli::ScriptHeliOn;
|
bool CHeli::ScriptHeliOn;
|
||||||
|
@ -67,6 +72,9 @@ CHeli::CHeli(int32 id, uint8 CreatedBy)
|
||||||
m_nBulletDamage = 0;
|
m_nBulletDamage = 0;
|
||||||
m_fAngularSpeed = 0.0f;
|
m_fAngularSpeed = 0.0f;
|
||||||
m_fRotation = 0.0f;
|
m_fRotation = 0.0f;
|
||||||
|
|
||||||
|
m_numSwat = 4;
|
||||||
|
|
||||||
m_nSearchLightTimer = CTimer::GetTimeInMilliseconds();
|
m_nSearchLightTimer = CTimer::GetTimeInMilliseconds();
|
||||||
for(i = 0; i < 6; i++){
|
for(i = 0; i < 6; i++){
|
||||||
m_aSearchLightHistoryX[i] = 0.0f;
|
m_aSearchLightHistoryX[i] = 0.0f;
|
||||||
|
@ -82,6 +90,8 @@ CHeli::CHeli(int32 id, uint8 CreatedBy)
|
||||||
m_fTargetOffset = 0.0f;
|
m_fTargetOffset = 0.0f;
|
||||||
m_fSearchLightX = m_fSearchLightY = 0.0f;
|
m_fSearchLightX = m_fSearchLightY = 0.0f;
|
||||||
|
|
||||||
|
m_aSwatState[0] = m_aSwatState[1] = m_aSwatState[2] = m_aSwatState[3] = 0;
|
||||||
|
|
||||||
// BUG: not in game but gets initialized to CDCDCDCD in debug
|
// BUG: not in game but gets initialized to CDCDCDCD in debug
|
||||||
m_nLastShotTime = 0;
|
m_nLastShotTime = 0;
|
||||||
}
|
}
|
||||||
|
@ -120,6 +130,8 @@ CHeli::ProcessControl(void)
|
||||||
if(gbModelViewer)
|
if(gbModelViewer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
CWindModifiers::RegisterOne(GetPosition(), 1);
|
||||||
|
|
||||||
// Find target
|
// Find target
|
||||||
CVector target(0.0f, 0.0f, 0.0f);
|
CVector target(0.0f, 0.0f, 0.0f);
|
||||||
CVector2D vTargetDist;
|
CVector2D vTargetDist;
|
||||||
|
@ -266,7 +278,9 @@ CHeli::ProcessControl(void)
|
||||||
if(fTargetDist > targetHeight)
|
if(fTargetDist > targetHeight)
|
||||||
m_heliStatus = HELI_STATUS_CHASE_PLAYER;
|
m_heliStatus = HELI_STATUS_CHASE_PLAYER;
|
||||||
}
|
}
|
||||||
// fall through, BUG?
|
if(m_numSwat)
|
||||||
|
SendDownSwat();
|
||||||
|
break;
|
||||||
case HELI_STATUS_CHASE_PLAYER:{
|
case HELI_STATUS_CHASE_PLAYER:{
|
||||||
float targetHeight;
|
float targetHeight;
|
||||||
if(m_heliType == HELI_TYPE_CATALINA)
|
if(m_heliType == HELI_TYPE_CATALINA)
|
||||||
|
@ -277,6 +291,7 @@ CHeli::ProcessControl(void)
|
||||||
fTargetDist < targetHeight && CWorld::GetIsLineOfSightClear(GetPosition(), FindPlayerCoors(), true, false, false, false, false, false))
|
fTargetDist < targetHeight && CWorld::GetIsLineOfSightClear(GetPosition(), FindPlayerCoors(), true, false, false, false, false, false))
|
||||||
m_heliStatus = HELI_STATUS_HOVER;
|
m_heliStatus = HELI_STATUS_HOVER;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find xy speed
|
// Find xy speed
|
||||||
|
@ -346,13 +361,6 @@ CHeli::ProcessControl(void)
|
||||||
if(m_fTargetOffset >= 2.0f)
|
if(m_fTargetOffset >= 2.0f)
|
||||||
m_fTargetOffset -= 2.0f;
|
m_fTargetOffset -= 2.0f;
|
||||||
|
|
||||||
if(m_heliType == HELI_TYPE_CATALINA)
|
|
||||||
if(m_pathState == 9 || m_pathState == 11 || m_pathState == 10){
|
|
||||||
float f = Pow(0.997f, CTimer::GetTimeStep());
|
|
||||||
m_vecMoveSpeed.x *= f;
|
|
||||||
m_vecMoveSpeed.y *= f;
|
|
||||||
}
|
|
||||||
|
|
||||||
CVector2D speedDir = targetSpeed - m_vecMoveSpeed;
|
CVector2D speedDir = targetSpeed - m_vecMoveSpeed;
|
||||||
float speedDiff = speedDir.Magnitude();
|
float speedDiff = speedDir.Magnitude();
|
||||||
if(speedDiff != 0.0f)
|
if(speedDiff != 0.0f)
|
||||||
|
@ -457,7 +465,7 @@ CHeli::ProcessControl(void)
|
||||||
else if (searchLightDist < 40.0f)
|
else if (searchLightDist < 40.0f)
|
||||||
m_fSearchLightIntensity = 1.0f;
|
m_fSearchLightIntensity = 1.0f;
|
||||||
else
|
else
|
||||||
m_fSearchLightIntensity = 1.0f - (40.0f - searchLightDist) / 40.0f;
|
m_fSearchLightIntensity = 1.0f - (40.0f - searchLightDist) / (60.0f-40.0f);
|
||||||
|
|
||||||
if (m_fSearchLightIntensity < 0.9f || sq(FindPlayerCoors().x - m_fSearchLightX) + sq(FindPlayerCoors().y - m_fSearchLightY) > sq(7.0f))
|
if (m_fSearchLightIntensity < 0.9f || sq(FindPlayerCoors().x - m_fSearchLightX) + sq(FindPlayerCoors().y - m_fSearchLightY) > sq(7.0f))
|
||||||
m_nShootTimer = CTimer::GetTimeInMilliseconds();
|
m_nShootTimer = CTimer::GetTimeInMilliseconds();
|
||||||
|
@ -524,28 +532,17 @@ CHeli::ProcessControl(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drop Catalina's bombs
|
// Process ropes
|
||||||
if(m_heliType == HELI_TYPE_CATALINA && m_pathState > 8 && (CTimer::GetTimeInMilliseconds()>>9) != (CTimer::GetPreviousTimeInMilliseconds()>>9)){
|
for(i = 0; i < 4; i++){
|
||||||
CVector bombPos = GetPosition() - 60.0f*m_vecMoveSpeed;
|
if(m_aSwatState[i] == 0)
|
||||||
if(sq(FindPlayerCoors().x-bombPos.x) + sq(FindPlayerCoors().y-bombPos.y) < sq(35.0f)){
|
continue;
|
||||||
bool found;
|
|
||||||
float groundZ = CWorld::FindGroundZFor3DCoord(bombPos.x, bombPos.y, bombPos.z, &found);
|
m_aSwatState[i]--;
|
||||||
float waterZ;
|
CRopes::RegisterRope((uintptr)this + i, GetMatrix()*FindSwatPositionRelativeToHeli(i), false);
|
||||||
if(!CWaterLevel::GetWaterLevelNoWaves(bombPos.x, bombPos.y, bombPos.z, &waterZ))
|
if(m_aSwatState[i] == 0){
|
||||||
waterZ = 0.0f;
|
CVector speed = Multiply3x3(GetMatrix(), 0.05f*FindSwatPositionRelativeToHeli(i));
|
||||||
if(groundZ > waterZ){
|
speed.z = 0.0f;
|
||||||
bombPos.z = groundZ + 2.0f;
|
CRopes::SetSpeedOfTopNode((uintptr)this + i, speed);
|
||||||
CExplosion::AddExplosion(nil, this, EXPLOSION_HELI_BOMB, bombPos, 0);
|
|
||||||
}else{
|
|
||||||
bombPos.z = waterZ;
|
|
||||||
CVector dir;
|
|
||||||
for(i = 0; i < 16; i++){
|
|
||||||
dir.x = ((CGeneral::GetRandomNumber()&0xFF)-127)*0.001f;
|
|
||||||
dir.y = ((CGeneral::GetRandomNumber()&0xFF)-127)*0.001f;
|
|
||||||
dir.z = 0.5f;
|
|
||||||
CParticle::AddParticle(PARTICLE_BOAT_SPLASH, bombPos, dir, nil, 0.2f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,6 +661,7 @@ CHeli::SpawnFlyingComponent(int32 component)
|
||||||
RpAtomicSetFrame(atomic, frame);
|
RpAtomicSetFrame(atomic, frame);
|
||||||
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
|
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
|
||||||
obj->AttachToRwObject((RwObject*)atomic);
|
obj->AttachToRwObject((RwObject*)atomic);
|
||||||
|
obj->bDontStream = true;
|
||||||
|
|
||||||
// init object
|
// init object
|
||||||
obj->m_fMass = 10.0f;
|
obj->m_fMass = 10.0f;
|
||||||
|
@ -709,6 +707,42 @@ CHeli::SpawnFlyingComponent(int32 component)
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CVector
|
||||||
|
CHeli::FindSwatPositionRelativeToHeli(int n)
|
||||||
|
{
|
||||||
|
switch(n){
|
||||||
|
case 0: return CVector(-1.2f, -1.0f, -0.5f);
|
||||||
|
case 1: return CVector( 1.2f, -1.0f, -0.5f);
|
||||||
|
case 2: return CVector(-1.2f, 1.0f, -0.5f);
|
||||||
|
case 3: return CVector( 1.2f, 1.0f, -0.5f);
|
||||||
|
default: return CVector(0.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CHeli::SendDownSwat(void)
|
||||||
|
{
|
||||||
|
if(m_numSwat == 0 || !CStreaming::HasModelLoaded(MI_SWAT) ||
|
||||||
|
CGeneral::GetRandomNumber() & 0x7F || (GetPosition() - FindPlayerCoors()).Magnitude() > 50.0f)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
CMatrix mat(GetMatrix());
|
||||||
|
CVector pos = Multiply3x3(mat, FindSwatPositionRelativeToHeli(m_numSwat-1)) + GetPosition();
|
||||||
|
|
||||||
|
float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, nil);
|
||||||
|
if(Abs(FindPlayerCoors().z - groundZ) < 2.5f && CRopes::RegisterRope((uintptr)this + m_numSwat-1, pos, false)){
|
||||||
|
CCopPed *swat = (CCopPed*)CPopulation::AddPed(PEDTYPE_COP, COP_ARMY, pos);
|
||||||
|
swat->bUsesCollision = false;
|
||||||
|
swat->m_pRopeEntity = this;
|
||||||
|
RegisterReference(&swat->m_pRopeEntity);
|
||||||
|
m_numSwat--;
|
||||||
|
swat->m_nRopeID = m_numSwat;
|
||||||
|
m_aSwatState[m_numSwat] = 255;
|
||||||
|
CAnimManager::BlendAnimation(swat->GetClump(), ASSOCGRP_STD, ANIM_ABSEIL, 4.0f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -718,7 +752,6 @@ CHeli::InitHelis(void)
|
||||||
|
|
||||||
NumRandomHelis = 0;
|
NumRandomHelis = 0;
|
||||||
TestForNewRandomHelisTimer = 0;
|
TestForNewRandomHelisTimer = 0;
|
||||||
NumScriptHelis = 0;
|
|
||||||
CatalinaHeliOn = false;
|
CatalinaHeliOn = false;
|
||||||
ScriptHeliOn = false;
|
ScriptHeliOn = false;
|
||||||
for(i = 0; i < NUM_HELIS; i++)
|
for(i = 0; i < NUM_HELIS; i++)
|
||||||
|
@ -734,17 +767,20 @@ GenerateHeli(bool catalina)
|
||||||
CVector heliPos;
|
CVector heliPos;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if(catalina)
|
||||||
|
assert(0 && "can't create catalina's heli");
|
||||||
|
else
|
||||||
heli = new CHeli(MI_CHOPPER, PERMANENT_VEHICLE);
|
heli = new CHeli(MI_CHOPPER, PERMANENT_VEHICLE);
|
||||||
|
|
||||||
if(catalina)
|
if(catalina)
|
||||||
heliPos = CVector(-224.0f, 201.0f, 83.0f);
|
heliPos = CVector(-224.0f, 201.0f, 83.0f);
|
||||||
else{
|
else{
|
||||||
heliPos = FindPlayerCoors();
|
heliPos = FindPlayerCoors();
|
||||||
float angle = (float)(CGeneral::GetRandomNumber() & 0xFF)/0xFF * 6.28f;
|
float angle = (float)(CGeneral::GetRandomNumber() & 0xFF)/0x100 * 6.28f;
|
||||||
heliPos.x += 250.0f*Sin(angle);
|
heliPos.x += 250.0f*Sin(angle);
|
||||||
heliPos.y += 250.0f*Cos(angle);
|
heliPos.y += 250.0f*Cos(angle);
|
||||||
if(heliPos.x < -2000.0f || heliPos.x > 2000.0f || heliPos.y < -2000.0f || heliPos.y > 2000.0f){
|
if(heliPos.x < -2000.0f-400.0f || heliPos.x > 2000.0f-400.0f || heliPos.y < -2000.0f || heliPos.y > 2000.0f){
|
||||||
// directly above player
|
heliPos = FindPlayerCoors();
|
||||||
heliPos.x -= 250.0f*Sin(angle);
|
heliPos.x -= 250.0f*Sin(angle);
|
||||||
heliPos.y -= 250.0f*Cos(angle);
|
heliPos.y -= 250.0f*Cos(angle);
|
||||||
}
|
}
|
||||||
|
@ -755,6 +791,7 @@ GenerateHeli(bool catalina)
|
||||||
heli->GetMatrix().SetRotateZOnly(DEGTORAD(270.0f)); // game actually uses 3.14 here
|
heli->GetMatrix().SetRotateZOnly(DEGTORAD(270.0f)); // game actually uses 3.14 here
|
||||||
|
|
||||||
heli->SetStatus(STATUS_ABANDONED);
|
heli->SetStatus(STATUS_ABANDONED);
|
||||||
|
heli->bIsLocked = true;
|
||||||
|
|
||||||
int id = -1;
|
int id = -1;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
@ -783,6 +820,8 @@ CHeli::UpdateHelis(void)
|
||||||
CReplay::IsPlayingBack() ? 0 :
|
CReplay::IsPlayingBack() ? 0 :
|
||||||
#endif
|
#endif
|
||||||
FindPlayerPed()->m_pWanted->NumOfHelisRequired();
|
FindPlayerPed()->m_pWanted->NumOfHelisRequired();
|
||||||
|
if(CCullZones::PlayerNoRain() || CGame::IsInInterior())
|
||||||
|
numHelisRequired = 0;
|
||||||
if(CStreaming::HasModelLoaded(MI_CHOPPER) && CTimer::GetTimeInMilliseconds() > TestForNewRandomHelisTimer){
|
if(CStreaming::HasModelLoaded(MI_CHOPPER) && CTimer::GetTimeInMilliseconds() > TestForNewRandomHelisTimer){
|
||||||
// Spawn a police heli
|
// Spawn a police heli
|
||||||
TestForNewRandomHelisTimer = CTimer::GetTimeInMilliseconds() + 15000;
|
TestForNewRandomHelisTimer = CTimer::GetTimeInMilliseconds() + 15000;
|
||||||
|
@ -831,7 +870,7 @@ CHeli::UpdateHelis(void)
|
||||||
TheCamera.CamShake(0.7f, pHelis[i]->GetPosition().x, pHelis[i]->GetPosition().y, pHelis[i]->GetPosition().z);
|
TheCamera.CamShake(0.7f, pHelis[i]->GetPosition().x, pHelis[i]->GetPosition().y, pHelis[i]->GetPosition().z);
|
||||||
|
|
||||||
colors[0] = CRGBA(0, 0, 0, 255);
|
colors[0] = CRGBA(0, 0, 0, 255);
|
||||||
colors[1] = CRGBA(224, 230, 238, 255);
|
colors[1] = CRGBA(224, 224, 224, 255);
|
||||||
colors[2] = CRGBA(0, 0, 0, 255);
|
colors[2] = CRGBA(0, 0, 0, 255);
|
||||||
colors[3] = CRGBA(0, 0, 0, 255);
|
colors[3] = CRGBA(0, 0, 0, 255);
|
||||||
colors[4] = CRGBA(66, 162, 252, 255);
|
colors[4] = CRGBA(66, 162, 252, 255);
|
||||||
|
@ -851,7 +890,7 @@ CHeli::UpdateHelis(void)
|
||||||
int f = ++nFrameGen & 3;
|
int f = ++nFrameGen & 3;
|
||||||
CParticle::AddParticle(PARTICLE_HELI_DEBRIS, pos, dir,
|
CParticle::AddParticle(PARTICLE_HELI_DEBRIS, pos, dir,
|
||||||
nil, CGeneral::GetRandomNumberInRange(0.1f, 1.0f),
|
nil, CGeneral::GetRandomNumberInRange(0.1f, 1.0f),
|
||||||
colors[nFrameGen], rotSpeed, 0, f, 0);
|
colors[nFrameGen&7], rotSpeed, 0, f, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CExplosion::AddExplosion(nil, nil, EXPLOSION_HELI, pos, 0);
|
CExplosion::AddExplosion(nil, nil, EXPLOSION_HELI, pos, 0);
|
||||||
|
@ -869,8 +908,7 @@ CHeli::UpdateHelis(void)
|
||||||
if(i == HELI_CATALINA)
|
if(i == HELI_CATALINA)
|
||||||
CatalinaHasBeenShotDown = true;
|
CatalinaHasBeenShotDown = true;
|
||||||
|
|
||||||
CStats::HelisDestroyed++;
|
CStats::PeopleKilledByPlayer += 2;
|
||||||
CStats::PeopleKilledByOthers += 2;
|
|
||||||
CStats::PedsKilledOfThisType[PEDTYPE_COP] += 2;
|
CStats::PedsKilledOfThisType[PEDTYPE_COP] += 2;
|
||||||
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 250;
|
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 250;
|
||||||
pos = CWorld::Players[CWorld::PlayerInFocus].m_pPed->GetPosition();
|
pos = CWorld::Players[CWorld::PlayerInFocus].m_pPed->GetPosition();
|
||||||
|
@ -888,8 +926,8 @@ CHeli::UpdateHelis(void)
|
||||||
|
|
||||||
TheCamera.CamShake(0.4f, pHelis[i]->GetPosition().x, pHelis[i]->GetPosition().y, pHelis[i]->GetPosition().z);
|
TheCamera.CamShake(0.4f, pHelis[i]->GetPosition().x, pHelis[i]->GetPosition().y, pHelis[i]->GetPosition().z);
|
||||||
|
|
||||||
CVector pos = pHelis[i]->GetPosition() - 2.5f*pHelis[i]->GetUp();
|
CVector pos = pHelis[i]->GetPosition() - 2.5f*pHelis[i]->GetForward();
|
||||||
CExplosion::AddExplosion(nil, nil, EXPLOSION_HELI, pos, 0);
|
CExplosion::AddExplosion(nil, nil, EXPLOSION_HELI2, pos, 0);
|
||||||
}else
|
}else
|
||||||
pHelis[i]->m_fAngularSpeed *= 1.03f;
|
pHelis[i]->m_fAngularSpeed *= 1.03f;
|
||||||
}
|
}
|
||||||
|
@ -904,7 +942,7 @@ CHeli::UpdateHelis(void)
|
||||||
pHelis[i]->m_heliStatus = HELI_STATUS_FLY_AWAY;
|
pHelis[i]->m_heliStatus = HELI_STATUS_FLY_AWAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove all helis if in a tunnel
|
// Remove all helis if in a tunnel or under water
|
||||||
if(FindPlayerCoors().z < - 2.0f)
|
if(FindPlayerCoors().z < - 2.0f)
|
||||||
for(i = 0; i < NUM_HELIS; i++)
|
for(i = 0; i < NUM_HELIS; i++)
|
||||||
if(pHelis[i] && pHelis[i]->m_heliStatus != HELI_STATUS_SHOT_DOWN)
|
if(pHelis[i] && pHelis[i]->m_heliStatus != HELI_STATUS_SHOT_DOWN)
|
||||||
|
@ -949,7 +987,7 @@ CHeli::TestBulletCollision(CVector *line0, CVector *line1, CVector *bulletPos, i
|
||||||
float distToHeli = (pHelis[i]->GetPosition() - *line0).Magnitude();
|
float distToHeli = (pHelis[i]->GetPosition() - *line0).Magnitude();
|
||||||
CVector line = (*line1 - *line0);
|
CVector line = (*line1 - *line0);
|
||||||
float lineLength = line.Magnitude();
|
float lineLength = line.Magnitude();
|
||||||
*bulletPos = *line0 + line*Max(1.0f, distToHeli-5.0f);
|
*bulletPos = *line0 + line*Max(1.0f, distToHeli-5.0f)/lineLength;
|
||||||
|
|
||||||
pHelis[i]->m_nBulletDamage += damage;
|
pHelis[i]->m_nBulletDamage += damage;
|
||||||
|
|
||||||
|
@ -965,6 +1003,26 @@ CHeli::TestBulletCollision(CVector *line0, CVector *line1, CVector *bulletPos, i
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CHeli::TestSniperCollision(CVector *line0, CVector *line1)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
bool hit = false;
|
||||||
|
|
||||||
|
for(i = 0; i < NUM_HELIS; i++){
|
||||||
|
CVector pilotPos = pHelis[i]->GetMatrix() * CVector(-0.43f, 1.49f, 1.5f);
|
||||||
|
if(pHelis[i] && !pHelis[i]->bBulletProof && CCollision::DistToLine(line0, line1, &pilotPos) < 0.8f){
|
||||||
|
pHelis[i]->m_fAngularSpeed = CGeneral::GetRandomTrueFalse() ? 0.05f : -0.05f;
|
||||||
|
pHelis[i]->m_heliStatus = HELI_STATUS_SHOT_DOWN;
|
||||||
|
pHelis[i]->m_nExplosionTimer = CTimer::GetTimeInMilliseconds() + 9999999;
|
||||||
|
pHelis[i]->m_numSwat = 0;
|
||||||
|
|
||||||
|
hit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hit;
|
||||||
|
}
|
||||||
|
|
||||||
void CHeli::StartCatalinaFlyBy(void)
|
void CHeli::StartCatalinaFlyBy(void)
|
||||||
{
|
{
|
||||||
CatalinaHeliOn = true;
|
CatalinaHeliOn = true;
|
||||||
|
|
|
@ -21,7 +21,7 @@ enum
|
||||||
HELI_RANDOM0,
|
HELI_RANDOM0,
|
||||||
HELI_RANDOM1,
|
HELI_RANDOM1,
|
||||||
HELI_SCRIPT,
|
HELI_SCRIPT,
|
||||||
HELI_CATALINA,
|
HELI_CATALINA, // TODO 2 in VC
|
||||||
NUM_HELIS
|
NUM_HELIS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@ enum
|
||||||
class CHeli : public CVehicle
|
class CHeli : public CVehicle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// 0x288
|
|
||||||
RwFrame *m_aHeliNodes[NUM_HELI_NODES];
|
RwFrame *m_aHeliNodes[NUM_HELI_NODES];
|
||||||
int8 m_heliStatus;
|
int8 m_heliStatus;
|
||||||
float m_fSearchLightX;
|
float m_fSearchLightX;
|
||||||
|
@ -49,6 +48,8 @@ public:
|
||||||
int8 m_nHeliId;
|
int8 m_nHeliId;
|
||||||
int8 m_heliType;
|
int8 m_heliType;
|
||||||
int8 m_pathState;
|
int8 m_pathState;
|
||||||
|
int8 m_numSwat;
|
||||||
|
uint8 m_aSwatState[4];
|
||||||
float m_aSearchLightHistoryX[6];
|
float m_aSearchLightHistoryX[6];
|
||||||
float m_aSearchLightHistoryY[6];
|
float m_aSearchLightHistoryY[6];
|
||||||
uint32 m_nSearchLightTimer;
|
uint32 m_nSearchLightTimer;
|
||||||
|
@ -64,7 +65,6 @@ public:
|
||||||
static CHeli *pHelis[NUM_HELIS];
|
static CHeli *pHelis[NUM_HELIS];
|
||||||
static int16 NumRandomHelis;
|
static int16 NumRandomHelis;
|
||||||
static uint32 TestForNewRandomHelisTimer;
|
static uint32 TestForNewRandomHelisTimer;
|
||||||
static int16 NumScriptHelis; // unused
|
|
||||||
static bool CatalinaHeliOn;
|
static bool CatalinaHeliOn;
|
||||||
static bool CatalinaHasBeenShotDown;
|
static bool CatalinaHasBeenShotDown;
|
||||||
static bool ScriptHeliOn;
|
static bool ScriptHeliOn;
|
||||||
|
@ -79,12 +79,15 @@ public:
|
||||||
|
|
||||||
void PreRenderAlways(void);
|
void PreRenderAlways(void);
|
||||||
CObject *SpawnFlyingComponent(int32 component);
|
CObject *SpawnFlyingComponent(int32 component);
|
||||||
|
CVector FindSwatPositionRelativeToHeli(int n);
|
||||||
|
bool SendDownSwat(void);
|
||||||
|
|
||||||
static void InitHelis(void);
|
static void InitHelis(void);
|
||||||
static void UpdateHelis(void);
|
static void UpdateHelis(void);
|
||||||
static void SpecialHeliPreRender(void);
|
static void SpecialHeliPreRender(void);
|
||||||
static bool TestRocketCollision(CVector *coors);
|
static bool TestRocketCollision(CVector *coors);
|
||||||
static bool TestBulletCollision(CVector *line0, CVector *line1, CVector *bulletPos, int32 damage);
|
static bool TestBulletCollision(CVector *line0, CVector *line1, CVector *bulletPos, int32 damage);
|
||||||
|
static bool TestSniperCollision(CVector *line0, CVector *line1);
|
||||||
|
|
||||||
static void StartCatalinaFlyBy(void);
|
static void StartCatalinaFlyBy(void);
|
||||||
static void RemoveCatalinaHeli(void);
|
static void RemoveCatalinaHeli(void);
|
||||||
|
|
Loading…
Reference in a new issue