mirror of
https://github.com/halpz/re3.git
synced 2024-12-25 18:05:27 +00:00
Miami Glass
This commit is contained in:
parent
96f36d16ae
commit
e4ac934dbf
|
@ -31,6 +31,7 @@
|
||||||
#include "GameLogic.h"
|
#include "GameLogic.h"
|
||||||
#include "Garages.h"
|
#include "Garages.h"
|
||||||
#include "General.h"
|
#include "General.h"
|
||||||
|
#include "Glass.h"
|
||||||
#ifdef MISSION_REPLAY
|
#ifdef MISSION_REPLAY
|
||||||
#include "GenericGameStorage.h"
|
#include "GenericGameStorage.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -13002,12 +13003,12 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
|
||||||
case COMMAND_HAS_GLASS_BEEN_SHATTERED_NEARBY:
|
case COMMAND_HAS_GLASS_BEEN_SHATTERED_NEARBY:
|
||||||
{
|
{
|
||||||
CollectParameters(&m_nIp, 3);
|
CollectParameters(&m_nIp, 3);
|
||||||
static bool bShowed = false;
|
|
||||||
if (!bShowed) {
|
bool shattered = false;
|
||||||
debug("HAS_GLASS_BEEN_SHATTERED_NEARBY not implemented, default to TRUE\n"); // TODO(MIAMI)
|
if ( CGlass::HasGlassBeenShatteredAtCoors(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2]) )
|
||||||
bShowed = true;
|
shattered = true;
|
||||||
}
|
|
||||||
UpdateCompareFlag(true);
|
UpdateCompareFlag(shattered);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_BONE:
|
case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_BONE:
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "AnimBlendClumpData.h"
|
#include "AnimBlendClumpData.h"
|
||||||
#include "AnimBlendAssociation.h"
|
#include "AnimBlendAssociation.h"
|
||||||
#include "Fire.h"
|
#include "Fire.h"
|
||||||
|
#include "Glass.h"
|
||||||
#include "DMAudio.h"
|
#include "DMAudio.h"
|
||||||
#include "General.h"
|
#include "General.h"
|
||||||
#include "SurfaceTable.h"
|
#include "SurfaceTable.h"
|
||||||
|
@ -5865,7 +5866,7 @@ CPed::FightStrike(CVector &touchedNodePos, bool fightWithWeapon)
|
||||||
if (m_fightState == FIGHTSTATE_JUST_ATTACKED)
|
if (m_fightState == FIGHTSTATE_JUST_ATTACKED)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// TODO(Miami): BreakGlassPhysically
|
CGlass::BreakGlassPhysically(touchedNodePos, radius);
|
||||||
|
|
||||||
for (int i = 0; i < m_numNearPeds; i++) {
|
for (int i = 0; i < m_numNearPeds; i++) {
|
||||||
int8 pedFound = 0;
|
int8 pedFound = 0;
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include "Glass.h"
|
#include "Glass.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
|
#include "Vehicle.h"
|
||||||
|
#include "Pools.h"
|
||||||
#include "General.h"
|
#include "General.h"
|
||||||
#include "AudioScriptObject.h"
|
#include "AudioScriptObject.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
|
@ -14,6 +16,7 @@
|
||||||
#include "ModelIndices.h"
|
#include "ModelIndices.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "soundlist.h"
|
#include "soundlist.h"
|
||||||
|
#include "SurfaceTable.h"
|
||||||
|
|
||||||
|
|
||||||
uint32 CGlass::NumGlassEntities;
|
uint32 CGlass::NumGlassEntities;
|
||||||
|
@ -57,17 +60,17 @@ const CVector2D CoorsWithTriangle[NUM_GLASSTRIANGLES][3] =
|
||||||
|
|
||||||
#define TEMPBUFFERVERTHILIGHTOFFSET 0
|
#define TEMPBUFFERVERTHILIGHTOFFSET 0
|
||||||
#define TEMPBUFFERINDEXHILIGHTOFFSET 0
|
#define TEMPBUFFERINDEXHILIGHTOFFSET 0
|
||||||
#define TEMPBUFFERVERTHILIGHTSIZE 128
|
#define TEMPBUFFERVERTHILIGHTSIZE 256
|
||||||
#define TEMPBUFFERINDEXHILIGHTSIZE 512
|
#define TEMPBUFFERINDEXHILIGHTSIZE 512
|
||||||
|
|
||||||
#define TEMPBUFFERVERTSHATTEREDOFFSET TEMPBUFFERVERTHILIGHTSIZE
|
#define TEMPBUFFERVERTSHATTEREDOFFSET TEMPBUFFERVERTHILIGHTSIZE
|
||||||
#define TEMPBUFFERINDEXSHATTEREDOFFSET TEMPBUFFERINDEXHILIGHTSIZE
|
#define TEMPBUFFERINDEXSHATTEREDOFFSET TEMPBUFFERINDEXHILIGHTSIZE
|
||||||
#define TEMPBUFFERVERTSHATTEREDSIZE 192
|
#define TEMPBUFFERVERTSHATTEREDSIZE 384
|
||||||
#define TEMPBUFFERINDEXSHATTEREDSIZE 768
|
#define TEMPBUFFERINDEXSHATTEREDSIZE 768
|
||||||
|
|
||||||
#define TEMPBUFFERVERTREFLECTIONOFFSET TEMPBUFFERVERTSHATTEREDSIZE
|
#define TEMPBUFFERVERTREFLECTIONOFFSET TEMPBUFFERVERTSHATTEREDSIZE
|
||||||
#define TEMPBUFFERINDEXREFLECTIONOFFSET TEMPBUFFERINDEXSHATTEREDSIZE
|
#define TEMPBUFFERINDEXREFLECTIONOFFSET TEMPBUFFERINDEXSHATTEREDSIZE
|
||||||
#define TEMPBUFFERVERTREFLECTIONSIZE 256
|
#define TEMPBUFFERVERTREFLECTIONSIZE 512
|
||||||
#define TEMPBUFFERINDEXREFLECTIONSIZE 1024
|
#define TEMPBUFFERINDEXREFLECTIONSIZE 1024
|
||||||
|
|
||||||
int32 TempBufferIndicesStoredHiLight = 0;
|
int32 TempBufferIndicesStoredHiLight = 0;
|
||||||
|
@ -83,10 +86,16 @@ CFallingGlassPane::Update(void)
|
||||||
if ( CTimer::GetTimeInMilliseconds() >= m_nTimer )
|
if ( CTimer::GetTimeInMilliseconds() >= m_nTimer )
|
||||||
{
|
{
|
||||||
// Apply MoveSpeed
|
// Apply MoveSpeed
|
||||||
GetPosition() += m_vecMoveSpeed * CTimer::GetTimeStep();
|
if ( m_bCarGlass )
|
||||||
|
GetPosition() += m_vecMoveSpeed * CTimer::GetTimeStep() * 0.35f;
|
||||||
|
else
|
||||||
|
GetPosition() += m_vecMoveSpeed * CTimer::GetTimeStep();
|
||||||
|
|
||||||
// Apply Gravity
|
// Apply Gravity
|
||||||
m_vecMoveSpeed.z -= 0.02f * CTimer::GetTimeStep();
|
if ( m_bCarGlass )
|
||||||
|
m_vecMoveSpeed.z -= 0.01f * CTimer::GetTimeStep();
|
||||||
|
else
|
||||||
|
m_vecMoveSpeed.z -= 0.02f * CTimer::GetTimeStep();
|
||||||
|
|
||||||
// Apply TurnSpeed
|
// Apply TurnSpeed
|
||||||
GetRight() += CrossProduct(m_vecTurn, GetRight());
|
GetRight() += CrossProduct(m_vecTurn, GetRight());
|
||||||
|
@ -106,24 +115,27 @@ CFallingGlassPane::Update(void)
|
||||||
|
|
||||||
RwRGBA color = { 255, 255, 255, 255 };
|
RwRGBA color = { 255, 255, 255, 255 };
|
||||||
|
|
||||||
static int32 nFrameGen = 0;
|
if ( !m_bCarGlass )
|
||||||
|
|
||||||
for ( int32 i = 0; i < 4; i++ )
|
|
||||||
{
|
{
|
||||||
dir.x = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f);
|
static int32 nFrameGen = 0;
|
||||||
dir.y = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f);
|
|
||||||
dir.z = CGeneral::GetRandomNumberInRange(0.05f, 0.20f);
|
for ( int32 i = 0; i < 4; i++ )
|
||||||
|
{
|
||||||
CParticle::AddParticle(PARTICLE_CAR_DEBRIS,
|
dir.x = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f);
|
||||||
pos,
|
dir.y = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f);
|
||||||
dir,
|
dir.z = CGeneral::GetRandomNumberInRange(0.05f, 0.20f);
|
||||||
nil,
|
|
||||||
CGeneral::GetRandomNumberInRange(0.02f, 0.2f),
|
CParticle::AddParticle(PARTICLE_CAR_DEBRIS,
|
||||||
color,
|
pos,
|
||||||
CGeneral::GetRandomNumberInRange(-40, 40),
|
dir,
|
||||||
0,
|
nil,
|
||||||
++nFrameGen & 3,
|
CGeneral::GetRandomNumberInRange(0.02f, 0.2f),
|
||||||
500);
|
color,
|
||||||
|
CGeneral::GetRandomNumberInRange(-40, 40),
|
||||||
|
0,
|
||||||
|
++nFrameGen & 3,
|
||||||
|
500);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,7 +158,10 @@ CFallingGlassPane::Render(void)
|
||||||
CGlass::RenderHiLightPolys();
|
CGlass::RenderHiLightPolys();
|
||||||
|
|
||||||
// HiLight Polys
|
// HiLight Polys
|
||||||
|
|
||||||
|
if ( m_bCarGlass && color < 64 )
|
||||||
|
color = 64;
|
||||||
|
|
||||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 0], color, color, color, color);
|
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 0], color, color, color, color);
|
||||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 1], color, color, color, color);
|
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 1], color, color, color, color);
|
||||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 2], color, color, color, color);
|
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 2], color, color, color, color);
|
||||||
|
@ -186,9 +201,9 @@ CFallingGlassPane::Render(void)
|
||||||
if ( TempBufferIndicesStoredShattered >= TEMPBUFFERINDEXSHATTEREDSIZE-7 || TempBufferVerticesStoredShattered >= TEMPBUFFERVERTSHATTEREDSIZE-4 )
|
if ( TempBufferIndicesStoredShattered >= TEMPBUFFERINDEXSHATTEREDSIZE-7 || TempBufferVerticesStoredShattered >= TEMPBUFFERVERTSHATTEREDSIZE-4 )
|
||||||
CGlass::RenderShatteredPolys();
|
CGlass::RenderShatteredPolys();
|
||||||
|
|
||||||
uint8 shatteredColor = 255;
|
uint8 shatteredColor = 140;
|
||||||
if ( distToCamera > 30.0f )
|
if ( distToCamera > 30.0f )
|
||||||
shatteredColor = int32((1.0f - (distToCamera - 30.0f) * 4.0f / 40.0f) * 255);
|
shatteredColor = int32((1.0f - (distToCamera - 30.0f) * 4.0f / 40.0f) * 140);
|
||||||
|
|
||||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], shatteredColor, shatteredColor, shatteredColor, shatteredColor);
|
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], shatteredColor, shatteredColor, shatteredColor, shatteredColor);
|
||||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], shatteredColor, shatteredColor, shatteredColor, shatteredColor);
|
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], shatteredColor, shatteredColor, shatteredColor, shatteredColor);
|
||||||
|
@ -292,8 +307,8 @@ CGlass::FindFreePane(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector right, CVector speed, CVector point,
|
CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector right, CVector speed, CVector center,
|
||||||
float moveSpeed, bool cracked, bool explosion)
|
float moveSpeed, bool cracked, bool explosion, int32 stepmul, bool carGlass)
|
||||||
{
|
{
|
||||||
float upLen = up.Magnitude();
|
float upLen = up.Magnitude();
|
||||||
float rightLen = right.Magnitude();
|
float rightLen = right.Magnitude();
|
||||||
|
@ -304,10 +319,10 @@ CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector rig
|
||||||
float rightSteps = rightLen + 0.75f;
|
float rightSteps = rightLen + 0.75f;
|
||||||
if ( rightSteps < 1.0f ) rightSteps = 1.0f;
|
if ( rightSteps < 1.0f ) rightSteps = 1.0f;
|
||||||
|
|
||||||
uint32 ysteps = (uint32)upSteps;
|
uint32 ysteps = stepmul * (uint32)upSteps;
|
||||||
if ( ysteps > 3 ) ysteps = 3;
|
if ( ysteps > 3 ) ysteps = 3;
|
||||||
|
|
||||||
uint32 xsteps = (uint32)rightSteps;
|
uint32 xsteps = stepmul * (uint32)rightSteps;
|
||||||
if ( xsteps > 3 ) xsteps = 3;
|
if ( xsteps > 3 ) xsteps = 3;
|
||||||
|
|
||||||
if ( explosion )
|
if ( explosion )
|
||||||
|
@ -338,11 +353,8 @@ CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector rig
|
||||||
pane->m_nTriIndex = i;
|
pane->m_nTriIndex = i;
|
||||||
|
|
||||||
pane->GetRight() = (right * rightScl) / rightLen;
|
pane->GetRight() = (right * rightScl) / rightLen;
|
||||||
#ifdef FIX_BUGS
|
|
||||||
pane->GetUp() = (up * upScl) / upLen;
|
pane->GetUp() = (up * upScl) / upLen;
|
||||||
#else
|
|
||||||
pane->GetUp() = (up * upScl) / rightLen; // copypaste bug
|
|
||||||
#endif
|
|
||||||
CVector fwd = CrossProduct(pane->GetRight(), pane->GetUp());
|
CVector fwd = CrossProduct(pane->GetRight(), pane->GetUp());
|
||||||
fwd.Normalise();
|
fwd.Normalise();
|
||||||
|
|
||||||
|
@ -358,7 +370,7 @@ CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector rig
|
||||||
|
|
||||||
if ( moveSpeed != 0.0f )
|
if ( moveSpeed != 0.0f )
|
||||||
{
|
{
|
||||||
CVector dist = pane->GetPosition() - point;
|
CVector dist = pane->GetPosition() - center;
|
||||||
dist.Normalise();
|
dist.Normalise();
|
||||||
|
|
||||||
pane->m_vecMoveSpeed += moveSpeed * dist;
|
pane->m_vecMoveSpeed += moveSpeed * dist;
|
||||||
|
@ -371,10 +383,11 @@ CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector rig
|
||||||
switch ( type )
|
switch ( type )
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
case 2:
|
||||||
pane->m_nTimer = CTimer::GetTimeInMilliseconds();
|
pane->m_nTimer = CTimer::GetTimeInMilliseconds();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
float dist = (pane->GetPosition() - point).Magnitude();
|
float dist = (pane->GetPosition() - center).Magnitude();
|
||||||
pane->m_nTimer = uint32(dist*100 + CTimer::GetTimeInMilliseconds());
|
pane->m_nTimer = uint32(dist*100 + CTimer::GetTimeInMilliseconds());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -382,6 +395,7 @@ CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector rig
|
||||||
pane->m_fGroundZ = groundZ;
|
pane->m_fGroundZ = groundZ;
|
||||||
pane->m_bShattered = cracked;
|
pane->m_bShattered = cracked;
|
||||||
pane->m_fStep = upLen / float(ysteps);
|
pane->m_fStep = upLen / float(ysteps);
|
||||||
|
pane->m_bCarGlass = carGlass;
|
||||||
pane->m_bActive = true;
|
pane->m_bActive = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -393,9 +407,9 @@ void
|
||||||
CGlass::AskForObjectToBeRenderedInGlass(CEntity *entity)
|
CGlass::AskForObjectToBeRenderedInGlass(CEntity *entity)
|
||||||
{
|
{
|
||||||
#ifdef FIX_BUGS
|
#ifdef FIX_BUGS
|
||||||
if ( NumGlassEntities < NUM_GLASSPANES )
|
if ( NumGlassEntities < NUM_GLASSENTITIES )
|
||||||
#else
|
#else
|
||||||
if ( NumGlassEntities < NUM_GLASSPANES-1 )
|
if ( NumGlassEntities < NUM_GLASSENTITIES-1 )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
apEntitiesToBeRendered[NumGlassEntities++] = entity;
|
apEntitiesToBeRendered[NumGlassEntities++] = entity;
|
||||||
|
@ -613,42 +627,48 @@ CGlass::WindowRespondsToCollision(CEntity *entity, float amount, CVector speed,
|
||||||
CColModel *col = object->GetColModel();
|
CColModel *col = object->GetColModel();
|
||||||
ASSERT(col!=nil);
|
ASSERT(col!=nil);
|
||||||
|
|
||||||
CVector a = object->GetMatrix() * col->vertices[0].Get();
|
if ( col->numTriangles == 2 )
|
||||||
CVector b = object->GetMatrix() * col->vertices[1].Get();
|
|
||||||
CVector c = object->GetMatrix() * col->vertices[2].Get();
|
|
||||||
CVector d = object->GetMatrix() * col->vertices[3].Get();
|
|
||||||
|
|
||||||
float minx = Min(Min(a.x, b.x), Min(c.x, d.x));
|
|
||||||
float maxx = Max(Max(a.x, b.x), Max(c.x, d.x));
|
|
||||||
float miny = Min(Min(a.y, b.y), Min(c.y, d.y));
|
|
||||||
float maxy = Max(Max(a.y, b.y), Max(c.y, d.y));
|
|
||||||
float minz = Min(Min(a.z, b.z), Min(c.z, d.z));
|
|
||||||
float maxz = Max(Max(a.z, b.z), Max(c.z, d.z));
|
|
||||||
|
|
||||||
|
|
||||||
if ( amount > 300.0f )
|
|
||||||
{
|
{
|
||||||
PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_L, object->GetPosition());
|
CVector a = col->vertices[0].Get();
|
||||||
|
CVector b = col->vertices[1].Get();
|
||||||
GeneratePanesForWindow(0,
|
CVector c = col->vertices[2].Get();
|
||||||
CVector(minx, miny, minz),
|
CVector d = col->vertices[3].Get();
|
||||||
CVector(0.0f, 0.0f, maxz-minz),
|
|
||||||
CVector(maxx-minx, maxy-miny, 0.0f),
|
float minx = Min(Min(a.x, b.x), Min(c.x, d.x));
|
||||||
speed, point, 0.1f, !!object->bGlassCracked, explosion);
|
float maxx = Max(Max(a.x, b.x), Max(c.x, d.x));
|
||||||
|
float miny = Min(Min(a.y, b.y), Min(c.y, d.y));
|
||||||
|
float maxy = Max(Max(a.y, b.y), Max(c.y, d.y));
|
||||||
|
float minz = Min(Min(a.z, b.z), Min(c.z, d.z));
|
||||||
|
float maxz = Max(Max(a.z, b.z), Max(c.z, d.z));
|
||||||
|
|
||||||
|
CVector pa = object->GetMatrix() * CVector(minx, miny, minz);
|
||||||
|
CVector pb = object->GetMatrix() * CVector(maxx, maxy, minz);
|
||||||
|
|
||||||
|
if ( amount > 300.0f )
|
||||||
|
{
|
||||||
|
PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_L, object->GetPosition());
|
||||||
|
|
||||||
|
GeneratePanesForWindow(0,
|
||||||
|
pa,
|
||||||
|
CVector(0.0f, 0.0f, maxz-minz),
|
||||||
|
pb - pa,
|
||||||
|
speed, point, 0.1f, !!object->bGlassCracked, explosion, 1, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_S, object->GetPosition());
|
||||||
|
|
||||||
|
GeneratePanesForWindow(1,
|
||||||
|
pa,
|
||||||
|
CVector(0.0f, 0.0f, maxz-minz),
|
||||||
|
pb - pa,
|
||||||
|
speed, point, 0.1f, !!object->bGlassCracked, explosion, 1, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_S, object->GetPosition());
|
|
||||||
|
|
||||||
GeneratePanesForWindow(1,
|
|
||||||
CVector(minx, miny, minz),
|
|
||||||
CVector(0.0f, 0.0f, maxz-minz),
|
|
||||||
CVector(maxx-minx, maxy-miny, 0.0f),
|
|
||||||
speed, point, 0.1f, !!object->bGlassCracked, explosion);
|
|
||||||
}
|
|
||||||
|
|
||||||
object->bGlassBroken = true;
|
object->bGlassBroken = true;
|
||||||
object->GetMatrix().GetPosition().z = -100.0f;
|
object->bIsVisible = false;
|
||||||
|
object->bUsesCollision = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -658,7 +678,7 @@ CGlass::WindowRespondsToSoftCollision(CEntity *entity, float amount)
|
||||||
|
|
||||||
CObject *object = (CObject *)entity;
|
CObject *object = (CObject *)entity;
|
||||||
|
|
||||||
if ( amount > 50.0f && !object->bGlassCracked )
|
if ( entity->bUsesCollision && amount > 50.0f && !object->bGlassCracked )
|
||||||
{
|
{
|
||||||
PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition());
|
PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition());
|
||||||
object->bGlassCracked = true;
|
object->bGlassCracked = true;
|
||||||
|
@ -674,15 +694,18 @@ CGlass::WasGlassHitByBullet(CEntity *entity, CVector point)
|
||||||
|
|
||||||
if ( IsGlass(object->GetModelIndex()) )
|
if ( IsGlass(object->GetModelIndex()) )
|
||||||
{
|
{
|
||||||
if ( !object->bGlassCracked )
|
if ( object->bUsesCollision )
|
||||||
{
|
{
|
||||||
PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition());
|
if ( !object->bGlassCracked )
|
||||||
object->bGlassCracked = true;
|
{
|
||||||
}
|
PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition());
|
||||||
else
|
object->bGlassCracked = true;
|
||||||
{
|
}
|
||||||
if ( (CGeneral::GetRandomNumber() & 3) == 2 )
|
else
|
||||||
WindowRespondsToCollision(object, 0.0f, CVector(0.0f, 0.0f, 0.0f), point, false);
|
{
|
||||||
|
if ( (CGeneral::GetRandomNumber() & 3) == 2 )
|
||||||
|
WindowRespondsToCollision(object, 0.0f, CVector(0.0f, 0.0f, 0.0f), point, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -693,19 +716,304 @@ CGlass::WindowRespondsToExplosion(CEntity *entity, CVector point)
|
||||||
ASSERT(entity!=nil);
|
ASSERT(entity!=nil);
|
||||||
|
|
||||||
CObject *object = (CObject *)entity;
|
CObject *object = (CObject *)entity;
|
||||||
|
|
||||||
CVector distToGlass = object->GetPosition() - point;
|
if ( object->bUsesCollision )
|
||||||
|
|
||||||
float fDistToGlass = distToGlass.Magnitude();
|
|
||||||
|
|
||||||
if ( fDistToGlass < 10.0f )
|
|
||||||
{
|
{
|
||||||
distToGlass *= (0.3f / fDistToGlass); // normalise
|
CVector distToGlass = object->GetPosition() - point;
|
||||||
WindowRespondsToCollision(object, 10000.0f, distToGlass, object->GetPosition(), true);
|
|
||||||
}
|
float fDistToGlass = distToGlass.Magnitude();
|
||||||
else
|
|
||||||
{
|
if ( fDistToGlass < 10.0f )
|
||||||
if ( fDistToGlass < 30.0f )
|
{
|
||||||
object->bGlassCracked = true;
|
distToGlass *= (0.3f / fDistToGlass); // normalise
|
||||||
|
WindowRespondsToCollision(object, 10000.0f, distToGlass, object->GetPosition(), true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( fDistToGlass < 30.0f )
|
||||||
|
object->bGlassCracked = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CGlass::CarWindscreenShatters(CVehicle *vehicle, bool unk)
|
||||||
|
{
|
||||||
|
ASSERT(vehicle!=nil);
|
||||||
|
|
||||||
|
CColModel *col = vehicle->GetColModel();
|
||||||
|
ASSERT(col!=nil);
|
||||||
|
|
||||||
|
if ( col->numTriangles < 2 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
CColTriangle *tria = nil;
|
||||||
|
int32 triIndex = -1;
|
||||||
|
CColTriangle *trib = nil;
|
||||||
|
|
||||||
|
for ( int32 i = 0; i < col->numTriangles; i++ )
|
||||||
|
{
|
||||||
|
CColTriangle *tri = &col->triangles[i];
|
||||||
|
if ( tri->surface == SURFACE_GLASS )
|
||||||
|
{
|
||||||
|
if ( tria )
|
||||||
|
{
|
||||||
|
trib = tri;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
triIndex = i;
|
||||||
|
tria = tri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( trib == nil )
|
||||||
|
return;
|
||||||
|
|
||||||
|
CCollision::CalculateTrianglePlanes(col);
|
||||||
|
|
||||||
|
CColTrianglePlane *triPlanes = col->trianglePlanes;
|
||||||
|
|
||||||
|
if ( triPlanes == nil )
|
||||||
|
return;
|
||||||
|
|
||||||
|
CVector planeNormal;
|
||||||
|
triPlanes[triIndex].GetNormal(planeNormal);
|
||||||
|
planeNormal = Multiply3x3(vehicle->GetMatrix(), planeNormal);
|
||||||
|
|
||||||
|
CVector vec1 = CrossProduct(vehicle->GetRight(), planeNormal);
|
||||||
|
vec1.Normalise();
|
||||||
|
|
||||||
|
CVector vec2 = CrossProduct(planeNormal, vehicle->GetUp());
|
||||||
|
vec2.Normalise();
|
||||||
|
|
||||||
|
CVector v[6];
|
||||||
|
float proj1[6];
|
||||||
|
float proj2[6];
|
||||||
|
|
||||||
|
v[0] = col->vertices[tria->a].Get();
|
||||||
|
v[1] = col->vertices[tria->b].Get();
|
||||||
|
v[2] = col->vertices[tria->c].Get();
|
||||||
|
|
||||||
|
v[3] = col->vertices[trib->a].Get();
|
||||||
|
v[4] = col->vertices[trib->b].Get();
|
||||||
|
v[5] = col->vertices[trib->c].Get();
|
||||||
|
|
||||||
|
v[0] = vehicle->GetMatrix() * v[0];
|
||||||
|
v[1] = vehicle->GetMatrix() * v[1];
|
||||||
|
v[2] = vehicle->GetMatrix() * v[2];
|
||||||
|
v[3] = vehicle->GetMatrix() * v[3];
|
||||||
|
v[4] = vehicle->GetMatrix() * v[4];
|
||||||
|
v[5] = vehicle->GetMatrix() * v[5];
|
||||||
|
|
||||||
|
proj1[0] = DotProduct(v[0], vec1);
|
||||||
|
proj2[0] = DotProduct(v[0], vec2);
|
||||||
|
proj1[1] = DotProduct(v[1], vec1);
|
||||||
|
proj2[1] = DotProduct(v[1], vec2);
|
||||||
|
proj1[2] = DotProduct(v[2], vec1);
|
||||||
|
proj2[2] = DotProduct(v[2], vec2);
|
||||||
|
|
||||||
|
proj1[3] = DotProduct(v[3], vec1);
|
||||||
|
proj2[3] = DotProduct(v[3], vec2);
|
||||||
|
proj1[4] = DotProduct(v[4], vec1);
|
||||||
|
proj2[4] = DotProduct(v[4], vec2);
|
||||||
|
proj1[5] = DotProduct(v[5], vec1);
|
||||||
|
proj2[5] = DotProduct(v[5], vec2);
|
||||||
|
|
||||||
|
int32 originIndex = 0;
|
||||||
|
float max1 = proj1[0];
|
||||||
|
float max2 = proj2[0];
|
||||||
|
float origin = proj1[0] + proj2[0];
|
||||||
|
|
||||||
|
for ( int32 i = 1; i < 6; i++ )
|
||||||
|
{
|
||||||
|
float o = proj1[i] + proj2[i];
|
||||||
|
if ( o < origin )
|
||||||
|
{
|
||||||
|
origin = o;
|
||||||
|
originIndex = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( proj1[i] > max1 )
|
||||||
|
max1 = proj1[i];
|
||||||
|
if ( proj2[i] > max2 )
|
||||||
|
max2 = proj2[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
float bound1 = max1 - proj1[originIndex];
|
||||||
|
float bound2 = max2 - proj2[originIndex];
|
||||||
|
|
||||||
|
PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_L, vehicle->GetPosition());
|
||||||
|
|
||||||
|
CVector center = v[originIndex] + ((0.5f*bound1) * vec1) + ((0.5f*bound2) * vec2);
|
||||||
|
CVector speed = vehicle->m_vecMoveSpeed;
|
||||||
|
CVector right = bound2 * vec2;
|
||||||
|
CVector up = bound1 * vec1;
|
||||||
|
CVector pos = v[originIndex];
|
||||||
|
|
||||||
|
GeneratePanesForWindow(2, pos, up, right, speed, center, 0.1f, false, false, 2, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CGlass::HasGlassBeenShatteredAtCoors(float x, float y, float z)
|
||||||
|
{
|
||||||
|
CEntity *entity = nil;
|
||||||
|
float dist = 20.0f;
|
||||||
|
|
||||||
|
int32 nStartX = Max(CWorld::GetSectorIndexX(x - 30.0f), 0);
|
||||||
|
int32 nStartY = Max(CWorld::GetSectorIndexY(y - 30.0f), 0);
|
||||||
|
int32 nEndX = Min(CWorld::GetSectorIndexX(x + 30.0f), NUMSECTORS_X-1);
|
||||||
|
int32 nEndY = Min(CWorld::GetSectorIndexY(y + 30.0f), NUMSECTORS_Y-1);
|
||||||
|
|
||||||
|
CWorld::AdvanceCurrentScanCode();
|
||||||
|
|
||||||
|
for ( int32 y = nStartY; y <= nEndY; y++ )
|
||||||
|
{
|
||||||
|
for ( int32 x = nStartX; x <= nEndX; x++ )
|
||||||
|
{
|
||||||
|
CSector *sector = CWorld::GetSector(x, y);
|
||||||
|
|
||||||
|
ASSERT(sector != nil);
|
||||||
|
|
||||||
|
FindWindowSectorList(sector->m_lists[ENTITYLIST_OBJECTS], &dist, &entity, x, y, z);
|
||||||
|
FindWindowSectorList(sector->m_lists[ENTITYLIST_DUMMIES], &dist, &entity, x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( entity )
|
||||||
|
{
|
||||||
|
if ( entity->GetType() == ENTITY_TYPE_DUMMY )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !!((CObject*)entity)->bGlassBroken;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CGlass::FindWindowSectorList(CPtrList &list, float *dist, CEntity **entity, float x, float y, float z)
|
||||||
|
{
|
||||||
|
ASSERT(dist!=nil);
|
||||||
|
ASSERT(entity!=nil);
|
||||||
|
|
||||||
|
CPtrNode *node = list.first;
|
||||||
|
|
||||||
|
while ( node != nil )
|
||||||
|
{
|
||||||
|
CEntity *ent = (CEntity *)node->item;
|
||||||
|
uint16 scanCode = ent->m_scanCode;
|
||||||
|
node = node->next;
|
||||||
|
|
||||||
|
ASSERT(ent!=nil);
|
||||||
|
|
||||||
|
if ( IsGlass(ent->GetModelIndex()) )
|
||||||
|
{
|
||||||
|
if ( scanCode != CWorld::GetCurrentScanCode() )
|
||||||
|
{
|
||||||
|
ent->m_scanCode = CWorld::GetCurrentScanCode();
|
||||||
|
|
||||||
|
float dst = (CVector(x,y,z) - ent->GetPosition()).Magnitude();
|
||||||
|
|
||||||
|
if ( dst < *dist )
|
||||||
|
{
|
||||||
|
*dist = dst;
|
||||||
|
*entity = ent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CGlass::BreakGlassPhysically(CVector pos, float radius)
|
||||||
|
{
|
||||||
|
static uint32 breakTime = 0;
|
||||||
|
|
||||||
|
if ( CTimer::GetTimeInMilliseconds() < breakTime + 1000 && CTimer::GetTimeInMilliseconds() >= breakTime )
|
||||||
|
return;
|
||||||
|
|
||||||
|
CColSphere sphere;
|
||||||
|
sphere.piece = 0;
|
||||||
|
sphere.radius = radius;
|
||||||
|
sphere.surface = 0;
|
||||||
|
|
||||||
|
for ( int32 i = CPools::GetObjectPool()->GetSize() - 1; i >= 0; i-- )
|
||||||
|
{
|
||||||
|
CObject *object = CPools::GetObjectPool()->GetSlot(i);
|
||||||
|
if (object)
|
||||||
|
{
|
||||||
|
if ( IsGlass(object->GetModelIndex()) )
|
||||||
|
{
|
||||||
|
if ( object->bUsesCollision )
|
||||||
|
{
|
||||||
|
CColModel *col = object->GetColModel();
|
||||||
|
ASSERT(col!=nil);
|
||||||
|
|
||||||
|
if ( col->numTriangles < 2 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool hit = false;
|
||||||
|
|
||||||
|
CVector dist = pos - object->GetPosition();
|
||||||
|
|
||||||
|
sphere.center.x = DotProduct(dist, object->GetRight());
|
||||||
|
sphere.center.y = DotProduct(dist, object->GetForward());
|
||||||
|
sphere.center.z = DotProduct(dist, object->GetUp());
|
||||||
|
|
||||||
|
CCollision::CalculateTrianglePlanes(col);
|
||||||
|
|
||||||
|
for ( int32 j = 0; j < col->numTriangles; j++ )
|
||||||
|
{
|
||||||
|
if ( CCollision::TestSphereTriangle(sphere,
|
||||||
|
col->vertices, col->triangles[i], col->trianglePlanes[i]) )
|
||||||
|
{
|
||||||
|
hit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( hit )
|
||||||
|
{
|
||||||
|
breakTime = CTimer::GetTimeInMilliseconds();
|
||||||
|
|
||||||
|
if ( object->bGlassCracked )
|
||||||
|
{
|
||||||
|
CVector a = col->vertices[0].Get();
|
||||||
|
CVector b = col->vertices[1].Get();
|
||||||
|
CVector c = col->vertices[2].Get();
|
||||||
|
CVector d = col->vertices[3].Get();
|
||||||
|
|
||||||
|
float minx = Min(Min(a.x, b.x), Min(c.x, d.x));
|
||||||
|
float maxx = Max(Max(a.x, b.x), Max(c.x, d.x));
|
||||||
|
float miny = Min(Min(a.y, b.y), Min(c.y, d.y));
|
||||||
|
float maxy = Max(Max(a.y, b.y), Max(c.y, d.y));
|
||||||
|
float minz = Min(Min(a.z, b.z), Min(c.z, d.z));
|
||||||
|
float maxz = Max(Max(a.z, b.z), Max(c.z, d.z));
|
||||||
|
|
||||||
|
CVector pa = object->GetMatrix() * CVector(minx, miny, minz);
|
||||||
|
CVector pb = object->GetMatrix() * CVector(maxx, maxy, minz);
|
||||||
|
|
||||||
|
PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_S, object->GetPosition());
|
||||||
|
|
||||||
|
GeneratePanesForWindow(1,
|
||||||
|
pa,
|
||||||
|
CVector(0.0f, 0.0f, maxz-minz),
|
||||||
|
pb - pa,
|
||||||
|
CVector(0.0f, 0.0f, 0.0f), pos, 0.1f, !!object->bGlassCracked, false, 1, false);
|
||||||
|
|
||||||
|
object->bGlassBroken = true;
|
||||||
|
object->bIsVisible = false;
|
||||||
|
object->bUsesCollision = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition());
|
||||||
|
object->bGlassCracked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
class CEntity;
|
class CEntity;
|
||||||
class CVehicle;
|
class CVehicle;
|
||||||
|
class CPtrList;
|
||||||
|
|
||||||
class CFallingGlassPane : public CMatrix
|
class CFallingGlassPane : public CMatrix
|
||||||
{
|
{
|
||||||
|
@ -14,6 +15,7 @@ public:
|
||||||
uint8 m_nTriIndex;
|
uint8 m_nTriIndex;
|
||||||
bool m_bActive;
|
bool m_bActive;
|
||||||
bool m_bShattered;
|
bool m_bShattered;
|
||||||
|
bool m_bCarGlass;
|
||||||
|
|
||||||
CFallingGlassPane() { }
|
CFallingGlassPane() { }
|
||||||
~CFallingGlassPane() { }
|
~CFallingGlassPane() { }
|
||||||
|
@ -39,7 +41,7 @@ public:
|
||||||
static void Update(void);
|
static void Update(void);
|
||||||
static void Render(void);
|
static void Render(void);
|
||||||
static CFallingGlassPane *FindFreePane(void);
|
static CFallingGlassPane *FindFreePane(void);
|
||||||
static void GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector right, CVector speed, CVector point, float moveSpeed, bool cracked, bool explosion);
|
static void GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector right, CVector speed, CVector center, float moveSpeed, bool cracked, bool explosion, int32 stepmul, bool carGlass);
|
||||||
static void AskForObjectToBeRenderedInGlass(CEntity *entity);
|
static void AskForObjectToBeRenderedInGlass(CEntity *entity);
|
||||||
static void RenderEntityInGlass(CEntity *entity);
|
static void RenderEntityInGlass(CEntity *entity);
|
||||||
static int32 CalcAlphaWithNormal(CVector *normal);
|
static int32 CalcAlphaWithNormal(CVector *normal);
|
||||||
|
@ -50,8 +52,8 @@ public:
|
||||||
static void WindowRespondsToSoftCollision(CEntity *entity, float amount);
|
static void WindowRespondsToSoftCollision(CEntity *entity, float amount);
|
||||||
static void WasGlassHitByBullet(CEntity *entity, CVector point);
|
static void WasGlassHitByBullet(CEntity *entity, CVector point);
|
||||||
static void WindowRespondsToExplosion(CEntity *entity, CVector point);
|
static void WindowRespondsToExplosion(CEntity *entity, CVector point);
|
||||||
|
static void CarWindscreenShatters(CVehicle *vehicle, bool unk);
|
||||||
//TODO(MIAMI)
|
static bool HasGlassBeenShatteredAtCoors(float x, float y, float z);
|
||||||
static void CarWindscreenShatters(CVehicle *vehicle, bool unk) {}
|
static void FindWindowSectorList(CPtrList &list, float *dist, CEntity **entity, float x, float y, float z);
|
||||||
static void BreakGlassPhysically(CVector, float) {}
|
static void BreakGlassPhysically(CVector pos, float radius);
|
||||||
};
|
};
|
Loading…
Reference in a new issue