mirror of https://github.com/Nofated095/re-GTA.git
Merge branch 'master' of github.com:gtamodding/re3
This commit is contained in:
commit
3b315fec26
|
@ -17,8 +17,6 @@
|
|||
|
||||
cMusicManager &MusicManager = *(cMusicManager *)0x8F3964;
|
||||
int32 &gNumRetunePresses = *(int32 *)0x650B80;
|
||||
wchar *pCurrentStation = (wchar *)0x650B9C;
|
||||
uint8 &cDisplay = *(uint8 *)0x650BA1;
|
||||
int32 &gRetuneCounter = *(int32*)0x650B84;
|
||||
bool& bHasStarted = *(bool*)0x650B7C;
|
||||
|
||||
|
@ -72,6 +70,8 @@ cMusicManager::DisplayRadioStationName()
|
|||
int8 pRetune;
|
||||
int8 gStreamedSound;
|
||||
int8 gRetuneCounter;
|
||||
static wchar *pCurrentStation = nil;
|
||||
static uint8 cDisplay = 0;
|
||||
|
||||
if(!CTimer::GetIsPaused() && !TheCamera.m_WideScreenOn && PlayerInCar() &&
|
||||
!CReplay::IsPlayingBack()) {
|
||||
|
|
|
@ -2078,14 +2078,12 @@ void CGarage::CenterCarInGarage(CVehicle* pVehicle)
|
|||
return;
|
||||
if (IsAnyOtherPedTouchingGarage(FindPlayerPed()))
|
||||
return;
|
||||
float posX = pVehicle->GetPosition().x;
|
||||
float posY = pVehicle->GetPosition().y;
|
||||
float posZ = pVehicle->GetPosition().z;
|
||||
CVector pos = pVehicle->GetPosition();
|
||||
float garageX = GetGarageCenterX();
|
||||
float garageY = GetGarageCenterY();
|
||||
float offsetX = garageX - posX;
|
||||
float offsetY = garageY - posY;
|
||||
float offsetZ = posZ - posZ;
|
||||
float offsetX = garageX - pos.x;
|
||||
float offsetY = garageY - pos.y;
|
||||
float offsetZ = pos.z - pos.z;
|
||||
float distance = CVector(offsetX, offsetY, offsetZ).Magnitude();
|
||||
if (distance < RESPRAY_CENTERING_COEFFICIENT) {
|
||||
pVehicle->GetPosition().x = GetGarageCenterX();
|
||||
|
@ -2096,7 +2094,7 @@ void CGarage::CenterCarInGarage(CVehicle* pVehicle)
|
|||
pVehicle->GetPosition().y += offsetY * RESPRAY_CENTERING_COEFFICIENT / distance;
|
||||
}
|
||||
if (!IsEntityEntirelyInside3D(pVehicle, 0.1f))
|
||||
pVehicle->GetPosition() = CVector(posX, posY, posZ);
|
||||
pVehicle->GetPosition() = pos;
|
||||
}
|
||||
|
||||
void CGarages::CloseHideOutGaragesBeforeSave()
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
#include "Fire.h"
|
||||
#include "PointLights.h"
|
||||
#include "Pools.h"
|
||||
#ifdef FIX_BUGS
|
||||
#include "Replay.h"
|
||||
#endif
|
||||
#include "Script.h"
|
||||
#include "Shadows.h"
|
||||
#include "SpecialFX.h"
|
||||
|
@ -642,32 +645,26 @@ CPickups::AddToCollectedPickupsArray(int32 index)
|
|||
void
|
||||
CPickups::Update()
|
||||
{
|
||||
#ifndef FIX_BUGS
|
||||
// BUG: this code can only reach 318 out of 320 pickups
|
||||
#ifdef FIX_BUGS // RIP speedrunning (solution from SA)
|
||||
if (CReplay::IsPlayingBack())
|
||||
return;
|
||||
#endif
|
||||
#define PICKUPS_FRAME_SPAN (6)
|
||||
#define PICKUPS_PER_FRAME (NUMGENERALPICKUPS/PICKUPS_FRAME_SPAN)
|
||||
|
||||
for (uint32 i = PICKUPS_PER_FRAME * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN); i < PICKUPS_PER_FRAME * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1); i++) {
|
||||
#ifdef FIX_BUGS
|
||||
for (uint32 i = NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN) / PICKUPS_FRAME_SPAN; i < NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1) / PICKUPS_FRAME_SPAN; i++) {
|
||||
#else // BUG: this code can only reach 318 out of 320 pickups
|
||||
for (uint32 i = NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN); i < NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1); i++) {
|
||||
#endif
|
||||
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
|
||||
AddToCollectedPickupsArray(i);
|
||||
}
|
||||
}
|
||||
|
||||
#undef PICKUPS_FRAME_SPAN
|
||||
for (uint32 i = NUMGENERALPICKUPS; i < NUMPICKUPS; i++) {
|
||||
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
|
||||
AddToCollectedPickupsArray(i);
|
||||
}
|
||||
}
|
||||
|
||||
#undef PICKUPS_FRAME_SPAN
|
||||
#undef PICKUPS_PER_FRAME
|
||||
#else
|
||||
for (uint32 i = 0; i < NUMPICKUPS; i++) {
|
||||
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
|
||||
AddToCollectedPickupsArray(i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1106,8 +1106,11 @@ void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D
|
|||
// Radar space goes from -1.0 to 1.0 in x and y, top right is (1.0, 1.0)
|
||||
void CRadar::TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in)
|
||||
{
|
||||
// FIX? scale RADAR_LEFT here somehow
|
||||
#ifdef FIX_BUGS
|
||||
out.x = (in.x + 1.0f)*0.5f*SCREEN_SCALE_X(RADAR_WIDTH) + SCREEN_SCALE_X(RADAR_LEFT);
|
||||
#else
|
||||
out.x = (in.x + 1.0f)*0.5f*SCREEN_SCALE_X(RADAR_WIDTH) + RADAR_LEFT;
|
||||
#endif
|
||||
out.y = (1.0f - in.y)*0.5f*SCREEN_SCALE_Y(RADAR_HEIGHT) + SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT);
|
||||
}
|
||||
|
||||
|
|
|
@ -215,6 +215,7 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con
|
|||
|
||||
#define ABS(a) (((a) < 0) ? (-(a)) : (a))
|
||||
#define norm(value, min, max) (((value) < (min)) ? 0 : (((value) > (max)) ? 1 : (((value) - (min)) / ((max) - (min)))))
|
||||
#define lerp(norm, min, max) ( (norm) * ((max) - (min)) + (min) )
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
#define STR(x) STRINGIFY(x)
|
||||
|
|
|
@ -94,6 +94,8 @@ enum Config {
|
|||
NUM_GARAGES = 32,
|
||||
NUM_PROJECTILES = 32,
|
||||
|
||||
NUM_GLASSPANES = 45,
|
||||
NUM_GLASSENTITIES = 32,
|
||||
NUM_WATERCANNONS = 3,
|
||||
|
||||
NUMPEDROUTES = 200,
|
||||
|
|
|
@ -38,8 +38,8 @@ CObject::CObject(void)
|
|||
bIsPickup = false;
|
||||
m_obj_flag2 = false;
|
||||
bOutOfStock = false;
|
||||
m_obj_flag8 = false;
|
||||
m_obj_flag10 = false;
|
||||
bGlassCracked = false;
|
||||
bGlassBroken = false;
|
||||
bHasBeenDamaged = false;
|
||||
m_nRefModelIndex = -1;
|
||||
bUseVehicleColours = false;
|
||||
|
|
|
@ -36,8 +36,8 @@ public:
|
|||
int8 bIsPickup : 1;
|
||||
int8 m_obj_flag2 : 1;
|
||||
int8 bOutOfStock : 1;
|
||||
int8 m_obj_flag8 : 1;
|
||||
int8 m_obj_flag10 : 1;
|
||||
int8 bGlassCracked : 1;
|
||||
int8 bGlassBroken : 1;
|
||||
int8 bHasBeenDamaged : 1;
|
||||
int8 bUseVehicleColours : 1;
|
||||
int8 m_obj_flag80 : 1;
|
||||
|
|
|
@ -116,7 +116,7 @@ int16 CFont::Size[3][193] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
uint16 foreign_table[128] = {
|
||||
wchar foreign_table[128] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
@ -228,7 +228,7 @@ CFont::InitPerFrame(void)
|
|||
}
|
||||
|
||||
void
|
||||
CFont::PrintChar(float x, float y, uint16 c)
|
||||
CFont::PrintChar(float x, float y, wchar c)
|
||||
{
|
||||
if(x <= 0.0f || x > SCREEN_WIDTH ||
|
||||
y <= 0.0f || y > SCREEN_HEIGHT) // BUG: game uses SCREENW again
|
||||
|
@ -274,14 +274,14 @@ CFont::PrintChar(float x, float y, uint16 c)
|
|||
}
|
||||
|
||||
void
|
||||
CFont::PrintString(float xstart, float ystart, uint16 *s)
|
||||
CFont::PrintString(float xstart, float ystart, wchar *s)
|
||||
{
|
||||
CRect rect;
|
||||
int numSpaces;
|
||||
float lineLength;
|
||||
float x, y;
|
||||
bool first;
|
||||
uint16 *start, *t;
|
||||
wchar *start, *t;
|
||||
|
||||
if(*s == '*')
|
||||
return;
|
||||
|
@ -357,11 +357,11 @@ CFont::PrintString(float xstart, float ystart, uint16 *s)
|
|||
}
|
||||
|
||||
int
|
||||
CFont::GetNumberLines(float xstart, float ystart, uint16 *s)
|
||||
CFont::GetNumberLines(float xstart, float ystart, wchar *s)
|
||||
{
|
||||
int n;
|
||||
float x, y;
|
||||
uint16 *t;
|
||||
wchar *t;
|
||||
|
||||
n = 0;
|
||||
if(Details.centre || Details.rightJustify)
|
||||
|
@ -400,12 +400,12 @@ CFont::GetNumberLines(float xstart, float ystart, uint16 *s)
|
|||
}
|
||||
|
||||
void
|
||||
CFont::GetTextRect(CRect *rect, float xstart, float ystart, uint16 *s)
|
||||
CFont::GetTextRect(CRect *rect, float xstart, float ystart, wchar *s)
|
||||
{
|
||||
int numLines;
|
||||
float x, y;
|
||||
int16 maxlength;
|
||||
uint16 *t;
|
||||
wchar *t;
|
||||
|
||||
maxlength = 0;
|
||||
numLines = 0;
|
||||
|
@ -469,9 +469,9 @@ CFont::GetTextRect(CRect *rect, float xstart, float ystart, uint16 *s)
|
|||
}
|
||||
|
||||
void
|
||||
CFont::PrintString(float x, float y, uint16 *start, uint16 *end, float spwidth)
|
||||
CFont::PrintString(float x, float y, wchar *start, wchar *end, float spwidth)
|
||||
{
|
||||
uint16 *s, c, unused;
|
||||
wchar *s, c, unused;
|
||||
|
||||
for(s = start; s < end; s++){
|
||||
if(*s == '~')
|
||||
|
@ -487,7 +487,7 @@ CFont::PrintString(float x, float y, uint16 *start, uint16 *end, float spwidth)
|
|||
}
|
||||
|
||||
float
|
||||
CFont::GetCharacterWidth(uint16 c)
|
||||
CFont::GetCharacterWidth(wchar c)
|
||||
{
|
||||
#ifdef MORE_LANGUAGES
|
||||
if (Details.proportional)
|
||||
|
@ -503,7 +503,7 @@ CFont::GetCharacterWidth(uint16 c)
|
|||
}
|
||||
|
||||
float
|
||||
CFont::GetCharacterSize(uint16 c)
|
||||
CFont::GetCharacterSize(wchar c)
|
||||
{
|
||||
#ifdef MORE_LANGUAGES
|
||||
if(Details.proportional)
|
||||
|
@ -519,7 +519,7 @@ CFont::GetCharacterSize(uint16 c)
|
|||
}
|
||||
|
||||
float
|
||||
CFont::GetStringWidth(uint16 *s, bool spaces)
|
||||
CFont::GetStringWidth(wchar *s, bool spaces)
|
||||
{
|
||||
float w;
|
||||
|
||||
|
@ -537,8 +537,8 @@ CFont::GetStringWidth(uint16 *s, bool spaces)
|
|||
return w;
|
||||
}
|
||||
|
||||
uint16*
|
||||
CFont::GetNextSpace(uint16 *s)
|
||||
wchar*
|
||||
CFont::GetNextSpace(wchar *s)
|
||||
{
|
||||
for(; *s != ' ' && *s != '\0'; s++)
|
||||
if(*s == '~'){
|
||||
|
@ -551,8 +551,8 @@ CFont::GetNextSpace(uint16 *s)
|
|||
return s;
|
||||
}
|
||||
|
||||
uint16*
|
||||
CFont::ParseToken(uint16 *s, uint16*)
|
||||
wchar*
|
||||
CFont::ParseToken(wchar *s, wchar*)
|
||||
{
|
||||
s++;
|
||||
if(Details.color.r || Details.color.g || Details.color.b)
|
||||
|
@ -582,7 +582,7 @@ CFont::DrawFonts(void)
|
|||
CSprite2d::DrawBank(Details.bank+2);
|
||||
}
|
||||
|
||||
uint16
|
||||
wchar
|
||||
CFont::character_code(uint8 c)
|
||||
{
|
||||
if(c < 128)
|
||||
|
@ -596,10 +596,10 @@ STARTPATCHES
|
|||
InjectHook(0x500BA0, CFont::Shutdown, PATCH_JUMP);
|
||||
InjectHook(0x500BE0, CFont::InitPerFrame, PATCH_JUMP);
|
||||
InjectHook(0x500C30, CFont::PrintChar, PATCH_JUMP);
|
||||
InjectHook(0x500F50, (void (*)(float, float, uint16*))CFont::PrintString, PATCH_JUMP);
|
||||
InjectHook(0x500F50, (void (*)(float, float, wchar*))CFont::PrintString, PATCH_JUMP);
|
||||
InjectHook(0x501260, CFont::GetNumberLines, PATCH_JUMP);
|
||||
InjectHook(0x5013B0, CFont::GetTextRect, PATCH_JUMP);
|
||||
InjectHook(0x501730, (void (*)(float, float, uint16*, uint16*, float))CFont::PrintString, PATCH_JUMP);
|
||||
InjectHook(0x501730, (void (*)(float, float, wchar*, wchar*, float))CFont::PrintString, PATCH_JUMP);
|
||||
InjectHook(0x5017E0, CFont::GetCharacterWidth, PATCH_JUMP);
|
||||
InjectHook(0x501840, CFont::GetCharacterSize, PATCH_JUMP);
|
||||
InjectHook(0x5018A0, CFont::GetStringWidth, PATCH_JUMP);
|
||||
|
|
|
@ -64,18 +64,18 @@ public:
|
|||
static void Initialise(void);
|
||||
static void Shutdown(void);
|
||||
static void InitPerFrame(void);
|
||||
static void PrintChar(float x, float y, uint16 c);
|
||||
static void PrintString(float x, float y, uint16 *s);
|
||||
static int GetNumberLines(float xstart, float ystart, uint16 *s);
|
||||
static void GetTextRect(CRect *rect, float xstart, float ystart, uint16 *s);
|
||||
static void PrintString(float x, float y, uint16 *start, uint16 *end, float spwidth);
|
||||
static float GetCharacterWidth(uint16 c);
|
||||
static float GetCharacterSize(uint16 c);
|
||||
static float GetStringWidth(uint16 *s, bool spaces = false);
|
||||
static uint16 *GetNextSpace(uint16 *s);
|
||||
static uint16 *ParseToken(uint16 *s, uint16*);
|
||||
static void PrintChar(float x, float y, wchar c);
|
||||
static void PrintString(float x, float y, wchar *s);
|
||||
static int GetNumberLines(float xstart, float ystart, wchar *s);
|
||||
static void GetTextRect(CRect *rect, float xstart, float ystart, wchar *s);
|
||||
static void PrintString(float x, float y, wchar *start, wchar *end, float spwidth);
|
||||
static float GetCharacterWidth(wchar c);
|
||||
static float GetCharacterSize(wchar c);
|
||||
static float GetStringWidth(wchar *s, bool spaces = false);
|
||||
static wchar *GetNextSpace(wchar *s);
|
||||
static wchar *ParseToken(wchar *s, wchar*);
|
||||
static void DrawFonts(void);
|
||||
static uint16 character_code(uint8 c);
|
||||
static wchar character_code(uint8 c);
|
||||
|
||||
static CFontDetails GetDetails() { return Details; }
|
||||
static void SetScale(float x, float y) { Details.scaleX = x; Details.scaleY = y; }
|
||||
|
|
|
@ -1,21 +1,721 @@
|
|||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Glass.h"
|
||||
#include "Timer.h"
|
||||
#include "Object.h"
|
||||
#include "General.h"
|
||||
#include "AudioScriptObject.h"
|
||||
#include "World.h"
|
||||
#include "TimeCycle.h"
|
||||
#include "Particle.h"
|
||||
#include "Camera.h"
|
||||
#include "RenderBuffer.h"
|
||||
#include "Shadows.h"
|
||||
#include "ModelIndices.h"
|
||||
#include "main.h"
|
||||
|
||||
WRAPPER void CGlass::AskForObjectToBeRenderedInGlass(CEntity *ent) { EAXJMP(0x5033F0); }
|
||||
|
||||
WRAPPER void
|
||||
CGlass::WindowRespondsToCollision(CEntity *ent, float amount, CVector speed, CVector point, bool foo)
|
||||
uint32 CGlass::NumGlassEntities;
|
||||
CEntity *CGlass::apEntitiesToBeRendered[NUM_GLASSENTITIES];
|
||||
CFallingGlassPane CGlass::aGlassPanes[NUM_GLASSPANES];
|
||||
|
||||
|
||||
CVector2D CentersWithTriangle[NUM_GLASSTRIANGLES];
|
||||
const CVector2D CoorsWithTriangle[NUM_GLASSTRIANGLES][3] =
|
||||
{
|
||||
EAXJMP(0x503F10);
|
||||
{
|
||||
CVector2D(0.0f, 0.0f),
|
||||
CVector2D(0.0f, 1.0f),
|
||||
CVector2D(0.4f, 0.5f)
|
||||
},
|
||||
|
||||
{
|
||||
CVector2D(0.0f, 1.0f),
|
||||
CVector2D(1.0f, 1.0f),
|
||||
CVector2D(0.4f, 0.5f)
|
||||
},
|
||||
|
||||
{
|
||||
CVector2D(0.0f, 0.0f),
|
||||
CVector2D(0.4f, 0.5f),
|
||||
CVector2D(0.7f, 0.0f)
|
||||
},
|
||||
|
||||
{
|
||||
CVector2D(0.7f, 0.0f),
|
||||
CVector2D(0.4f, 0.5f),
|
||||
CVector2D(1.0f, 1.0f)
|
||||
},
|
||||
|
||||
{
|
||||
CVector2D(0.7f, 0.0f),
|
||||
CVector2D(1.0f, 1.0f),
|
||||
CVector2D(1.0f, 0.0f)
|
||||
}
|
||||
};
|
||||
|
||||
#define TEMPBUFFERVERTHILIGHTOFFSET 0
|
||||
#define TEMPBUFFERINDEXHILIGHTOFFSET 0
|
||||
#define TEMPBUFFERVERTHILIGHTSIZE 128
|
||||
#define TEMPBUFFERINDEXHILIGHTSIZE 512
|
||||
|
||||
#define TEMPBUFFERVERTSHATTEREDOFFSET TEMPBUFFERVERTHILIGHTSIZE
|
||||
#define TEMPBUFFERINDEXSHATTEREDOFFSET TEMPBUFFERINDEXHILIGHTSIZE
|
||||
#define TEMPBUFFERVERTSHATTEREDSIZE 192
|
||||
#define TEMPBUFFERINDEXSHATTEREDSIZE 768
|
||||
|
||||
#define TEMPBUFFERVERTREFLECTIONOFFSET TEMPBUFFERVERTSHATTEREDSIZE
|
||||
#define TEMPBUFFERINDEXREFLECTIONOFFSET TEMPBUFFERINDEXSHATTEREDSIZE
|
||||
#define TEMPBUFFERVERTREFLECTIONSIZE 256
|
||||
#define TEMPBUFFERINDEXREFLECTIONSIZE 1024
|
||||
|
||||
int32 TempBufferIndicesStoredHiLight = 0;
|
||||
int32 TempBufferVerticesStoredHiLight = 0;
|
||||
int32 TempBufferIndicesStoredShattered = 0;
|
||||
int32 TempBufferVerticesStoredShattered = 0;
|
||||
int32 TempBufferIndicesStoredReflection = 0;
|
||||
int32 TempBufferVerticesStoredReflection = 0;
|
||||
|
||||
void
|
||||
CFallingGlassPane::Update(void)
|
||||
{
|
||||
if ( CTimer::GetTimeInMilliseconds() >= m_nTimer )
|
||||
{
|
||||
// Apply MoveSpeed
|
||||
GetPosition() += m_vecMoveSpeed * CTimer::GetTimeStep();
|
||||
|
||||
// Apply Gravity
|
||||
m_vecMoveSpeed.z -= 0.02f * CTimer::GetTimeStep();
|
||||
|
||||
// Apply TurnSpeed
|
||||
GetRight() += CrossProduct(m_vecTurn, GetRight());
|
||||
GetForward() += CrossProduct(m_vecTurn, GetForward());
|
||||
GetUp() += CrossProduct(m_vecTurn, GetUp());
|
||||
|
||||
if ( GetPosition().z < m_fGroundZ )
|
||||
{
|
||||
CVector pos;
|
||||
CVector dir;
|
||||
|
||||
m_bActive = false;
|
||||
|
||||
pos = CVector(GetPosition().x, GetPosition().y, m_fGroundZ);
|
||||
|
||||
PlayOneShotScriptObject(_SCRSOUND_GLASS_SHARD, pos);
|
||||
|
||||
RwRGBA color = { 255, 255, 255, 255 };
|
||||
|
||||
static int32 nFrameGen = 0;
|
||||
|
||||
for ( int32 i = 0; i < 4; i++ )
|
||||
{
|
||||
dir.x = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f);
|
||||
dir.y = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f);
|
||||
dir.z = CGeneral::GetRandomNumberInRange(0.05f, 0.20f);
|
||||
|
||||
CParticle::AddParticle(PARTICLE_CAR_DEBRIS,
|
||||
pos,
|
||||
dir,
|
||||
nil,
|
||||
CGeneral::GetRandomNumberInRange(0.02f, 0.2f),
|
||||
color,
|
||||
CGeneral::GetRandomNumberInRange(-40, 40),
|
||||
0,
|
||||
++nFrameGen & 3,
|
||||
500);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WRAPPER void
|
||||
CGlass::WindowRespondsToSoftCollision(CEntity *ent, float amount)
|
||||
void
|
||||
CFallingGlassPane::Render(void)
|
||||
{
|
||||
EAXJMP(0x504630);
|
||||
float distToCamera = (TheCamera.GetPosition() - GetPosition()).Magnitude();
|
||||
|
||||
CVector fwdNorm = GetForward();
|
||||
fwdNorm.Normalise();
|
||||
uint8 alpha = CGlass::CalcAlphaWithNormal(&fwdNorm);
|
||||
|
||||
int32 time = clamp(CTimer::GetTimeInMilliseconds() - m_nTimer, 0, 500);
|
||||
|
||||
uint8 color = int32( float(alpha) * (float(time) / 500) );
|
||||
|
||||
if ( TempBufferIndicesStoredHiLight >= TEMPBUFFERINDEXHILIGHTSIZE-7 || TempBufferVerticesStoredHiLight >= TEMPBUFFERVERTHILIGHTSIZE-4 )
|
||||
CGlass::RenderHiLightPolys();
|
||||
|
||||
// HiLight Polys
|
||||
|
||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 0], color, color, color, color);
|
||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 1], color, color, color, color);
|
||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 2], color, color, color, color);
|
||||
|
||||
RwIm3DVertexSetU (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 0], 0.5f);
|
||||
RwIm3DVertexSetV (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 0], 0.5f);
|
||||
RwIm3DVertexSetU (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 1], 0.5f);
|
||||
RwIm3DVertexSetV (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 1], 0.6f);
|
||||
RwIm3DVertexSetU (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 2], 0.6f);
|
||||
RwIm3DVertexSetV (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 2], 0.6f);
|
||||
|
||||
ASSERT(m_nTriIndex < NUM_GLASSTRIANGLES);
|
||||
|
||||
CVector2D p0 = CoorsWithTriangle[m_nTriIndex][0] - CentersWithTriangle[m_nTriIndex];
|
||||
CVector2D p1 = CoorsWithTriangle[m_nTriIndex][1] - CentersWithTriangle[m_nTriIndex];
|
||||
CVector2D p2 = CoorsWithTriangle[m_nTriIndex][2] - CentersWithTriangle[m_nTriIndex];
|
||||
CVector v0 = *this * CVector(p0.x, 0.0f, p0.y);
|
||||
CVector v1 = *this * CVector(p1.x, 0.0f, p1.y);
|
||||
CVector v2 = *this * CVector(p2.x, 0.0f, p2.y);
|
||||
|
||||
RwIm3DVertexSetPos (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 0], v0.x, v0.y, v0.z);
|
||||
RwIm3DVertexSetPos (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 1], v1.x, v1.y, v1.z);
|
||||
RwIm3DVertexSetPos (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 2], v2.x, v2.y, v2.z);
|
||||
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredHiLight + 0] = TempBufferVerticesStoredHiLight + 0;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredHiLight + 1] = TempBufferVerticesStoredHiLight + 1;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredHiLight + 2] = TempBufferVerticesStoredHiLight + 2;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredHiLight + 3] = TempBufferVerticesStoredHiLight + 0;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredHiLight + 4] = TempBufferVerticesStoredHiLight + 2;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredHiLight + 5] = TempBufferVerticesStoredHiLight + 1;
|
||||
|
||||
TempBufferVerticesStoredHiLight += 3;
|
||||
TempBufferIndicesStoredHiLight += 6;
|
||||
|
||||
if ( m_bShattered )
|
||||
{
|
||||
if ( TempBufferIndicesStoredShattered >= TEMPBUFFERINDEXSHATTEREDSIZE-7 || TempBufferVerticesStoredShattered >= TEMPBUFFERVERTSHATTEREDSIZE-4 )
|
||||
CGlass::RenderShatteredPolys();
|
||||
|
||||
uint8 shatteredColor = 255;
|
||||
if ( distToCamera > 30.0f )
|
||||
shatteredColor = int32((1.0f - (distToCamera - 30.0f) * 4.0f / 40.0f) * 255);
|
||||
|
||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], shatteredColor, shatteredColor, shatteredColor, shatteredColor);
|
||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], shatteredColor, shatteredColor, shatteredColor, shatteredColor);
|
||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], shatteredColor, shatteredColor, shatteredColor, shatteredColor);
|
||||
|
||||
RwIm3DVertexSetU (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], 4.0f * CoorsWithTriangle[m_nTriIndex][0].x * m_fStep);
|
||||
RwIm3DVertexSetV (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], 4.0f * CoorsWithTriangle[m_nTriIndex][0].y * m_fStep);
|
||||
RwIm3DVertexSetU (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], 4.0f * CoorsWithTriangle[m_nTriIndex][1].x * m_fStep);
|
||||
RwIm3DVertexSetV (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], 4.0f * CoorsWithTriangle[m_nTriIndex][1].y * m_fStep);
|
||||
RwIm3DVertexSetU (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], 4.0f * CoorsWithTriangle[m_nTriIndex][2].x * m_fStep);
|
||||
RwIm3DVertexSetV (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], 4.0f * CoorsWithTriangle[m_nTriIndex][2].y * m_fStep);
|
||||
|
||||
RwIm3DVertexSetPos (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], v0.x, v0.y, v0.z);
|
||||
RwIm3DVertexSetPos (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], v1.x, v1.y, v1.z);
|
||||
RwIm3DVertexSetPos (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], v2.x, v2.y, v2.z);
|
||||
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 0] = TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET + 0;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 1] = TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET + 1;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 2] = TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET + 2;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 3] = TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET + 0;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 4] = TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET + 2;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 5] = TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET + 1;
|
||||
|
||||
TempBufferIndicesStoredShattered += 6;
|
||||
TempBufferVerticesStoredShattered += 3;
|
||||
}
|
||||
}
|
||||
|
||||
WRAPPER void CGlass::Render(void) { EAXJMP(0x502350); }
|
||||
WRAPPER void CGlass::Update(void) { EAXJMP(0x502050); }
|
||||
WRAPPER void CGlass::Init(void) { EAXJMP(0x501F20); }
|
||||
void
|
||||
CGlass::Init(void)
|
||||
{
|
||||
for ( int32 i = 0; i < NUM_GLASSPANES; i++ )
|
||||
aGlassPanes[i].m_bActive = false;
|
||||
|
||||
for ( int32 i = 0; i < NUM_GLASSTRIANGLES; i++ )
|
||||
CentersWithTriangle[i] = (CoorsWithTriangle[i][0] + CoorsWithTriangle[i][1] + CoorsWithTriangle[i][2]) / 3;
|
||||
}
|
||||
|
||||
void
|
||||
CGlass::Update(void)
|
||||
{
|
||||
for ( int32 i = 0; i < NUM_GLASSPANES; i++ )
|
||||
{
|
||||
if ( aGlassPanes[i].m_bActive )
|
||||
aGlassPanes[i].Update();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGlass::Render(void)
|
||||
{
|
||||
TempBufferVerticesStoredHiLight = 0;
|
||||
TempBufferIndicesStoredHiLight = 0;
|
||||
|
||||
TempBufferVerticesStoredShattered = TEMPBUFFERVERTSHATTEREDOFFSET;
|
||||
TempBufferIndicesStoredShattered = TEMPBUFFERINDEXSHATTEREDOFFSET;
|
||||
|
||||
TempBufferVerticesStoredReflection = TEMPBUFFERVERTREFLECTIONOFFSET;
|
||||
TempBufferIndicesStoredReflection = TEMPBUFFERINDEXREFLECTIONOFFSET;
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR);
|
||||
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEFOGCOLOR, (void *)RWRGBALONG(CTimeCycle::GetFogRed(), CTimeCycle::GetFogGreen(), CTimeCycle::GetFogBlue(), 255));
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
|
||||
|
||||
for ( int32 i = 0; i < NUM_GLASSPANES; i++ )
|
||||
{
|
||||
if ( aGlassPanes[i].m_bActive )
|
||||
aGlassPanes[i].Render();
|
||||
}
|
||||
|
||||
for ( uint32 i = 0; i < NumGlassEntities; i++ )
|
||||
RenderEntityInGlass(apEntitiesToBeRendered[i]);
|
||||
|
||||
NumGlassEntities = 0;
|
||||
|
||||
RenderHiLightPolys();
|
||||
RenderShatteredPolys();
|
||||
RenderReflectionPolys();
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)FALSE);
|
||||
}
|
||||
|
||||
CFallingGlassPane *
|
||||
CGlass::FindFreePane(void)
|
||||
{
|
||||
for ( int32 i = 0; i < NUM_GLASSPANES; i++ )
|
||||
{
|
||||
if ( !aGlassPanes[i].m_bActive )
|
||||
return &aGlassPanes[i];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector right, CVector speed, CVector point,
|
||||
float moveSpeed, bool cracked, bool explosion)
|
||||
{
|
||||
float upLen = up.Magnitude();
|
||||
float rightLen = right.Magnitude();
|
||||
|
||||
float upSteps = upLen + 0.75f;
|
||||
if ( upSteps < 1.0f ) upSteps = 1.0f;
|
||||
|
||||
float rightSteps = rightLen + 0.75f;
|
||||
if ( rightSteps < 1.0f ) rightSteps = 1.0f;
|
||||
|
||||
uint32 ysteps = (uint32)upSteps;
|
||||
if ( ysteps > 3 ) ysteps = 3;
|
||||
|
||||
uint32 xsteps = (uint32)rightSteps;
|
||||
if ( xsteps > 3 ) xsteps = 3;
|
||||
|
||||
if ( explosion )
|
||||
{
|
||||
if ( ysteps > 1 ) ysteps = 1;
|
||||
if ( xsteps > 1 ) xsteps = 1;
|
||||
}
|
||||
|
||||
float upScl = upLen / float(ysteps);
|
||||
float rightScl = rightLen / float(xsteps);
|
||||
|
||||
bool bZFound;
|
||||
float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, &bZFound);
|
||||
if ( !bZFound ) groundZ = pos.z - 2.0f;
|
||||
|
||||
for ( uint32 y = 0; y < ysteps; y++ )
|
||||
{
|
||||
for ( uint32 x = 0; x < xsteps; x++ )
|
||||
{
|
||||
float stepy = float(y) * upLen / float(ysteps);
|
||||
float stepx = float(x) * rightLen / float(xsteps);
|
||||
|
||||
for ( int32 i = 0; i < NUM_GLASSTRIANGLES; i++ )
|
||||
{
|
||||
CFallingGlassPane *pane = FindFreePane();
|
||||
if ( pane )
|
||||
{
|
||||
pane->m_nTriIndex = i;
|
||||
|
||||
pane->GetRight() = (right * rightScl) / rightLen;
|
||||
#ifdef FIX_BUGS
|
||||
pane->GetUp() = (up * upScl) / upLen;
|
||||
#else
|
||||
pane->GetUp() = (up * upScl) / rightLen; // copypaste bug
|
||||
#endif
|
||||
CVector fwd = CrossProduct(pane->GetRight(), pane->GetUp());
|
||||
fwd.Normalise();
|
||||
|
||||
pane->GetForward() = fwd;
|
||||
|
||||
pane->GetPosition() = right / rightLen * (rightScl * CentersWithTriangle[i].x + stepx)
|
||||
+ up / upLen * (upScl * CentersWithTriangle[i].y + stepy)
|
||||
+ pos;
|
||||
|
||||
pane->m_vecMoveSpeed.x = float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0015f + speed.x;
|
||||
pane->m_vecMoveSpeed.y = float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0015f + speed.y;
|
||||
pane->m_vecMoveSpeed.z = 0.0f + speed.z;
|
||||
|
||||
if ( moveSpeed != 0.0f )
|
||||
{
|
||||
CVector dist = pane->GetPosition() - point;
|
||||
dist.Normalise();
|
||||
|
||||
pane->m_vecMoveSpeed += moveSpeed * dist;
|
||||
}
|
||||
|
||||
pane->m_vecTurn.x = float((CGeneral::GetRandomNumber() & 127) - 64) * 0.002f;
|
||||
pane->m_vecTurn.y = float((CGeneral::GetRandomNumber() & 127) - 64) * 0.002f;
|
||||
pane->m_vecTurn.z = float((CGeneral::GetRandomNumber() & 127) - 64) * 0.002f;
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case 0:
|
||||
pane->m_nTimer = CTimer::GetTimeInMilliseconds();
|
||||
break;
|
||||
case 1:
|
||||
float dist = (pane->GetPosition() - point).Magnitude();
|
||||
pane->m_nTimer = uint32(dist*100 + CTimer::GetTimeInMilliseconds());
|
||||
break;
|
||||
}
|
||||
|
||||
pane->m_fGroundZ = groundZ;
|
||||
pane->m_bShattered = cracked;
|
||||
pane->m_fStep = upLen / float(ysteps);
|
||||
pane->m_bActive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGlass::AskForObjectToBeRenderedInGlass(CEntity *entity)
|
||||
{
|
||||
#ifdef FIX_BUGS
|
||||
if ( NumGlassEntities < NUM_GLASSPANES )
|
||||
#else
|
||||
if ( NumGlassEntities < NUM_GLASSPANES-1 )
|
||||
#endif
|
||||
{
|
||||
apEntitiesToBeRendered[NumGlassEntities++] = entity;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGlass::RenderEntityInGlass(CEntity *entity)
|
||||
{
|
||||
CObject *object = (CObject *)entity;
|
||||
|
||||
if ( object->bGlassBroken )
|
||||
return;
|
||||
|
||||
float distToCamera = (TheCamera.GetPosition() - object->GetPosition()).Magnitude();
|
||||
|
||||
if ( distToCamera > 40.0f )
|
||||
return;
|
||||
|
||||
CVector fwdNorm = object->GetForward();
|
||||
fwdNorm.Normalise();
|
||||
uint8 alpha = CalcAlphaWithNormal(&fwdNorm);
|
||||
|
||||
CColModel *col = object->GetColModel();
|
||||
|
||||
if ( col->numTriangles >= 2 )
|
||||
{
|
||||
CVector a = object->GetMatrix() * col->vertices[0];
|
||||
CVector b = object->GetMatrix() * col->vertices[1];
|
||||
CVector c = object->GetMatrix() * col->vertices[2];
|
||||
CVector d = object->GetMatrix() * col->vertices[3];
|
||||
|
||||
if ( object->bGlassCracked )
|
||||
{
|
||||
uint8 color = 255;
|
||||
if ( distToCamera > 30.0f )
|
||||
color = int32((1.0f - (distToCamera - 30.0f) * 4.0f / 40.0f) * 255);
|
||||
|
||||
if ( TempBufferIndicesStoredShattered >= TEMPBUFFERINDEXSHATTEREDSIZE-13 || TempBufferVerticesStoredShattered >= TEMPBUFFERVERTSHATTEREDSIZE-5 )
|
||||
RenderShatteredPolys();
|
||||
|
||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], color, color, color, color);
|
||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], color, color, color, color);
|
||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], color, color, color, color);
|
||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 3], color, color, color, color);
|
||||
|
||||
RwIm3DVertexSetU (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], 0.0f);
|
||||
RwIm3DVertexSetV (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], 0.0f);
|
||||
RwIm3DVertexSetU (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], 16.0f);
|
||||
RwIm3DVertexSetV (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], 0.0f);
|
||||
RwIm3DVertexSetU (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], 0.0f);
|
||||
RwIm3DVertexSetV (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], 16.0f);
|
||||
RwIm3DVertexSetU (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 3], 16.0f);
|
||||
RwIm3DVertexSetV (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 3], 16.0f);
|
||||
|
||||
RwIm3DVertexSetPos (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], a.x, a.y, a.z);
|
||||
RwIm3DVertexSetPos (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], b.x, b.y, b.z);
|
||||
RwIm3DVertexSetPos (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], c.x, c.y, c.z);
|
||||
RwIm3DVertexSetPos (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 3], d.x, d.y, d.z);
|
||||
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 0] = col->triangles[0].a + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 1] = col->triangles[0].b + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 2] = col->triangles[0].c + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 3] = col->triangles[1].a + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 4] = col->triangles[1].b + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 5] = col->triangles[1].c + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 6] = col->triangles[0].a + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 7] = col->triangles[0].c + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 8] = col->triangles[0].b + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 9] = col->triangles[1].a + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 10] = col->triangles[1].c + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 11] = col->triangles[1].b + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
|
||||
|
||||
TempBufferIndicesStoredShattered += 12;
|
||||
TempBufferVerticesStoredShattered += 4;
|
||||
}
|
||||
|
||||
if ( TempBufferIndicesStoredReflection >= TEMPBUFFERINDEXREFLECTIONSIZE-13 || TempBufferVerticesStoredReflection >= TEMPBUFFERVERTREFLECTIONSIZE-5 )
|
||||
RenderReflectionPolys();
|
||||
|
||||
uint8 color = 100;
|
||||
if ( distToCamera > 30.0f )
|
||||
color = int32((1.0f - (distToCamera - 30.0f) * 4.0f / 40.0f) * 100);
|
||||
|
||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 0], color, color, color, color);
|
||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 1], color, color, color, color);
|
||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 2], color, color, color, color);
|
||||
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 3], color, color, color, color);
|
||||
|
||||
float FwdAngle = CGeneral::GetATanOfXY(TheCamera.GetForward().x, TheCamera.GetForward().y);
|
||||
float v = 2.0f * TheCamera.GetForward().z * 0.2f;
|
||||
float u = float(object->m_randomSeed & 15) * 0.02f + (FwdAngle / TWOPI);
|
||||
|
||||
RwIm3DVertexSetU (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 0], u);
|
||||
RwIm3DVertexSetV (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 0], v);
|
||||
RwIm3DVertexSetU (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 1], u+0.2f);
|
||||
RwIm3DVertexSetV (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 1], v);
|
||||
RwIm3DVertexSetU (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 2], u);
|
||||
RwIm3DVertexSetV (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 2], v+0.2f);
|
||||
RwIm3DVertexSetU (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 3], u+0.2f);
|
||||
RwIm3DVertexSetV (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 3], v+0.2f);
|
||||
|
||||
RwIm3DVertexSetPos (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 0], a.x, a.y, a.z);
|
||||
RwIm3DVertexSetPos (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 1], b.x, b.y, b.z);
|
||||
RwIm3DVertexSetPos (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 2], c.x, c.y, c.z);
|
||||
RwIm3DVertexSetPos (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 3], d.x, d.y, d.z);
|
||||
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 0] = col->triangles[0].a + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 1] = col->triangles[0].b + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 2] = col->triangles[0].c + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 3] = col->triangles[1].a + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 4] = col->triangles[1].b + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 5] = col->triangles[1].c + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 6] = col->triangles[0].a + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 7] = col->triangles[0].c + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 8] = col->triangles[0].b + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 9] = col->triangles[1].a + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 10] = col->triangles[1].c + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
|
||||
TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 11] = col->triangles[1].b + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
|
||||
|
||||
TempBufferIndicesStoredReflection += 12;
|
||||
TempBufferVerticesStoredReflection += 4;
|
||||
}
|
||||
}
|
||||
|
||||
int32
|
||||
CGlass::CalcAlphaWithNormal(CVector *normal)
|
||||
{
|
||||
float fwdDir = 2.0f * DotProduct(*normal, TheCamera.GetForward());
|
||||
float fwdDot = DotProduct(TheCamera.GetForward()-fwdDir*(*normal), CVector(0.57f, 0.57f, -0.57f));
|
||||
return int32(lerp(fwdDot*fwdDot*fwdDot*fwdDot*fwdDot*fwdDot, 20.0f, 255.0f));
|
||||
}
|
||||
|
||||
void
|
||||
CGlass::RenderHiLightPolys(void)
|
||||
{
|
||||
if ( TempBufferVerticesStoredHiLight != TEMPBUFFERVERTHILIGHTOFFSET )
|
||||
{
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)RwTextureGetRaster(gpShadowExplosionTex));
|
||||
|
||||
LittleTest();
|
||||
|
||||
if ( RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStoredHiLight, nil, rwIM3D_VERTEXUV) )
|
||||
{
|
||||
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStoredHiLight);
|
||||
RwIm3DEnd();
|
||||
}
|
||||
|
||||
TempBufferVerticesStoredHiLight = TEMPBUFFERVERTHILIGHTOFFSET;
|
||||
TempBufferIndicesStoredHiLight = TEMPBUFFERINDEXHILIGHTOFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGlass::RenderShatteredPolys(void)
|
||||
{
|
||||
if ( TempBufferVerticesStoredShattered != TEMPBUFFERVERTSHATTEREDOFFSET )
|
||||
{
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)RwTextureGetRaster(gpCrackedGlassTex));
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
|
||||
|
||||
LittleTest();
|
||||
|
||||
if ( RwIm3DTransform(&TempBufferRenderVertices[TEMPBUFFERVERTSHATTEREDOFFSET], TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET, nil, rwIM3D_VERTEXUV) )
|
||||
{
|
||||
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, &TempBufferRenderIndexList[TEMPBUFFERINDEXSHATTEREDOFFSET], TempBufferIndicesStoredShattered - TEMPBUFFERINDEXSHATTEREDOFFSET);
|
||||
RwIm3DEnd();
|
||||
}
|
||||
|
||||
TempBufferIndicesStoredShattered = TEMPBUFFERINDEXSHATTEREDOFFSET;
|
||||
TempBufferVerticesStoredShattered = TEMPBUFFERVERTSHATTEREDOFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGlass::RenderReflectionPolys(void)
|
||||
{
|
||||
if ( TempBufferVerticesStoredReflection != TEMPBUFFERVERTREFLECTIONOFFSET )
|
||||
{
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)RwTextureGetRaster(gpShadowHeadLightsTex));
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
|
||||
|
||||
LittleTest();
|
||||
|
||||
if ( RwIm3DTransform(&TempBufferRenderVertices[TEMPBUFFERVERTREFLECTIONOFFSET], TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET, nil, rwIM3D_VERTEXUV) )
|
||||
{
|
||||
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, &TempBufferRenderIndexList[TEMPBUFFERINDEXREFLECTIONOFFSET], TempBufferIndicesStoredReflection - TEMPBUFFERINDEXREFLECTIONOFFSET);
|
||||
RwIm3DEnd();
|
||||
}
|
||||
|
||||
TempBufferIndicesStoredReflection = TEMPBUFFERINDEXREFLECTIONOFFSET;
|
||||
TempBufferVerticesStoredReflection = TEMPBUFFERVERTREFLECTIONOFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGlass::WindowRespondsToCollision(CEntity *entity, float amount, CVector speed, CVector point, bool explosion)
|
||||
{
|
||||
CObject *object = (CObject *)entity;
|
||||
|
||||
if ( object->bGlassBroken )
|
||||
return;
|
||||
|
||||
object->bGlassCracked = true;
|
||||
|
||||
CColModel *col = object->GetColModel();
|
||||
|
||||
CVector a = object->GetMatrix() * col->vertices[0];
|
||||
CVector b = object->GetMatrix() * col->vertices[1];
|
||||
CVector c = object->GetMatrix() * col->vertices[2];
|
||||
CVector d = object->GetMatrix() * col->vertices[3];
|
||||
|
||||
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(_SCRSOUND_GLASS_SMASH_1, object->GetPosition());
|
||||
|
||||
GeneratePanesForWindow(0,
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayOneShotScriptObject(_SCRSOUND_GLASS_SMASH_2, 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->GetPosition().z = -100.0f;
|
||||
}
|
||||
|
||||
void
|
||||
CGlass::WindowRespondsToSoftCollision(CEntity *entity, float amount)
|
||||
{
|
||||
CObject *object = (CObject *)entity;
|
||||
|
||||
if ( amount > 50.0f && !object->bGlassCracked )
|
||||
{
|
||||
PlayOneShotScriptObject(_SCRSOUND_GLASS_CRACK, object->GetPosition());
|
||||
object->bGlassCracked = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGlass::WasGlassHitByBullet(CEntity *entity, CVector point)
|
||||
{
|
||||
CObject *object = (CObject *)entity;
|
||||
|
||||
if ( IsGlass(object->GetModelIndex()) )
|
||||
{
|
||||
if ( !object->bGlassCracked )
|
||||
{
|
||||
PlayOneShotScriptObject(_SCRSOUND_GLASS_CRACK, object->GetPosition());
|
||||
object->bGlassCracked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (CGeneral::GetRandomNumber() & 3) == 2 )
|
||||
WindowRespondsToCollision(object, 0.0f, CVector(0.0f, 0.0f, 0.0f), point, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGlass::WindowRespondsToExplosion(CEntity *entity, CVector point)
|
||||
{
|
||||
CObject *object = (CObject *)entity;
|
||||
|
||||
CVector distToGlass = object->GetPosition() - point;
|
||||
|
||||
float fDistToGlass = distToGlass.Magnitude();
|
||||
|
||||
if ( fDistToGlass < 10.0f )
|
||||
{
|
||||
distToGlass.Normalise(0.3f);
|
||||
WindowRespondsToCollision(object, 10000.0f, distToGlass, object->GetPosition(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fDistToGlass < 30.0f )
|
||||
object->bGlassCracked = true;
|
||||
}
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x501F20, CGlass::Init, PATCH_JUMP);
|
||||
InjectHook(0x502050, CGlass::Update, PATCH_JUMP);
|
||||
InjectHook(0x502080, &CFallingGlassPane::Update, PATCH_JUMP);
|
||||
InjectHook(0x502350, CGlass::Render, PATCH_JUMP);
|
||||
InjectHook(0x502490, CGlass::FindFreePane, PATCH_JUMP);
|
||||
InjectHook(0x5024C0, &CFallingGlassPane::Render, PATCH_JUMP);
|
||||
InjectHook(0x502AC0, CGlass::GeneratePanesForWindow, PATCH_JUMP);
|
||||
InjectHook(0x5033F0, CGlass::AskForObjectToBeRenderedInGlass, PATCH_JUMP);
|
||||
InjectHook(0x503420, CGlass::RenderEntityInGlass, PATCH_JUMP);
|
||||
InjectHook(0x503C90, CGlass::CalcAlphaWithNormal, PATCH_JUMP);
|
||||
InjectHook(0x503D60, CGlass::RenderHiLightPolys, PATCH_JUMP);
|
||||
InjectHook(0x503DE0, CGlass::RenderShatteredPolys, PATCH_JUMP);
|
||||
InjectHook(0x503E70, CGlass::RenderReflectionPolys, PATCH_JUMP);
|
||||
InjectHook(0x503F10, CGlass::WindowRespondsToCollision, PATCH_JUMP);
|
||||
InjectHook(0x504630, CGlass::WindowRespondsToSoftCollision, PATCH_JUMP);
|
||||
InjectHook(0x504670, CGlass::WasGlassHitByBullet, PATCH_JUMP);
|
||||
InjectHook(0x504790, CGlass::WindowRespondsToExplosion, PATCH_JUMP);
|
||||
//InjectHook(0x504880, `global constructor keyed to'glass.cpp, PATCH_JUMP);
|
||||
//InjectHook(0x5048D0, CFallingGlassPane::~CFallingGlassPane, PATCH_JUMP);
|
||||
//InjectHook(0x5048E0, CFallingGlassPane::CFallingGlassPane, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
|
|
@ -2,13 +2,52 @@
|
|||
|
||||
class CEntity;
|
||||
|
||||
class CGlass
|
||||
class CFallingGlassPane : public CMatrix
|
||||
{
|
||||
public:
|
||||
static void AskForObjectToBeRenderedInGlass(CEntity *ent);
|
||||
static void WindowRespondsToCollision(CEntity *ent, float amount, CVector speed, CVector point, bool foo);
|
||||
static void WindowRespondsToSoftCollision(CEntity *ent, float amount);
|
||||
static void Render(void);
|
||||
static void Update(void);
|
||||
static void Init(void);
|
||||
CVector m_vecMoveSpeed;
|
||||
CVector m_vecTurn;
|
||||
uint32 m_nTimer;
|
||||
float m_fGroundZ;
|
||||
float m_fStep;
|
||||
uint8 m_nTriIndex;
|
||||
bool m_bActive;
|
||||
bool m_bShattered;
|
||||
char _pad0[1];
|
||||
|
||||
CFallingGlassPane() { }
|
||||
~CFallingGlassPane() { }
|
||||
|
||||
void Update(void);
|
||||
void Render(void);
|
||||
};
|
||||
|
||||
VALIDATE_SIZE(CFallingGlassPane, 0x70);
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_GLASSTRIANGLES = 5,
|
||||
};
|
||||
|
||||
class CGlass
|
||||
{
|
||||
static uint32 NumGlassEntities;
|
||||
static CEntity *apEntitiesToBeRendered[NUM_GLASSENTITIES];
|
||||
static CFallingGlassPane aGlassPanes[NUM_GLASSPANES];
|
||||
public:
|
||||
static void Init(void);
|
||||
static void Update(void);
|
||||
static void Render(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 AskForObjectToBeRenderedInGlass(CEntity *entity);
|
||||
static void RenderEntityInGlass(CEntity *entity);
|
||||
static int32 CalcAlphaWithNormal(CVector *normal);
|
||||
static void RenderHiLightPolys(void);
|
||||
static void RenderShatteredPolys(void);
|
||||
static void RenderReflectionPolys(void);
|
||||
static void WindowRespondsToCollision(CEntity *entity, float amount, CVector speed, CVector point, bool explosion);
|
||||
static void WindowRespondsToSoftCollision(CEntity *entity, float amount);
|
||||
static void WasGlassHitByBullet(CEntity *entity, CVector point);
|
||||
static void WindowRespondsToExplosion(CEntity *entity, CVector point);
|
||||
};
|
|
@ -793,8 +793,11 @@ void CHud::Draw()
|
|||
if (m_ItemToFlash == ITEM_RADAR && CTimer::GetFrameCounter() & 8 || m_ItemToFlash != ITEM_RADAR) {
|
||||
CRadar::DrawMap();
|
||||
CRect rect(0.0f, 0.0f, SCREEN_SCALE_X(RADAR_WIDTH), SCREEN_SCALE_Y(RADAR_HEIGHT));
|
||||
// FIX? scale RADAR_LEFT here somehow
|
||||
#ifdef FIX_BUGS
|
||||
rect.Translate(SCREEN_SCALE_X(RADAR_LEFT), SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT));
|
||||
#else
|
||||
rect.Translate(RADAR_LEFT, SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT));
|
||||
#endif
|
||||
rect.Grow(4.0f);
|
||||
Sprites[HUD_RADARDISC].Draw(rect, CRGBA(0, 0, 0, 255));
|
||||
CRadar::DrawBlips();
|
||||
|
@ -1094,7 +1097,6 @@ void CHud::DrawAfterFade()
|
|||
CFont::SetColor(CRGBA(175, 175, 175, 255));
|
||||
CFont::PrintString(SCREEN_SCALE_X(26.0f), SCREEN_SCALE_Y(28.0f + (150.0f - PagerXOffset) * 0.6f), CHud::m_HelpMessageToPrint);
|
||||
CFont::SetAlphaFade(255.0f);
|
||||
CFont::DrawFonts();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -182,3 +182,4 @@ extern RwTexture *&gpGoalTex;
|
|||
extern RwTexture *&gpOutline1Tex;
|
||||
extern RwTexture *&gpOutline2Tex;
|
||||
extern RwTexture *&gpOutline3Tex;
|
||||
extern RwTexture *&gpCrackedGlassTex;
|
||||
|
|
|
@ -31,10 +31,17 @@ void *CVehicle::operator new(size_t sz, int handle) { return CPools::GetVehicleP
|
|||
void CVehicle::operator delete(void *p, size_t sz) { CPools::GetVehiclePool()->Delete((CVehicle*)p); }
|
||||
void CVehicle::operator delete(void *p, int handle) { CPools::GetVehiclePool()->Delete((CVehicle*)p); }
|
||||
|
||||
WRAPPER bool CVehicle::ShufflePassengersToMakeSpace(void) { EAXJMP(0x5528A0); }
|
||||
// or Weapon.cpp?
|
||||
WRAPPER void FireOneInstantHitRound(CVector *shotSource, CVector *shotTarget, int32 damage) { EAXJMP(0x563B00); }
|
||||
WRAPPER void CVehicle::InflictDamage(CEntity *damagedBy, uint32 weaponType, float damage) { EAXJMP(0x551950); }
|
||||
#ifdef FIX_BUGS
|
||||
// I think they meant that
|
||||
#define DAMAGE_FLEE_IN_CAR_PROBABILITY_VALUE (MYRAND_MAX * 35 / 100)
|
||||
#define DAMAGE_FLEE_ON_FOOT_PROBABILITY_VALUE (MYRAND_MAX * 70 / 100)
|
||||
#else
|
||||
#define DAMAGE_FLEE_IN_CAR_PROBABILITY_VALUE (35000)
|
||||
#define DAMAGE_FLEE_ON_FOOT_PROBABILITY_VALUE (70000)
|
||||
#endif
|
||||
#define DAMAGE_HEALTH_TO_FLEE_ALWAYS (200.0f)
|
||||
#define DAMAGE_HEALTH_TO_CATCH_FIRE (250.0f)
|
||||
|
||||
|
||||
CVehicle::CVehicle(uint8 CreatedBy)
|
||||
{
|
||||
|
@ -361,6 +368,119 @@ CVehicle::ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVec
|
|||
return angularVelocity * CTimer::GetTimeStep();
|
||||
}
|
||||
|
||||
void
|
||||
CVehicle::InflictDamage(CEntity* damagedBy, eWeaponType weaponType, float damage)
|
||||
{
|
||||
if (!bCanBeDamaged)
|
||||
return;
|
||||
if (bOnlyDamagedByPlayer && (damagedBy != FindPlayerPed() && damagedBy != FindPlayerVehicle()))
|
||||
return;
|
||||
bool bFrightensDriver = false;
|
||||
switch (weaponType) {
|
||||
case WEAPONTYPE_UNARMED:
|
||||
case WEAPONTYPE_BASEBALLBAT:
|
||||
if (bMeleeProof)
|
||||
return;
|
||||
break;
|
||||
case WEAPONTYPE_COLT45:
|
||||
case WEAPONTYPE_UZI:
|
||||
case WEAPONTYPE_SHOTGUN:
|
||||
case WEAPONTYPE_AK47:
|
||||
case WEAPONTYPE_M16:
|
||||
case WEAPONTYPE_SNIPERRIFLE:
|
||||
case WEAPONTYPE_TOTAL_INVENTORY_WEAPONS:
|
||||
case WEAPONTYPE_UZI_DRIVEBY:
|
||||
if (bBulletProof)
|
||||
return;
|
||||
bFrightensDriver = true;
|
||||
break;
|
||||
case WEAPONTYPE_ROCKETLAUNCHER:
|
||||
case WEAPONTYPE_MOLOTOV:
|
||||
case WEAPONTYPE_GRENADE:
|
||||
case WEAPONTYPE_EXPLOSION:
|
||||
if (bExplosionProof)
|
||||
return;
|
||||
bFrightensDriver = true;
|
||||
break;
|
||||
case WEAPONTYPE_FLAMETHROWER:
|
||||
if (bFireProof)
|
||||
return;
|
||||
break;
|
||||
case WEAPONTYPE_RAMMEDBYCAR:
|
||||
if (bCollisionProof)
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (m_fHealth > 0.0f) {
|
||||
if (VehicleCreatedBy == RANDOM_VEHICLE && pDriver &&
|
||||
(m_status == STATUS_SIMPLE || m_status == STATUS_PHYSICS) &&
|
||||
AutoPilot.m_nCarMission == MISSION_CRUISE) {
|
||||
if (m_randomSeed < DAMAGE_FLEE_IN_CAR_PROBABILITY_VALUE) {
|
||||
CCarCtrl::SwitchVehicleToRealPhysics(this);
|
||||
AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
|
||||
AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * pHandling->Transmission.fUnkMaxVelocity;
|
||||
m_status = STATUS_PHYSICS;
|
||||
}
|
||||
}
|
||||
m_nLastWeaponDamage = weaponType;
|
||||
float oldHealth = m_fHealth;
|
||||
if (m_fHealth > damage) {
|
||||
m_fHealth -= damage;
|
||||
if (VehicleCreatedBy == RANDOM_VEHICLE &&
|
||||
(m_fHealth < DAMAGE_HEALTH_TO_FLEE_ALWAYS ||
|
||||
bFrightensDriver && m_randomSeed > DAMAGE_FLEE_ON_FOOT_PROBABILITY_VALUE)) {
|
||||
switch (m_status) {
|
||||
case STATUS_SIMPLE:
|
||||
case STATUS_PHYSICS:
|
||||
if (pDriver) {
|
||||
m_status = STATUS_ABANDONED;
|
||||
pDriver->bFleeAfterExitingCar = true;
|
||||
pDriver->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this);
|
||||
}
|
||||
for (int i = 0; i < m_nNumMaxPassengers; i++) {
|
||||
if (pPassengers[i]) {
|
||||
pPassengers[i]->bFleeAfterExitingCar = true;
|
||||
pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (oldHealth > DAMAGE_HEALTH_TO_CATCH_FIRE && m_fHealth < DAMAGE_HEALTH_TO_CATCH_FIRE) {
|
||||
if (IsCar()) {
|
||||
CAutomobile* pThisCar = (CAutomobile*)this;
|
||||
pThisCar->Damage.SetEngineStatus(ENGINE_STATUS_ON_FIRE);
|
||||
pThisCar->m_pSetOnFireEntity = damagedBy;
|
||||
if (damagedBy)
|
||||
damagedBy->RegisterReference((CEntity**)&pThisCar->m_pSetOnFireEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_fHealth = 0.0f;
|
||||
if (weaponType == WEAPONTYPE_EXPLOSION) {
|
||||
// between 1000 and 3047. Also not very nice: can't be saved by respray or cheat
|
||||
m_nBombTimer = 1000 + CGeneral::GetRandomNumber() & 0x7FF;
|
||||
m_pBlowUpEntity = damagedBy;
|
||||
if (damagedBy)
|
||||
damagedBy->RegisterReference((CEntity**)&m_pBlowUpEntity);
|
||||
}
|
||||
else
|
||||
BlowUpCar(damagedBy);
|
||||
}
|
||||
}
|
||||
#ifdef FIX_BUGS // removing dumb case when shooting police car in player's own garage gives wanted level
|
||||
if (GetModelIndex() == MI_POLICE && damagedBy == FindPlayerPed() && !bHasBeenOwnedByPlayer)
|
||||
#else
|
||||
if (GetModelIndex() == MI_POLICE && damagedBy == FindPlayerPed())
|
||||
#endif
|
||||
FindPlayerPed()->SetWantedLevelNoDrop(1);
|
||||
}
|
||||
|
||||
void
|
||||
CVehicle::ExtinguishCarFire(void)
|
||||
{
|
||||
|
@ -375,6 +495,65 @@ CVehicle::ExtinguishCarFire(void)
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CVehicle::ShufflePassengersToMakeSpace(void)
|
||||
{
|
||||
if (m_nNumPassengers >= m_nNumMaxPassengers)
|
||||
return false;
|
||||
if (pPassengers[1] &&
|
||||
!(m_nGettingInFlags & CAR_DOOR_FLAG_LR) &&
|
||||
IsRoomForPedToLeaveCar(COMPONENT_DOOR_REAR_LEFT, nil)) {
|
||||
if (!pPassengers[2] && !(m_nGettingInFlags & CAR_DOOR_FLAG_RR)) {
|
||||
pPassengers[2] = pPassengers[1];
|
||||
pPassengers[1] = nil;
|
||||
pPassengers[2]->m_vehEnterType = CAR_DOOR_RR;
|
||||
return true;
|
||||
}
|
||||
if (!pPassengers[0] && !(m_nGettingInFlags & CAR_DOOR_FLAG_RF)) {
|
||||
pPassengers[0] = pPassengers[1];
|
||||
pPassengers[1] = nil;
|
||||
pPassengers[0]->m_vehEnterType = CAR_DOOR_RF;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (pPassengers[2] &&
|
||||
!(m_nGettingInFlags & CAR_DOOR_FLAG_RR) &&
|
||||
IsRoomForPedToLeaveCar(COMPONENT_DOOR_REAR_RIGHT, nil)) {
|
||||
if (!pPassengers[1] && !(m_nGettingInFlags & CAR_DOOR_FLAG_LR)) {
|
||||
pPassengers[1] = pPassengers[2];
|
||||
pPassengers[2] = nil;
|
||||
pPassengers[1]->m_vehEnterType = CAR_DOOR_LR;
|
||||
return true;
|
||||
}
|
||||
if (!pPassengers[0] && !(m_nGettingInFlags & CAR_DOOR_FLAG_RF)) {
|
||||
pPassengers[0] = pPassengers[2];
|
||||
pPassengers[2] = nil;
|
||||
pPassengers[0]->m_vehEnterType = CAR_DOOR_RF;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (pPassengers[0] &&
|
||||
!(m_nGettingInFlags & CAR_DOOR_FLAG_RF) &&
|
||||
IsRoomForPedToLeaveCar(COMPONENT_DOOR_FRONT_RIGHT, nil)) {
|
||||
if (!pPassengers[1] && !(m_nGettingInFlags & CAR_DOOR_FLAG_LR)) {
|
||||
pPassengers[1] = pPassengers[0];
|
||||
pPassengers[0] = nil;
|
||||
pPassengers[1]->m_vehEnterType = CAR_DOOR_LR;
|
||||
return true;
|
||||
}
|
||||
if (!pPassengers[2] && !(m_nGettingInFlags & CAR_DOOR_FLAG_RR)) {
|
||||
pPassengers[2] = pPassengers[0];
|
||||
pPassengers[0] = nil;
|
||||
pPassengers[2]->m_vehEnterType = CAR_DOOR_RR;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CVehicle::ProcessDelayedExplosion(void)
|
||||
{
|
||||
|
@ -831,4 +1010,5 @@ STARTPATCHES
|
|||
InjectHook(0x551EB0, &CVehicle::RemovePassenger, PATCH_JUMP);
|
||||
InjectHook(0x5525A0, &CVehicle::ProcessCarAlarm, PATCH_JUMP);
|
||||
InjectHook(0x552620, &CVehicle::IsSphereTouchingVehicle, PATCH_JUMP);
|
||||
InjectHook(0x551950, &CVehicle::InflictDamage, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "AutoPilot.h"
|
||||
#include "ModelIndices.h"
|
||||
#include "AnimManager.h"
|
||||
#include "Weapon.h"
|
||||
|
||||
class CPed;
|
||||
class CFire;
|
||||
|
@ -266,7 +267,7 @@ public:
|
|||
void ProcessCarAlarm(void);
|
||||
bool IsSphereTouchingVehicle(float sx, float sy, float sz, float radius);
|
||||
bool ShufflePassengersToMakeSpace(void);
|
||||
void InflictDamage(CEntity *damagedBy, uint32 weaponType, float damage);
|
||||
void InflictDamage(CEntity *damagedBy, eWeaponType weaponType, float damage);
|
||||
|
||||
bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1; }
|
||||
CVehicleModelInfo* GetModelInfo() { return (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); }
|
||||
|
|
|
@ -14,6 +14,7 @@ WRAPPER void CWeapon::AddGunshell(CEntity*, CVector const&, CVector2D const&, fl
|
|||
WRAPPER void CWeapon::Update(int32 audioEntity) { EAXJMP(0x563A10); }
|
||||
WRAPPER void CWeapon::DoTankDoomAiming(CEntity *playerVehicle, CEntity *playerPed, CVector *start, CVector *end) { EAXJMP(0x563200); }
|
||||
WRAPPER void CWeapon::InitialiseWeapons(void) { EAXJMP(0x55C2D0); }
|
||||
WRAPPER void FireOneInstantHitRound(CVector* shotSource, CVector* shotTarget, int32 damage) { EAXJMP(0x563B00); }
|
||||
|
||||
void
|
||||
CWeapon::Initialise(eWeaponType type, int ammo)
|
||||
|
|
|
@ -81,3 +81,5 @@ public:
|
|||
static void UpdateWeapons(void);
|
||||
};
|
||||
static_assert(sizeof(CWeapon) == 0x18, "CWeapon: error");
|
||||
|
||||
void FireOneInstantHitRound(CVector* shotSource, CVector* shotTarget, int32 damage);
|
Loading…
Reference in New Issue