Merge branch 'master' into garages_dev
This commit is contained in:
commit
be260b49b1
11
README.md
11
README.md
@ -16,12 +16,6 @@ such that we have a working game at all times.
|
||||
- Since re3 is a DLL that works with original GTA III for now, you need Simple DLL Loader. You can get it [here](https://github.com/aap/simpledllloader).
|
||||
- Build re3 or download it from one of the above links (Debug or Release).
|
||||
- Make sure you included the re3 in `plugins.cfg` or `dlls.cfg`.
|
||||
- re3 starts the script `main_freeroam.scm` that comes along with it by default, so you should copy it to from `gamefiles/` to your game's `data/` directory.
|
||||
|
||||
![#ffa500](https://placehold.it/15/ffa500/000000?text=+) **Notice**
|
||||
|
||||
If you want to load original script/story, press and hold G while game is loading.
|
||||
This includes both starting new game and loading save game.
|
||||
|
||||
![#ffa500](https://placehold.it/15/ffa500/000000?text=+) **Notice if you will build it**
|
||||
|
||||
@ -41,21 +35,16 @@ to reverse at the time, calling the original functions is acceptable.
|
||||
cAudioManager - WIP
|
||||
CBoat
|
||||
CBulletInfo
|
||||
CExplosion
|
||||
CMenuManager - WIP
|
||||
CObject
|
||||
CPacManPickups
|
||||
CPad - only cheats
|
||||
CPedPath
|
||||
CPools - save/loading
|
||||
CRecordDataForChase
|
||||
CRecordDataForGame
|
||||
CRoadBlocks
|
||||
CSkidmarks
|
||||
CStats
|
||||
CTrafficLights
|
||||
CWeapon
|
||||
CWeather
|
||||
CWorld
|
||||
GenericLoad
|
||||
```
|
||||
|
@ -134,8 +134,8 @@ uint32 &CCutsceneMgr::ms_cutsceneLoadStatus = *(uint32*)0x95CB40;
|
||||
RpAtomic *
|
||||
CalculateBoundingSphereRadiusCB(RpAtomic *atomic, void *data)
|
||||
{
|
||||
float radius = RpAtomicGetBoundingSphereMacro(atomic)->radius;
|
||||
RwV3d center = RpAtomicGetBoundingSphereMacro(atomic)->center;
|
||||
float radius = RpAtomicGetBoundingSphere(atomic)->radius;
|
||||
RwV3d center = RpAtomicGetBoundingSphere(atomic)->center;
|
||||
|
||||
for (RwFrame *frame = RpAtomicGetFrame(atomic); RwFrameGetParent(frame); frame = RwFrameGetParent(frame))
|
||||
RwV3dTransformPoints(¢er, ¢er, 1, RwFrameGetMatrix(frame));
|
||||
@ -326,7 +326,7 @@ CCutsceneMgr::CreateCutsceneObject(int modelId)
|
||||
|
||||
pModelInfo->SetColModel(pColModel);
|
||||
clump = (RpClump*)pModelInfo->GetRwObject();
|
||||
assert(RwObjectGetType(clump) == rpCLUMP);
|
||||
assert(RwObjectGetType((RwObject*)clump) == rpCLUMP);
|
||||
RpClumpForAllAtomics(clump, CalculateBoundingSphereRadiusCB, &radius);
|
||||
|
||||
pColModel->boundingSphere.radius = radius;
|
||||
@ -352,6 +352,7 @@ CCutsceneMgr::DeleteCutsceneData(void)
|
||||
CWorld::Remove(ms_pCutsceneObjects[ms_numCutsceneObjs]);
|
||||
ms_pCutsceneObjects[ms_numCutsceneObjs]->DeleteRwObject();
|
||||
delete ms_pCutsceneObjects[ms_numCutsceneObjs];
|
||||
ms_pCutsceneObjects[ms_numCutsceneObjs] = nil;
|
||||
}
|
||||
ms_numCutsceneObjs = 0;
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
static CDirectory *&ms_pCutsceneDir;
|
||||
static uint32 &ms_cutsceneLoadStatus;
|
||||
|
||||
static void SetRunning(bool running) { ms_running = running; }
|
||||
static void StartCutsceneProcessing() { ms_cutsceneProcessing = true; }
|
||||
static bool IsRunning(void) { return ms_running; }
|
||||
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
|
||||
static bool UseLodMultiplier(void) { return ms_useLodMultiplier; }
|
@ -1,403 +1,403 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "DMAudio.h"
|
||||
#include "Entity.h"
|
||||
#include "AudioCollision.h"
|
||||
#include "AudioManager.h"
|
||||
#include "AudioSamples.h"
|
||||
#include "SurfaceTable.h"
|
||||
#include "sampman.h"
|
||||
|
||||
const int CollisionSoundIntensity = 60;
|
||||
|
||||
void
|
||||
cAudioCollisionManager::AddCollisionToRequestedQueue()
|
||||
{
|
||||
int32 collisionsIndex;
|
||||
int32 i;
|
||||
|
||||
|
||||
if (m_bCollisionsInQueue < NUMAUDIOCOLLISIONS)
|
||||
collisionsIndex = m_bCollisionsInQueue++;
|
||||
else {
|
||||
collisionsIndex = m_bIndicesTable[NUMAUDIOCOLLISIONS - 1];
|
||||
if (m_sQueue.m_fDistance >= m_asCollisions1[collisionsIndex].m_fDistance) return;
|
||||
}
|
||||
|
||||
m_asCollisions1[collisionsIndex] = m_sQueue;
|
||||
|
||||
i = 0;
|
||||
if(collisionsIndex) {
|
||||
while(m_asCollisions1[m_bIndicesTable[i]].m_fDistance <= m_asCollisions1[collisionsIndex].m_fDistance) {
|
||||
if(++i >= collisionsIndex) {
|
||||
m_bIndicesTable[i] = collisionsIndex;
|
||||
return;
|
||||
}
|
||||
}
|
||||
memmove(&m_bIndicesTable[i + 1], &m_bIndicesTable[i], NUMAUDIOCOLLISIONS - 1 - i);
|
||||
}
|
||||
m_bIndicesTable[i] = collisionsIndex;
|
||||
}
|
||||
|
||||
float
|
||||
cAudioManager::GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const
|
||||
{
|
||||
return GetCollisionRatio(c, 0.0f, 0.02f, 0.02f);
|
||||
}
|
||||
|
||||
float
|
||||
cAudioManager::GetCollisionOneShotRatio(int32 a, float b) const
|
||||
{
|
||||
float result;
|
||||
|
||||
switch(a) {
|
||||
case SURFACE_DEFAULT:
|
||||
case SURFACE_TARMAC:
|
||||
case SURFACE_PAVEMENT:
|
||||
case SURFACE_STONE:
|
||||
case SURFACE_BOLLARD: result = GetCollisionRatio(b, 10.f, 60.f, 50.f); break;
|
||||
case SURFACE_GRASS:
|
||||
case SURFACE_LOOSE30: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
|
||||
case SURFACE_DIRT: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
|
||||
case SURFACE_DIRTTRACK: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
|
||||
case SURFACE_METAL6: result = GetCollisionRatio(b, 6.f, 50.f, 44.f); break;
|
||||
case SURFACE_GLASS: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break;
|
||||
case SURFACE_SCAFFOLD:
|
||||
case SURFACE_STEEL: result = GetCollisionRatio(b, 30.f, 130.f, 100.f); break;
|
||||
case SURFACE_METAL_DOOR: result = GetCollisionRatio(b, 20.f, 100.f, 80.f); break;
|
||||
case SURFACE_BILLBOARD: result = GetCollisionRatio(b, 0.f, 4.f, 4.f); break;
|
||||
case SURFACE_METAL_POLE:
|
||||
case SURFACE_GATE: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break;
|
||||
case SURFACE_STREET_LIGHT: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break;
|
||||
case SURFACE_METAL14: result = GetCollisionRatio(b, 1.f, 15.f, 14.f); break;
|
||||
case SURFACE_METAL15: result = GetCollisionRatio(b, 8.f, 50.f, 42.f); break;
|
||||
case SURFACE_METAL_FENCE: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break;
|
||||
case SURFACE_FLESH: result = GetCollisionRatio(b, 0.f, 20.f, 20.f); break;
|
||||
case SURFACE_SAND: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
|
||||
case SURFACE_PUDDLE: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
|
||||
case SURFACE_WOOD: result = GetCollisionRatio(b, 1.f, 4.f, 3.f); break;
|
||||
case SURFACE_WOOD_BOX: result = GetCollisionRatio(b, 0.1f, 5.f, 4.9f); break;
|
||||
case SURFACE_WOOD_PLANK: result = GetCollisionRatio(b, 0.1f, 40.f, 39.9f); break;
|
||||
case SURFACE_TIRE:
|
||||
case SURFACE_RUBBER29: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
|
||||
case SURFACE_HARD24: result = GetCollisionRatio(b, 0.1f, 4.f, 3.9f); break;
|
||||
case SURFACE_HEDGE: result = GetCollisionRatio(b, 0.f, 0.5f, 0.5f); break;
|
||||
case SURFACE_METAL27: result = GetCollisionRatio(b, 4.f, 40.f, 36.f); break;
|
||||
case SURFACE_METAL28: result = GetCollisionRatio(b, 0.f, 5.f, 5.f); break;
|
||||
default: result = 0.f; break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float
|
||||
cAudioManager::GetCollisionRatio(float a, float b, float c, float d) const
|
||||
{
|
||||
float e;
|
||||
e = a;
|
||||
if(a <= b) return 0.0f;
|
||||
if(c <= a) e = c;
|
||||
return (e - b) / d;
|
||||
}
|
||||
|
||||
uint32
|
||||
cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(cAudioCollision *audioCollision)
|
||||
{
|
||||
uint8 surface1 = audioCollision->m_bSurface1;
|
||||
uint8 surface2 = audioCollision->m_bSurface2;
|
||||
int32 vol;
|
||||
float ratio;
|
||||
|
||||
if(surface1 == SURFACE_GRASS || surface2 == SURFACE_GRASS || surface1 == SURFACE_HEDGE ||
|
||||
surface2 == SURFACE_HEDGE) {
|
||||
ratio = GetCollisionRatio(audioCollision->m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
|
||||
m_sQueueSample.m_nSampleIndex = SFX_RAIN;
|
||||
m_sQueueSample.m_nFrequency = 13000.f * ratio + 35000;
|
||||
vol = 50.f * ratio;
|
||||
} else {
|
||||
if(surface1 == SURFACE_PUDDLE || surface2 == SURFACE_PUDDLE) {
|
||||
ratio = GetCollisionRatio(audioCollision->m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
|
||||
m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP;
|
||||
m_sQueueSample.m_nFrequency = 6050.f * ratio + 16000;
|
||||
vol = 30.f * ratio;
|
||||
|
||||
} else {
|
||||
if(surface1 == SURFACE_DIRT || surface2 == SURFACE_DIRT || surface1 == SURFACE_DIRTTRACK ||
|
||||
surface2 == SURFACE_DIRTTRACK || surface1 == SURFACE_SAND || surface2 == SURFACE_SAND) {
|
||||
ratio = GetCollisionRatio(audioCollision->m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
|
||||
m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID;
|
||||
m_sQueueSample.m_nFrequency = 6000.f * ratio + 10000;
|
||||
vol = 50.f * ratio;
|
||||
} else {
|
||||
if(surface1 == SURFACE_FLESH || surface2 == SURFACE_FLESH) { return 0; }
|
||||
ratio = GetCollisionRatio(audioCollision->m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
|
||||
m_sQueueSample.m_nSampleIndex = SFX_SCRAPE_CAR_1;
|
||||
m_sQueueSample.m_nFrequency = 10000.f * ratio + 10000;
|
||||
vol = 40.f * ratio;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(audioCollision->m_nBaseVolume < 2) vol = audioCollision->m_nBaseVolume * vol / 2;
|
||||
return vol;
|
||||
}
|
||||
|
||||
void
|
||||
cAudioManager::SetUpLoopingCollisionSound(cAudioCollision *col, uint8 counter)
|
||||
{
|
||||
if(col->m_fIntensity2 > 0.0016f) {
|
||||
uint8 emittingVol = SetLoopingCollisionRequestedSfxFreqAndGetVol(col);
|
||||
if(emittingVol) {
|
||||
m_sQueueSample.m_fDistance = Sqrt(col->m_fDistance);
|
||||
m_sQueueSample.m_bVolume =
|
||||
ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
|
||||
if(m_sQueueSample.m_bVolume) {
|
||||
m_sQueueSample.m_counter = counter;
|
||||
m_sQueueSample.m_vecPos = col->m_vecPosition;
|
||||
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
|
||||
m_sQueueSample.m_bIs2D = false;
|
||||
m_sQueueSample.m_nReleasingVolumeModificator = 7;
|
||||
m_sQueueSample.m_nLoopCount = 0;
|
||||
m_sQueueSample.m_bEmittingVolume = emittingVol;
|
||||
m_sQueueSample.m_nLoopStart =
|
||||
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
|
||||
m_sQueueSample.m_nLoopEnd =
|
||||
SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
|
||||
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
|
||||
m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity;
|
||||
m_sQueueSample.m_bReleasingSoundFlag = 0;
|
||||
m_sQueueSample.m_nReleasingVolumeDivider = 5;
|
||||
m_sQueueSample.m_bReverbFlag = true;
|
||||
m_sQueueSample.m_bRequireReflection = false;
|
||||
AddSampleToRequestedQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cAudioManager::SetUpOneShotCollisionSound(cAudioCollision *col)
|
||||
{
|
||||
static const int32 gOneShotCol[] = {
|
||||
SFX_COL_TARMAC_1, SFX_COL_TARMAC_1, SFX_COL_GRASS_1,
|
||||
SFX_COL_GRAVEL_1, SFX_COL_MUD_1, SFX_COL_TARMAC_1,
|
||||
SFX_COL_CAR_1, SFX_COL_GRASS_1, SFX_COL_SCAFFOLD_POLE_1,
|
||||
SFX_COL_GARAGE_DOOR_1, SFX_COL_CAR_PANEL_1, SFX_COL_THICK_METAL_PLATE_1,
|
||||
SFX_COL_SCAFFOLD_POLE_1, SFX_COL_LAMP_POST_1, SFX_COL_HYDRANT_1,
|
||||
SFX_COL_HYDRANT_1, SFX_COL_METAL_CHAIN_FENCE_1, SFX_COL_PED_1,
|
||||
SFX_COL_SAND_1, SFX_SPLASH_1, SFX_COL_WOOD_CRATES_1,
|
||||
SFX_COL_WOOD_BENCH_1, SFX_COL_WOOD_SOLID_1, SFX_COL_GRASS_1,
|
||||
SFX_COL_GRASS_1, SFX_COL_VEG_1, SFX_COL_TARMAC_1,
|
||||
SFX_COL_CONTAINER_1, SFX_COL_NEWS_VENDOR_1, SFX_TYRE_BUMP,
|
||||
SFX_COL_CARDBOARD_1, SFX_COL_TARMAC_1, SFX_COL_GATE};
|
||||
|
||||
int16 s1;
|
||||
int16 s2;
|
||||
|
||||
int32 emittingVol;
|
||||
float ratio;
|
||||
|
||||
static uint16 counter = 28;
|
||||
|
||||
for(int32 i = 0; i < 2; i++) {
|
||||
if(i) {
|
||||
s1 = col->m_bSurface2;
|
||||
s2 = col->m_bSurface1;
|
||||
} else {
|
||||
s1 = col->m_bSurface1;
|
||||
s2 = col->m_bSurface2;
|
||||
}
|
||||
ratio = GetCollisionOneShotRatio(s1, col->m_fIntensity1);
|
||||
if(s1 == SURFACE_METAL6 && s2 == SURFACE_FLESH) ratio = 0.25f * ratio;
|
||||
if(s1 == SURFACE_METAL6 && ratio < 0.6f) {
|
||||
s1 = SURFACE_BILLBOARD;
|
||||
ratio = min(1.f, 2.f * ratio);
|
||||
}
|
||||
emittingVol = 40.f * ratio;
|
||||
if(emittingVol) {
|
||||
m_sQueueSample.m_fDistance = Sqrt(col->m_fDistance);
|
||||
m_sQueueSample.m_bVolume =
|
||||
ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
|
||||
if(m_sQueueSample.m_bVolume) {
|
||||
m_sQueueSample.m_nSampleIndex = gOneShotCol[s1];
|
||||
switch(m_sQueueSample.m_nSampleIndex) {
|
||||
case SFX_COL_TARMAC_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 5;
|
||||
break;
|
||||
case SFX_COL_CAR_PANEL_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[0] % 6;
|
||||
break;
|
||||
case SFX_COL_LAMP_POST_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[1] % 2;
|
||||
break;
|
||||
case SFX_COL_METAL_CHAIN_FENCE_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 4;
|
||||
break;
|
||||
case SFX_COL_PED_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 5;
|
||||
break;
|
||||
case SFX_COL_WOOD_CRATES_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 4;
|
||||
break;
|
||||
case SFX_COL_WOOD_BENCH_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[1] % 4;
|
||||
break;
|
||||
case SFX_COL_VEG_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[2] % 5;
|
||||
break;
|
||||
case SFX_COL_NEWS_VENDOR_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[2] % 3;
|
||||
break;
|
||||
case SFX_COL_CAR_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[1] % 5;
|
||||
break;
|
||||
case SFX_COL_CARDBOARD_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 2;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
switch(s1) {
|
||||
case SURFACE_GLASS: m_sQueueSample.m_nFrequency = 13500; break;
|
||||
case SURFACE_METAL15: m_sQueueSample.m_nFrequency = 8819; break;
|
||||
case SURFACE_PUDDLE:
|
||||
m_sQueueSample.m_nFrequency =
|
||||
2 * SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
|
||||
break;
|
||||
case SURFACE_TIRE: m_sQueueSample.m_nFrequency = 6000; break;
|
||||
case SURFACE_HARD24: m_sQueueSample.m_nFrequency = 8000; break;
|
||||
default:
|
||||
m_sQueueSample.m_nFrequency =
|
||||
SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
|
||||
break;
|
||||
}
|
||||
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
|
||||
m_sQueueSample.m_counter = counter++;
|
||||
if(counter >= 255) counter = 28;
|
||||
m_sQueueSample.m_vecPos = col->m_vecPosition;
|
||||
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
|
||||
m_sQueueSample.m_bIs2D = false;
|
||||
m_sQueueSample.m_nReleasingVolumeModificator = 11;
|
||||
m_sQueueSample.m_nLoopCount = 1;
|
||||
m_sQueueSample.m_bEmittingVolume = emittingVol;
|
||||
m_sQueueSample.m_nLoopStart = 0;
|
||||
m_sQueueSample.m_nLoopEnd = -1;
|
||||
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
|
||||
m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity;
|
||||
m_sQueueSample.m_bReleasingSoundFlag = 1;
|
||||
m_sQueueSample.m_bReverbFlag = true;
|
||||
m_sQueueSample.m_bRequireReflection = false;
|
||||
AddSampleToRequestedQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cAudioManager::ServiceCollisions()
|
||||
{
|
||||
int i, j;
|
||||
bool someArr1[NUMAUDIOCOLLISIONS];
|
||||
bool someArr2[NUMAUDIOCOLLISIONS];
|
||||
|
||||
m_sQueueSample.m_nEntityIndex = m_nCollisionEntity;
|
||||
|
||||
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
|
||||
someArr1[i] = someArr2[i] = false;
|
||||
|
||||
for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
|
||||
for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
|
||||
int index = m_sCollisionManager.m_bIndicesTable[i];
|
||||
if ((m_sCollisionManager.m_asCollisions1[index].m_pEntity1 == m_sCollisionManager.m_asCollisions2[j].m_pEntity1)
|
||||
&& (m_sCollisionManager.m_asCollisions1[index].m_pEntity2 == m_sCollisionManager.m_asCollisions2[j].m_pEntity2)
|
||||
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface1 == m_sCollisionManager.m_asCollisions2[j].m_bSurface1)
|
||||
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface2 == m_sCollisionManager.m_asCollisions2[j].m_bSurface2)
|
||||
) {
|
||||
someArr1[index] = true;
|
||||
someArr2[j] = true;
|
||||
m_sCollisionManager.m_asCollisions1[index].m_nBaseVolume = ++m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume;
|
||||
SetUpLoopingCollisionSound(&m_sCollisionManager.m_asCollisions1[index], j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMAUDIOCOLLISIONS; i++) {
|
||||
if (!someArr2[i]) {
|
||||
m_sCollisionManager.m_asCollisions2[i].m_pEntity1 = nil;
|
||||
m_sCollisionManager.m_asCollisions2[i].m_pEntity2 = nil;
|
||||
m_sCollisionManager.m_asCollisions2[i].m_bSurface1 = SURFACE_DEFAULT;
|
||||
m_sCollisionManager.m_asCollisions2[i].m_bSurface2 = SURFACE_DEFAULT;
|
||||
m_sCollisionManager.m_asCollisions2[i].m_fIntensity2 = 0.0f;
|
||||
m_sCollisionManager.m_asCollisions2[i].m_fIntensity1 = 0.0f;
|
||||
m_sCollisionManager.m_asCollisions2[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
|
||||
m_sCollisionManager.m_asCollisions2[i].m_fDistance = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
|
||||
int index = m_sCollisionManager.m_bIndicesTable[i];
|
||||
if (!someArr1[index]) {
|
||||
for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
|
||||
if (someArr2[j]) {
|
||||
m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume = 1;
|
||||
m_sCollisionManager.m_asCollisions2[j].m_pEntity1 = m_sCollisionManager.m_asCollisions1[index].m_pEntity1;
|
||||
m_sCollisionManager.m_asCollisions2[j].m_pEntity2 = m_sCollisionManager.m_asCollisions1[index].m_pEntity2;
|
||||
m_sCollisionManager.m_asCollisions2[j].m_bSurface1 = m_sCollisionManager.m_asCollisions1[index].m_bSurface1;
|
||||
m_sCollisionManager.m_asCollisions2[j].m_bSurface2 = m_sCollisionManager.m_asCollisions1[index].m_bSurface2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SetUpOneShotCollisionSound(&m_sCollisionManager.m_asCollisions1[index]);
|
||||
SetUpLoopingCollisionSound(&m_sCollisionManager.m_asCollisions1[index], j);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
|
||||
m_sCollisionManager.m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
|
||||
m_sCollisionManager.m_bCollisionsInQueue = 0;
|
||||
}
|
||||
|
||||
void
|
||||
cAudioManager::ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower,
|
||||
float velocity)
|
||||
{
|
||||
float distSquared;
|
||||
CVector v1;
|
||||
CVector v2;
|
||||
|
||||
if(!m_bIsInitialised || m_nCollisionEntity < 0 || m_bUserPause ||
|
||||
(velocity < 0.0016f && collisionPower < 0.01f))
|
||||
return;
|
||||
|
||||
if(entity1->IsBuilding()) {
|
||||
v1 = v2 = entity2->GetPosition();
|
||||
} else if(entity2->IsBuilding()) {
|
||||
v1 = v2 = entity1->GetPosition();
|
||||
} else {
|
||||
v1 = entity1->GetPosition();
|
||||
v2 = entity2->GetPosition();
|
||||
}
|
||||
CVector pos = (v1 + v2) * 0.5f;
|
||||
distSquared = GetDistanceSquared(&pos);
|
||||
if(distSquared < SQR(CollisionSoundIntensity)) {
|
||||
m_sCollisionManager.m_sQueue.m_pEntity1 = entity1;
|
||||
m_sCollisionManager.m_sQueue.m_pEntity2 = entity2;
|
||||
m_sCollisionManager.m_sQueue.m_bSurface1 = surface1;
|
||||
m_sCollisionManager.m_sQueue.m_bSurface2 = surface2;
|
||||
m_sCollisionManager.m_sQueue.m_fIntensity1 = collisionPower;
|
||||
m_sCollisionManager.m_sQueue.m_fIntensity2 = velocity;
|
||||
m_sCollisionManager.m_sQueue.m_vecPosition = pos;
|
||||
m_sCollisionManager.m_sQueue.m_fDistance = distSquared;
|
||||
m_sCollisionManager.AddCollisionToRequestedQueue();
|
||||
}
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x5685E0, &cAudioCollisionManager::AddCollisionToRequestedQueue, PATCH_JUMP);
|
||||
InjectHook(0x569060, &cAudioManager::GetCollisionOneShotRatio, PATCH_JUMP);
|
||||
InjectHook(0x5693B0, &cAudioManager::GetCollisionRatio, PATCH_JUMP);
|
||||
InjectHook(0x568410, &cAudioManager::ReportCollision, PATCH_JUMP);
|
||||
InjectHook(0x5686D0, &cAudioManager::ServiceCollisions, PATCH_JUMP);
|
||||
InjectHook(0x568E20, &cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol, PATCH_JUMP);
|
||||
InjectHook(0x568D30, &cAudioManager::SetUpLoopingCollisionSound, PATCH_JUMP);
|
||||
InjectHook(0x5689D0, &cAudioManager::SetUpOneShotCollisionSound, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "DMAudio.h"
|
||||
#include "Entity.h"
|
||||
#include "AudioCollision.h"
|
||||
#include "AudioManager.h"
|
||||
#include "AudioSamples.h"
|
||||
#include "SurfaceTable.h"
|
||||
#include "sampman.h"
|
||||
|
||||
const int CollisionSoundIntensity = 60;
|
||||
|
||||
void
|
||||
cAudioCollisionManager::AddCollisionToRequestedQueue()
|
||||
{
|
||||
int32 collisionsIndex;
|
||||
int32 i;
|
||||
|
||||
|
||||
if (m_bCollisionsInQueue < NUMAUDIOCOLLISIONS)
|
||||
collisionsIndex = m_bCollisionsInQueue++;
|
||||
else {
|
||||
collisionsIndex = m_bIndicesTable[NUMAUDIOCOLLISIONS - 1];
|
||||
if (m_sQueue.m_fDistance >= m_asCollisions1[collisionsIndex].m_fDistance) return;
|
||||
}
|
||||
|
||||
m_asCollisions1[collisionsIndex] = m_sQueue;
|
||||
|
||||
i = 0;
|
||||
if(collisionsIndex) {
|
||||
while(m_asCollisions1[m_bIndicesTable[i]].m_fDistance <= m_asCollisions1[collisionsIndex].m_fDistance) {
|
||||
if(++i >= collisionsIndex) {
|
||||
m_bIndicesTable[i] = collisionsIndex;
|
||||
return;
|
||||
}
|
||||
}
|
||||
memmove(&m_bIndicesTable[i + 1], &m_bIndicesTable[i], NUMAUDIOCOLLISIONS - 1 - i);
|
||||
}
|
||||
m_bIndicesTable[i] = collisionsIndex;
|
||||
}
|
||||
|
||||
float
|
||||
cAudioManager::GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const
|
||||
{
|
||||
return GetCollisionRatio(c, 0.0f, 0.02f, 0.02f);
|
||||
}
|
||||
|
||||
float
|
||||
cAudioManager::GetCollisionOneShotRatio(int32 a, float b) const
|
||||
{
|
||||
float result;
|
||||
|
||||
switch(a) {
|
||||
case SURFACE_DEFAULT:
|
||||
case SURFACE_TARMAC:
|
||||
case SURFACE_PAVEMENT:
|
||||
case SURFACE_STONE:
|
||||
case SURFACE_BOLLARD: result = GetCollisionRatio(b, 10.f, 60.f, 50.f); break;
|
||||
case SURFACE_GRASS:
|
||||
case SURFACE_LOOSE30: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
|
||||
case SURFACE_DIRT: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
|
||||
case SURFACE_DIRTTRACK: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
|
||||
case SURFACE_METAL6: result = GetCollisionRatio(b, 6.f, 50.f, 44.f); break;
|
||||
case SURFACE_GLASS: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break;
|
||||
case SURFACE_SCAFFOLD:
|
||||
case SURFACE_STEEL: result = GetCollisionRatio(b, 30.f, 130.f, 100.f); break;
|
||||
case SURFACE_METAL_DOOR: result = GetCollisionRatio(b, 20.f, 100.f, 80.f); break;
|
||||
case SURFACE_BILLBOARD: result = GetCollisionRatio(b, 0.f, 4.f, 4.f); break;
|
||||
case SURFACE_METAL_POLE:
|
||||
case SURFACE_GATE: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break;
|
||||
case SURFACE_STREET_LIGHT: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break;
|
||||
case SURFACE_METAL14: result = GetCollisionRatio(b, 1.f, 15.f, 14.f); break;
|
||||
case SURFACE_METAL15: result = GetCollisionRatio(b, 8.f, 50.f, 42.f); break;
|
||||
case SURFACE_METAL_FENCE: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break;
|
||||
case SURFACE_FLESH: result = GetCollisionRatio(b, 0.f, 20.f, 20.f); break;
|
||||
case SURFACE_SAND: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
|
||||
case SURFACE_PUDDLE: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
|
||||
case SURFACE_WOOD: result = GetCollisionRatio(b, 1.f, 4.f, 3.f); break;
|
||||
case SURFACE_WOOD_BOX: result = GetCollisionRatio(b, 0.1f, 5.f, 4.9f); break;
|
||||
case SURFACE_WOOD_PLANK: result = GetCollisionRatio(b, 0.1f, 40.f, 39.9f); break;
|
||||
case SURFACE_TIRE:
|
||||
case SURFACE_RUBBER29: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
|
||||
case SURFACE_HARD24: result = GetCollisionRatio(b, 0.1f, 4.f, 3.9f); break;
|
||||
case SURFACE_HEDGE: result = GetCollisionRatio(b, 0.f, 0.5f, 0.5f); break;
|
||||
case SURFACE_METAL27: result = GetCollisionRatio(b, 4.f, 40.f, 36.f); break;
|
||||
case SURFACE_METAL28: result = GetCollisionRatio(b, 0.f, 5.f, 5.f); break;
|
||||
default: result = 0.f; break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float
|
||||
cAudioManager::GetCollisionRatio(float a, float b, float c, float d) const
|
||||
{
|
||||
float e;
|
||||
e = a;
|
||||
if(a <= b) return 0.0f;
|
||||
if(c <= a) e = c;
|
||||
return (e - b) / d;
|
||||
}
|
||||
|
||||
uint32
|
||||
cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(cAudioCollision *audioCollision)
|
||||
{
|
||||
uint8 surface1 = audioCollision->m_bSurface1;
|
||||
uint8 surface2 = audioCollision->m_bSurface2;
|
||||
int32 vol;
|
||||
float ratio;
|
||||
|
||||
if(surface1 == SURFACE_GRASS || surface2 == SURFACE_GRASS || surface1 == SURFACE_HEDGE ||
|
||||
surface2 == SURFACE_HEDGE) {
|
||||
ratio = GetCollisionRatio(audioCollision->m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
|
||||
m_sQueueSample.m_nSampleIndex = SFX_RAIN;
|
||||
m_sQueueSample.m_nFrequency = 13000.f * ratio + 35000;
|
||||
vol = 50.f * ratio;
|
||||
} else {
|
||||
if(surface1 == SURFACE_PUDDLE || surface2 == SURFACE_PUDDLE) {
|
||||
ratio = GetCollisionRatio(audioCollision->m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
|
||||
m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP;
|
||||
m_sQueueSample.m_nFrequency = 6050.f * ratio + 16000;
|
||||
vol = 30.f * ratio;
|
||||
|
||||
} else {
|
||||
if(surface1 == SURFACE_DIRT || surface2 == SURFACE_DIRT || surface1 == SURFACE_DIRTTRACK ||
|
||||
surface2 == SURFACE_DIRTTRACK || surface1 == SURFACE_SAND || surface2 == SURFACE_SAND) {
|
||||
ratio = GetCollisionRatio(audioCollision->m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
|
||||
m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID;
|
||||
m_sQueueSample.m_nFrequency = 6000.f * ratio + 10000;
|
||||
vol = 50.f * ratio;
|
||||
} else {
|
||||
if(surface1 == SURFACE_FLESH || surface2 == SURFACE_FLESH) { return 0; }
|
||||
ratio = GetCollisionRatio(audioCollision->m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
|
||||
m_sQueueSample.m_nSampleIndex = SFX_SCRAPE_CAR_1;
|
||||
m_sQueueSample.m_nFrequency = 10000.f * ratio + 10000;
|
||||
vol = 40.f * ratio;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(audioCollision->m_nBaseVolume < 2) vol = audioCollision->m_nBaseVolume * vol / 2;
|
||||
return vol;
|
||||
}
|
||||
|
||||
void
|
||||
cAudioManager::SetUpLoopingCollisionSound(cAudioCollision *col, uint8 counter)
|
||||
{
|
||||
if(col->m_fIntensity2 > 0.0016f) {
|
||||
uint8 emittingVol = SetLoopingCollisionRequestedSfxFreqAndGetVol(col);
|
||||
if(emittingVol) {
|
||||
m_sQueueSample.m_fDistance = Sqrt(col->m_fDistance);
|
||||
m_sQueueSample.m_bVolume =
|
||||
ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
|
||||
if(m_sQueueSample.m_bVolume) {
|
||||
m_sQueueSample.m_counter = counter;
|
||||
m_sQueueSample.m_vecPos = col->m_vecPosition;
|
||||
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
|
||||
m_sQueueSample.m_bIs2D = false;
|
||||
m_sQueueSample.m_nReleasingVolumeModificator = 7;
|
||||
m_sQueueSample.m_nLoopCount = 0;
|
||||
m_sQueueSample.m_bEmittingVolume = emittingVol;
|
||||
m_sQueueSample.m_nLoopStart =
|
||||
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
|
||||
m_sQueueSample.m_nLoopEnd =
|
||||
SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
|
||||
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
|
||||
m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity;
|
||||
m_sQueueSample.m_bReleasingSoundFlag = 0;
|
||||
m_sQueueSample.m_nReleasingVolumeDivider = 5;
|
||||
m_sQueueSample.m_bReverbFlag = true;
|
||||
m_sQueueSample.m_bRequireReflection = false;
|
||||
AddSampleToRequestedQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cAudioManager::SetUpOneShotCollisionSound(cAudioCollision *col)
|
||||
{
|
||||
static const int32 gOneShotCol[] = {
|
||||
SFX_COL_TARMAC_1, SFX_COL_TARMAC_1, SFX_COL_GRASS_1,
|
||||
SFX_COL_GRAVEL_1, SFX_COL_MUD_1, SFX_COL_TARMAC_1,
|
||||
SFX_COL_CAR_1, SFX_COL_GRASS_1, SFX_COL_SCAFFOLD_POLE_1,
|
||||
SFX_COL_GARAGE_DOOR_1, SFX_COL_CAR_PANEL_1, SFX_COL_THICK_METAL_PLATE_1,
|
||||
SFX_COL_SCAFFOLD_POLE_1, SFX_COL_LAMP_POST_1, SFX_COL_HYDRANT_1,
|
||||
SFX_COL_HYDRANT_1, SFX_COL_METAL_CHAIN_FENCE_1, SFX_COL_PED_1,
|
||||
SFX_COL_SAND_1, SFX_SPLASH_1, SFX_COL_WOOD_CRATES_1,
|
||||
SFX_COL_WOOD_BENCH_1, SFX_COL_WOOD_SOLID_1, SFX_COL_GRASS_1,
|
||||
SFX_COL_GRASS_1, SFX_COL_VEG_1, SFX_COL_TARMAC_1,
|
||||
SFX_COL_CONTAINER_1, SFX_COL_NEWS_VENDOR_1, SFX_TYRE_BUMP,
|
||||
SFX_COL_CARDBOARD_1, SFX_COL_TARMAC_1, SFX_COL_GATE};
|
||||
|
||||
int16 s1;
|
||||
int16 s2;
|
||||
|
||||
int32 emittingVol;
|
||||
float ratio;
|
||||
|
||||
static uint16 counter = 28;
|
||||
|
||||
for(int32 i = 0; i < 2; i++) {
|
||||
if(i) {
|
||||
s1 = col->m_bSurface2;
|
||||
s2 = col->m_bSurface1;
|
||||
} else {
|
||||
s1 = col->m_bSurface1;
|
||||
s2 = col->m_bSurface2;
|
||||
}
|
||||
ratio = GetCollisionOneShotRatio(s1, col->m_fIntensity1);
|
||||
if(s1 == SURFACE_METAL6 && s2 == SURFACE_FLESH) ratio = 0.25f * ratio;
|
||||
if(s1 == SURFACE_METAL6 && ratio < 0.6f) {
|
||||
s1 = SURFACE_BILLBOARD;
|
||||
ratio = min(1.f, 2.f * ratio);
|
||||
}
|
||||
emittingVol = 40.f * ratio;
|
||||
if(emittingVol) {
|
||||
m_sQueueSample.m_fDistance = Sqrt(col->m_fDistance);
|
||||
m_sQueueSample.m_bVolume =
|
||||
ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
|
||||
if(m_sQueueSample.m_bVolume) {
|
||||
m_sQueueSample.m_nSampleIndex = gOneShotCol[s1];
|
||||
switch(m_sQueueSample.m_nSampleIndex) {
|
||||
case SFX_COL_TARMAC_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 5;
|
||||
break;
|
||||
case SFX_COL_CAR_PANEL_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[0] % 6;
|
||||
break;
|
||||
case SFX_COL_LAMP_POST_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[1] % 2;
|
||||
break;
|
||||
case SFX_COL_METAL_CHAIN_FENCE_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 4;
|
||||
break;
|
||||
case SFX_COL_PED_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 5;
|
||||
break;
|
||||
case SFX_COL_WOOD_CRATES_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 4;
|
||||
break;
|
||||
case SFX_COL_WOOD_BENCH_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[1] % 4;
|
||||
break;
|
||||
case SFX_COL_VEG_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[2] % 5;
|
||||
break;
|
||||
case SFX_COL_NEWS_VENDOR_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[2] % 3;
|
||||
break;
|
||||
case SFX_COL_CAR_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[1] % 5;
|
||||
break;
|
||||
case SFX_COL_CARDBOARD_1:
|
||||
m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 2;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
switch(s1) {
|
||||
case SURFACE_GLASS: m_sQueueSample.m_nFrequency = 13500; break;
|
||||
case SURFACE_METAL15: m_sQueueSample.m_nFrequency = 8819; break;
|
||||
case SURFACE_PUDDLE:
|
||||
m_sQueueSample.m_nFrequency =
|
||||
2 * SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
|
||||
break;
|
||||
case SURFACE_TIRE: m_sQueueSample.m_nFrequency = 6000; break;
|
||||
case SURFACE_HARD24: m_sQueueSample.m_nFrequency = 8000; break;
|
||||
default:
|
||||
m_sQueueSample.m_nFrequency =
|
||||
SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
|
||||
break;
|
||||
}
|
||||
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
|
||||
m_sQueueSample.m_counter = counter++;
|
||||
if(counter >= 255) counter = 28;
|
||||
m_sQueueSample.m_vecPos = col->m_vecPosition;
|
||||
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
|
||||
m_sQueueSample.m_bIs2D = false;
|
||||
m_sQueueSample.m_nReleasingVolumeModificator = 11;
|
||||
m_sQueueSample.m_nLoopCount = 1;
|
||||
m_sQueueSample.m_bEmittingVolume = emittingVol;
|
||||
m_sQueueSample.m_nLoopStart = 0;
|
||||
m_sQueueSample.m_nLoopEnd = -1;
|
||||
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
|
||||
m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity;
|
||||
m_sQueueSample.m_bReleasingSoundFlag = 1;
|
||||
m_sQueueSample.m_bReverbFlag = true;
|
||||
m_sQueueSample.m_bRequireReflection = false;
|
||||
AddSampleToRequestedQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cAudioManager::ServiceCollisions()
|
||||
{
|
||||
int i, j;
|
||||
bool someArr1[NUMAUDIOCOLLISIONS];
|
||||
bool someArr2[NUMAUDIOCOLLISIONS];
|
||||
|
||||
m_sQueueSample.m_nEntityIndex = m_nCollisionEntity;
|
||||
|
||||
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
|
||||
someArr1[i] = someArr2[i] = false;
|
||||
|
||||
for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
|
||||
for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
|
||||
int index = m_sCollisionManager.m_bIndicesTable[i];
|
||||
if ((m_sCollisionManager.m_asCollisions1[index].m_pEntity1 == m_sCollisionManager.m_asCollisions2[j].m_pEntity1)
|
||||
&& (m_sCollisionManager.m_asCollisions1[index].m_pEntity2 == m_sCollisionManager.m_asCollisions2[j].m_pEntity2)
|
||||
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface1 == m_sCollisionManager.m_asCollisions2[j].m_bSurface1)
|
||||
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface2 == m_sCollisionManager.m_asCollisions2[j].m_bSurface2)
|
||||
) {
|
||||
someArr1[index] = true;
|
||||
someArr2[j] = true;
|
||||
m_sCollisionManager.m_asCollisions1[index].m_nBaseVolume = ++m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume;
|
||||
SetUpLoopingCollisionSound(&m_sCollisionManager.m_asCollisions1[index], j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMAUDIOCOLLISIONS; i++) {
|
||||
if (!someArr2[i]) {
|
||||
m_sCollisionManager.m_asCollisions2[i].m_pEntity1 = nil;
|
||||
m_sCollisionManager.m_asCollisions2[i].m_pEntity2 = nil;
|
||||
m_sCollisionManager.m_asCollisions2[i].m_bSurface1 = SURFACE_DEFAULT;
|
||||
m_sCollisionManager.m_asCollisions2[i].m_bSurface2 = SURFACE_DEFAULT;
|
||||
m_sCollisionManager.m_asCollisions2[i].m_fIntensity2 = 0.0f;
|
||||
m_sCollisionManager.m_asCollisions2[i].m_fIntensity1 = 0.0f;
|
||||
m_sCollisionManager.m_asCollisions2[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
|
||||
m_sCollisionManager.m_asCollisions2[i].m_fDistance = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
|
||||
int index = m_sCollisionManager.m_bIndicesTable[i];
|
||||
if (!someArr1[index]) {
|
||||
for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
|
||||
if (someArr2[j]) {
|
||||
m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume = 1;
|
||||
m_sCollisionManager.m_asCollisions2[j].m_pEntity1 = m_sCollisionManager.m_asCollisions1[index].m_pEntity1;
|
||||
m_sCollisionManager.m_asCollisions2[j].m_pEntity2 = m_sCollisionManager.m_asCollisions1[index].m_pEntity2;
|
||||
m_sCollisionManager.m_asCollisions2[j].m_bSurface1 = m_sCollisionManager.m_asCollisions1[index].m_bSurface1;
|
||||
m_sCollisionManager.m_asCollisions2[j].m_bSurface2 = m_sCollisionManager.m_asCollisions1[index].m_bSurface2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SetUpOneShotCollisionSound(&m_sCollisionManager.m_asCollisions1[index]);
|
||||
SetUpLoopingCollisionSound(&m_sCollisionManager.m_asCollisions1[index], j);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
|
||||
m_sCollisionManager.m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
|
||||
m_sCollisionManager.m_bCollisionsInQueue = 0;
|
||||
}
|
||||
|
||||
void
|
||||
cAudioManager::ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower,
|
||||
float velocity)
|
||||
{
|
||||
float distSquared;
|
||||
CVector v1;
|
||||
CVector v2;
|
||||
|
||||
if(!m_bIsInitialised || m_nCollisionEntity < 0 || m_bUserPause ||
|
||||
(velocity < 0.0016f && collisionPower < 0.01f))
|
||||
return;
|
||||
|
||||
if(entity1->IsBuilding()) {
|
||||
v1 = v2 = entity2->GetPosition();
|
||||
} else if(entity2->IsBuilding()) {
|
||||
v1 = v2 = entity1->GetPosition();
|
||||
} else {
|
||||
v1 = entity1->GetPosition();
|
||||
v2 = entity2->GetPosition();
|
||||
}
|
||||
CVector pos = (v1 + v2) * 0.5f;
|
||||
distSquared = GetDistanceSquared(&pos);
|
||||
if(distSquared < SQR(CollisionSoundIntensity)) {
|
||||
m_sCollisionManager.m_sQueue.m_pEntity1 = entity1;
|
||||
m_sCollisionManager.m_sQueue.m_pEntity2 = entity2;
|
||||
m_sCollisionManager.m_sQueue.m_bSurface1 = surface1;
|
||||
m_sCollisionManager.m_sQueue.m_bSurface2 = surface2;
|
||||
m_sCollisionManager.m_sQueue.m_fIntensity1 = collisionPower;
|
||||
m_sCollisionManager.m_sQueue.m_fIntensity2 = velocity;
|
||||
m_sCollisionManager.m_sQueue.m_vecPosition = pos;
|
||||
m_sCollisionManager.m_sQueue.m_fDistance = distSquared;
|
||||
m_sCollisionManager.AddCollisionToRequestedQueue();
|
||||
}
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x5685E0, &cAudioCollisionManager::AddCollisionToRequestedQueue, PATCH_JUMP);
|
||||
InjectHook(0x569060, &cAudioManager::GetCollisionOneShotRatio, PATCH_JUMP);
|
||||
InjectHook(0x5693B0, &cAudioManager::GetCollisionRatio, PATCH_JUMP);
|
||||
InjectHook(0x568410, &cAudioManager::ReportCollision, PATCH_JUMP);
|
||||
InjectHook(0x5686D0, &cAudioManager::ServiceCollisions, PATCH_JUMP);
|
||||
InjectHook(0x568E20, &cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol, PATCH_JUMP);
|
||||
InjectHook(0x568D30, &cAudioManager::SetUpLoopingCollisionSound, PATCH_JUMP);
|
||||
InjectHook(0x5689D0, &cAudioManager::SetUpOneShotCollisionSound, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -1,36 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#define NUMAUDIOCOLLISIONS 10
|
||||
|
||||
class cAudioCollision
|
||||
{
|
||||
public:
|
||||
CEntity *m_pEntity1;
|
||||
CEntity *m_pEntity2;
|
||||
uint8 m_bSurface1;
|
||||
uint8 m_bSurface2;
|
||||
float m_fIntensity1;
|
||||
float m_fIntensity2;
|
||||
CVector m_vecPosition;
|
||||
float m_fDistance;
|
||||
int32 m_nBaseVolume;
|
||||
|
||||
// no methods
|
||||
};
|
||||
|
||||
static_assert(sizeof(cAudioCollision) == 40, "cAudioCollision: error");
|
||||
|
||||
class cAudioCollisionManager
|
||||
{
|
||||
public:
|
||||
cAudioCollision m_asCollisions1[NUMAUDIOCOLLISIONS];
|
||||
cAudioCollision m_asCollisions2[NUMAUDIOCOLLISIONS];
|
||||
uint8 m_bIndicesTable[NUMAUDIOCOLLISIONS];
|
||||
uint8 m_bCollisionsInQueue;
|
||||
cAudioCollision m_sQueue;
|
||||
|
||||
// reversed all methods
|
||||
void AddCollisionToRequestedQueue(); /// ok
|
||||
};
|
||||
|
||||
#pragma once
|
||||
|
||||
#define NUMAUDIOCOLLISIONS 10
|
||||
|
||||
class cAudioCollision
|
||||
{
|
||||
public:
|
||||
CEntity *m_pEntity1;
|
||||
CEntity *m_pEntity2;
|
||||
uint8 m_bSurface1;
|
||||
uint8 m_bSurface2;
|
||||
float m_fIntensity1;
|
||||
float m_fIntensity2;
|
||||
CVector m_vecPosition;
|
||||
float m_fDistance;
|
||||
int32 m_nBaseVolume;
|
||||
|
||||
// no methods
|
||||
};
|
||||
|
||||
static_assert(sizeof(cAudioCollision) == 40, "cAudioCollision: error");
|
||||
|
||||
class cAudioCollisionManager
|
||||
{
|
||||
public:
|
||||
cAudioCollision m_asCollisions1[NUMAUDIOCOLLISIONS];
|
||||
cAudioCollision m_asCollisions2[NUMAUDIOCOLLISIONS];
|
||||
uint8 m_bIndicesTable[NUMAUDIOCOLLISIONS];
|
||||
uint8 m_bCollisionsInQueue;
|
||||
cAudioCollision m_sQueue;
|
||||
|
||||
// reversed all methods
|
||||
void AddCollisionToRequestedQueue(); /// ok
|
||||
};
|
||||
|
||||
static_assert(sizeof(cAudioCollisionManager) == 852, "cAudioCollisionManager: error");
|
@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include "DMAudio.h"
|
||||
#include "common.h"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,46 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include "Wanted.h"
|
||||
|
||||
struct cAMCrime {
|
||||
int32 type;
|
||||
CVector position;
|
||||
uint16 timer;
|
||||
|
||||
cAMCrime()
|
||||
{
|
||||
type = CRIME_NONE;
|
||||
position = CVector(0.0f, 0.0f, 0.0f);
|
||||
timer = 0;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(cAMCrime) == 20, "cAMCrime: error ");
|
||||
|
||||
class cPoliceRadioQueue
|
||||
{
|
||||
public:
|
||||
int32 crimesSamples[60];
|
||||
uint8 policeChannelTimer;
|
||||
uint8 policeChannelTimerSeconds;
|
||||
uint8 policeChannelCounterSeconds;
|
||||
cAMCrime crimes[10];
|
||||
|
||||
cPoliceRadioQueue()
|
||||
{
|
||||
policeChannelTimerSeconds = 0;
|
||||
policeChannelCounterSeconds = 0;
|
||||
policeChannelTimer = 0;
|
||||
}
|
||||
|
||||
void Add(uint32 sample)
|
||||
{
|
||||
if (policeChannelTimer != 60) {
|
||||
crimesSamples[policeChannelTimerSeconds] = sample;
|
||||
policeChannelTimer++;
|
||||
policeChannelTimerSeconds = (policeChannelTimerSeconds + 1) % 60;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Wanted.h"
|
||||
|
||||
struct cAMCrime {
|
||||
int32 type;
|
||||
CVector position;
|
||||
uint16 timer;
|
||||
|
||||
cAMCrime()
|
||||
{
|
||||
type = CRIME_NONE;
|
||||
position = CVector(0.0f, 0.0f, 0.0f);
|
||||
timer = 0;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(cAMCrime) == 20, "cAMCrime: error ");
|
||||
|
||||
class cPoliceRadioQueue
|
||||
{
|
||||
public:
|
||||
int32 crimesSamples[60];
|
||||
uint8 policeChannelTimer;
|
||||
uint8 policeChannelTimerSeconds;
|
||||
uint8 policeChannelCounterSeconds;
|
||||
cAMCrime crimes[10];
|
||||
|
||||
cPoliceRadioQueue()
|
||||
{
|
||||
policeChannelTimerSeconds = 0;
|
||||
policeChannelCounterSeconds = 0;
|
||||
policeChannelTimer = 0;
|
||||
}
|
||||
|
||||
void Add(uint32 sample)
|
||||
{
|
||||
if (policeChannelTimer != 60) {
|
||||
crimesSamples[policeChannelTimerSeconds] = sample;
|
||||
policeChannelTimer++;
|
||||
policeChannelTimerSeconds = (policeChannelTimerSeconds + 1) % 60;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(cPoliceRadioQueue) == 444, "cPoliceRadioQueue: error ");
|
@ -90,7 +90,7 @@ uint32 (&aCarsToKeepTime)[MAX_CARS_TO_KEEP] = *(uint32(*)[MAX_CARS_TO_KEEP])*(ui
|
||||
void
|
||||
CCarCtrl::GenerateRandomCars()
|
||||
{
|
||||
if (CCutsceneMgr::IsCutsceneProcessing())
|
||||
if (CCutsceneMgr::IsRunning())
|
||||
return;
|
||||
if (NumRandomCars < 30){
|
||||
if (CountDownToCarsAtStart == 0){
|
||||
|
@ -242,7 +242,7 @@ void CCarGenerator::Load(uint8 *&buffer)
|
||||
|
||||
void CTheCarGenerators::Process()
|
||||
{
|
||||
if (FindPlayerTrain() || CCutsceneMgr::IsRunning())
|
||||
if (FindPlayerTrain() || CCutsceneMgr::IsCutsceneProcessing())
|
||||
return;
|
||||
if (++CTheCarGenerators::ProcessCounter == 4)
|
||||
CTheCarGenerators::ProcessCounter = 0;
|
||||
|
@ -1,294 +1,294 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "GameLogic.h"
|
||||
#include "Clock.h"
|
||||
#include "Stats.h"
|
||||
#include "Pickups.h"
|
||||
#include "Timer.h"
|
||||
#include "Streaming.h"
|
||||
#include "CutsceneMgr.h"
|
||||
#include "World.h"
|
||||
#include "PlayerPed.h"
|
||||
#include "Wanted.h"
|
||||
#include "Camera.h"
|
||||
#include "Messages.h"
|
||||
#include "CarCtrl.h"
|
||||
#include "Restart.h"
|
||||
#include "Pad.h"
|
||||
#include "References.h"
|
||||
#include "Fire.h"
|
||||
#include "Script.h"
|
||||
#include "Garages.h"
|
||||
|
||||
uint8 CGameLogic::ActivePlayers; // 0x95CD5E
|
||||
|
||||
void
|
||||
CGameLogic::InitAtStartOfGame()
|
||||
{
|
||||
ActivePlayers = 1;
|
||||
}
|
||||
|
||||
void
|
||||
CGameLogic::PassTime(uint32 time)
|
||||
{
|
||||
int32 minutes, hours, days;
|
||||
|
||||
minutes = time + CClock::GetMinutes();
|
||||
hours = CClock::GetHours();
|
||||
|
||||
for (; minutes >= 60; minutes -= 60)
|
||||
hours++;
|
||||
|
||||
if (hours > 23) {
|
||||
days = CStats::DaysPassed;
|
||||
for (; hours >= 24; hours -= 24)
|
||||
days++;
|
||||
CStats::DaysPassed = days;
|
||||
}
|
||||
|
||||
CClock::SetGameClock(hours, minutes);
|
||||
CPickups::PassTime(time * 1000);
|
||||
}
|
||||
|
||||
void
|
||||
CGameLogic::SortOutStreamingAndMemory(const CVector &pos)
|
||||
{
|
||||
CTimer::Stop();
|
||||
CStreaming::FlushRequestList();
|
||||
CStreaming::DeleteRwObjectsAfterDeath(pos);
|
||||
CStreaming::RemoveUnusedModelsInLoadedList();
|
||||
CGame::DrasticTidyUpMemory(true);
|
||||
CStreaming::LoadScene(pos);
|
||||
CTimer::Update();
|
||||
}
|
||||
|
||||
void
|
||||
CGameLogic::Update()
|
||||
{
|
||||
CVector vecRestartPos;
|
||||
float fRestartFloat;
|
||||
|
||||
if (CCutsceneMgr::IsCutsceneProcessing()) return;
|
||||
|
||||
CPlayerInfo &pPlayerInfo = CWorld::Players[CWorld::PlayerInFocus];
|
||||
switch (pPlayerInfo.m_WBState) {
|
||||
case WBSTATE_PLAYING:
|
||||
if (pPlayerInfo.m_pPed->m_nPedState == PED_DEAD) {
|
||||
pPlayerInfo.m_pPed->ClearAdrenaline();
|
||||
pPlayerInfo.KillPlayer();
|
||||
}
|
||||
if (pPlayerInfo.m_pPed->m_nPedState == PED_ARRESTED) {
|
||||
pPlayerInfo.m_pPed->ClearAdrenaline();
|
||||
pPlayerInfo.ArrestPlayer();
|
||||
}
|
||||
break;
|
||||
case WBSTATE_WASTED:
|
||||
if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) {
|
||||
TheCamera.SetFadeColour(200, 200, 200);
|
||||
TheCamera.Fade(2.0f, FADE_OUT);
|
||||
}
|
||||
|
||||
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
|
||||
pPlayerInfo.m_WBState = WBSTATE_PLAYING;
|
||||
if (pPlayerInfo.m_bGetOutOfHospitalFree) {
|
||||
pPlayerInfo.m_bGetOutOfHospitalFree = false;
|
||||
} else {
|
||||
pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - 1000);
|
||||
pPlayerInfo.m_pPed->ClearWeapons();
|
||||
}
|
||||
|
||||
if (pPlayerInfo.m_pPed->bInVehicle) {
|
||||
CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle;
|
||||
if (pVehicle != nil) {
|
||||
if (pVehicle->pDriver == pPlayerInfo.m_pPed) {
|
||||
pVehicle->pDriver = nil;
|
||||
if (pVehicle->m_status != STATUS_WRECKED)
|
||||
pVehicle->m_status = STATUS_ABANDONED;
|
||||
} else
|
||||
pVehicle->RemovePassenger(pPlayerInfo.m_pPed);
|
||||
}
|
||||
}
|
||||
CEventList::Initialise();
|
||||
CMessages::ClearMessages();
|
||||
CCarCtrl::ClearInterestingVehicleList();
|
||||
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
|
||||
CRestart::FindClosestHospitalRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
|
||||
CRestart::OverrideHospitalLevel = LEVEL_NONE;
|
||||
CRestart::OverridePoliceStationLevel = LEVEL_NONE;
|
||||
PassTime(720);
|
||||
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
|
||||
SortOutStreamingAndMemory(pPlayerInfo.GetPos());
|
||||
TheCamera.m_fCamShakeForce = 0.0f;
|
||||
TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
|
||||
CPad::GetPad(0)->StopShaking(0);
|
||||
CReferences::RemoveReferencesToPlayer();
|
||||
CCarCtrl::CountDownToCarsAtStart = 2;
|
||||
CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
|
||||
if (CRestart::bFadeInAfterNextDeath) {
|
||||
TheCamera.SetFadeColour(200, 200, 200);
|
||||
TheCamera.Fade(4.0f, FADE_IN);
|
||||
} else CRestart::bFadeInAfterNextDeath = true;
|
||||
}
|
||||
break;
|
||||
case WBSTATE_BUSTED:
|
||||
if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) {
|
||||
TheCamera.SetFadeColour(0, 0, 0);
|
||||
TheCamera.Fade(2.0f, FADE_OUT);
|
||||
}
|
||||
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
|
||||
pPlayerInfo.m_WBState = WBSTATE_PLAYING;
|
||||
int takeMoney;
|
||||
|
||||
switch (pPlayerInfo.m_pPed->m_pWanted->m_nWantedLevel) {
|
||||
case 0:
|
||||
case 1:
|
||||
takeMoney = 100;
|
||||
break;
|
||||
case 2:
|
||||
takeMoney = 200;
|
||||
break;
|
||||
case 3:
|
||||
takeMoney = 400;
|
||||
break;
|
||||
case 4:
|
||||
takeMoney = 600;
|
||||
break;
|
||||
case 5:
|
||||
takeMoney = 900;
|
||||
break;
|
||||
case 6:
|
||||
takeMoney = 1500;
|
||||
break;
|
||||
}
|
||||
if (pPlayerInfo.m_bGetOutOfJailFree) {
|
||||
pPlayerInfo.m_bGetOutOfJailFree = false;
|
||||
} else {
|
||||
pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - takeMoney);
|
||||
pPlayerInfo.m_pPed->ClearWeapons();
|
||||
}
|
||||
|
||||
if (pPlayerInfo.m_pPed->bInVehicle) {
|
||||
CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle;
|
||||
if (pVehicle != nil) {
|
||||
if (pVehicle->pDriver == pPlayerInfo.m_pPed) {
|
||||
pVehicle->pDriver = nil;
|
||||
if (pVehicle->m_status != STATUS_WRECKED)
|
||||
pVehicle->m_status = STATUS_ABANDONED;
|
||||
}
|
||||
else
|
||||
pVehicle->RemovePassenger(pPlayerInfo.m_pPed);
|
||||
}
|
||||
}
|
||||
CEventList::Initialise();
|
||||
CMessages::ClearMessages();
|
||||
CCarCtrl::ClearInterestingVehicleList();
|
||||
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
|
||||
CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
|
||||
CRestart::OverrideHospitalLevel = LEVEL_NONE;
|
||||
CRestart::OverridePoliceStationLevel = LEVEL_NONE;
|
||||
PassTime(720);
|
||||
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
|
||||
pPlayerInfo.m_pPed->ClearWeapons();
|
||||
SortOutStreamingAndMemory(pPlayerInfo.GetPos());
|
||||
TheCamera.m_fCamShakeForce = 0.0f;
|
||||
TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
|
||||
CPad::GetPad(0)->StopShaking(0);
|
||||
CReferences::RemoveReferencesToPlayer();
|
||||
CCarCtrl::CountDownToCarsAtStart = 2;
|
||||
CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
|
||||
if (CRestart::bFadeInAfterNextArrest) {
|
||||
TheCamera.SetFadeColour(0, 0, 0);
|
||||
TheCamera.Fade(4.0f, FADE_IN);
|
||||
} else CRestart::bFadeInAfterNextArrest = true;
|
||||
}
|
||||
break;
|
||||
case WBSTATE_FAILED_CRITICAL_MISSION:
|
||||
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800 && CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800) {
|
||||
TheCamera.SetFadeColour(0, 0, 0);
|
||||
TheCamera.Fade(2.0f, FADE_OUT);
|
||||
}
|
||||
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
|
||||
pPlayerInfo.m_WBState = WBSTATE_PLAYING;
|
||||
if (pPlayerInfo.m_pPed->bInVehicle) {
|
||||
CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle;
|
||||
if (pVehicle != nil) {
|
||||
if (pVehicle->pDriver == pPlayerInfo.m_pPed) {
|
||||
pVehicle->pDriver = nil;
|
||||
if (pVehicle->m_status != STATUS_WRECKED)
|
||||
pVehicle->m_status = STATUS_ABANDONED;
|
||||
} else
|
||||
pVehicle->RemovePassenger(pPlayerInfo.m_pPed);
|
||||
}
|
||||
}
|
||||
CEventList::Initialise();
|
||||
CMessages::ClearMessages();
|
||||
CCarCtrl::ClearInterestingVehicleList();
|
||||
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
|
||||
CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
|
||||
CRestart::OverridePoliceStationLevel = LEVEL_NONE;
|
||||
CRestart::OverrideHospitalLevel = LEVEL_NONE;
|
||||
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
|
||||
SortOutStreamingAndMemory(pPlayerInfo.GetPos());
|
||||
TheCamera.m_fCamShakeForce = 0.0f;
|
||||
TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
|
||||
CPad::GetPad(0)->StopShaking(0);
|
||||
CReferences::RemoveReferencesToPlayer();
|
||||
CCarCtrl::CountDownToCarsAtStart = 2;
|
||||
CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
|
||||
TheCamera.SetFadeColour(0, 0, 0);
|
||||
TheCamera.Fade(4.0f, FADE_IN);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector pos, float angle)
|
||||
{
|
||||
pPlayerPed->m_fHealth = 100.0f;
|
||||
pPlayerPed->m_fArmour = 0.0f;
|
||||
pPlayerPed->bIsVisible = true;
|
||||
pPlayerPed->m_bloodyFootprintCountOrDeathTime = 0;
|
||||
pPlayerPed->bDoBloodyFootprints = false;
|
||||
pPlayerPed->ClearAdrenaline();
|
||||
pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina;
|
||||
if (pPlayerPed->m_pFire)
|
||||
pPlayerPed->m_pFire->Extinguish();
|
||||
pPlayerPed->bInVehicle = false;
|
||||
pPlayerPed->m_pMyVehicle = nil;
|
||||
pPlayerPed->m_pVehicleAnim = nil;
|
||||
pPlayerPed->m_pWanted->Reset();
|
||||
pPlayerPed->RestartNonPartialAnims();
|
||||
pPlayerPed->GetPlayerInfoForThisPlayerPed()->MakePlayerSafe(false);
|
||||
pPlayerPed->bRemoveFromWorld = false;
|
||||
pPlayerPed->ClearWeaponTarget();
|
||||
pPlayerPed->SetInitialState();
|
||||
CCarCtrl::ClearInterestingVehicleList();
|
||||
|
||||
pos.z += 1.0f;
|
||||
pPlayerPed->Teleport(pos);
|
||||
pPlayerPed->SetMoveSpeed(CVector(0.0f, 0.0f, 0.0f));
|
||||
|
||||
pPlayerPed->m_fRotationCur = DEGTORAD(angle);
|
||||
pPlayerPed->m_fRotationDest = pPlayerPed->m_fRotationCur;
|
||||
pPlayerPed->SetHeading(pPlayerPed->m_fRotationCur);
|
||||
CTheScripts::ClearSpaceForMissionEntity(pos, pPlayerPed);
|
||||
CWorld::ClearExcitingStuffFromArea(pos, 4000.0, 1);
|
||||
pPlayerPed->RestoreHeadingRate();
|
||||
TheCamera.SetCameraDirectlyInFrontForFollowPed_CamOnAString();
|
||||
CReferences::RemoveReferencesToPlayer();
|
||||
CGarages::PlayerArrestedOrDied();
|
||||
CStats::CheckPointReachedUnsuccessfully();
|
||||
CWorld::Remove(pPlayerPed);
|
||||
CWorld::Add(pPlayerPed);
|
||||
}
|
||||
|
||||
#include "GameLogic.h"
|
||||
#include "Clock.h"
|
||||
#include "Stats.h"
|
||||
#include "Pickups.h"
|
||||
#include "Timer.h"
|
||||
#include "Streaming.h"
|
||||
#include "CutsceneMgr.h"
|
||||
#include "World.h"
|
||||
#include "PlayerPed.h"
|
||||
#include "Wanted.h"
|
||||
#include "Camera.h"
|
||||
#include "Messages.h"
|
||||
#include "CarCtrl.h"
|
||||
#include "Restart.h"
|
||||
#include "Pad.h"
|
||||
#include "References.h"
|
||||
#include "Fire.h"
|
||||
#include "Script.h"
|
||||
#include "Garages.h"
|
||||
|
||||
uint8 CGameLogic::ActivePlayers; // 0x95CD5E
|
||||
|
||||
void
|
||||
CGameLogic::InitAtStartOfGame()
|
||||
{
|
||||
ActivePlayers = 1;
|
||||
}
|
||||
|
||||
void
|
||||
CGameLogic::PassTime(uint32 time)
|
||||
{
|
||||
int32 minutes, hours, days;
|
||||
|
||||
minutes = time + CClock::GetMinutes();
|
||||
hours = CClock::GetHours();
|
||||
|
||||
for (; minutes >= 60; minutes -= 60)
|
||||
hours++;
|
||||
|
||||
if (hours > 23) {
|
||||
days = CStats::DaysPassed;
|
||||
for (; hours >= 24; hours -= 24)
|
||||
days++;
|
||||
CStats::DaysPassed = days;
|
||||
}
|
||||
|
||||
CClock::SetGameClock(hours, minutes);
|
||||
CPickups::PassTime(time * 1000);
|
||||
}
|
||||
|
||||
void
|
||||
CGameLogic::SortOutStreamingAndMemory(const CVector &pos)
|
||||
{
|
||||
CTimer::Stop();
|
||||
CStreaming::FlushRequestList();
|
||||
CStreaming::DeleteRwObjectsAfterDeath(pos);
|
||||
CStreaming::RemoveUnusedModelsInLoadedList();
|
||||
CGame::DrasticTidyUpMemory(true);
|
||||
CStreaming::LoadScene(pos);
|
||||
CTimer::Update();
|
||||
}
|
||||
|
||||
void
|
||||
CGameLogic::Update()
|
||||
{
|
||||
CVector vecRestartPos;
|
||||
float fRestartFloat;
|
||||
|
||||
if (CCutsceneMgr::IsCutsceneProcessing()) return;
|
||||
|
||||
CPlayerInfo &pPlayerInfo = CWorld::Players[CWorld::PlayerInFocus];
|
||||
switch (pPlayerInfo.m_WBState) {
|
||||
case WBSTATE_PLAYING:
|
||||
if (pPlayerInfo.m_pPed->m_nPedState == PED_DEAD) {
|
||||
pPlayerInfo.m_pPed->ClearAdrenaline();
|
||||
pPlayerInfo.KillPlayer();
|
||||
}
|
||||
if (pPlayerInfo.m_pPed->m_nPedState == PED_ARRESTED) {
|
||||
pPlayerInfo.m_pPed->ClearAdrenaline();
|
||||
pPlayerInfo.ArrestPlayer();
|
||||
}
|
||||
break;
|
||||
case WBSTATE_WASTED:
|
||||
if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) {
|
||||
TheCamera.SetFadeColour(200, 200, 200);
|
||||
TheCamera.Fade(2.0f, FADE_OUT);
|
||||
}
|
||||
|
||||
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
|
||||
pPlayerInfo.m_WBState = WBSTATE_PLAYING;
|
||||
if (pPlayerInfo.m_bGetOutOfHospitalFree) {
|
||||
pPlayerInfo.m_bGetOutOfHospitalFree = false;
|
||||
} else {
|
||||
pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - 1000);
|
||||
pPlayerInfo.m_pPed->ClearWeapons();
|
||||
}
|
||||
|
||||
if (pPlayerInfo.m_pPed->bInVehicle) {
|
||||
CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle;
|
||||
if (pVehicle != nil) {
|
||||
if (pVehicle->pDriver == pPlayerInfo.m_pPed) {
|
||||
pVehicle->pDriver = nil;
|
||||
if (pVehicle->m_status != STATUS_WRECKED)
|
||||
pVehicle->m_status = STATUS_ABANDONED;
|
||||
} else
|
||||
pVehicle->RemovePassenger(pPlayerInfo.m_pPed);
|
||||
}
|
||||
}
|
||||
CEventList::Initialise();
|
||||
CMessages::ClearMessages();
|
||||
CCarCtrl::ClearInterestingVehicleList();
|
||||
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
|
||||
CRestart::FindClosestHospitalRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
|
||||
CRestart::OverrideHospitalLevel = LEVEL_NONE;
|
||||
CRestart::OverridePoliceStationLevel = LEVEL_NONE;
|
||||
PassTime(720);
|
||||
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
|
||||
SortOutStreamingAndMemory(pPlayerInfo.GetPos());
|
||||
TheCamera.m_fCamShakeForce = 0.0f;
|
||||
TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
|
||||
CPad::GetPad(0)->StopShaking(0);
|
||||
CReferences::RemoveReferencesToPlayer();
|
||||
CCarCtrl::CountDownToCarsAtStart = 2;
|
||||
CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
|
||||
if (CRestart::bFadeInAfterNextDeath) {
|
||||
TheCamera.SetFadeColour(200, 200, 200);
|
||||
TheCamera.Fade(4.0f, FADE_IN);
|
||||
} else CRestart::bFadeInAfterNextDeath = true;
|
||||
}
|
||||
break;
|
||||
case WBSTATE_BUSTED:
|
||||
if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) {
|
||||
TheCamera.SetFadeColour(0, 0, 0);
|
||||
TheCamera.Fade(2.0f, FADE_OUT);
|
||||
}
|
||||
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
|
||||
pPlayerInfo.m_WBState = WBSTATE_PLAYING;
|
||||
int takeMoney;
|
||||
|
||||
switch (pPlayerInfo.m_pPed->m_pWanted->m_nWantedLevel) {
|
||||
case 0:
|
||||
case 1:
|
||||
takeMoney = 100;
|
||||
break;
|
||||
case 2:
|
||||
takeMoney = 200;
|
||||
break;
|
||||
case 3:
|
||||
takeMoney = 400;
|
||||
break;
|
||||
case 4:
|
||||
takeMoney = 600;
|
||||
break;
|
||||
case 5:
|
||||
takeMoney = 900;
|
||||
break;
|
||||
case 6:
|
||||
takeMoney = 1500;
|
||||
break;
|
||||
}
|
||||
if (pPlayerInfo.m_bGetOutOfJailFree) {
|
||||
pPlayerInfo.m_bGetOutOfJailFree = false;
|
||||
} else {
|
||||
pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - takeMoney);
|
||||
pPlayerInfo.m_pPed->ClearWeapons();
|
||||
}
|
||||
|
||||
if (pPlayerInfo.m_pPed->bInVehicle) {
|
||||
CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle;
|
||||
if (pVehicle != nil) {
|
||||
if (pVehicle->pDriver == pPlayerInfo.m_pPed) {
|
||||
pVehicle->pDriver = nil;
|
||||
if (pVehicle->m_status != STATUS_WRECKED)
|
||||
pVehicle->m_status = STATUS_ABANDONED;
|
||||
}
|
||||
else
|
||||
pVehicle->RemovePassenger(pPlayerInfo.m_pPed);
|
||||
}
|
||||
}
|
||||
CEventList::Initialise();
|
||||
CMessages::ClearMessages();
|
||||
CCarCtrl::ClearInterestingVehicleList();
|
||||
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
|
||||
CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
|
||||
CRestart::OverrideHospitalLevel = LEVEL_NONE;
|
||||
CRestart::OverridePoliceStationLevel = LEVEL_NONE;
|
||||
PassTime(720);
|
||||
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
|
||||
pPlayerInfo.m_pPed->ClearWeapons();
|
||||
SortOutStreamingAndMemory(pPlayerInfo.GetPos());
|
||||
TheCamera.m_fCamShakeForce = 0.0f;
|
||||
TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
|
||||
CPad::GetPad(0)->StopShaking(0);
|
||||
CReferences::RemoveReferencesToPlayer();
|
||||
CCarCtrl::CountDownToCarsAtStart = 2;
|
||||
CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
|
||||
if (CRestart::bFadeInAfterNextArrest) {
|
||||
TheCamera.SetFadeColour(0, 0, 0);
|
||||
TheCamera.Fade(4.0f, FADE_IN);
|
||||
} else CRestart::bFadeInAfterNextArrest = true;
|
||||
}
|
||||
break;
|
||||
case WBSTATE_FAILED_CRITICAL_MISSION:
|
||||
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800 && CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800) {
|
||||
TheCamera.SetFadeColour(0, 0, 0);
|
||||
TheCamera.Fade(2.0f, FADE_OUT);
|
||||
}
|
||||
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
|
||||
pPlayerInfo.m_WBState = WBSTATE_PLAYING;
|
||||
if (pPlayerInfo.m_pPed->bInVehicle) {
|
||||
CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle;
|
||||
if (pVehicle != nil) {
|
||||
if (pVehicle->pDriver == pPlayerInfo.m_pPed) {
|
||||
pVehicle->pDriver = nil;
|
||||
if (pVehicle->m_status != STATUS_WRECKED)
|
||||
pVehicle->m_status = STATUS_ABANDONED;
|
||||
} else
|
||||
pVehicle->RemovePassenger(pPlayerInfo.m_pPed);
|
||||
}
|
||||
}
|
||||
CEventList::Initialise();
|
||||
CMessages::ClearMessages();
|
||||
CCarCtrl::ClearInterestingVehicleList();
|
||||
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
|
||||
CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
|
||||
CRestart::OverridePoliceStationLevel = LEVEL_NONE;
|
||||
CRestart::OverrideHospitalLevel = LEVEL_NONE;
|
||||
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
|
||||
SortOutStreamingAndMemory(pPlayerInfo.GetPos());
|
||||
TheCamera.m_fCamShakeForce = 0.0f;
|
||||
TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
|
||||
CPad::GetPad(0)->StopShaking(0);
|
||||
CReferences::RemoveReferencesToPlayer();
|
||||
CCarCtrl::CountDownToCarsAtStart = 2;
|
||||
CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
|
||||
TheCamera.SetFadeColour(0, 0, 0);
|
||||
TheCamera.Fade(4.0f, FADE_IN);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector pos, float angle)
|
||||
{
|
||||
pPlayerPed->m_fHealth = 100.0f;
|
||||
pPlayerPed->m_fArmour = 0.0f;
|
||||
pPlayerPed->bIsVisible = true;
|
||||
pPlayerPed->m_bloodyFootprintCountOrDeathTime = 0;
|
||||
pPlayerPed->bDoBloodyFootprints = false;
|
||||
pPlayerPed->ClearAdrenaline();
|
||||
pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina;
|
||||
if (pPlayerPed->m_pFire)
|
||||
pPlayerPed->m_pFire->Extinguish();
|
||||
pPlayerPed->bInVehicle = false;
|
||||
pPlayerPed->m_pMyVehicle = nil;
|
||||
pPlayerPed->m_pVehicleAnim = nil;
|
||||
pPlayerPed->m_pWanted->Reset();
|
||||
pPlayerPed->RestartNonPartialAnims();
|
||||
pPlayerPed->GetPlayerInfoForThisPlayerPed()->MakePlayerSafe(false);
|
||||
pPlayerPed->bRemoveFromWorld = false;
|
||||
pPlayerPed->ClearWeaponTarget();
|
||||
pPlayerPed->SetInitialState();
|
||||
CCarCtrl::ClearInterestingVehicleList();
|
||||
|
||||
pos.z += 1.0f;
|
||||
pPlayerPed->Teleport(pos);
|
||||
pPlayerPed->SetMoveSpeed(CVector(0.0f, 0.0f, 0.0f));
|
||||
|
||||
pPlayerPed->m_fRotationCur = DEGTORAD(angle);
|
||||
pPlayerPed->m_fRotationDest = pPlayerPed->m_fRotationCur;
|
||||
pPlayerPed->SetHeading(pPlayerPed->m_fRotationCur);
|
||||
CTheScripts::ClearSpaceForMissionEntity(pos, pPlayerPed);
|
||||
CWorld::ClearExcitingStuffFromArea(pos, 4000.0, 1);
|
||||
pPlayerPed->RestoreHeadingRate();
|
||||
TheCamera.SetCameraDirectlyInFrontForFollowPed_CamOnAString();
|
||||
CReferences::RemoveReferencesToPlayer();
|
||||
CGarages::PlayerArrestedOrDied();
|
||||
CStats::CheckPointReachedUnsuccessfully();
|
||||
CWorld::Remove(pPlayerPed);
|
||||
CWorld::Add(pPlayerPed);
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x4213F0, &CGameLogic::InitAtStartOfGame, PATCH_JUMP);
|
||||
InjectHook(0x421C00, &CGameLogic::PassTime, PATCH_JUMP);
|
||||
InjectHook(0x421A20, &CGameLogic::SortOutStreamingAndMemory, PATCH_JUMP);
|
||||
InjectHook(0x421400, &CGameLogic::Update, PATCH_JUMP);
|
||||
InjectHook(0x421A60, &CGameLogic::RestorePlayerStuffDuringResurrection, PATCH_JUMP);
|
||||
InjectHook(0x421A60, &CGameLogic::RestorePlayerStuffDuringResurrection, PATCH_JUMP);
|
||||
ENDPATCHES
|
@ -1,13 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
class CGameLogic
|
||||
{
|
||||
public:
|
||||
static void InitAtStartOfGame();
|
||||
static void PassTime(uint32 time);
|
||||
static void SortOutStreamingAndMemory(const CVector &pos);
|
||||
static void Update();
|
||||
static void RestorePlayerStuffDuringResurrection(class CPlayerPed *pPlayerPed, CVector pos, float angle);
|
||||
|
||||
static uint8 ActivePlayers;
|
||||
#pragma once
|
||||
|
||||
class CGameLogic
|
||||
{
|
||||
public:
|
||||
static void InitAtStartOfGame();
|
||||
static void PassTime(uint32 time);
|
||||
static void SortOutStreamingAndMemory(const CVector &pos);
|
||||
static void Update();
|
||||
static void RestorePlayerStuffDuringResurrection(class CPlayerPed *pPlayerPed, CVector pos, float angle);
|
||||
|
||||
static uint8 ActivePlayers;
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "ModelIndices.h"
|
||||
#include "Gangs.h"
|
||||
#include "Gangs.h"
|
||||
#include "Weapon.h"
|
||||
|
||||
//CGangInfo(&CGangs::Gang)[NUM_GANGS] = *(CGangInfo(*)[NUM_GANGS])*(uintptr*)0x6EDF78;
|
||||
@ -57,20 +57,20 @@ void CGangs::SaveAllGangData(uint8 *buf, uint32 *size)
|
||||
{
|
||||
INITSAVEBUF
|
||||
|
||||
*size = SAVE_HEADER_SIZE + sizeof(Gang);
|
||||
*size = SAVE_HEADER_SIZE + sizeof(Gang);
|
||||
WriteSaveHeader(buf, 'G','N','G','\0', *size - SAVE_HEADER_SIZE);
|
||||
for (int i = 0; i < NUM_GANGS; i++)
|
||||
WriteSaveBuf(buf, Gang[i]);
|
||||
|
||||
for (int i = 0; i < NUM_GANGS; i++)
|
||||
WriteSaveBuf(buf, Gang[i]);
|
||||
|
||||
VALIDATESAVEBUF(*size);
|
||||
}
|
||||
|
||||
void CGangs::LoadAllGangData(uint8 *buf, uint32 size)
|
||||
{
|
||||
Initialise();
|
||||
|
||||
INITSAVEBUF
|
||||
// original: SkipSaveBuf(buf, SAVE_HEADER_SIZE);
|
||||
Initialise();
|
||||
|
||||
INITSAVEBUF
|
||||
// original: SkipSaveBuf(buf, SAVE_HEADER_SIZE);
|
||||
CheckSaveHeader(buf, 'G','N','G','\0', size - SAVE_HEADER_SIZE);
|
||||
|
||||
for (int i = 0; i < NUM_GANGS; i++)
|
||||
|
@ -1,49 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
COUNTER_DISPLAY_NUMBER,
|
||||
COUNTER_DISPLAY_BAR,
|
||||
};
|
||||
|
||||
class COnscreenTimerEntry
|
||||
{
|
||||
public:
|
||||
uint32 m_nTimerOffset;
|
||||
uint32 m_nCounterOffset;
|
||||
char m_aTimerText[10];
|
||||
char m_aCounterText[10];
|
||||
uint16 m_nType;
|
||||
char m_bCounterBuffer[42];
|
||||
char m_bTimerBuffer[42];
|
||||
bool m_bTimerProcessed;
|
||||
bool m_bCounterProcessed;
|
||||
|
||||
void Process();
|
||||
bool ProcessForDisplay();
|
||||
|
||||
void ProcessForDisplayClock();
|
||||
void ProcessForDisplayCounter();
|
||||
};
|
||||
|
||||
static_assert(sizeof(COnscreenTimerEntry) == 0x74, "COnscreenTimerEntry: error");
|
||||
|
||||
class COnscreenTimer
|
||||
{
|
||||
public:
|
||||
COnscreenTimerEntry m_sEntries[NUMONSCREENTIMERENTRIES];
|
||||
bool m_bProcessed;
|
||||
bool m_bDisabled;
|
||||
|
||||
void Init();
|
||||
void Process();
|
||||
void ProcessForDisplay();
|
||||
|
||||
void ClearCounter(uint32 offset);
|
||||
void ClearClock(uint32 offset);
|
||||
|
||||
void AddCounter(uint32 offset, uint16 type, char* text);
|
||||
void AddClock(uint32 offset, char* text);
|
||||
};
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
COUNTER_DISPLAY_NUMBER,
|
||||
COUNTER_DISPLAY_BAR,
|
||||
};
|
||||
|
||||
class COnscreenTimerEntry
|
||||
{
|
||||
public:
|
||||
uint32 m_nTimerOffset;
|
||||
uint32 m_nCounterOffset;
|
||||
char m_aTimerText[10];
|
||||
char m_aCounterText[10];
|
||||
uint16 m_nType;
|
||||
char m_bCounterBuffer[42];
|
||||
char m_bTimerBuffer[42];
|
||||
bool m_bTimerProcessed;
|
||||
bool m_bCounterProcessed;
|
||||
|
||||
void Process();
|
||||
bool ProcessForDisplay();
|
||||
|
||||
void ProcessForDisplayClock();
|
||||
void ProcessForDisplayCounter();
|
||||
};
|
||||
|
||||
static_assert(sizeof(COnscreenTimerEntry) == 0x74, "COnscreenTimerEntry: error");
|
||||
|
||||
class COnscreenTimer
|
||||
{
|
||||
public:
|
||||
COnscreenTimerEntry m_sEntries[NUMONSCREENTIMERENTRIES];
|
||||
bool m_bProcessed;
|
||||
bool m_bDisabled;
|
||||
|
||||
void Init();
|
||||
void Process();
|
||||
void ProcessForDisplay();
|
||||
|
||||
void ClearCounter(uint32 offset);
|
||||
void ClearClock(uint32 offset);
|
||||
|
||||
void AddCounter(uint32 offset, uint16 type, char* text);
|
||||
void AddClock(uint32 offset, char* text);
|
||||
};
|
||||
|
||||
static_assert(sizeof(COnscreenTimer) == 0x78, "COnscreenTimer: error");
|
File diff suppressed because it is too large
Load Diff
@ -1,124 +1,124 @@
|
||||
#pragma once
|
||||
#include "Weapon.h"
|
||||
|
||||
enum ePickupType : uint8
|
||||
{
|
||||
PICKUP_NONE = 0,
|
||||
PICKUP_IN_SHOP,
|
||||
PICKUP_ON_STREET,
|
||||
PICKUP_ONCE,
|
||||
PICKUP_ONCE_TIMEOUT,
|
||||
PICKUP_COLLECTABLE1,
|
||||
PICKUP_IN_SHOP_OUT_OF_STOCK,
|
||||
PICKUP_MONEY,
|
||||
PICKUP_MINE_INACTIVE,
|
||||
PICKUP_MINE_ARMED,
|
||||
PICKUP_NAUTICAL_MINE_INACTIVE,
|
||||
PICKUP_NAUTICAL_MINE_ARMED,
|
||||
PICKUP_FLOATINGPACKAGE,
|
||||
PICKUP_FLOATINGPACKAGE_FLOATING,
|
||||
PICKUP_ON_STREET_SLOW,
|
||||
PICKUP_NUMOFTYPES
|
||||
};
|
||||
|
||||
class CEntity;
|
||||
class CObject;
|
||||
class CVehicle;
|
||||
class CPlayerPed;
|
||||
|
||||
class CPickup
|
||||
{
|
||||
public:
|
||||
ePickupType m_eType;
|
||||
bool m_bRemoved;
|
||||
uint16 m_nQuantity;
|
||||
CObject *m_pObject;
|
||||
uint32 m_nTimer;
|
||||
int16 m_eModelIndex;
|
||||
uint16 m_nIndex;
|
||||
CVector m_vecPos;
|
||||
|
||||
CObject *GiveUsAPickUpObject(int32 handle);
|
||||
bool Update(CPlayerPed *player, CVehicle *vehicle, int playerId);
|
||||
private:
|
||||
bool IsMine() { return m_eType >= PICKUP_MINE_INACTIVE && m_eType <= PICKUP_FLOATINGPACKAGE_FLOATING; }
|
||||
inline bool CanBePickedUp(CPlayerPed *player);
|
||||
void RemoveKeepType();
|
||||
void Remove();
|
||||
};
|
||||
|
||||
static_assert(sizeof(CPickup) == 0x1C, "CPickup: error");
|
||||
|
||||
struct tPickupMessage
|
||||
{
|
||||
CVector2D m_pos;
|
||||
eWeaponType m_weaponType;
|
||||
CVector2D m_dist;
|
||||
CRGBA m_color;
|
||||
uint8 m_bOutOfStock : 1;
|
||||
uint8 m_quantity;
|
||||
};
|
||||
|
||||
class CPickups
|
||||
{
|
||||
static int32 aPickUpsCollected[NUMCOLLECTEDPICKUPS];
|
||||
static int16 CollectedPickUpIndex;
|
||||
static int16 NumMessages;
|
||||
static tPickupMessage aMessages[NUMPICKUPMESSAGES];
|
||||
public:
|
||||
static void Init();
|
||||
static void Update();
|
||||
static void RenderPickUpText();
|
||||
static void DoCollectableEffects(CEntity *ent);
|
||||
static void DoMoneyEffects(CEntity *ent);
|
||||
static void DoMineEffects(CEntity *ent);
|
||||
static void DoPickUpEffects(CEntity *ent);
|
||||
static int32 GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity);
|
||||
static int32 GenerateNewOne_WeaponType(CVector pos, eWeaponType weaponType, uint8 type, uint32 quantity);
|
||||
static void RemovePickUp(int32 pickupIndex);
|
||||
static void RemoveAllFloatingPickups();
|
||||
static void AddToCollectedPickupsArray(int32 index);
|
||||
static bool IsPickUpPickedUp(int32 pickupId);
|
||||
static int32 ModelForWeapon(eWeaponType weaponType);
|
||||
static enum eWeaponType WeaponForModel(int32 model);
|
||||
static int32 FindColourIndexForWeaponMI(int32 model);
|
||||
static int32 GetActualPickupIndex(int32 index);
|
||||
static int32 GetNewUniquePickupIndex(int32 slot);
|
||||
static void PassTime(uint32 time);
|
||||
static bool GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex);
|
||||
static void Load(uint8 *buf, uint32 size);
|
||||
static void Save(uint8 *buf, uint32 *size);
|
||||
|
||||
static CPickup(&aPickUps)[NUMPICKUPS];
|
||||
|
||||
// unused
|
||||
static bool &bPickUpcamActivated;
|
||||
static CVehicle *&pPlayerVehicle;
|
||||
static CVector &StaticCamCoors;
|
||||
static uint32 &StaticCamStartTime;
|
||||
};
|
||||
|
||||
extern uint16 AmmoForWeapon[20];
|
||||
extern uint16 AmmoForWeapon_OnStreet[20];
|
||||
extern uint16 CostOfWeapon[20];
|
||||
|
||||
class CPacManPickups
|
||||
{
|
||||
public:
|
||||
static void Init(void);
|
||||
static void Update(void);
|
||||
static void GeneratePMPickUps(CVector, float, int16, uint8);
|
||||
static void GeneratePMPickUpsForRace(int32);
|
||||
static void GenerateOnePMPickUp(CVector);
|
||||
static void Render(void);
|
||||
static void DoCleanUpPacManStuff(void);
|
||||
static void StartPacManRace(int32);
|
||||
static void StartPacManRecord(void);
|
||||
static uint32 QueryPowerPillsEatenInRace(void);
|
||||
static void ResetPowerPillsEatenInRace(void);
|
||||
static void CleanUpPacManStuff(void);
|
||||
static void StartPacManScramble(CVector, float, int16);
|
||||
static uint32 QueryPowerPillsCarriedByPlayer(void);
|
||||
static void ResetPowerPillsCarriedByPlayer(void);
|
||||
|
||||
};
|
||||
#pragma once
|
||||
#include "Weapon.h"
|
||||
|
||||
enum ePickupType : uint8
|
||||
{
|
||||
PICKUP_NONE = 0,
|
||||
PICKUP_IN_SHOP,
|
||||
PICKUP_ON_STREET,
|
||||
PICKUP_ONCE,
|
||||
PICKUP_ONCE_TIMEOUT,
|
||||
PICKUP_COLLECTABLE1,
|
||||
PICKUP_IN_SHOP_OUT_OF_STOCK,
|
||||
PICKUP_MONEY,
|
||||
PICKUP_MINE_INACTIVE,
|
||||
PICKUP_MINE_ARMED,
|
||||
PICKUP_NAUTICAL_MINE_INACTIVE,
|
||||
PICKUP_NAUTICAL_MINE_ARMED,
|
||||
PICKUP_FLOATINGPACKAGE,
|
||||
PICKUP_FLOATINGPACKAGE_FLOATING,
|
||||
PICKUP_ON_STREET_SLOW,
|
||||
PICKUP_NUMOFTYPES
|
||||
};
|
||||
|
||||
class CEntity;
|
||||
class CObject;
|
||||
class CVehicle;
|
||||
class CPlayerPed;
|
||||
|
||||
class CPickup
|
||||
{
|
||||
public:
|
||||
ePickupType m_eType;
|
||||
bool m_bRemoved;
|
||||
uint16 m_nQuantity;
|
||||
CObject *m_pObject;
|
||||
uint32 m_nTimer;
|
||||
int16 m_eModelIndex;
|
||||
uint16 m_nIndex;
|
||||
CVector m_vecPos;
|
||||
|
||||
CObject *GiveUsAPickUpObject(int32 handle);
|
||||
bool Update(CPlayerPed *player, CVehicle *vehicle, int playerId);
|
||||
private:
|
||||
bool IsMine() { return m_eType >= PICKUP_MINE_INACTIVE && m_eType <= PICKUP_FLOATINGPACKAGE_FLOATING; }
|
||||
inline bool CanBePickedUp(CPlayerPed *player);
|
||||
void RemoveKeepType();
|
||||
void Remove();
|
||||
};
|
||||
|
||||
static_assert(sizeof(CPickup) == 0x1C, "CPickup: error");
|
||||
|
||||
struct tPickupMessage
|
||||
{
|
||||
CVector2D m_pos;
|
||||
eWeaponType m_weaponType;
|
||||
CVector2D m_dist;
|
||||
CRGBA m_color;
|
||||
uint8 m_bOutOfStock : 1;
|
||||
uint8 m_quantity;
|
||||
};
|
||||
|
||||
class CPickups
|
||||
{
|
||||
static int32 aPickUpsCollected[NUMCOLLECTEDPICKUPS];
|
||||
static int16 CollectedPickUpIndex;
|
||||
static int16 NumMessages;
|
||||
static tPickupMessage aMessages[NUMPICKUPMESSAGES];
|
||||
public:
|
||||
static void Init();
|
||||
static void Update();
|
||||
static void RenderPickUpText();
|
||||
static void DoCollectableEffects(CEntity *ent);
|
||||
static void DoMoneyEffects(CEntity *ent);
|
||||
static void DoMineEffects(CEntity *ent);
|
||||
static void DoPickUpEffects(CEntity *ent);
|
||||
static int32 GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity);
|
||||
static int32 GenerateNewOne_WeaponType(CVector pos, eWeaponType weaponType, uint8 type, uint32 quantity);
|
||||
static void RemovePickUp(int32 pickupIndex);
|
||||
static void RemoveAllFloatingPickups();
|
||||
static void AddToCollectedPickupsArray(int32 index);
|
||||
static bool IsPickUpPickedUp(int32 pickupId);
|
||||
static int32 ModelForWeapon(eWeaponType weaponType);
|
||||
static enum eWeaponType WeaponForModel(int32 model);
|
||||
static int32 FindColourIndexForWeaponMI(int32 model);
|
||||
static int32 GetActualPickupIndex(int32 index);
|
||||
static int32 GetNewUniquePickupIndex(int32 slot);
|
||||
static void PassTime(uint32 time);
|
||||
static bool GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex);
|
||||
static void Load(uint8 *buf, uint32 size);
|
||||
static void Save(uint8 *buf, uint32 *size);
|
||||
|
||||
static CPickup(&aPickUps)[NUMPICKUPS];
|
||||
|
||||
// unused
|
||||
static bool &bPickUpcamActivated;
|
||||
static CVehicle *&pPlayerVehicle;
|
||||
static CVector &StaticCamCoors;
|
||||
static uint32 &StaticCamStartTime;
|
||||
};
|
||||
|
||||
extern uint16 AmmoForWeapon[20];
|
||||
extern uint16 AmmoForWeapon_OnStreet[20];
|
||||
extern uint16 CostOfWeapon[20];
|
||||
|
||||
class CPacManPickups
|
||||
{
|
||||
public:
|
||||
static void Init(void);
|
||||
static void Update(void);
|
||||
static void GeneratePMPickUps(CVector, float, int16, uint8);
|
||||
static void GeneratePMPickUpsForRace(int32);
|
||||
static void GenerateOnePMPickUp(CVector);
|
||||
static void Render(void);
|
||||
static void DoCleanUpPacManStuff(void);
|
||||
static void StartPacManRace(int32);
|
||||
static void StartPacManRecord(void);
|
||||
static uint32 QueryPowerPillsEatenInRace(void);
|
||||
static void ResetPowerPillsEatenInRace(void);
|
||||
static void CleanUpPacManStuff(void);
|
||||
static void StartPacManScramble(CVector, float, int16);
|
||||
static uint32 QueryPowerPillsCarriedByPlayer(void);
|
||||
static void ResetPowerPillsCarriedByPlayer(void);
|
||||
|
||||
};
|
||||
|
@ -1,22 +1,22 @@
|
||||
#include "common.h"
|
||||
#include "PowerPoints.h"
|
||||
|
||||
// Some cut beta feature
|
||||
|
||||
void CPowerPoint::Update()
|
||||
{}
|
||||
|
||||
void CPowerPoints::Init()
|
||||
{}
|
||||
|
||||
void CPowerPoints::Update()
|
||||
{}
|
||||
|
||||
void CPowerPoints::GenerateNewOne(float, float, float, float, float, float, uint8)
|
||||
{}
|
||||
|
||||
void CPowerPoints::Save(uint8**, uint32*)
|
||||
{}
|
||||
|
||||
void CPowerPoints::Load(uint8*, uint32)
|
||||
#include "common.h"
|
||||
#include "PowerPoints.h"
|
||||
|
||||
// Some cut beta feature
|
||||
|
||||
void CPowerPoint::Update()
|
||||
{}
|
||||
|
||||
void CPowerPoints::Init()
|
||||
{}
|
||||
|
||||
void CPowerPoints::Update()
|
||||
{}
|
||||
|
||||
void CPowerPoints::GenerateNewOne(float, float, float, float, float, float, uint8)
|
||||
{}
|
||||
|
||||
void CPowerPoints::Save(uint8**, uint32*)
|
||||
{}
|
||||
|
||||
void CPowerPoints::Load(uint8*, uint32)
|
||||
{}
|
@ -1,26 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
POWERPOINT_NONE = 0,
|
||||
POWERPOINT_HEALTH,
|
||||
POWERPOINT_HIDEOUT_INDUSTRIAL,
|
||||
POWERPOINT_HIDEOUT_COMMERCIAL,
|
||||
POWERPOINT_HIDEOUT_SUBURBAN
|
||||
};
|
||||
|
||||
class CPowerPoint
|
||||
{
|
||||
public:
|
||||
void Update();
|
||||
};
|
||||
|
||||
class CPowerPoints
|
||||
{
|
||||
public:
|
||||
static void Init();
|
||||
static void Update();
|
||||
static void GenerateNewOne(float, float, float, float, float, float, uint8);
|
||||
static void Save(uint8**, uint32*);
|
||||
static void Load(uint8*, uint32);
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
POWERPOINT_NONE = 0,
|
||||
POWERPOINT_HEALTH,
|
||||
POWERPOINT_HIDEOUT_INDUSTRIAL,
|
||||
POWERPOINT_HIDEOUT_COMMERCIAL,
|
||||
POWERPOINT_HIDEOUT_SUBURBAN
|
||||
};
|
||||
|
||||
class CPowerPoint
|
||||
{
|
||||
public:
|
||||
void Update();
|
||||
};
|
||||
|
||||
class CPowerPoints
|
||||
{
|
||||
public:
|
||||
static void Init();
|
||||
static void Update();
|
||||
static void GenerateNewOne(float, float, float, float, float, float, uint8);
|
||||
static void Save(uint8**, uint32*);
|
||||
static void Load(uint8*, uint32);
|
||||
};
|
@ -1129,8 +1129,8 @@ void CReplay::StoreStuffInMem(void)
|
||||
pEmptyReferences = CReferences::pEmptyList;
|
||||
pStoredCam = new uint8[sizeof(CCamera)];
|
||||
memcpy(pStoredCam, &TheCamera, sizeof(CCamera));
|
||||
pRadarBlips = new uint8[sizeof(CBlip) * NUMRADARBLIPS];
|
||||
memcpy(pRadarBlips, CRadar::ms_RadarTrace, NUMRADARBLIPS * sizeof(CBlip));
|
||||
pRadarBlips = new uint8[sizeof(sRadarTrace) * NUMRADARBLIPS];
|
||||
memcpy(pRadarBlips, CRadar::ms_RadarTrace, NUMRADARBLIPS * sizeof(sRadarTrace));
|
||||
PlayerWanted = *FindPlayerPed()->m_pWanted;
|
||||
PlayerInfo = CWorld::Players[0];
|
||||
Time1 = CTimer::GetTimeInMilliseconds();
|
||||
@ -1179,7 +1179,7 @@ void CReplay::RestoreStuffFromMem(void)
|
||||
memcpy(&TheCamera, pStoredCam, sizeof(CCamera));
|
||||
delete[] pStoredCam;
|
||||
pStoredCam = nil;
|
||||
memcpy(CRadar::ms_RadarTrace, pRadarBlips, sizeof(CBlip) * NUMRADARBLIPS);
|
||||
memcpy(CRadar::ms_RadarTrace, pRadarBlips, sizeof(sRadarTrace) * NUMRADARBLIPS);
|
||||
delete[] pRadarBlips;
|
||||
pRadarBlips = nil;
|
||||
FindPlayerPed()->m_pWanted = new CWanted(PlayerWanted);
|
||||
|
@ -21,234 +21,234 @@ CVector(&CRestart::PoliceRestartPoints)[NUM_RESTART_POINTS] = *(CVector(*)[NUM_R
|
||||
float(&CRestart::PoliceRestartHeadings)[NUM_RESTART_POINTS] = *(float(*)[NUM_RESTART_POINTS])*(uintptr*)0x6F1D20;
|
||||
uint16 &CRestart::NumberOfPoliceRestarts = *(uint16*)0x95CC44;
|
||||
|
||||
void
|
||||
CRestart::Initialise()
|
||||
{
|
||||
OverridePoliceStationLevel = LEVEL_NONE;
|
||||
OverrideHospitalLevel = LEVEL_NONE;
|
||||
bFadeInAfterNextArrest = true;
|
||||
bFadeInAfterNextDeath = true;
|
||||
OverrideHeading = 0.0f;
|
||||
OverridePosition = CVector(0.0f, 0.0f, 0.0f);
|
||||
bOverrideRestart = false;
|
||||
NumberOfPoliceRestarts = 0;
|
||||
NumberOfHospitalRestarts = 0;
|
||||
|
||||
for (int i = 0; i < NUM_RESTART_POINTS; i++) {
|
||||
HospitalRestartPoints[i] = CVector(0.0f, 0.0f, 0.0f);
|
||||
HospitalRestartHeadings[i] = 0.0f;
|
||||
PoliceRestartPoints[i] = CVector(0.0f, 0.0f, 0.0f);
|
||||
PoliceRestartHeadings[i] = 0.0f;
|
||||
}
|
||||
void
|
||||
CRestart::Initialise()
|
||||
{
|
||||
OverridePoliceStationLevel = LEVEL_NONE;
|
||||
OverrideHospitalLevel = LEVEL_NONE;
|
||||
bFadeInAfterNextArrest = true;
|
||||
bFadeInAfterNextDeath = true;
|
||||
OverrideHeading = 0.0f;
|
||||
OverridePosition = CVector(0.0f, 0.0f, 0.0f);
|
||||
bOverrideRestart = false;
|
||||
NumberOfPoliceRestarts = 0;
|
||||
NumberOfHospitalRestarts = 0;
|
||||
|
||||
for (int i = 0; i < NUM_RESTART_POINTS; i++) {
|
||||
HospitalRestartPoints[i] = CVector(0.0f, 0.0f, 0.0f);
|
||||
HospitalRestartHeadings[i] = 0.0f;
|
||||
PoliceRestartPoints[i] = CVector(0.0f, 0.0f, 0.0f);
|
||||
PoliceRestartHeadings[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CRestart::AddHospitalRestartPoint(const CVector &pos, float heading)
|
||||
{
|
||||
HospitalRestartPoints[NumberOfHospitalRestarts] = pos;
|
||||
HospitalRestartHeadings[NumberOfHospitalRestarts++] = heading;
|
||||
void
|
||||
CRestart::AddHospitalRestartPoint(const CVector &pos, float heading)
|
||||
{
|
||||
HospitalRestartPoints[NumberOfHospitalRestarts] = pos;
|
||||
HospitalRestartHeadings[NumberOfHospitalRestarts++] = heading;
|
||||
}
|
||||
|
||||
void
|
||||
CRestart::AddPoliceRestartPoint(const CVector &pos, float heading)
|
||||
{
|
||||
PoliceRestartPoints[NumberOfPoliceRestarts] = pos;
|
||||
PoliceRestartHeadings[NumberOfPoliceRestarts++] = heading;
|
||||
void
|
||||
CRestart::AddPoliceRestartPoint(const CVector &pos, float heading)
|
||||
{
|
||||
PoliceRestartPoints[NumberOfPoliceRestarts] = pos;
|
||||
PoliceRestartHeadings[NumberOfPoliceRestarts++] = heading;
|
||||
}
|
||||
|
||||
void
|
||||
CRestart::OverrideNextRestart(const CVector &pos, float heading)
|
||||
{
|
||||
bOverrideRestart = true;
|
||||
OverridePosition = pos;
|
||||
OverrideHeading = heading;
|
||||
void
|
||||
CRestart::OverrideNextRestart(const CVector &pos, float heading)
|
||||
{
|
||||
bOverrideRestart = true;
|
||||
OverridePosition = pos;
|
||||
OverrideHeading = heading;
|
||||
}
|
||||
|
||||
void
|
||||
CRestart::CancelOverrideRestart()
|
||||
{
|
||||
bOverrideRestart = false;
|
||||
void
|
||||
CRestart::CancelOverrideRestart()
|
||||
{
|
||||
bOverrideRestart = false;
|
||||
}
|
||||
|
||||
void
|
||||
CRestart::FindClosestHospitalRestartPoint(const CVector &pos, CVector *outPos, float *outHeading)
|
||||
{
|
||||
if (bOverrideRestart) {
|
||||
*outPos = OverridePosition;
|
||||
*outHeading = OverrideHeading;
|
||||
CancelOverrideRestart();
|
||||
return;
|
||||
}
|
||||
|
||||
eLevelName curlevel = CTheZones::FindZoneForPoint(pos);
|
||||
float fMinDist = 16000000.0f;
|
||||
int closestPoint = NUM_RESTART_POINTS;
|
||||
|
||||
// find closest point on this level
|
||||
for (int i = 0; i < NumberOfHospitalRestarts; i++) {
|
||||
if (CTheZones::FindZoneForPoint(HospitalRestartPoints[i]) == (OverrideHospitalLevel != LEVEL_NONE ? OverrideHospitalLevel : curlevel)) {
|
||||
float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr();
|
||||
if (fMinDist >= dist) {
|
||||
fMinDist = dist;
|
||||
closestPoint = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we didn't find anything, find closest point on any level
|
||||
if (closestPoint == NUM_RESTART_POINTS) {
|
||||
for (int i = 0; i < NumberOfHospitalRestarts; i++) {
|
||||
float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr();
|
||||
if (fMinDist >= dist) {
|
||||
fMinDist = dist;
|
||||
closestPoint = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we still didn't find anything, find closest path node
|
||||
if (closestPoint == NUM_RESTART_POINTS) {
|
||||
*outPos = ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, PATH_PED, 999999.9f)].pos;
|
||||
*outHeading = 0.0f;
|
||||
printf("Couldn't find a hospital restart zone near the player %f %f %f->%f %f %f\n", pos.x, pos.y, pos.z, outPos->x, outPos->y, outPos->z);
|
||||
} else {
|
||||
*outPos = HospitalRestartPoints[closestPoint];
|
||||
*outHeading = HospitalRestartHeadings[closestPoint];
|
||||
}
|
||||
void
|
||||
CRestart::FindClosestHospitalRestartPoint(const CVector &pos, CVector *outPos, float *outHeading)
|
||||
{
|
||||
if (bOverrideRestart) {
|
||||
*outPos = OverridePosition;
|
||||
*outHeading = OverrideHeading;
|
||||
CancelOverrideRestart();
|
||||
return;
|
||||
}
|
||||
|
||||
eLevelName curlevel = CTheZones::FindZoneForPoint(pos);
|
||||
float fMinDist = 16000000.0f;
|
||||
int closestPoint = NUM_RESTART_POINTS;
|
||||
|
||||
// find closest point on this level
|
||||
for (int i = 0; i < NumberOfHospitalRestarts; i++) {
|
||||
if (CTheZones::FindZoneForPoint(HospitalRestartPoints[i]) == (OverrideHospitalLevel != LEVEL_NONE ? OverrideHospitalLevel : curlevel)) {
|
||||
float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr();
|
||||
if (fMinDist >= dist) {
|
||||
fMinDist = dist;
|
||||
closestPoint = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we didn't find anything, find closest point on any level
|
||||
if (closestPoint == NUM_RESTART_POINTS) {
|
||||
for (int i = 0; i < NumberOfHospitalRestarts; i++) {
|
||||
float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr();
|
||||
if (fMinDist >= dist) {
|
||||
fMinDist = dist;
|
||||
closestPoint = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we still didn't find anything, find closest path node
|
||||
if (closestPoint == NUM_RESTART_POINTS) {
|
||||
*outPos = ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, PATH_PED, 999999.9f)].pos;
|
||||
*outHeading = 0.0f;
|
||||
printf("Couldn't find a hospital restart zone near the player %f %f %f->%f %f %f\n", pos.x, pos.y, pos.z, outPos->x, outPos->y, outPos->z);
|
||||
} else {
|
||||
*outPos = HospitalRestartPoints[closestPoint];
|
||||
*outHeading = HospitalRestartHeadings[closestPoint];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CRestart::FindClosestPoliceRestartPoint(const CVector &pos, CVector *outPos, float *outHeading)
|
||||
{
|
||||
if (bOverrideRestart) {
|
||||
*outPos = OverridePosition;
|
||||
*outHeading = OverrideHeading;
|
||||
CancelOverrideRestart();
|
||||
return;
|
||||
}
|
||||
|
||||
eLevelName curlevel = CTheZones::FindZoneForPoint(pos);
|
||||
float fMinDist = 16000000.0f;
|
||||
int closestPoint = NUM_RESTART_POINTS;
|
||||
|
||||
// find closest point on this level
|
||||
for (int i = 0; i < NumberOfPoliceRestarts; i++) {
|
||||
if (CTheZones::FindZoneForPoint(PoliceRestartPoints[i]) == (OverridePoliceStationLevel != LEVEL_NONE ? OverridePoliceStationLevel : curlevel)) {
|
||||
float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr();
|
||||
if (fMinDist >= dist) {
|
||||
fMinDist = dist;
|
||||
closestPoint = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we didn't find anything, find closest point on any level
|
||||
if (closestPoint == NUM_RESTART_POINTS) {
|
||||
for (int i = 0; i < NumberOfPoliceRestarts; i++) {
|
||||
float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr();
|
||||
if (fMinDist >= dist) {
|
||||
fMinDist = dist;
|
||||
closestPoint = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we still didn't find anything, find closest path node
|
||||
if (closestPoint == NUM_RESTART_POINTS) {
|
||||
printf("Couldn't find a police restart zone near the player\n");
|
||||
*outPos = ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, PATH_PED, 999999.9f)].pos;
|
||||
*outHeading = 0.0f;
|
||||
} else {
|
||||
*outPos = PoliceRestartPoints[closestPoint];
|
||||
*outHeading = PoliceRestartHeadings[closestPoint];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CRestart::LoadAllRestartPoints(uint8 *buf, uint32 size)
|
||||
{
|
||||
Initialise();
|
||||
|
||||
INITSAVEBUF
|
||||
CheckSaveHeader(buf, 'R','S','T','\0', size - SAVE_HEADER_SIZE);
|
||||
|
||||
for (int i = 0; i < NUM_RESTART_POINTS; i++) {
|
||||
HospitalRestartPoints[i] = ReadSaveBuf<CVector>(buf);
|
||||
HospitalRestartHeadings[i] = ReadSaveBuf<float>(buf);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUM_RESTART_POINTS; i++) {
|
||||
PoliceRestartPoints[i] = ReadSaveBuf<CVector>(buf);
|
||||
PoliceRestartHeadings[i] = ReadSaveBuf<float>(buf);
|
||||
}
|
||||
|
||||
NumberOfHospitalRestarts = ReadSaveBuf<uint16>(buf);
|
||||
NumberOfPoliceRestarts = ReadSaveBuf<uint16>(buf);
|
||||
bOverrideRestart = ReadSaveBuf<bool>(buf);
|
||||
|
||||
// skip something unused
|
||||
ReadSaveBuf<uint8>(buf);
|
||||
ReadSaveBuf<uint16>(buf);
|
||||
|
||||
OverridePosition = ReadSaveBuf<CVector>(buf);
|
||||
OverrideHeading = ReadSaveBuf<float>(buf);
|
||||
bFadeInAfterNextDeath = ReadSaveBuf<bool>(buf);
|
||||
bFadeInAfterNextArrest = ReadSaveBuf<bool>(buf);
|
||||
OverrideHospitalLevel = ReadSaveBuf<uint8>(buf);
|
||||
OverridePoliceStationLevel = ReadSaveBuf<uint8>(buf);
|
||||
VALIDATESAVEBUF(size);
|
||||
}
|
||||
|
||||
void
|
||||
CRestart::SaveAllRestartPoints(uint8 *buf, uint32 *size)
|
||||
{
|
||||
*size = SAVE_HEADER_SIZE
|
||||
+ sizeof(HospitalRestartPoints)
|
||||
+ sizeof(HospitalRestartHeadings)
|
||||
+ sizeof(PoliceRestartPoints)
|
||||
+ sizeof(PoliceRestartHeadings)
|
||||
+ sizeof(NumberOfHospitalRestarts)
|
||||
+ sizeof(NumberOfPoliceRestarts)
|
||||
+ sizeof(bOverrideRestart)
|
||||
+ sizeof(uint8)
|
||||
+ sizeof(uint16)
|
||||
+ sizeof(OverridePosition)
|
||||
+ sizeof(OverrideHeading)
|
||||
+ sizeof(bFadeInAfterNextDeath)
|
||||
+ sizeof(bFadeInAfterNextArrest)
|
||||
+ sizeof(OverrideHospitalLevel)
|
||||
+ sizeof(OverridePoliceStationLevel); // == 292
|
||||
|
||||
INITSAVEBUF
|
||||
WriteSaveHeader(buf, 'R','S','T','\0', *size - SAVE_HEADER_SIZE);
|
||||
|
||||
for (int i = 0; i < NUM_RESTART_POINTS; i++) {
|
||||
WriteSaveBuf(buf, HospitalRestartPoints[i]);
|
||||
WriteSaveBuf(buf, HospitalRestartHeadings[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUM_RESTART_POINTS; i++) {
|
||||
WriteSaveBuf(buf, PoliceRestartPoints[i]);
|
||||
WriteSaveBuf(buf, PoliceRestartHeadings[i]);
|
||||
}
|
||||
|
||||
WriteSaveBuf(buf, NumberOfHospitalRestarts);
|
||||
WriteSaveBuf(buf, NumberOfPoliceRestarts);
|
||||
WriteSaveBuf(buf, bOverrideRestart);
|
||||
|
||||
WriteSaveBuf(buf, (uint8)0);
|
||||
WriteSaveBuf(buf, (uint16)0);
|
||||
|
||||
WriteSaveBuf(buf, OverridePosition);
|
||||
WriteSaveBuf(buf, OverrideHeading);
|
||||
WriteSaveBuf(buf, bFadeInAfterNextDeath);
|
||||
WriteSaveBuf(buf, bFadeInAfterNextArrest);
|
||||
WriteSaveBuf(buf, OverrideHospitalLevel);
|
||||
WriteSaveBuf(buf, OverridePoliceStationLevel);
|
||||
VALIDATESAVEBUF(*size);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CRestart::FindClosestPoliceRestartPoint(const CVector &pos, CVector *outPos, float *outHeading)
|
||||
{
|
||||
if (bOverrideRestart) {
|
||||
*outPos = OverridePosition;
|
||||
*outHeading = OverrideHeading;
|
||||
CancelOverrideRestart();
|
||||
return;
|
||||
}
|
||||
|
||||
eLevelName curlevel = CTheZones::FindZoneForPoint(pos);
|
||||
float fMinDist = 16000000.0f;
|
||||
int closestPoint = NUM_RESTART_POINTS;
|
||||
|
||||
// find closest point on this level
|
||||
for (int i = 0; i < NumberOfPoliceRestarts; i++) {
|
||||
if (CTheZones::FindZoneForPoint(PoliceRestartPoints[i]) == (OverridePoliceStationLevel != LEVEL_NONE ? OverridePoliceStationLevel : curlevel)) {
|
||||
float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr();
|
||||
if (fMinDist >= dist) {
|
||||
fMinDist = dist;
|
||||
closestPoint = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we didn't find anything, find closest point on any level
|
||||
if (closestPoint == NUM_RESTART_POINTS) {
|
||||
for (int i = 0; i < NumberOfPoliceRestarts; i++) {
|
||||
float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr();
|
||||
if (fMinDist >= dist) {
|
||||
fMinDist = dist;
|
||||
closestPoint = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we still didn't find anything, find closest path node
|
||||
if (closestPoint == NUM_RESTART_POINTS) {
|
||||
printf("Couldn't find a police restart zone near the player\n");
|
||||
*outPos = ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, PATH_PED, 999999.9f)].pos;
|
||||
*outHeading = 0.0f;
|
||||
} else {
|
||||
*outPos = PoliceRestartPoints[closestPoint];
|
||||
*outHeading = PoliceRestartHeadings[closestPoint];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CRestart::LoadAllRestartPoints(uint8 *buf, uint32 size)
|
||||
{
|
||||
Initialise();
|
||||
|
||||
INITSAVEBUF
|
||||
CheckSaveHeader(buf, 'R','S','T','\0', size - SAVE_HEADER_SIZE);
|
||||
|
||||
for (int i = 0; i < NUM_RESTART_POINTS; i++) {
|
||||
HospitalRestartPoints[i] = ReadSaveBuf<CVector>(buf);
|
||||
HospitalRestartHeadings[i] = ReadSaveBuf<float>(buf);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUM_RESTART_POINTS; i++) {
|
||||
PoliceRestartPoints[i] = ReadSaveBuf<CVector>(buf);
|
||||
PoliceRestartHeadings[i] = ReadSaveBuf<float>(buf);
|
||||
}
|
||||
|
||||
NumberOfHospitalRestarts = ReadSaveBuf<uint16>(buf);
|
||||
NumberOfPoliceRestarts = ReadSaveBuf<uint16>(buf);
|
||||
bOverrideRestart = ReadSaveBuf<bool>(buf);
|
||||
|
||||
// skip something unused
|
||||
ReadSaveBuf<uint8>(buf);
|
||||
ReadSaveBuf<uint16>(buf);
|
||||
|
||||
OverridePosition = ReadSaveBuf<CVector>(buf);
|
||||
OverrideHeading = ReadSaveBuf<float>(buf);
|
||||
bFadeInAfterNextDeath = ReadSaveBuf<bool>(buf);
|
||||
bFadeInAfterNextArrest = ReadSaveBuf<bool>(buf);
|
||||
OverrideHospitalLevel = ReadSaveBuf<uint8>(buf);
|
||||
OverridePoliceStationLevel = ReadSaveBuf<uint8>(buf);
|
||||
VALIDATESAVEBUF(size);
|
||||
}
|
||||
|
||||
void
|
||||
CRestart::SaveAllRestartPoints(uint8 *buf, uint32 *size)
|
||||
{
|
||||
*size = SAVE_HEADER_SIZE
|
||||
+ sizeof(HospitalRestartPoints)
|
||||
+ sizeof(HospitalRestartHeadings)
|
||||
+ sizeof(PoliceRestartPoints)
|
||||
+ sizeof(PoliceRestartHeadings)
|
||||
+ sizeof(NumberOfHospitalRestarts)
|
||||
+ sizeof(NumberOfPoliceRestarts)
|
||||
+ sizeof(bOverrideRestart)
|
||||
+ sizeof(uint8)
|
||||
+ sizeof(uint16)
|
||||
+ sizeof(OverridePosition)
|
||||
+ sizeof(OverrideHeading)
|
||||
+ sizeof(bFadeInAfterNextDeath)
|
||||
+ sizeof(bFadeInAfterNextArrest)
|
||||
+ sizeof(OverrideHospitalLevel)
|
||||
+ sizeof(OverridePoliceStationLevel); // == 292
|
||||
|
||||
INITSAVEBUF
|
||||
WriteSaveHeader(buf, 'R','S','T','\0', *size - SAVE_HEADER_SIZE);
|
||||
|
||||
for (int i = 0; i < NUM_RESTART_POINTS; i++) {
|
||||
WriteSaveBuf(buf, HospitalRestartPoints[i]);
|
||||
WriteSaveBuf(buf, HospitalRestartHeadings[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUM_RESTART_POINTS; i++) {
|
||||
WriteSaveBuf(buf, PoliceRestartPoints[i]);
|
||||
WriteSaveBuf(buf, PoliceRestartHeadings[i]);
|
||||
}
|
||||
|
||||
WriteSaveBuf(buf, NumberOfHospitalRestarts);
|
||||
WriteSaveBuf(buf, NumberOfPoliceRestarts);
|
||||
WriteSaveBuf(buf, bOverrideRestart);
|
||||
|
||||
WriteSaveBuf(buf, (uint8)0);
|
||||
WriteSaveBuf(buf, (uint16)0);
|
||||
|
||||
WriteSaveBuf(buf, OverridePosition);
|
||||
WriteSaveBuf(buf, OverrideHeading);
|
||||
WriteSaveBuf(buf, bFadeInAfterNextDeath);
|
||||
WriteSaveBuf(buf, bFadeInAfterNextArrest);
|
||||
WriteSaveBuf(buf, OverrideHospitalLevel);
|
||||
WriteSaveBuf(buf, OverridePoliceStationLevel);
|
||||
VALIDATESAVEBUF(*size);
|
||||
}
|
||||
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x435E20, &CRestart::Initialise, PATCH_JUMP);
|
||||
InjectHook(0x436100, &CRestart::AddHospitalRestartPoint, PATCH_JUMP);
|
||||
@ -258,5 +258,5 @@ STARTPATCHES
|
||||
InjectHook(0x4361A0, &CRestart::FindClosestHospitalRestartPoint, PATCH_JUMP);
|
||||
InjectHook(0x436450, &CRestart::FindClosestPoliceRestartPoint, PATCH_JUMP);
|
||||
InjectHook(0x436B20, &CRestart::LoadAllRestartPoints, PATCH_JUMP);
|
||||
InjectHook(0x436700, &CRestart::SaveAllRestartPoints, PATCH_JUMP);
|
||||
InjectHook(0x436700, &CRestart::SaveAllRestartPoints, PATCH_JUMP);
|
||||
ENDPATCHES
|
@ -91,10 +91,10 @@ uint8 (&CTheScripts::ScriptSpace)[SIZE_SCRIPT_SPACE] = *(uint8(*)[SIZE_SCRIPT_SP
|
||||
CRunningScript(&CTheScripts::ScriptsArray)[MAX_NUM_SCRIPTS] = *(CRunningScript(*)[MAX_NUM_SCRIPTS])*(uintptr*)0x6F5C08;
|
||||
int32(&CTheScripts::BaseBriefIdForContact)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x880200;
|
||||
int32(&CTheScripts::OnAMissionForContactFlag)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x8622F0;
|
||||
CTextLine (&CTheScripts::IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES] = *(CTextLine (*)[MAX_NUM_INTRO_TEXT_LINES])*(uintptr*)0x70EA68;
|
||||
CScriptRectangle (&CTheScripts::IntroRectangles)[MAX_NUM_INTRO_RECTANGLES] = *(CScriptRectangle (*)[MAX_NUM_INTRO_RECTANGLES])*(uintptr*)0x72D108;
|
||||
intro_text_line (&CTheScripts::IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES] = *(intro_text_line (*)[MAX_NUM_INTRO_TEXT_LINES])*(uintptr*)0x70EA68;
|
||||
intro_script_rectangle (&CTheScripts::IntroRectangles)[MAX_NUM_INTRO_RECTANGLES] = *(intro_script_rectangle (*)[MAX_NUM_INTRO_RECTANGLES])*(uintptr*)0x72D108;
|
||||
CSprite2d (&CTheScripts::ScriptSprites)[MAX_NUM_SCRIPT_SRPITES] = *(CSprite2d(*)[MAX_NUM_SCRIPT_SRPITES])*(uintptr*)0x72B090;
|
||||
CScriptSphere(&CTheScripts::ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES] = *(CScriptSphere(*)[MAX_NUM_SCRIPT_SPHERES])*(uintptr*)0x727D60;
|
||||
script_sphere_struct(&CTheScripts::ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES] = *(script_sphere_struct(*)[MAX_NUM_SCRIPT_SPHERES])*(uintptr*)0x727D60;
|
||||
tCollectiveData(&CTheScripts::CollectiveArray)[MAX_NUM_COLLECTIVES] = *(tCollectiveData(*)[MAX_NUM_COLLECTIVES])*(uintptr*)0x6FA008;
|
||||
tUsedObject(&CTheScripts::UsedObjectArray)[MAX_NUM_USED_OBJECTS] = *(tUsedObject(*)[MAX_NUM_USED_OBJECTS])*(uintptr*)0x6E69C8;
|
||||
int32(&CTheScripts::MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS] = *(int32(*)[MAX_NUM_MISSION_SCRIPTS])*(uintptr*)0x6F0558;
|
||||
@ -313,7 +313,7 @@ bool CUpsideDownCarCheck::HasCarBeenUpsideDownForAWhile(int32 id)
|
||||
return false;
|
||||
}
|
||||
|
||||
void CStuckCarCheckEntry::Reset()
|
||||
void stuck_car_data::Reset()
|
||||
{
|
||||
m_nVehicleIndex = -1;
|
||||
m_vecPos = CVector(-5000.0f, -5000.0f, -5000.0f);
|
||||
@ -8442,7 +8442,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
|
||||
CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
|
||||
CPad::GetPad(ScriptParams[0])->DisablePlayerControls |= PLAYERCONTROL_DISABLED_80;
|
||||
pPlayerInfo->MakePlayerSafe(true);
|
||||
CCutsceneMgr::SetRunning(true);
|
||||
CCutsceneMgr::StartCutsceneProcessing();
|
||||
return 0;
|
||||
}
|
||||
case COMMAND_USE_TEXT_COMMANDS:
|
||||
@ -11373,15 +11373,15 @@ void CTheScripts::ClearSpaceForMissionEntity(const CVector& pos, CEntity* pEntit
|
||||
continue;
|
||||
CEntity* pFound = aEntities[i];
|
||||
int cols;
|
||||
if (CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel()->numLines <= 0)
|
||||
cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel(),
|
||||
pFound->GetMatrix(), *CModelInfo::GetModelInfo(pFound->GetModelIndex())->GetColModel(), aTempColPoints, nil, nil);
|
||||
if (pEntity->GetColModel()->numLines <= 0)
|
||||
cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *pEntity->GetColModel(),
|
||||
pFound->GetMatrix(), *pFound->GetColModel(), aTempColPoints, nil, nil);
|
||||
else {
|
||||
float lines[4];
|
||||
lines[0] = lines[1] = lines[2] = lines[3] = 1.0f;
|
||||
CColPoint tmp;
|
||||
cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel(),
|
||||
pFound->GetMatrix(), *CModelInfo::GetModelInfo(pFound->GetModelIndex())->GetColModel(), aTempColPoints, &tmp, lines);
|
||||
CColPoint tmp[4];
|
||||
cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *pEntity->GetColModel(),
|
||||
pFound->GetMatrix(), *pFound->GetColModel(), aTempColPoints,tmp, lines);
|
||||
}
|
||||
if (cols <= 0)
|
||||
continue;
|
||||
|
@ -15,22 +15,25 @@ class CRunningScript;
|
||||
|
||||
#define KEY_LENGTH_IN_SCRIPT 8
|
||||
|
||||
struct CScriptRectangle
|
||||
struct intro_script_rectangle
|
||||
{
|
||||
bool m_bIsUsed;
|
||||
bool m_bBeforeFade;
|
||||
int16 m_nTextureId;
|
||||
CRect m_sRect;
|
||||
CRGBA m_sColor;
|
||||
|
||||
intro_script_rectangle() { }
|
||||
~intro_script_rectangle() { }
|
||||
};
|
||||
|
||||
static_assert(sizeof(CScriptRectangle) == 0x18, "Script.h: error");
|
||||
static_assert(sizeof(intro_script_rectangle) == 0x18, "Script.h: error");
|
||||
|
||||
enum {
|
||||
SCRIPT_TEXT_MAX_LENGTH = 500
|
||||
};
|
||||
|
||||
struct CTextLine
|
||||
struct intro_text_line
|
||||
{
|
||||
float m_fScaleX;
|
||||
float m_fScaleY;
|
||||
@ -50,6 +53,9 @@ struct CTextLine
|
||||
float m_fAtY;
|
||||
wchar m_Text[SCRIPT_TEXT_MAX_LENGTH];
|
||||
|
||||
intro_text_line() { }
|
||||
~intro_text_line() { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_fScaleX = 0.48f;
|
||||
@ -72,15 +78,17 @@ struct CTextLine
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(CTextLine) == 0x414, "Script.h: error");
|
||||
static_assert(sizeof(intro_text_line) == 0x414, "Script.h: error");
|
||||
|
||||
struct CScriptSphere
|
||||
struct script_sphere_struct
|
||||
{
|
||||
bool m_bInUse;
|
||||
uint16 m_Index;
|
||||
uint32 m_Id;
|
||||
CVector m_vecCenter;
|
||||
float m_fRadius;
|
||||
|
||||
script_sphere_struct() { }
|
||||
};
|
||||
|
||||
struct CStoredLine
|
||||
@ -145,7 +153,7 @@ public:
|
||||
bool HasCarBeenUpsideDownForAWhile(int32);
|
||||
};
|
||||
|
||||
struct CStuckCarCheckEntry
|
||||
struct stuck_car_data
|
||||
{
|
||||
int32 m_nVehicleIndex;
|
||||
CVector m_vecPos;
|
||||
@ -154,12 +162,13 @@ struct CStuckCarCheckEntry
|
||||
uint32 m_nStuckTime;
|
||||
bool m_bStuck;
|
||||
|
||||
stuck_car_data() { }
|
||||
inline void Reset();
|
||||
};
|
||||
|
||||
class CStuckCarCheck
|
||||
{
|
||||
CStuckCarCheckEntry m_sCars[MAX_STUCK_CAR_CHECKS];
|
||||
stuck_car_data m_sCars[MAX_STUCK_CAR_CHECKS];
|
||||
|
||||
public:
|
||||
void Init();
|
||||
@ -235,10 +244,10 @@ class CTheScripts
|
||||
static CRunningScript(&ScriptsArray)[MAX_NUM_SCRIPTS];
|
||||
static int32(&BaseBriefIdForContact)[MAX_NUM_CONTACTS];
|
||||
static int32(&OnAMissionForContactFlag)[MAX_NUM_CONTACTS];
|
||||
static CTextLine(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES];
|
||||
static CScriptRectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES];
|
||||
static intro_text_line(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES];
|
||||
static intro_script_rectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES];
|
||||
static CSprite2d(&ScriptSprites)[MAX_NUM_SCRIPT_SRPITES];
|
||||
static CScriptSphere(&ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES];
|
||||
static script_sphere_struct(&ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES];
|
||||
static tCollectiveData(&CollectiveArray)[MAX_NUM_COLLECTIVES];
|
||||
static tUsedObject(&UsedObjectArray)[MAX_NUM_USED_OBJECTS];
|
||||
static int32(&MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS];
|
||||
|
@ -142,7 +142,7 @@ CCamera::Init(void)
|
||||
PlayerExhaustion = 1.0f;
|
||||
DebugCamMode = CCam::MODE_NONE;
|
||||
m_PedOrientForBehindOrInFront = 0.0f;
|
||||
if(!FrontEndMenuManager.m_bStartGameLoading){
|
||||
if(!FrontEndMenuManager.m_bWantToRestart){
|
||||
m_bFading = false;
|
||||
CDraw::FadeValue = 0;
|
||||
m_fFLOATingFade = 0.0f;
|
||||
@ -151,7 +151,7 @@ CCamera::Init(void)
|
||||
m_fFLOATingFadeMusic = 0.0f;
|
||||
}
|
||||
m_bMoveCamToAvoidGeom = false;
|
||||
if(FrontEndMenuManager.m_bStartGameLoading)
|
||||
if(FrontEndMenuManager.m_bWantToRestart)
|
||||
m_bMoveCamToAvoidGeom = true;
|
||||
m_bStartingSpline = false;
|
||||
m_iTypeOfSwitch = INTERPOLATION;
|
||||
@ -3269,7 +3269,7 @@ void
|
||||
CCamera::SetRwCamera(RwCamera *cam)
|
||||
{
|
||||
m_pRwCamera = cam;
|
||||
m_viewMatrix.Attach(&m_pRwCamera->viewMatrix, false);
|
||||
m_viewMatrix.Attach(RwCameraGetViewMatrix(m_pRwCamera), false);
|
||||
CMBlur::MotionBlurOpen(m_pRwCamera);
|
||||
}
|
||||
|
||||
|
@ -311,7 +311,7 @@ CFileLoader::FindRelatedModelInfoCB(RpAtomic *atomic, void *data)
|
||||
int n;
|
||||
RpClump *clump = (RpClump*)data;
|
||||
|
||||
nodename = GetFrameNodeName(RpClumpGetFrame(atomic));
|
||||
nodename = GetFrameNodeName(RpAtomicGetFrame(atomic));
|
||||
GetNameAndLOD(nodename, name, &n);
|
||||
mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(name, nil);
|
||||
if(mi){
|
||||
|
@ -555,7 +555,7 @@ void CMenuManager::DoSettingsBeforeStartingAGame()
|
||||
m_PrefsVsync = m_PrefsVsyncDisp;
|
||||
|
||||
DMAudio.Service();
|
||||
m_bStartGameLoading = true;
|
||||
m_bWantToRestart = true;
|
||||
|
||||
ShutdownJustMenu();
|
||||
UnloadTextures();
|
||||
@ -2819,7 +2819,7 @@ void CMenuManager::Process(void)
|
||||
if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus() != FADE_0)
|
||||
return;
|
||||
|
||||
m_bStartGameLoading = false;
|
||||
m_bWantToRestart = false;
|
||||
InitialiseChangedLanguageSettings();
|
||||
|
||||
if (CPad::GetPad(0)->GetEscapeJustDown())
|
||||
@ -2861,9 +2861,9 @@ void CMenuManager::Process(void)
|
||||
if (m_PrefsVsyncDisp != m_PrefsVsync)
|
||||
m_PrefsVsync = m_PrefsVsyncDisp;
|
||||
DMAudio.Service();
|
||||
m_bStartGameLoading = true;
|
||||
m_bWantToRestart = true;
|
||||
RequestFrontEndShutDown();
|
||||
m_bLoadingSavedGame = true;
|
||||
m_bWantToLoad = true;
|
||||
b_FoundRecentSavedGameWantToLoad = true;
|
||||
DMAudio.SetEffectsFadeVol(0);
|
||||
DMAudio.SetMusicFadeVol(0);
|
||||
@ -2960,7 +2960,7 @@ void CMenuManager::Process(void)
|
||||
m_bWaitingForNewKeyBind = false;
|
||||
}
|
||||
|
||||
if (!m_bStartGameLoading) {
|
||||
if (!m_bWantToRestart) {
|
||||
if (m_bGameNotLoaded)
|
||||
DMAudio.Service();
|
||||
}
|
||||
|
@ -464,7 +464,7 @@ public:
|
||||
bool m_bMenuActive;
|
||||
bool m_bMenuStateChanged;
|
||||
bool m_bWaitingForNewKeyBind;
|
||||
bool m_bStartGameLoading;
|
||||
bool m_bWantToRestart;
|
||||
bool m_bFirstTime;
|
||||
bool m_bGameNotLoaded;
|
||||
int32 m_nMousePosX;
|
||||
@ -484,7 +484,7 @@ public:
|
||||
bool m_bQuitGameNoCD;
|
||||
bool m_bRenderGameInMenu;
|
||||
bool m_bSaveMenuActive;
|
||||
bool m_bLoadingSavedGame;
|
||||
bool m_bWantToLoad;
|
||||
char field_455;
|
||||
bool m_bStartWaitingForKeyBind;
|
||||
bool m_bSpritesLoaded;
|
||||
@ -550,10 +550,10 @@ public:
|
||||
static int32 &sthWithButtons;
|
||||
static int32 &sthWithButtons2;
|
||||
|
||||
#ifndef MASTER
|
||||
static bool m_PrefsMarketing;
|
||||
static bool m_PrefsDisableTutorials;
|
||||
#endif // !MASTER
|
||||
#ifndef MASTER
|
||||
static bool m_PrefsMarketing;
|
||||
static bool m_PrefsDisableTutorials;
|
||||
#endif // !MASTER
|
||||
|
||||
#ifdef MENU_MAP
|
||||
static bool bMenuMapActive;
|
||||
|
@ -89,8 +89,6 @@
|
||||
|
||||
|
||||
|
||||
#define DEFAULT_VIEWWINDOW (0.7f)
|
||||
|
||||
eLevelName &CGame::currLevel = *(eLevelName*)0x941514;
|
||||
bool &CGame::bDemoMode = *(bool*)0x5F4DD0;
|
||||
bool &CGame::nastyGame = *(bool*)0x5F4DD4;
|
||||
@ -492,7 +490,7 @@ void CGame::ReInitGameObjectVariables(void)
|
||||
CParticle::ReloadConfig();
|
||||
CCullZones::ResolveVisibilities();
|
||||
|
||||
if ( !FrontEndMenuManager.m_bLoadingSavedGame )
|
||||
if ( !FrontEndMenuManager.m_bWantToLoad )
|
||||
{
|
||||
CCranes::InitCranes();
|
||||
CTheScripts::StartTestScript();
|
||||
@ -566,7 +564,7 @@ void CGame::InitialiseWhenRestarting(void)
|
||||
|
||||
TheCamera.Init();
|
||||
|
||||
if ( FrontEndMenuManager.m_bLoadingSavedGame == true )
|
||||
if ( FrontEndMenuManager.m_bWantToLoad == true )
|
||||
{
|
||||
RestoreForStartLoad();
|
||||
CStreaming::LoadScene(TheCamera.GetPosition());
|
||||
@ -574,7 +572,7 @@ void CGame::InitialiseWhenRestarting(void)
|
||||
|
||||
ReInitGameObjectVariables();
|
||||
|
||||
if ( FrontEndMenuManager.m_bLoadingSavedGame == true )
|
||||
if ( FrontEndMenuManager.m_bWantToLoad == true )
|
||||
{
|
||||
if ( GenericLoad() == true )
|
||||
{
|
||||
@ -593,7 +591,7 @@ void CGame::InitialiseWhenRestarting(void)
|
||||
ShutDownForRestart();
|
||||
CTimer::Stop();
|
||||
CTimer::Initialise();
|
||||
FrontEndMenuManager.m_bLoadingSavedGame = false;
|
||||
FrontEndMenuManager.m_bWantToLoad = false;
|
||||
ReInitGameObjectVariables();
|
||||
currLevel = LEVEL_INDUSTRIAL;
|
||||
CCollision::SortOutCollisionAfterLoad();
|
||||
@ -609,6 +607,9 @@ extern void (*DebugMenuProcess)(void);
|
||||
void CGame::Process(void)
|
||||
{
|
||||
CPad::UpdatePads();
|
||||
#ifdef GTA_PS2
|
||||
ProcessTidyUpMemory();
|
||||
#endif
|
||||
TheCamera.SetMotionBlurAlpha(0);
|
||||
if (TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_SNIPER || TheCamera.m_BlurType == MBLUR_NORMAL)
|
||||
TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
|
||||
@ -695,6 +696,13 @@ void CGame::TidyUpMemory(bool, bool)
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGame::ProcessTidyUpMemory(void)
|
||||
{
|
||||
#ifdef PS2
|
||||
// meow
|
||||
#endif
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x48BB80, CGame::InitialiseOnceBeforeRW, PATCH_JUMP);
|
||||
InjectHook(0x48BBA0, CGame::InitialiseRenderWare, PATCH_JUMP);
|
||||
|
@ -39,4 +39,5 @@ public:
|
||||
// NB: these do something on PS2
|
||||
static void TidyUpMemory(bool, bool);
|
||||
static void DrasticTidyUpMemory(bool);
|
||||
static void ProcessTidyUpMemory(void);
|
||||
};
|
||||
|
394
src/core/Pad.cpp
394
src/core/Pad.cpp
@ -29,12 +29,17 @@
|
||||
#include "Replay.h"
|
||||
#include "Weather.h"
|
||||
#include "win.h"
|
||||
#include "Streaming.h"
|
||||
#include "PathFind.h"
|
||||
#include "Wanted.h"
|
||||
#include "General.h"
|
||||
|
||||
CPad *Pads = (CPad*)0x6F0360; // [2]
|
||||
CMousePointerStateHelper &MousePointerStateHelper = *(CMousePointerStateHelper*)0x95CC8C;
|
||||
|
||||
bool &CPad::bDisplayNoControllerMessage = *(bool *)0x95CD52;
|
||||
bool &CPad::bObsoleteControllerMessage = *(bool *)0x95CDB8;
|
||||
bool CPad::bOldDisplayNoControllerMessage;
|
||||
bool &CPad::m_bMapPadOneToPadTwo = *(bool *)0x95CD48;
|
||||
|
||||
CKeyboardState &CPad::OldKeyState = *(CKeyboardState*)0x6F1E70;
|
||||
@ -50,29 +55,217 @@ CMouseControllerState &CPad::PCTempMouseControllerState = *(CMouseControllerStat
|
||||
_TODO("gbFastTime");
|
||||
extern bool &gbFastTime;
|
||||
|
||||
WRAPPER void WeaponCheat() { EAXJMP(0x490D90); }
|
||||
WRAPPER void HealthCheat() { EAXJMP(0x490E70); }
|
||||
WRAPPER void TankCheat() { EAXJMP(0x490EE0); }
|
||||
WRAPPER void BlowUpCarsCheat() { EAXJMP(0x491040); }
|
||||
WRAPPER void ChangePlayerCheat() { EAXJMP(0x4910B0); }
|
||||
WRAPPER void MayhemCheat() { EAXJMP(0x4911C0); }
|
||||
WRAPPER void EverybodyAttacksPlayerCheat() { EAXJMP(0x491270); }
|
||||
WRAPPER void WeaponsForAllCheat() { EAXJMP(0x491370); }
|
||||
WRAPPER void FastTimeCheat() { EAXJMP(0x4913A0); }
|
||||
WRAPPER void SlowTimeCheat() { EAXJMP(0x4913F0); }
|
||||
WRAPPER void MoneyCheat() { EAXJMP(0x491430); }
|
||||
WRAPPER void ArmourCheat() { EAXJMP(0x491460); }
|
||||
WRAPPER void WantedLevelUpCheat() { EAXJMP(0x491490); }
|
||||
WRAPPER void WantedLevelDownCheat() { EAXJMP(0x4914F0); }
|
||||
WRAPPER void SunnyWeatherCheat() { EAXJMP(0x491520); }
|
||||
WRAPPER void CloudyWeatherCheat() { EAXJMP(0x491550); }
|
||||
WRAPPER void RainyWeatherCheat() { EAXJMP(0x491580); }
|
||||
WRAPPER void FoggyWeatherCheat() { EAXJMP(0x4915B0); }
|
||||
WRAPPER void FastWeatherCheat() { EAXJMP(0x4915E0); }
|
||||
WRAPPER void OnlyRenderWheelsCheat() { EAXJMP(0x491610); }
|
||||
WRAPPER void ChittyChittyBangBangCheat() { EAXJMP(0x491640); }
|
||||
WRAPPER void StrongGripCheat() { EAXJMP(0x491670); }
|
||||
WRAPPER void NastyLimbsCheat() { EAXJMP(0x4916A0); }
|
||||
void WeaponCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT2"), true);
|
||||
FindPlayerPed()->GiveWeapon(WEAPONTYPE_BASEBALLBAT, 0);
|
||||
FindPlayerPed()->GiveWeapon(WEAPONTYPE_COLT45, 100);
|
||||
FindPlayerPed()->GiveWeapon(WEAPONTYPE_UZI, 100);
|
||||
FindPlayerPed()->GiveWeapon(WEAPONTYPE_SHOTGUN, 20);
|
||||
FindPlayerPed()->GiveWeapon(WEAPONTYPE_AK47, 200);
|
||||
FindPlayerPed()->GiveWeapon(WEAPONTYPE_M16, 200);
|
||||
FindPlayerPed()->GiveWeapon(WEAPONTYPE_SNIPERRIFLE, 5);
|
||||
FindPlayerPed()->GiveWeapon(WEAPONTYPE_ROCKETLAUNCHER, 5);
|
||||
FindPlayerPed()->GiveWeapon(WEAPONTYPE_MOLOTOV, 5);
|
||||
FindPlayerPed()->GiveWeapon(WEAPONTYPE_GRENADE, 5);
|
||||
FindPlayerPed()->GiveWeapon(WEAPONTYPE_FLAMETHROWER, 200);
|
||||
}
|
||||
|
||||
void HealthCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT3"), true);
|
||||
FindPlayerPed()->m_fHealth = 100.0f;
|
||||
if (FindPlayerVehicle()) {
|
||||
FindPlayerVehicle()->m_fHealth = 1000.0f;
|
||||
if (FindPlayerVehicle()->m_vehType == VEHICLE_TYPE_CAR)
|
||||
((CAutomobile*)FindPlayerVehicle())->Damage.SetEngineStatus(0);
|
||||
}
|
||||
}
|
||||
|
||||
void TankCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
|
||||
CStreaming::RequestModel(MI_RHINO, 0);
|
||||
CStreaming::LoadAllRequestedModels(false);
|
||||
if (CStreaming::ms_aInfoForModel[MI_RHINO].m_loadState == STREAMSTATE_LOADED) {
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
|
||||
int32 node = ThePaths.FindNodeClosestToCoors(FindPlayerCoors(), PATH_CAR, 100.0f);
|
||||
|
||||
if (node < 0) return;
|
||||
|
||||
#ifdef FIX_BUGS
|
||||
CAutomobile* tank = new CAutomobile(MI_RHINO, RANDOM_VEHICLE);
|
||||
#else
|
||||
CAutomobile *tank = new CAutomobile(MI_RHINO, MISSION_VEHICLE);
|
||||
#endif
|
||||
if (tank != nil) {
|
||||
CVector pos = ThePaths.m_pathNodes[node].pos;
|
||||
pos.z += 4.0f;
|
||||
tank->GetPosition() = pos;
|
||||
tank->SetOrientation(0.0f, 0.0f, DEGTORAD(200.0f));
|
||||
|
||||
tank->m_status = STATUS_ABANDONED;
|
||||
tank->m_nDoorLock = CARLOCK_UNLOCKED;
|
||||
CWorld::Add(tank);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BlowUpCarsCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
|
||||
|
||||
int i = CPools::GetVehiclePool()->GetSize();
|
||||
while (i-- > 0) {
|
||||
if (CVehicle *veh = CPools::GetVehiclePool()->GetSlot(i))
|
||||
veh->BlowUpCar(nil);
|
||||
}
|
||||
}
|
||||
|
||||
void ChangePlayerCheat()
|
||||
{
|
||||
int modelId;
|
||||
|
||||
if (FindPlayerPed()->IsPedInControl() && CModelInfo::GetModelInfo("player", nil)) {
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
|
||||
CPlayerPed *ped = FindPlayerPed();
|
||||
AssocGroupId AnimGrp = ped->m_animGroup;
|
||||
do
|
||||
{
|
||||
do
|
||||
modelId = CGeneral::GetRandomNumberInRange(0, MI_CAS_WOM+1);
|
||||
while (!CModelInfo::GetModelInfo(modelId));
|
||||
} while (modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL04 || modelId == MI_TAXI_D);
|
||||
|
||||
uint8 flags = CStreaming::ms_aInfoForModel[modelId].m_flags;
|
||||
ped->DeleteRwObject();
|
||||
CStreaming::RequestModel(modelId, STREAMFLAGS_DEPENDENCY| STREAMFLAGS_DONT_REMOVE);
|
||||
CStreaming::LoadAllRequestedModels(false);
|
||||
ped->m_modelIndex = -1;
|
||||
ped->SetModelIndex(modelId);
|
||||
ped->m_animGroup = AnimGrp;
|
||||
if (modelId != MI_PLAYER) {
|
||||
if (!(flags & STREAMFLAGS_DONT_REMOVE))
|
||||
CStreaming::SetModelIsDeletable(modelId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MayhemCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
|
||||
for (int i = PEDTYPE_CIVMALE; i < PEDTYPE_SPECIAL; i++)
|
||||
CPedType::SetThreats(i, PED_FLAG_PLAYER1 | PED_FLAG_PLAYER2 | PED_FLAG_PLAYER3 | PED_FLAG_PLAYER4 |
|
||||
PED_FLAG_CIVMALE | PED_FLAG_CIVFEMALE | PED_FLAG_COP | PED_FLAG_GANG1 |
|
||||
PED_FLAG_GANG2 | PED_FLAG_GANG3 | PED_FLAG_GANG4 | PED_FLAG_GANG5 |
|
||||
PED_FLAG_GANG6 | PED_FLAG_GANG7 | PED_FLAG_GANG8 | PED_FLAG_GANG9 |
|
||||
PED_FLAG_EMERGENCY | PED_FLAG_PROSTITUTE | PED_FLAG_CRIMINAL | PED_FLAG_SPECIAL );
|
||||
}
|
||||
|
||||
void EverybodyAttacksPlayerCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
|
||||
for (int i = PEDTYPE_CIVMALE; i < PEDTYPE_SPECIAL; i++)
|
||||
CPedType::AddThreat(i, PED_FLAG_PLAYER1);
|
||||
}
|
||||
|
||||
void WeaponsForAllCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
|
||||
CPopulation::ms_bGivePedsWeapons = !CPopulation::ms_bGivePedsWeapons;
|
||||
}
|
||||
|
||||
void FastTimeCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
|
||||
if (CTimer::GetTimeScale() < 4.0f)
|
||||
CTimer::SetTimeScale(CTimer::GetTimeScale() * 2.0f);
|
||||
}
|
||||
|
||||
void SlowTimeCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
|
||||
if (CTimer::GetTimeScale() > 0.25f)
|
||||
CTimer::SetTimeScale(CTimer::GetTimeScale() * 0.5f);
|
||||
}
|
||||
|
||||
void MoneyCheat()
|
||||
{
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 250000;
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT6"), true);
|
||||
}
|
||||
|
||||
void ArmourCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT4"), true);
|
||||
FindPlayerPed()->m_fArmour = 100.0f;
|
||||
}
|
||||
|
||||
void WantedLevelUpCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT5"), true);
|
||||
FindPlayerPed()->SetWantedLevel(min(FindPlayerPed()->m_pWanted->m_nWantedLevel + 2, 6));
|
||||
}
|
||||
|
||||
void WantedLevelDownCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT5"), true);
|
||||
FindPlayerPed()->SetWantedLevel(0);
|
||||
}
|
||||
|
||||
void SunnyWeatherCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
|
||||
CWeather::ForceWeatherNow(WEATHER_SUNNY);
|
||||
}
|
||||
|
||||
void CloudyWeatherCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
|
||||
CWeather::ForceWeatherNow(WEATHER_CLOUDY);
|
||||
}
|
||||
|
||||
void RainyWeatherCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
|
||||
CWeather::ForceWeatherNow(WEATHER_RAINY);
|
||||
}
|
||||
|
||||
void FoggyWeatherCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
|
||||
CWeather::ForceWeatherNow(WEATHER_FOGGY);
|
||||
}
|
||||
|
||||
void FastWeatherCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
|
||||
gbFastTime = !gbFastTime;
|
||||
}
|
||||
|
||||
void OnlyRenderWheelsCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
|
||||
CVehicle::bWheelsOnlyCheat = !CVehicle::bWheelsOnlyCheat;
|
||||
}
|
||||
|
||||
|
||||
void ChittyChittyBangBangCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
|
||||
CVehicle::bAllDodosCheat = !CVehicle::bAllDodosCheat;
|
||||
}
|
||||
|
||||
void StrongGripCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
|
||||
CVehicle::bCheat3 = !CVehicle::bCheat3;
|
||||
}
|
||||
|
||||
void NastyLimbsCheat()
|
||||
{
|
||||
CPed::bNastyLimbsCheat = !CPed::bNastyLimbsCheat;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef KANGAROO_CHEAT
|
||||
@ -89,7 +282,7 @@ void KangarooCheat()
|
||||
string = TheText.Get("CHEAT1");
|
||||
m_fMass = 15.0f;
|
||||
}
|
||||
CHud::SetHelpMessage(string, 1);
|
||||
CHud::SetHelpMessage(string, true);
|
||||
playerPed->m_ped_flagI80 = !playerPed->m_ped_flagI80;
|
||||
|
||||
playerPed->m_fMass = m_fMass;
|
||||
@ -138,6 +331,21 @@ void CKeyboardState::Clear()
|
||||
LWIN = RWIN = APPS = 0;
|
||||
}
|
||||
|
||||
#ifdef GTA_PS2_STUFF
|
||||
void CPad::Initialise(void)
|
||||
{
|
||||
for (int i = 0; i < MAX_PADS; i++)
|
||||
{
|
||||
CPad::GetPad(i)->Clear(true);
|
||||
CPad::GetPad(i)->Mode = 0;
|
||||
}
|
||||
|
||||
bObsoleteControllerMessage = false;
|
||||
bOldDisplayNoControllerMessage = false;
|
||||
bDisplayNoControllerMessage = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void CPad::Clear(bool bResetPlayerControls)
|
||||
{
|
||||
NewState.Clear();
|
||||
@ -165,13 +373,13 @@ void CPad::Clear(bool bResetPlayerControls)
|
||||
bApplyBrakes = false;
|
||||
|
||||
|
||||
for ( int32 i = 0; i < _TODOCONST(5); i++ )
|
||||
for ( int32 i = 0; i < HORNHISTORY_SIZE; i++ )
|
||||
bHornHistory[i] = false;
|
||||
|
||||
iCurrHornHistory = 0;
|
||||
|
||||
for ( int32 i = 0; i < _TODOCONST(12); i++ )
|
||||
_unk[i] = ' ';
|
||||
for ( int32 i = 0; i < ARRAY_SIZE(CheatString); i++ )
|
||||
CheatString[i] = ' ';
|
||||
|
||||
LastTimeTouched = CTimer::GetTimeInMilliseconds();
|
||||
AverageWeapon = 0;
|
||||
@ -430,6 +638,108 @@ void CPad::StartShake_Train(float fX, float fY)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GTA_PS2_STUFF
|
||||
void CPad::AddToCheatString(char c)
|
||||
{
|
||||
for ( int32 i = ARRAY_SIZE(CheatString) - 2; i >= 0; i-- )
|
||||
CheatString[i + 1] = CheatString[i];
|
||||
|
||||
#define _CHEATCMP(str) strncmp(str, CheatString, sizeof(str)-1)
|
||||
// "4414LDRULDRU" - R2 R2 L1 R2 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
|
||||
if ( !_CHEATCMP("URDLURDL4144") )
|
||||
WeaponCheat();
|
||||
|
||||
// "4411LDRULDRU" - R2 R2 L1 L1 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
|
||||
else if ( !_CHEATCMP("URDLURDL1144") )
|
||||
MoneyCheat();
|
||||
|
||||
// "4412LDRULDRU" - R2 R2 L1 L2 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
|
||||
else if ( !_CHEATCMP("URDLURDL2144") )
|
||||
ArmourCheat();
|
||||
|
||||
// "4413LDRULDRU" - R2 R2 L1 R1 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
|
||||
else if ( !_CHEATCMP("URDLURDL3144") )
|
||||
HealthCheat();
|
||||
|
||||
// "4414LRLRLR" - R2 R2 L1 R2 LEFT RIGHT LEFT RIGHT LEFT RIGHT
|
||||
else if ( !_CHEATCMP("RLRLRL4144") )
|
||||
WantedLevelUpCheat();
|
||||
|
||||
// "4414UDUDUD" - R2 R2 L1 R2 UP DOWN UP DOWN UP DOWN
|
||||
else if ( !_CHEATCMP("DUDUDU4144") )
|
||||
WantedLevelDownCheat();
|
||||
|
||||
// "1234432T" - L1 L2 R1 R2 R2 R1 L2 TRIANGLE
|
||||
else if ( !_CHEATCMP("T2344321") )
|
||||
SunnyWeatherCheat();
|
||||
|
||||
// "1234432S" - L1 L2 R1 R2 R2 R1 L2 SQUARE
|
||||
else if ( !_CHEATCMP("S2344321") )
|
||||
CloudyWeatherCheat();
|
||||
|
||||
// "1234432C" - L1 L2 R1 R2 R2 R1 L2 CIRCLE
|
||||
else if ( !_CHEATCMP("C2344321") )
|
||||
RainyWeatherCheat();
|
||||
|
||||
// "1234432X" - L1 L2 R1 R2 R2 R1 L2 CROSS
|
||||
else if ( !_CHEATCMP("X2344321") )
|
||||
FoggyWeatherCheat();
|
||||
|
||||
// "CCCCCC321TCT" - CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE R1 L2 L1 TRIANGLE CIRCLE TRIANGLE
|
||||
else if ( !_CHEATCMP("TCT123CCCCCC") )
|
||||
TankCheat();
|
||||
|
||||
// "CCCSSSSS1TCT" - CIRCLE CIRCLE CIRCLE SQUARE SQUARE SQUARE SQUARE SQUARE L1 TRIANGLE CIRCLE TRIANGLE
|
||||
else if ( !_CHEATCMP("TCT1SSSSSCCC") )
|
||||
FastWeatherCheat();
|
||||
|
||||
// "241324TSCT21" - L2 R2 L1 R1 L2 R2 TRIANGLE SQUARE CIRCLE TRIANGLE L2 L1
|
||||
else if ( !_CHEATCMP("12TCST423142") )
|
||||
BlowUpCarsCheat();
|
||||
|
||||
// "RDLU12ULDR" - RIGHT DOWN LEFT UP L1 L2 UP LEFT DOWN RIGHT
|
||||
else if ( !_CHEATCMP("RDLU21ULDR") )
|
||||
ChangePlayerCheat();
|
||||
|
||||
// "DULUX3421" - DOWN UP LEFT UP CROSS R1 R2 L2 L1
|
||||
else if ( !_CHEATCMP("1243XULUD") )
|
||||
MayhemCheat();
|
||||
|
||||
// "DULUX3412" - DOWN UP LEFT UP CROSS R1 R2 L1 L2
|
||||
else if ( !_CHEATCMP("2143XULUD") )
|
||||
EverybodyAttacksPlayerCheat();
|
||||
|
||||
// "43TX21UD" - R2 R1 TRIANGLE CROSS L2 L1 UP DOWN
|
||||
else if ( !_CHEATCMP("DU12XT34") )
|
||||
WeaponsForAllCheat();
|
||||
|
||||
// "TURDS12" - TRIANGLE UP RIGHT DOWN SQUARE L1 L2
|
||||
else if ( !_CHEATCMP("21SDRUT") )
|
||||
FastTimeCheat();
|
||||
|
||||
// "TURDS34" - TRIANGLE UP RIGHT DOWN SQUARE R1 R2
|
||||
else if ( !_CHEATCMP("43SDRUT") )
|
||||
SlowTimeCheat();
|
||||
|
||||
// "11S4T1T" - L1 L1 SQUARE R2 TRIANGLE L1 TRIANGLE
|
||||
else if ( !_CHEATCMP("T1T4S11") )
|
||||
OnlyRenderWheelsCheat();
|
||||
|
||||
// "R4C32D13" - RIGHT R2 CIRCLE R1 L2 DOWN L1 R1
|
||||
else if ( !_CHEATCMP("31D23C4R") )
|
||||
ChittyChittyBangBangCheat();
|
||||
|
||||
// "3141L33T" - R1 L1 R2 L1 LEFT R1 R1 TRIANGLE
|
||||
else if ( !_CHEATCMP("T33L1413") )
|
||||
StrongGripCheat();
|
||||
|
||||
// "S1CD13TR1X" - SQUARE L1 CIRCLE DOWN L1 R1 TRIANGLE RIGHT L1 CROSS
|
||||
else if ( !_CHEATCMP("X1RT31DC1S") )
|
||||
NastyLimbsCheat();
|
||||
#undef _CHEATCMP
|
||||
}
|
||||
#endif
|
||||
|
||||
void CPad::AddToPCCheatString(char c)
|
||||
{
|
||||
for ( int32 i = ARRAY_SIZE(KeyBoardCheatString) - 2; i >= 0; i-- )
|
||||
@ -672,7 +982,7 @@ void CPad::Update(int16 unk)
|
||||
|
||||
ProcessPCSpecificStuff();
|
||||
|
||||
if ( ++iCurrHornHistory >= _TODOCONST(5) )
|
||||
if ( ++iCurrHornHistory >= HORNHISTORY_SIZE )
|
||||
iCurrHornHistory = 0;
|
||||
|
||||
bHornHistory[iCurrHornHistory] = GetHorn();
|
||||
@ -689,7 +999,7 @@ void CPad::DoCheats(void)
|
||||
|
||||
void CPad::DoCheats(int16 unk)
|
||||
{
|
||||
#ifdef PS2
|
||||
#ifdef GTA_PS2_STUFF
|
||||
if ( GetTriangleJustDown() )
|
||||
AddToCheatString('T');
|
||||
|
||||
@ -2092,7 +2402,31 @@ int32 *CPad::EditCodesForControls(int32 *pRsKeys, int32 nSize)
|
||||
return pRsKeys;
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
STARTPATCHES
|
||||
InjectHook(0x490D90, &WeaponCheat, PATCH_JUMP);
|
||||
InjectHook(0x490E70, &HealthCheat, PATCH_JUMP);
|
||||
InjectHook(0x490EE0, &TankCheat, PATCH_JUMP);
|
||||
InjectHook(0x491040, &BlowUpCarsCheat, PATCH_JUMP);
|
||||
InjectHook(0x4910B0, &ChangePlayerCheat, PATCH_JUMP);
|
||||
InjectHook(0x4911C0, &MayhemCheat, PATCH_JUMP);
|
||||
InjectHook(0x491270, &EverybodyAttacksPlayerCheat, PATCH_JUMP);
|
||||
InjectHook(0x491370, &WeaponsForAllCheat, PATCH_JUMP);
|
||||
InjectHook(0x4913A0, &FastTimeCheat, PATCH_JUMP);
|
||||
InjectHook(0x4913F0, &SlowTimeCheat, PATCH_JUMP);
|
||||
InjectHook(0x491430, &MoneyCheat, PATCH_JUMP);
|
||||
InjectHook(0x491460, &ArmourCheat, PATCH_JUMP);
|
||||
InjectHook(0x491490, &WantedLevelUpCheat, PATCH_JUMP);
|
||||
InjectHook(0x4914F0, &WantedLevelDownCheat, PATCH_JUMP);
|
||||
InjectHook(0x491520, &SunnyWeatherCheat, PATCH_JUMP);
|
||||
InjectHook(0x491550, &CloudyWeatherCheat, PATCH_JUMP);
|
||||
InjectHook(0x491580, &RainyWeatherCheat, PATCH_JUMP);
|
||||
InjectHook(0x4915B0, &FoggyWeatherCheat, PATCH_JUMP);
|
||||
InjectHook(0x4915E0, &FastWeatherCheat, PATCH_JUMP);
|
||||
InjectHook(0x491610, &OnlyRenderWheelsCheat, PATCH_JUMP);
|
||||
InjectHook(0x491640, &ChittyChittyBangBangCheat, PATCH_JUMP);
|
||||
InjectHook(0x491670, &StrongGripCheat, PATCH_JUMP);
|
||||
InjectHook(0x4916A0, &NastyLimbsCheat, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x4916C0, &CControllerState::Clear, PATCH_JUMP);
|
||||
InjectHook(0x491760, &CKeyboardState::Clear, PATCH_JUMP);
|
||||
InjectHook(0x491A10, &CPad::Clear, PATCH_JUMP);
|
||||
|
@ -136,6 +136,10 @@ enum
|
||||
class CPad
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
HORNHISTORY_SIZE = 5,
|
||||
};
|
||||
CControllerState NewState;
|
||||
CControllerState OldState;
|
||||
CControllerState PCTempKeyState;
|
||||
@ -146,11 +150,11 @@ public:
|
||||
int16 Mode;
|
||||
int16 ShakeDur;
|
||||
uint8 ShakeFreq;
|
||||
bool bHornHistory[5];
|
||||
bool bHornHistory[HORNHISTORY_SIZE];
|
||||
uint8 iCurrHornHistory;
|
||||
uint8 DisablePlayerControls;
|
||||
int8 bApplyBrakes;
|
||||
char _unk[12]; //int32 unk[3];
|
||||
char CheatString[12];
|
||||
char _pad0[3];
|
||||
int32 LastTimeTouched;
|
||||
int32 AverageWeapon;
|
||||
@ -161,6 +165,7 @@ public:
|
||||
|
||||
static bool &bDisplayNoControllerMessage;
|
||||
static bool &bObsoleteControllerMessage;
|
||||
static bool bOldDisplayNoControllerMessage;
|
||||
static bool &m_bMapPadOneToPadTwo;
|
||||
|
||||
static CKeyboardState &OldKeyState;
|
||||
@ -172,8 +177,9 @@ public:
|
||||
static CMouseControllerState &PCTempMouseControllerState;
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef GTA_PS2_STUFF
|
||||
static void Initialise(void);
|
||||
#endif
|
||||
void Clear(bool bResetPlayerControls);
|
||||
void ClearMouseHistory();
|
||||
void UpdateMouse();
|
||||
@ -181,6 +187,9 @@ public:
|
||||
void StartShake(int16 nDur, uint8 nFreq);
|
||||
void StartShake_Distance(int16 nDur, uint8 nFreq, float fX, float fY, float fz);
|
||||
void StartShake_Train(float fX, float fY);
|
||||
#ifdef GTA_PS2_STUFF
|
||||
void AddToCheatString(char c);
|
||||
#endif
|
||||
void AddToPCCheatString(char c);
|
||||
|
||||
static void UpdatePads(void);
|
||||
|
@ -48,45 +48,45 @@ CPlayerInfo::GetPos()
|
||||
|
||||
void
|
||||
CPlayerInfo::LoadPlayerSkin()
|
||||
{
|
||||
DeletePlayerSkin();
|
||||
|
||||
m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName);
|
||||
if (!m_pSkinTexture)
|
||||
{
|
||||
DeletePlayerSkin();
|
||||
|
||||
m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName);
|
||||
if (!m_pSkinTexture)
|
||||
m_pSkinTexture = CPlayerSkin::GetSkinTexture(DEFAULT_SKIN_NAME);
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::DeletePlayerSkin()
|
||||
{
|
||||
if (m_pSkinTexture) {
|
||||
RwTextureDestroy(m_pSkinTexture);
|
||||
m_pSkinTexture = nil;
|
||||
{
|
||||
if (m_pSkinTexture) {
|
||||
RwTextureDestroy(m_pSkinTexture);
|
||||
m_pSkinTexture = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::KillPlayer()
|
||||
{
|
||||
if (m_WBState != WBSTATE_PLAYING) return;
|
||||
|
||||
m_WBState = WBSTATE_WASTED;
|
||||
m_nWBTime = CTimer::GetTimeInMilliseconds();
|
||||
CDarkel::ResetOnPlayerDeath();
|
||||
CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2);
|
||||
CStats::TimesDied++;
|
||||
void
|
||||
CPlayerInfo::KillPlayer()
|
||||
{
|
||||
if (m_WBState != WBSTATE_PLAYING) return;
|
||||
|
||||
m_WBState = WBSTATE_WASTED;
|
||||
m_nWBTime = CTimer::GetTimeInMilliseconds();
|
||||
CDarkel::ResetOnPlayerDeath();
|
||||
CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2);
|
||||
CStats::TimesDied++;
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::ArrestPlayer()
|
||||
{
|
||||
if (m_WBState != WBSTATE_PLAYING) return;
|
||||
|
||||
m_WBState = WBSTATE_BUSTED;
|
||||
m_nWBTime = CTimer::GetTimeInMilliseconds();
|
||||
CDarkel::ResetOnPlayerDeath();
|
||||
CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2);
|
||||
CStats::TimesArrested++;
|
||||
void
|
||||
CPlayerInfo::ArrestPlayer()
|
||||
{
|
||||
if (m_WBState != WBSTATE_PLAYING) return;
|
||||
|
||||
m_WBState = WBSTATE_BUSTED;
|
||||
m_nWBTime = CTimer::GetTimeInMilliseconds();
|
||||
CDarkel::ResetOnPlayerDeath();
|
||||
CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2);
|
||||
CStats::TimesArrested++;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -105,102 +105,102 @@ CPlayerInfo::PlayerFailedCriticalMission()
|
||||
CDarkel::ResetOnPlayerDeath();
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::Clear(void)
|
||||
{
|
||||
m_pPed = nil;
|
||||
m_pRemoteVehicle = nil;
|
||||
if (m_pVehicleEx) {
|
||||
m_pVehicleEx->bUsingSpecialColModel = false;
|
||||
m_pVehicleEx = nil;
|
||||
}
|
||||
m_nVisibleMoney = 0;
|
||||
m_nMoney = m_nVisibleMoney;
|
||||
m_WBState = WBSTATE_PLAYING;
|
||||
m_nWBTime = 0;
|
||||
m_nTrafficMultiplier = 0;
|
||||
m_fRoadDensity = 1.0f;
|
||||
m_bInRemoteMode = false;
|
||||
m_bUnusedTaxiThing = false;
|
||||
m_nUnusedTaxiTimer = 0;
|
||||
m_nCollectedPackages = 0;
|
||||
m_nTotalPackages = 3;
|
||||
m_nTimeLastHealthLoss = 0;
|
||||
m_nTimeLastArmourLoss = 0;
|
||||
m_nNextSexFrequencyUpdateTime = 0;
|
||||
m_nNextSexMoneyUpdateTime = 0;
|
||||
m_nSexFrequency = 0;
|
||||
m_pHooker = nil;
|
||||
m_nTimeTankShotGun = 0;
|
||||
field_248 = 0;
|
||||
m_nUpsideDownCounter = 0;
|
||||
m_bInfiniteSprint = false;
|
||||
m_bFastReload = false;
|
||||
m_bGetOutOfJailFree = false;
|
||||
m_bGetOutOfHospitalFree = false;
|
||||
m_nPreviousTimeRewardedForExplosion = 0;
|
||||
m_nExplosionsSinceLastReward = 0;
|
||||
void
|
||||
CPlayerInfo::Clear(void)
|
||||
{
|
||||
m_pPed = nil;
|
||||
m_pRemoteVehicle = nil;
|
||||
if (m_pVehicleEx) {
|
||||
m_pVehicleEx->bUsingSpecialColModel = false;
|
||||
m_pVehicleEx = nil;
|
||||
}
|
||||
m_nVisibleMoney = 0;
|
||||
m_nMoney = m_nVisibleMoney;
|
||||
m_WBState = WBSTATE_PLAYING;
|
||||
m_nWBTime = 0;
|
||||
m_nTrafficMultiplier = 0;
|
||||
m_fRoadDensity = 1.0f;
|
||||
m_bInRemoteMode = false;
|
||||
m_bUnusedTaxiThing = false;
|
||||
m_nUnusedTaxiTimer = 0;
|
||||
m_nCollectedPackages = 0;
|
||||
m_nTotalPackages = 3;
|
||||
m_nTimeLastHealthLoss = 0;
|
||||
m_nTimeLastArmourLoss = 0;
|
||||
m_nNextSexFrequencyUpdateTime = 0;
|
||||
m_nNextSexMoneyUpdateTime = 0;
|
||||
m_nSexFrequency = 0;
|
||||
m_pHooker = nil;
|
||||
m_nTimeTankShotGun = 0;
|
||||
field_248 = 0;
|
||||
m_nUpsideDownCounter = 0;
|
||||
m_bInfiniteSprint = false;
|
||||
m_bFastReload = false;
|
||||
m_bGetOutOfJailFree = false;
|
||||
m_bGetOutOfHospitalFree = false;
|
||||
m_nPreviousTimeRewardedForExplosion = 0;
|
||||
m_nExplosionsSinceLastReward = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::BlowUpRCBuggy(void)
|
||||
{
|
||||
if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld)
|
||||
return;
|
||||
|
||||
CRemote::TakeRemoteControlledCarFromPlayer();
|
||||
m_pRemoteVehicle->BlowUpCar(FindPlayerPed());
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car)
|
||||
{
|
||||
if (!car || car == m_pPed->m_pMyVehicle) {
|
||||
if (m_pPed->EnteringCar())
|
||||
m_pPed->QuitEnteringCar();
|
||||
}
|
||||
if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
|
||||
m_pPed->ClearObjective();
|
||||
void
|
||||
CPlayerInfo::BlowUpRCBuggy(void)
|
||||
{
|
||||
if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld)
|
||||
return;
|
||||
|
||||
CRemote::TakeRemoteControlledCarFromPlayer();
|
||||
m_pRemoteVehicle->BlowUpCar(FindPlayerPed());
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::MakePlayerSafe(bool toggle)
|
||||
{
|
||||
if (toggle) {
|
||||
CTheScripts::ResetCountdownToMakePlayerUnsafe();
|
||||
m_pPed->m_pWanted->m_bIgnoredByEveryone = true;
|
||||
CWorld::StopAllLawEnforcersInTheirTracks();
|
||||
CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_20;
|
||||
CPad::StopPadsShaking();
|
||||
m_pPed->bBulletProof = true;
|
||||
m_pPed->bFireProof = true;
|
||||
m_pPed->bCollisionProof = true;
|
||||
m_pPed->bMeleeProof = true;
|
||||
m_pPed->bOnlyDamagedByPlayer = true;
|
||||
m_pPed->bExplosionProof = true;
|
||||
m_pPed->m_bCanBeDamaged = false;
|
||||
((CPlayerPed*)m_pPed)->ClearAdrenaline();
|
||||
CancelPlayerEnteringCars(false);
|
||||
gFireManager.ExtinguishPoint(GetPos(), 4000.0f);
|
||||
CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f);
|
||||
CProjectileInfo::RemoveAllProjectiles();
|
||||
CWorld::SetAllCarsCanBeDamaged(false);
|
||||
CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f);
|
||||
CReplay::DisableReplays();
|
||||
|
||||
} else if (!CGame::playingIntro && !CTheScripts::IsCountdownToMakePlayerUnsafeOn()) {
|
||||
m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
|
||||
CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_20;
|
||||
m_pPed->bBulletProof = false;
|
||||
m_pPed->bFireProof = false;
|
||||
m_pPed->bCollisionProof = false;
|
||||
m_pPed->bMeleeProof = false;
|
||||
m_pPed->bOnlyDamagedByPlayer = false;
|
||||
m_pPed->bExplosionProof = false;
|
||||
m_pPed->m_bCanBeDamaged = true;
|
||||
CWorld::SetAllCarsCanBeDamaged(true);
|
||||
CReplay::EnableReplays();
|
||||
}
|
||||
void
|
||||
CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car)
|
||||
{
|
||||
if (!car || car == m_pPed->m_pMyVehicle) {
|
||||
if (m_pPed->EnteringCar())
|
||||
m_pPed->QuitEnteringCar();
|
||||
}
|
||||
if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
|
||||
m_pPed->ClearObjective();
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::MakePlayerSafe(bool toggle)
|
||||
{
|
||||
if (toggle) {
|
||||
CTheScripts::ResetCountdownToMakePlayerUnsafe();
|
||||
m_pPed->m_pWanted->m_bIgnoredByEveryone = true;
|
||||
CWorld::StopAllLawEnforcersInTheirTracks();
|
||||
CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_20;
|
||||
CPad::StopPadsShaking();
|
||||
m_pPed->bBulletProof = true;
|
||||
m_pPed->bFireProof = true;
|
||||
m_pPed->bCollisionProof = true;
|
||||
m_pPed->bMeleeProof = true;
|
||||
m_pPed->bOnlyDamagedByPlayer = true;
|
||||
m_pPed->bExplosionProof = true;
|
||||
m_pPed->m_bCanBeDamaged = false;
|
||||
((CPlayerPed*)m_pPed)->ClearAdrenaline();
|
||||
CancelPlayerEnteringCars(false);
|
||||
gFireManager.ExtinguishPoint(GetPos(), 4000.0f);
|
||||
CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f);
|
||||
CProjectileInfo::RemoveAllProjectiles();
|
||||
CWorld::SetAllCarsCanBeDamaged(false);
|
||||
CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f);
|
||||
CReplay::DisableReplays();
|
||||
|
||||
} else if (!CGame::playingIntro && !CTheScripts::IsCountdownToMakePlayerUnsafeOn()) {
|
||||
m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
|
||||
CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_20;
|
||||
m_pPed->bBulletProof = false;
|
||||
m_pPed->bFireProof = false;
|
||||
m_pPed->bCollisionProof = false;
|
||||
m_pPed->bMeleeProof = false;
|
||||
m_pPed->bOnlyDamagedByPlayer = false;
|
||||
m_pPed->bExplosionProof = false;
|
||||
m_pPed->m_bCanBeDamaged = true;
|
||||
CWorld::SetAllCarsCanBeDamaged(true);
|
||||
CReplay::EnableReplays();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@ -216,347 +216,347 @@ CPlayerInfo::IsRestartingAfterArrest()
|
||||
}
|
||||
|
||||
// lastCloseness is passed to other calls of this function
|
||||
void
|
||||
CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput)
|
||||
{
|
||||
// This dist used for determining the angle to face
|
||||
CVector2D dist(carToTest->GetPosition() - player->GetPosition());
|
||||
float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y);
|
||||
while (neededTurn >= PI) {
|
||||
neededTurn -= 2 * PI;
|
||||
}
|
||||
|
||||
while (neededTurn < -PI) {
|
||||
neededTurn += 2 * PI;
|
||||
}
|
||||
|
||||
// This dist used for evaluating cars' distances, weird...
|
||||
// Accounts inverted needed turn (or needed turn in long way) and car dist.
|
||||
float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist);
|
||||
if (closeness > *lastCloseness) {
|
||||
*lastCloseness = closeness;
|
||||
*closestCarOutput = (CVehicle*)carToTest;
|
||||
}
|
||||
void
|
||||
CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput)
|
||||
{
|
||||
// This dist used for determining the angle to face
|
||||
CVector2D dist(carToTest->GetPosition() - player->GetPosition());
|
||||
float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y);
|
||||
while (neededTurn >= PI) {
|
||||
neededTurn -= 2 * PI;
|
||||
}
|
||||
|
||||
while (neededTurn < -PI) {
|
||||
neededTurn += 2 * PI;
|
||||
}
|
||||
|
||||
// This dist used for evaluating cars' distances, weird...
|
||||
// Accounts inverted needed turn (or needed turn in long way) and car dist.
|
||||
float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist);
|
||||
if (closeness > *lastCloseness) {
|
||||
*lastCloseness = closeness;
|
||||
*closestCarOutput = (CVehicle*)carToTest;
|
||||
}
|
||||
}
|
||||
|
||||
// There is something unfinished in here... Sadly all IDBs we have have it unfinished.
|
||||
void
|
||||
CPlayerInfo::AwardMoneyForExplosion(CVehicle *wreckedCar)
|
||||
{
|
||||
if (CTimer::GetTimeInMilliseconds() - m_nPreviousTimeRewardedForExplosion < 6000)
|
||||
++m_nExplosionsSinceLastReward;
|
||||
else
|
||||
m_nExplosionsSinceLastReward = 1;
|
||||
|
||||
m_nPreviousTimeRewardedForExplosion = CTimer::GetTimeInMilliseconds();
|
||||
int award = wreckedCar->pHandling->nMonetaryValue * 0.002f;
|
||||
sprintf(gString, "$%d", award);
|
||||
#ifdef MONEY_MESSAGES
|
||||
// This line is a leftover from PS2, I don't know what it was meant to be.
|
||||
// CVector sth(TheCamera.GetPosition() * 4.0f);
|
||||
|
||||
CMoneyMessages::RegisterOne(wreckedCar->GetPosition() + CVector(0.0f, 0.0f, 2.0f), gString, 0, 255, 0, 2.0f, 0.5f);
|
||||
#endif
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
|
||||
|
||||
for (int i = m_nExplosionsSinceLastReward; i > 1; --i) {
|
||||
CGeneral::GetRandomNumber();
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
|
||||
}
|
||||
void
|
||||
CPlayerInfo::AwardMoneyForExplosion(CVehicle *wreckedCar)
|
||||
{
|
||||
if (CTimer::GetTimeInMilliseconds() - m_nPreviousTimeRewardedForExplosion < 6000)
|
||||
++m_nExplosionsSinceLastReward;
|
||||
else
|
||||
m_nExplosionsSinceLastReward = 1;
|
||||
|
||||
m_nPreviousTimeRewardedForExplosion = CTimer::GetTimeInMilliseconds();
|
||||
int award = wreckedCar->pHandling->nMonetaryValue * 0.002f;
|
||||
sprintf(gString, "$%d", award);
|
||||
#ifdef MONEY_MESSAGES
|
||||
// This line is a leftover from PS2, I don't know what it was meant to be.
|
||||
// CVector sth(TheCamera.GetPosition() * 4.0f);
|
||||
|
||||
CMoneyMessages::RegisterOne(wreckedCar->GetPosition() + CVector(0.0f, 0.0f, 2.0f), gString, 0, 255, 0, 2.0f, 0.5f);
|
||||
#endif
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
|
||||
|
||||
for (int i = m_nExplosionsSinceLastReward; i > 1; --i) {
|
||||
CGeneral::GetRandomNumber();
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size)
|
||||
{
|
||||
// Interesting
|
||||
*size = sizeof(CPlayerInfo);
|
||||
|
||||
INITSAVEBUF
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
|
||||
for (int i = 0; i < sizeof(CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); i++) {
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName[i]);
|
||||
}
|
||||
// Save struct is different
|
||||
// VALIDATESAVEBUF(*size)
|
||||
void
|
||||
CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size)
|
||||
{
|
||||
// Interesting
|
||||
*size = sizeof(CPlayerInfo);
|
||||
|
||||
INITSAVEBUF
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
|
||||
for (int i = 0; i < sizeof(CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); i++) {
|
||||
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName[i]);
|
||||
}
|
||||
// Save struct is different
|
||||
// VALIDATESAVEBUF(*size)
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size)
|
||||
{
|
||||
INITSAVEBUF
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nMoney = ReadSaveBuf<uint32>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_WBState = ReadSaveBuf<int8>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nWBTime = ReadSaveBuf<uint32>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier = ReadSaveBuf<int16>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity = ReadSaveBuf<float>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney = ReadSaveBuf<int32>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages = ReadSaveBuf<int32>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages = ReadSaveBuf<int32>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint = ReadSaveBuf<bool>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_bFastReload = ReadSaveBuf<bool>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree = ReadSaveBuf<bool>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree = ReadSaveBuf<bool>(buf);
|
||||
for (int i = 0; i < sizeof(CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); i++) {
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName[i] = ReadSaveBuf<char>(buf);
|
||||
}
|
||||
// Save struct is different
|
||||
// VALIDATESAVEBUF(size)
|
||||
void
|
||||
CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size)
|
||||
{
|
||||
INITSAVEBUF
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nMoney = ReadSaveBuf<uint32>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_WBState = ReadSaveBuf<int8>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nWBTime = ReadSaveBuf<uint32>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier = ReadSaveBuf<int16>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity = ReadSaveBuf<float>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney = ReadSaveBuf<int32>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages = ReadSaveBuf<int32>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages = ReadSaveBuf<int32>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint = ReadSaveBuf<bool>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_bFastReload = ReadSaveBuf<bool>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree = ReadSaveBuf<bool>(buf);
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree = ReadSaveBuf<bool>(buf);
|
||||
for (int i = 0; i < sizeof(CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); i++) {
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName[i] = ReadSaveBuf<char>(buf);
|
||||
}
|
||||
// Save struct is different
|
||||
// VALIDATESAVEBUF(size)
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput)
|
||||
{
|
||||
for (CPtrNode* node = carList.first; node; node = node->next) {
|
||||
CVehicle *car = (CVehicle*)node->item;
|
||||
if(car->m_scanCode != CWorld::GetCurrentScanCode()) {
|
||||
if (!car->bUsesCollision || !car->IsVehicle())
|
||||
continue;
|
||||
|
||||
car->m_scanCode = CWorld::GetCurrentScanCode();
|
||||
if (car->m_status != STATUS_WRECKED && car->m_status != STATUS_TRAIN_MOVING
|
||||
&& (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) {
|
||||
CVector carCentre = car->GetBoundCentre();
|
||||
|
||||
if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f) {
|
||||
float dist = (ped->GetPosition() - carCentre).Magnitude2D();
|
||||
if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) {
|
||||
EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void
|
||||
CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput)
|
||||
{
|
||||
for (CPtrNode* node = carList.first; node; node = node->next) {
|
||||
CVehicle *car = (CVehicle*)node->item;
|
||||
if(car->m_scanCode != CWorld::GetCurrentScanCode()) {
|
||||
if (!car->bUsesCollision || !car->IsVehicle())
|
||||
continue;
|
||||
|
||||
car->m_scanCode = CWorld::GetCurrentScanCode();
|
||||
if (car->m_status != STATUS_WRECKED && car->m_status != STATUS_TRAIN_MOVING
|
||||
&& (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) {
|
||||
CVector carCentre = car->GetBoundCentre();
|
||||
|
||||
if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f) {
|
||||
float dist = (ped->GetPosition() - carCentre).Magnitude2D();
|
||||
if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) {
|
||||
EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::Process(void)
|
||||
{
|
||||
// Unused taxi feature. Gives you a dollar for every second with a passenger. Can be toggled via 0x29A opcode.
|
||||
bool startTaxiTimer = true;
|
||||
if (m_bUnusedTaxiThing && m_pPed->bInVehicle) {
|
||||
CVehicle *veh = m_pPed->m_pMyVehicle;
|
||||
if ((veh->m_modelIndex == MI_TAXI || veh->m_modelIndex == MI_CABBIE || veh->m_modelIndex == MI_BORGNINE)
|
||||
&& veh->pDriver == m_pPed && veh->m_nNumPassengers != 0) {
|
||||
for (uint32 timePassed = CTimer::GetTimeInMilliseconds() - m_nUnusedTaxiTimer; timePassed >= 1000; m_nUnusedTaxiTimer += 1000) {
|
||||
timePassed -= 1000;
|
||||
++m_nMoney;
|
||||
}
|
||||
startTaxiTimer = false;
|
||||
}
|
||||
}
|
||||
if (startTaxiTimer)
|
||||
m_nUnusedTaxiTimer = CTimer::GetTimeInMilliseconds();
|
||||
|
||||
// The effect that makes money counter does while earning/losing money
|
||||
if (m_nVisibleMoney != m_nMoney) {
|
||||
int diff = m_nMoney - m_nVisibleMoney;
|
||||
int diffAbs = Abs(diff);
|
||||
int changeBy;
|
||||
|
||||
if (diffAbs > 100000)
|
||||
changeBy = 12345;
|
||||
else if (diffAbs > 10000)
|
||||
changeBy = 1234;
|
||||
else if (diffAbs > 1000)
|
||||
changeBy = 123;
|
||||
else if (diffAbs > 50)
|
||||
changeBy = 42;
|
||||
else
|
||||
changeBy = 1;
|
||||
|
||||
if (diff < 0)
|
||||
m_nVisibleMoney -= changeBy;
|
||||
else
|
||||
m_nVisibleMoney += changeBy;
|
||||
}
|
||||
|
||||
if (!(CTimer::GetFrameCounter() & 15)) {
|
||||
CVector2D playerPos = m_pPed->bInVehicle ? m_pPed->m_pMyVehicle->GetPosition() : m_pPed->GetPosition();
|
||||
m_fRoadDensity = ThePaths.CalcRoadDensity(playerPos.x, playerPos.y);
|
||||
}
|
||||
|
||||
m_fRoadDensity = clamp(m_fRoadDensity, 0.4f, 1.45f);
|
||||
|
||||
// Because vehicle enter/exit use same key binding.
|
||||
bool enterOrExitVeh;
|
||||
if (m_pPed->bVehExitWillBeInstant && m_pPed->bInVehicle)
|
||||
enterOrExitVeh = CPad::GetPad(0)->ExitVehicleJustDown();
|
||||
else
|
||||
enterOrExitVeh = CPad::GetPad(0)->GetExitVehicle();
|
||||
|
||||
if (enterOrExitVeh && m_pPed->m_nPedState != PED_SNIPER_MODE && m_pPed->m_nPedState != PED_ROCKET_ODE) {
|
||||
if (m_pPed->bInVehicle) {
|
||||
if (!m_pRemoteVehicle) {
|
||||
CEntity *surfaceBelowVeh = m_pPed->m_pMyVehicle->m_pCurGroundEntity;
|
||||
if (!surfaceBelowVeh || !CBridge::ThisIsABridgeObjectMovingUp(surfaceBelowVeh->m_modelIndex)) {
|
||||
CVehicle *veh = m_pPed->m_pMyVehicle;
|
||||
if (!veh->IsBoat() || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
|
||||
|
||||
// This condition will always return true, else block was probably WIP Miami code.
|
||||
if (veh->m_vehType != VEHICLE_TYPE_BIKE || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
|
||||
if (veh->m_status != STATUS_WRECKED && veh->m_status != STATUS_TRAIN_MOVING && veh->m_nDoorLock != CARLOCK_LOCKED_PLAYER_INSIDE) {
|
||||
if (veh->m_vecMoveSpeed.Magnitude() < 0.17f && CTimer::GetTimeScale() >= 0.5f && !veh->bIsInWater) {
|
||||
m_pPed->SetObjective(OBJECTIVE_LEAVE_VEHICLE, veh);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CVector sth = 0.7f * veh->GetRight() + veh->GetPosition();
|
||||
bool found = false;
|
||||
float groundZ = CWorld::FindGroundZFor3DCoord(sth.x, sth.y, 2.0f + sth.z, &found);
|
||||
|
||||
if (found)
|
||||
sth.z = 1.0f + groundZ;
|
||||
m_pPed->m_nPedState = PED_IDLE;
|
||||
m_pPed->SetMoveState(PEDMOVE_STILL);
|
||||
CPed::PedSetOutCarCB(0, m_pPed);
|
||||
CAnimManager::BlendAnimation(m_pPed->GetClump(), m_pPed->m_animGroup, ANIM_IDLE_STANCE, 100.0f);
|
||||
CAnimManager::BlendAnimation(m_pPed->GetClump(), ASSOCGRP_STD, ANIM_FALL_LAND, 100.0f);
|
||||
m_pPed->GetPosition() = sth;
|
||||
m_pPed->SetMoveState(PEDMOVE_STILL);
|
||||
m_pPed->m_vecMoveSpeed = veh->m_vecMoveSpeed;
|
||||
}
|
||||
} else {
|
||||
// The code in here was under CPed::SetExitBoat in VC, did the same for here.
|
||||
m_pPed->SetExitBoat(veh);
|
||||
m_pPed->bTryingToReachDryLand = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Enter vehicle
|
||||
if (CPad::GetPad(0)->ExitVehicleJustDown()) {
|
||||
bool weAreOnBoat = false;
|
||||
float lastCloseness = 0.0f;
|
||||
CVehicle *carBelow = nil;
|
||||
CEntity *surfaceBelow = m_pPed->m_pCurrentPhysSurface;
|
||||
if (surfaceBelow && surfaceBelow->IsVehicle()) {
|
||||
carBelow = (CVehicle*)surfaceBelow;
|
||||
if (carBelow->IsBoat()) {
|
||||
weAreOnBoat = true;
|
||||
m_pPed->bOnBoat = true;
|
||||
#ifdef VC_PED_PORTS
|
||||
if (carBelow->m_status != STATUS_WRECKED && carBelow->GetUp().z > 0.3f)
|
||||
#else
|
||||
if (carBelow->m_status != STATUS_WRECKED)
|
||||
#endif
|
||||
m_pPed->SetSeekBoatPosition(carBelow);
|
||||
}
|
||||
}
|
||||
// Find closest car
|
||||
if (!weAreOnBoat) {
|
||||
float minX = m_pPed->GetPosition().x - 10.0f;
|
||||
float maxX = 10.0f + m_pPed->GetPosition().x;
|
||||
float minY = m_pPed->GetPosition().y - 10.0f;
|
||||
float maxY = 10.0f + m_pPed->GetPosition().y;
|
||||
|
||||
int minXSector = CWorld::GetSectorIndexX(minX);
|
||||
if (minXSector < 0) minXSector = 0;
|
||||
int minYSector = CWorld::GetSectorIndexY(minY);
|
||||
if (minYSector < 0) minYSector = 0;
|
||||
int maxXSector = CWorld::GetSectorIndexX(maxX);
|
||||
if (maxXSector > NUMSECTORS_X - 1) maxXSector = NUMSECTORS_X - 1;
|
||||
int maxYSector = CWorld::GetSectorIndexY(maxY);
|
||||
if (maxYSector > NUMSECTORS_Y - 1) maxYSector = NUMSECTORS_Y - 1;
|
||||
|
||||
CWorld::AdvanceCurrentScanCode();
|
||||
|
||||
for (int curY = minYSector; curY <= maxYSector; curY++) {
|
||||
for (int curX = minXSector; curX <= maxXSector; curX++) {
|
||||
CSector *sector = CWorld::GetSector(curX, curY);
|
||||
FindClosestCarSectorList(sector->m_lists[ENTITYLIST_VEHICLES], m_pPed,
|
||||
minX, minY, maxX, maxY, &lastCloseness, &carBelow);
|
||||
FindClosestCarSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], m_pPed,
|
||||
minX, minY, maxX, maxY, &lastCloseness, &carBelow);
|
||||
}
|
||||
}
|
||||
}
|
||||
// carBelow is now closest vehicle
|
||||
if (carBelow && !weAreOnBoat) {
|
||||
if (carBelow->m_status == STATUS_TRAIN_NOT_MOVING) {
|
||||
m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, carBelow);
|
||||
} else if (carBelow->IsBoat()) {
|
||||
if (!carBelow->pDriver) {
|
||||
m_pPed->m_vehEnterType = 0;
|
||||
m_pPed->SetEnterCar(carBelow, m_pPed->m_vehEnterType);
|
||||
}
|
||||
} else {
|
||||
m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, carBelow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_bInRemoteMode) {
|
||||
uint32 timeWithoutRemoteCar = CTimer::GetTimeInMilliseconds() - m_nTimeLostRemoteCar;
|
||||
if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING) {
|
||||
TheCamera.SetFadeColour(0, 0, 0);
|
||||
TheCamera.Fade(1.0f, 0);
|
||||
}
|
||||
if (timeWithoutRemoteCar > 2000) {
|
||||
if (m_WBState == WBSTATE_PLAYING) {
|
||||
TheCamera.RestoreWithJumpCut();
|
||||
TheCamera.SetFadeColour(0, 0, 0);
|
||||
TheCamera.Fade(1.0f, 1);
|
||||
TheCamera.Process();
|
||||
CTimer::Stop();
|
||||
CCullZones::ForceCullZoneCoors(TheCamera.GetPosition());
|
||||
CRenderer::RequestObjectsInFrustum();
|
||||
CStreaming::LoadAllRequestedModels(false);
|
||||
CTimer::Update();
|
||||
}
|
||||
m_bInRemoteMode = false;
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle = nil;
|
||||
if (FindPlayerVehicle()) {
|
||||
FindPlayerVehicle()->m_status = STATUS_PLAYER;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(CTimer::GetFrameCounter() & 31)) {
|
||||
CVehicle *veh = FindPlayerVehicle();
|
||||
if (veh && m_pPed->bInVehicle && veh->GetUp().z < 0.0f
|
||||
&& veh->m_vecMoveSpeed.Magnitude() < 0.05f && veh->IsCar() && !veh->bIsInWater) {
|
||||
|
||||
if (veh->GetUp().z < -0.5f) {
|
||||
m_nUpsideDownCounter += 2;
|
||||
|
||||
} else {
|
||||
m_nUpsideDownCounter++;
|
||||
}
|
||||
} else {
|
||||
m_nUpsideDownCounter = 0;
|
||||
}
|
||||
|
||||
if (m_nUpsideDownCounter > 6 && veh->bCanBeDamaged) {
|
||||
veh->m_fHealth = 249.0f < veh->m_fHealth ? 249.0f : veh->m_fHealth;
|
||||
if (veh->IsCar()) {
|
||||
CAutomobile* car = (CAutomobile*)veh;
|
||||
car->Damage.SetEngineStatus(225);
|
||||
car->m_pSetOnFireEntity = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (FindPlayerVehicle()) {
|
||||
CVehicle *veh = FindPlayerVehicle();
|
||||
veh->m_nZoneLevel = -1;
|
||||
for (int i = 0; i < ARRAY_SIZE(veh->pPassengers); i++) {
|
||||
if (veh->pPassengers[i])
|
||||
veh->pPassengers[i]->m_nZoneLevel = 0;
|
||||
}
|
||||
CStats::DistanceTravelledInVehicle += veh->m_fDistanceTravelled;
|
||||
} else {
|
||||
CStats::DistanceTravelledOnFoot += FindPlayerPed()->m_fDistanceTravelled;
|
||||
}
|
||||
void
|
||||
CPlayerInfo::Process(void)
|
||||
{
|
||||
// Unused taxi feature. Gives you a dollar for every second with a passenger. Can be toggled via 0x29A opcode.
|
||||
bool startTaxiTimer = true;
|
||||
if (m_bUnusedTaxiThing && m_pPed->bInVehicle) {
|
||||
CVehicle *veh = m_pPed->m_pMyVehicle;
|
||||
if ((veh->m_modelIndex == MI_TAXI || veh->m_modelIndex == MI_CABBIE || veh->m_modelIndex == MI_BORGNINE)
|
||||
&& veh->pDriver == m_pPed && veh->m_nNumPassengers != 0) {
|
||||
for (uint32 timePassed = CTimer::GetTimeInMilliseconds() - m_nUnusedTaxiTimer; timePassed >= 1000; m_nUnusedTaxiTimer += 1000) {
|
||||
timePassed -= 1000;
|
||||
++m_nMoney;
|
||||
}
|
||||
startTaxiTimer = false;
|
||||
}
|
||||
}
|
||||
if (startTaxiTimer)
|
||||
m_nUnusedTaxiTimer = CTimer::GetTimeInMilliseconds();
|
||||
|
||||
// The effect that makes money counter does while earning/losing money
|
||||
if (m_nVisibleMoney != m_nMoney) {
|
||||
int diff = m_nMoney - m_nVisibleMoney;
|
||||
int diffAbs = Abs(diff);
|
||||
int changeBy;
|
||||
|
||||
if (diffAbs > 100000)
|
||||
changeBy = 12345;
|
||||
else if (diffAbs > 10000)
|
||||
changeBy = 1234;
|
||||
else if (diffAbs > 1000)
|
||||
changeBy = 123;
|
||||
else if (diffAbs > 50)
|
||||
changeBy = 42;
|
||||
else
|
||||
changeBy = 1;
|
||||
|
||||
if (diff < 0)
|
||||
m_nVisibleMoney -= changeBy;
|
||||
else
|
||||
m_nVisibleMoney += changeBy;
|
||||
}
|
||||
|
||||
if (!(CTimer::GetFrameCounter() & 15)) {
|
||||
CVector2D playerPos = m_pPed->bInVehicle ? m_pPed->m_pMyVehicle->GetPosition() : m_pPed->GetPosition();
|
||||
m_fRoadDensity = ThePaths.CalcRoadDensity(playerPos.x, playerPos.y);
|
||||
}
|
||||
|
||||
m_fRoadDensity = clamp(m_fRoadDensity, 0.4f, 1.45f);
|
||||
|
||||
// Because vehicle enter/exit use same key binding.
|
||||
bool enterOrExitVeh;
|
||||
if (m_pPed->bVehExitWillBeInstant && m_pPed->bInVehicle)
|
||||
enterOrExitVeh = CPad::GetPad(0)->ExitVehicleJustDown();
|
||||
else
|
||||
enterOrExitVeh = CPad::GetPad(0)->GetExitVehicle();
|
||||
|
||||
if (enterOrExitVeh && m_pPed->m_nPedState != PED_SNIPER_MODE && m_pPed->m_nPedState != PED_ROCKET_ODE) {
|
||||
if (m_pPed->bInVehicle) {
|
||||
if (!m_pRemoteVehicle) {
|
||||
CEntity *surfaceBelowVeh = m_pPed->m_pMyVehicle->m_pCurGroundEntity;
|
||||
if (!surfaceBelowVeh || !CBridge::ThisIsABridgeObjectMovingUp(surfaceBelowVeh->m_modelIndex)) {
|
||||
CVehicle *veh = m_pPed->m_pMyVehicle;
|
||||
if (!veh->IsBoat() || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
|
||||
|
||||
// This condition will always return true, else block was probably WIP Miami code.
|
||||
if (veh->m_vehType != VEHICLE_TYPE_BIKE || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
|
||||
if (veh->m_status != STATUS_WRECKED && veh->m_status != STATUS_TRAIN_MOVING && veh->m_nDoorLock != CARLOCK_LOCKED_PLAYER_INSIDE) {
|
||||
if (veh->m_vecMoveSpeed.Magnitude() < 0.17f && CTimer::GetTimeScale() >= 0.5f && !veh->bIsInWater) {
|
||||
m_pPed->SetObjective(OBJECTIVE_LEAVE_VEHICLE, veh);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CVector sth = 0.7f * veh->GetRight() + veh->GetPosition();
|
||||
bool found = false;
|
||||
float groundZ = CWorld::FindGroundZFor3DCoord(sth.x, sth.y, 2.0f + sth.z, &found);
|
||||
|
||||
if (found)
|
||||
sth.z = 1.0f + groundZ;
|
||||
m_pPed->m_nPedState = PED_IDLE;
|
||||
m_pPed->SetMoveState(PEDMOVE_STILL);
|
||||
CPed::PedSetOutCarCB(0, m_pPed);
|
||||
CAnimManager::BlendAnimation(m_pPed->GetClump(), m_pPed->m_animGroup, ANIM_IDLE_STANCE, 100.0f);
|
||||
CAnimManager::BlendAnimation(m_pPed->GetClump(), ASSOCGRP_STD, ANIM_FALL_LAND, 100.0f);
|
||||
m_pPed->GetPosition() = sth;
|
||||
m_pPed->SetMoveState(PEDMOVE_STILL);
|
||||
m_pPed->m_vecMoveSpeed = veh->m_vecMoveSpeed;
|
||||
}
|
||||
} else {
|
||||
// The code in here was under CPed::SetExitBoat in VC, did the same for here.
|
||||
m_pPed->SetExitBoat(veh);
|
||||
m_pPed->bTryingToReachDryLand = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Enter vehicle
|
||||
if (CPad::GetPad(0)->ExitVehicleJustDown()) {
|
||||
bool weAreOnBoat = false;
|
||||
float lastCloseness = 0.0f;
|
||||
CVehicle *carBelow = nil;
|
||||
CEntity *surfaceBelow = m_pPed->m_pCurrentPhysSurface;
|
||||
if (surfaceBelow && surfaceBelow->IsVehicle()) {
|
||||
carBelow = (CVehicle*)surfaceBelow;
|
||||
if (carBelow->IsBoat()) {
|
||||
weAreOnBoat = true;
|
||||
m_pPed->bOnBoat = true;
|
||||
#ifdef VC_PED_PORTS
|
||||
if (carBelow->m_status != STATUS_WRECKED && carBelow->GetUp().z > 0.3f)
|
||||
#else
|
||||
if (carBelow->m_status != STATUS_WRECKED)
|
||||
#endif
|
||||
m_pPed->SetSeekBoatPosition(carBelow);
|
||||
}
|
||||
}
|
||||
// Find closest car
|
||||
if (!weAreOnBoat) {
|
||||
float minX = m_pPed->GetPosition().x - 10.0f;
|
||||
float maxX = 10.0f + m_pPed->GetPosition().x;
|
||||
float minY = m_pPed->GetPosition().y - 10.0f;
|
||||
float maxY = 10.0f + m_pPed->GetPosition().y;
|
||||
|
||||
int minXSector = CWorld::GetSectorIndexX(minX);
|
||||
if (minXSector < 0) minXSector = 0;
|
||||
int minYSector = CWorld::GetSectorIndexY(minY);
|
||||
if (minYSector < 0) minYSector = 0;
|
||||
int maxXSector = CWorld::GetSectorIndexX(maxX);
|
||||
if (maxXSector > NUMSECTORS_X - 1) maxXSector = NUMSECTORS_X - 1;
|
||||
int maxYSector = CWorld::GetSectorIndexY(maxY);
|
||||
if (maxYSector > NUMSECTORS_Y - 1) maxYSector = NUMSECTORS_Y - 1;
|
||||
|
||||
CWorld::AdvanceCurrentScanCode();
|
||||
|
||||
for (int curY = minYSector; curY <= maxYSector; curY++) {
|
||||
for (int curX = minXSector; curX <= maxXSector; curX++) {
|
||||
CSector *sector = CWorld::GetSector(curX, curY);
|
||||
FindClosestCarSectorList(sector->m_lists[ENTITYLIST_VEHICLES], m_pPed,
|
||||
minX, minY, maxX, maxY, &lastCloseness, &carBelow);
|
||||
FindClosestCarSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], m_pPed,
|
||||
minX, minY, maxX, maxY, &lastCloseness, &carBelow);
|
||||
}
|
||||
}
|
||||
}
|
||||
// carBelow is now closest vehicle
|
||||
if (carBelow && !weAreOnBoat) {
|
||||
if (carBelow->m_status == STATUS_TRAIN_NOT_MOVING) {
|
||||
m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, carBelow);
|
||||
} else if (carBelow->IsBoat()) {
|
||||
if (!carBelow->pDriver) {
|
||||
m_pPed->m_vehEnterType = 0;
|
||||
m_pPed->SetEnterCar(carBelow, m_pPed->m_vehEnterType);
|
||||
}
|
||||
} else {
|
||||
m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, carBelow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_bInRemoteMode) {
|
||||
uint32 timeWithoutRemoteCar = CTimer::GetTimeInMilliseconds() - m_nTimeLostRemoteCar;
|
||||
if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING) {
|
||||
TheCamera.SetFadeColour(0, 0, 0);
|
||||
TheCamera.Fade(1.0f, 0);
|
||||
}
|
||||
if (timeWithoutRemoteCar > 2000) {
|
||||
if (m_WBState == WBSTATE_PLAYING) {
|
||||
TheCamera.RestoreWithJumpCut();
|
||||
TheCamera.SetFadeColour(0, 0, 0);
|
||||
TheCamera.Fade(1.0f, 1);
|
||||
TheCamera.Process();
|
||||
CTimer::Stop();
|
||||
CCullZones::ForceCullZoneCoors(TheCamera.GetPosition());
|
||||
CRenderer::RequestObjectsInFrustum();
|
||||
CStreaming::LoadAllRequestedModels(false);
|
||||
CTimer::Update();
|
||||
}
|
||||
m_bInRemoteMode = false;
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle = nil;
|
||||
if (FindPlayerVehicle()) {
|
||||
FindPlayerVehicle()->m_status = STATUS_PLAYER;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(CTimer::GetFrameCounter() & 31)) {
|
||||
CVehicle *veh = FindPlayerVehicle();
|
||||
if (veh && m_pPed->bInVehicle && veh->GetUp().z < 0.0f
|
||||
&& veh->m_vecMoveSpeed.Magnitude() < 0.05f && veh->IsCar() && !veh->bIsInWater) {
|
||||
|
||||
if (veh->GetUp().z < -0.5f) {
|
||||
m_nUpsideDownCounter += 2;
|
||||
|
||||
} else {
|
||||
m_nUpsideDownCounter++;
|
||||
}
|
||||
} else {
|
||||
m_nUpsideDownCounter = 0;
|
||||
}
|
||||
|
||||
if (m_nUpsideDownCounter > 6 && veh->bCanBeDamaged) {
|
||||
veh->m_fHealth = 249.0f < veh->m_fHealth ? 249.0f : veh->m_fHealth;
|
||||
if (veh->IsCar()) {
|
||||
CAutomobile* car = (CAutomobile*)veh;
|
||||
car->Damage.SetEngineStatus(225);
|
||||
car->m_pSetOnFireEntity = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (FindPlayerVehicle()) {
|
||||
CVehicle *veh = FindPlayerVehicle();
|
||||
veh->m_nZoneLevel = -1;
|
||||
for (int i = 0; i < ARRAY_SIZE(veh->pPassengers); i++) {
|
||||
if (veh->pPassengers[i])
|
||||
veh->pPassengers[i]->m_nZoneLevel = 0;
|
||||
}
|
||||
CStats::DistanceTravelledInVehicle += veh->m_fDistanceTravelled;
|
||||
} else {
|
||||
CStats::DistanceTravelledOnFoot += FindPlayerPed()->m_fDistanceTravelled;
|
||||
}
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
|
3006
src/core/Radar.cpp
3006
src/core/Radar.cpp
File diff suppressed because it is too large
Load Diff
@ -56,7 +56,7 @@ enum
|
||||
BLIP_MODE_SQUARE,
|
||||
};
|
||||
|
||||
struct CBlip
|
||||
struct sRadarTrace
|
||||
{
|
||||
uint32 m_nColor;
|
||||
uint32 m_eBlipType; // eBlipType
|
||||
@ -71,7 +71,7 @@ struct CBlip
|
||||
uint16 m_eBlipDisplay; // eBlipDisplay
|
||||
uint16 m_eRadarSprite; // eRadarSprite
|
||||
};
|
||||
static_assert(sizeof(CBlip) == 0x30, "CBlip: error");
|
||||
static_assert(sizeof(sRadarTrace) == 0x30, "sRadarTrace: error");
|
||||
|
||||
// Values for screen space
|
||||
#define RADAR_LEFT (40.0f)
|
||||
@ -83,7 +83,7 @@ class CRadar
|
||||
{
|
||||
public:
|
||||
static float &m_radarRange;
|
||||
static CBlip (&ms_RadarTrace)[NUMRADARBLIPS];
|
||||
static sRadarTrace (&ms_RadarTrace)[NUMRADARBLIPS];
|
||||
static CSprite2d AsukaSprite;
|
||||
static CSprite2d BombSprite;
|
||||
static CSprite2d CatSprite;
|
||||
@ -144,7 +144,6 @@ public:
|
||||
static void LoadAllRadarBlips(uint8 *buf, uint32 size);
|
||||
static void LoadTextures();
|
||||
static void RemoveRadarSections();
|
||||
static void RequestMapSection(int32 x, int32 y);
|
||||
static void SaveAllRadarBlips(uint8*, uint32*);
|
||||
static void SetBlipSprite(int32 i, int32 icon);
|
||||
static int32 SetCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay);
|
||||
@ -161,10 +160,6 @@ public:
|
||||
static void TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in);
|
||||
static void TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in);
|
||||
|
||||
// no in CRadar in the game:
|
||||
static void GetTextureCorners(int32 x, int32 y, CVector2D *out);
|
||||
static void ClipRadarTileCoords(int32 &x, int32 &y);
|
||||
static bool IsPointInsideRadar(const CVector2D &);
|
||||
static int LineRadarBoxCollision(CVector2D &, const CVector2D &, const CVector2D &);
|
||||
// no in CRadar in the game:
|
||||
static void CalculateCachedSinCos();
|
||||
};
|
||||
|
@ -347,13 +347,6 @@ CameraCreate(RwInt32 width, RwInt32 height, RwBool zBuffer)
|
||||
return (nil);
|
||||
}
|
||||
|
||||
WRAPPER void ReadVideoCardCapsFile(uint32&, uint32&, uint32&, uint32&) { EAXJMP(0x5926C0); }
|
||||
WRAPPER bool CheckVideoCardCaps(void) { EAXJMP(0x592740); }
|
||||
WRAPPER void WriteVideoCardCapsFile(void) { EAXJMP(0x5927D0); }
|
||||
WRAPPER void ConvertingTexturesScreen(uint32, uint32, const char*) { EAXJMP(0x592880); }
|
||||
WRAPPER void DealWithTxdWriteError(uint32, uint32, const char*) { EAXJMP(0x592BF0); }
|
||||
WRAPPER bool CreateTxdImageForVideoCard() { EAXJMP(0x592C70); }
|
||||
|
||||
void CreateDebugFont()
|
||||
{
|
||||
;
|
||||
|
@ -3,10 +3,24 @@
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
#include <dinput.h>
|
||||
#pragma warning( pop )
|
||||
#define WITHWINDOWS
|
||||
#include "common.h"
|
||||
#include "win.h"
|
||||
#include "patcher.h"
|
||||
#include "Timer.h"
|
||||
#ifdef GTA_PC
|
||||
#include "FileMgr.h"
|
||||
#include "Pad.h"
|
||||
#include "main.h"
|
||||
#include "Directory.h"
|
||||
#include "Streaming.h"
|
||||
#include "TxdStore.h"
|
||||
#include "CdStream.h"
|
||||
#include "Font.h"
|
||||
#include "Sprite2d.h"
|
||||
#include "Text.h"
|
||||
#include "RwHelper.h"
|
||||
#endif //GTA_PC
|
||||
|
||||
float &texLoadTime = *(float*)0x8F1B50;
|
||||
int32 &texNumLoaded = *(int32*)0x8F252C;
|
||||
@ -132,9 +146,198 @@ RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict)
|
||||
return texDict;
|
||||
}
|
||||
|
||||
#ifdef GTA_PC
|
||||
WRAPPER RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags) { EAXJMP(0x59A350); }
|
||||
|
||||
void
|
||||
ReadVideoCardCapsFile(uint32 &cap32, uint32 &cap24, uint32 &cap16, uint32 &cap8)
|
||||
{
|
||||
cap32 = UINT32_MAX;
|
||||
cap24 = UINT32_MAX;
|
||||
cap16 = UINT32_MAX;
|
||||
cap8 = UINT32_MAX;
|
||||
|
||||
int32 file = CFileMgr::OpenFile("DATA\\CAPS.DAT", "rb");
|
||||
if (file != 0) {
|
||||
CFileMgr::Read(file, (char*)&cap32, 4);
|
||||
CFileMgr::Read(file, (char*)&cap24, 4);
|
||||
CFileMgr::Read(file, (char*)&cap16, 4);
|
||||
CFileMgr::Read(file, (char*)&cap8, 4);
|
||||
CFileMgr::CloseFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CheckVideoCardCaps(void)
|
||||
{
|
||||
uint32 cap32 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT8888);
|
||||
uint32 cap24 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT888);
|
||||
uint32 cap16 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT1555);
|
||||
uint32 cap8 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMATPAL8 | rwRASTERFORMAT8888);
|
||||
uint32 fcap32, fcap24, fcap16, fcap8;
|
||||
ReadVideoCardCapsFile(fcap32, fcap24, fcap16, fcap8);
|
||||
return cap32 != fcap32 || cap24 != fcap24 || cap16 != fcap16 || cap8 != fcap8;
|
||||
}
|
||||
|
||||
void
|
||||
WriteVideoCardCapsFile(void)
|
||||
{
|
||||
uint32 cap32 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT8888);
|
||||
uint32 cap24 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT888);
|
||||
uint32 cap16 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT1555);
|
||||
uint32 cap8 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMATPAL8 | rwRASTERFORMAT8888);
|
||||
int32 file = CFileMgr::OpenFile("DATA\\CAPS.DAT", "wb");
|
||||
if (file != 0) {
|
||||
CFileMgr::Write(file, (char*)&cap32, 4);
|
||||
CFileMgr::Write(file, (char*)&cap24, 4);
|
||||
CFileMgr::Write(file, (char*)&cap16, 4);
|
||||
CFileMgr::Write(file, (char*)&cap8, 4);
|
||||
CFileMgr::CloseFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
|
||||
void DoRWStuffEndOfFrame(void);
|
||||
|
||||
void
|
||||
ConvertingTexturesScreen(uint32 num, uint32 count, const char *text)
|
||||
{
|
||||
HandleExit();
|
||||
|
||||
CSprite2d *splash = LoadSplash(nil);
|
||||
if (!DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255))
|
||||
return;
|
||||
|
||||
CSprite2d::SetRecipNearClip();
|
||||
CSprite2d::InitPerFrame();
|
||||
CFont::InitPerFrame();
|
||||
DefinedState();
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
|
||||
splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
|
||||
|
||||
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), SCREEN_SCALE_FROM_RIGHT(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(64, 64, 64, 255));
|
||||
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), (SCREEN_SCALE_FROM_RIGHT(200.0f) - SCREEN_SCALE_X(200.0f)) * ((float)num / (float)count) + SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(255, 217, 106, 255));
|
||||
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(120.0f), SCREEN_SCALE_Y(150.0f), SCREEN_SCALE_FROM_RIGHT(120.0f), SCREEN_HEIGHT - SCREEN_SCALE_Y(220.0f)), CRGBA(50, 50, 50, 210));
|
||||
|
||||
CFont::SetBackgroundOff();
|
||||
CFont::SetPropOn();
|
||||
CFont::SetScale(SCREEN_SCALE_X(0.45f), SCREEN_SCALE_Y(0.7f));
|
||||
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(170.0f));
|
||||
CFont::SetJustifyOff();
|
||||
CFont::SetColor(CRGBA(255, 217, 106, 255));
|
||||
CFont::SetBackGroundOnlyTextOff();
|
||||
CFont::SetFontStyle(FONT_BANK);
|
||||
CFont::PrintString(SCREEN_SCALE_X(170.0f), SCREEN_SCALE_Y(160.0f), TheText.Get(text));
|
||||
CFont::DrawFonts();
|
||||
DoRWStuffEndOfFrame();
|
||||
}
|
||||
|
||||
void
|
||||
DealWithTxdWriteError(uint32 num, uint32 count, const char *text)
|
||||
{
|
||||
while (!RsGlobal.quit) {
|
||||
ConvertingTexturesScreen(num, count, text);
|
||||
CPad::UpdatePads();
|
||||
if (CPad::GetPad(0)->GetEscapeJustDown())
|
||||
break;
|
||||
}
|
||||
RsGlobal.quit = false;
|
||||
LoadingScreen(nil, nil, nil);
|
||||
RsGlobal.quit = true;
|
||||
}
|
||||
|
||||
bool
|
||||
CreateTxdImageForVideoCard()
|
||||
{
|
||||
uint8 *buf = new uint8[CDSTREAM_SECTOR_SIZE];
|
||||
CDirectory *pDir = new CDirectory(TXDSTORESIZE);
|
||||
CDirectory::DirectoryInfo dirInfo;
|
||||
|
||||
CStreaming::FlushRequestList();
|
||||
|
||||
RwFileFunctions *filesys = RwOsGetFileInterface();
|
||||
|
||||
RwStream *img = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMWRITE, "models\\txd.img");
|
||||
if (img == nil) {
|
||||
if (_dwOperatingSystemVersion == OS_WINNT || _dwOperatingSystemVersion == OS_WIN2000 || _dwOperatingSystemVersion == OS_WINXP) {
|
||||
DealWithTxdWriteError(0, TXDSTORESIZE, "CVT_CRT");
|
||||
delete []buf;
|
||||
delete pDir;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int32 i;
|
||||
for (i = 0; i < TXDSTORESIZE; i++) {
|
||||
ConvertingTexturesScreen(i, TXDSTORESIZE, "CVT_MSG");
|
||||
|
||||
if (CTxdStore::GetSlot(i) != nil && CStreaming::IsObjectInCdImage(i + STREAM_OFFSET_TXD)) {
|
||||
CStreaming::RequestTxd(i, STREAMFLAGS_KEEP_IN_MEMORY);
|
||||
CStreaming::RequestModelStream(0);
|
||||
CStreaming::FlushChannels();
|
||||
|
||||
char filename[64];
|
||||
sprintf(filename, "%s.txd", CTxdStore::GetTxdName(i));
|
||||
|
||||
if (CTxdStore::GetSlot(i)->texDict) {
|
||||
int32 pos = filesys->rwftell(img->Type.file.fpFile);
|
||||
|
||||
if (RwTexDictionaryStreamWrite(CTxdStore::GetSlot(i)->texDict, img) == nil) {
|
||||
DealWithTxdWriteError(i, TXDSTORESIZE, "CVT_ERR");
|
||||
RwStreamClose(img, nil);
|
||||
delete []buf;
|
||||
delete pDir;
|
||||
CStreaming::RemoveTxd(i);
|
||||
return false;
|
||||
}
|
||||
|
||||
int32 size = filesys->rwftell(img->Type.file.fpFile) - pos;
|
||||
int32 num = size % CDSTREAM_SECTOR_SIZE;
|
||||
|
||||
size /= CDSTREAM_SECTOR_SIZE;
|
||||
if (num != 0) {
|
||||
size++;
|
||||
num = CDSTREAM_SECTOR_SIZE - num;
|
||||
RwStreamWrite(img, buf, num);
|
||||
}
|
||||
|
||||
dirInfo.offset = pos / CDSTREAM_SECTOR_SIZE;
|
||||
dirInfo.size = size;
|
||||
strncpy(dirInfo.name, filename, sizeof(dirInfo.name));
|
||||
pDir->AddItem(dirInfo);
|
||||
CStreaming::RemoveTxd(i);
|
||||
}
|
||||
CStreaming::FlushRequestList();
|
||||
}
|
||||
}
|
||||
|
||||
RwStreamClose(img, nil);
|
||||
delete []buf;
|
||||
|
||||
if (!pDir->WriteDirFile("models\\txd.dir")) {
|
||||
DealWithTxdWriteError(i, TXDSTORESIZE, "CVT_ERR");
|
||||
delete pDir;
|
||||
return false;
|
||||
}
|
||||
|
||||
delete pDir;
|
||||
|
||||
WriteVideoCardCapsFile();
|
||||
return true;
|
||||
}
|
||||
#endif // GTA_PC
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x592380, RwTextureGtaStreamRead, PATCH_JUMP);
|
||||
InjectHook(0x5924A0, RwTexDictionaryGtaStreamRead, PATCH_JUMP);
|
||||
InjectHook(0x592550, RwTexDictionaryGtaStreamRead1, PATCH_JUMP);
|
||||
InjectHook(0x592650, RwTexDictionaryGtaStreamRead2, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x5926C0, ReadVideoCardCapsFile, PATCH_JUMP);
|
||||
InjectHook(0x592740, CheckVideoCardCaps, PATCH_JUMP);
|
||||
InjectHook(0x5927D0, WriteVideoCardCapsFile, PATCH_JUMP);
|
||||
InjectHook(0x592880, ConvertingTexturesScreen, PATCH_JUMP);
|
||||
InjectHook(0x592BF0, DealWithTxdWriteError, PATCH_JUMP);
|
||||
InjectHook(0x592C70, CreateTxdImageForVideoCard, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -1,14 +1,14 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Stats.h"
|
||||
|
||||
WRAPPER void CStats::SaveStats(uint8 *buf, uint32 *size) { EAXJMP(0x4ab3e0); }
|
||||
#include "Text.h"
|
||||
#include "World.h"
|
||||
|
||||
int32 &CStats::DaysPassed = *(int32*)0x8F2BB8;
|
||||
int32 &CStats::HeadsPopped = *(int32*)0x8F647C;
|
||||
bool& CStats::CommercialPassed = *(bool*)0x8F4334;
|
||||
bool& CStats::IndustrialPassed = *(bool*)0x8E2A68;
|
||||
bool& CStats::SuburbanPassed = *(bool*)0x8F2740;
|
||||
int32& CStats::CommercialPassed = *(int32*)0x8F4334;
|
||||
int32& CStats::IndustrialPassed = *(int32*)0x8E2A68;
|
||||
int32& CStats::SuburbanPassed = *(int32*)0x8F2740;
|
||||
int32 &CStats::NumberKillFrenziesPassed = *(int32*)0x8E287C;
|
||||
int32 &CStats::PeopleKilledByOthers = *(int32*)0x8E2C50;
|
||||
int32 &CStats::HelisDestroyed = *(int32*)0x8E2A64;
|
||||
@ -48,7 +48,7 @@ int32& CStats::LongestFlightInDodo = *(int32*)0x8F5FE4;
|
||||
int32& CStats::TimeTakenDefuseMission = *(int32*)0x880E24;
|
||||
int32& CStats::TotalNumberKillFrenzies = *(int32*)0x8E2884;
|
||||
int32& CStats::TotalNumberMissions = *(int32*)0x8E2820;
|
||||
int32& CStats::ShotsMade = *(int32*)0x8E2BE8;
|
||||
int32& CStats::RoundsFiredByPlayer = *(int32*)0x8E2BE8;
|
||||
int32& CStats::KgsOfExplosivesUsed = *(int32*)0x8F2510;
|
||||
int32& CStats::InstantHitsFiredByPlayer = *(int32*)0x943070;
|
||||
int32& CStats::InstantHitsHitByPlayer = *(int32*)0x95CB8C;
|
||||
@ -62,7 +62,7 @@ void CStats::Init()
|
||||
{
|
||||
PeopleKilledByOthers = 0;
|
||||
PeopleKilledByPlayer = 0;
|
||||
ShotsMade = 0;
|
||||
RoundsFiredByPlayer = 0;
|
||||
CarsExploded = 0;
|
||||
HelisDestroyed = 0;
|
||||
ProgressMade = 0;
|
||||
@ -200,6 +200,229 @@ void CStats::SetTotalNumberMissions(int32 total)
|
||||
TotalNumberMissions = total;
|
||||
}
|
||||
|
||||
wchar *CStats::FindCriminalRatingString()
|
||||
{
|
||||
int rating = FindCriminalRatingNumber();
|
||||
|
||||
if (rating < 10) return TheText.Get("RATNG1");
|
||||
if (rating < 25) return TheText.Get("RATNG2");
|
||||
if (rating < 70) return TheText.Get("RATNG3");
|
||||
if (rating < 150) return TheText.Get("RATNG4");
|
||||
if (rating < 250) return TheText.Get("RATNG5");
|
||||
if (rating < 450) return TheText.Get("RATNG6");
|
||||
if (rating < 700) return TheText.Get("RATNG7");
|
||||
if (rating < 1000) return TheText.Get("RATNG8");
|
||||
if (rating < 1400) return TheText.Get("RATNG9");
|
||||
if (rating < 1900) return TheText.Get("RATNG10");
|
||||
if (rating < 2500) return TheText.Get("RATNG11");
|
||||
if (rating < 3200) return TheText.Get("RATNG12");
|
||||
if (rating < 4000) return TheText.Get("RATNG13");
|
||||
if (rating < 5000) return TheText.Get("RATNG14");
|
||||
return TheText.Get("RATNG15");
|
||||
}
|
||||
|
||||
int32 CStats::FindCriminalRatingNumber()
|
||||
{
|
||||
int32 rating;
|
||||
|
||||
rating = FiresExtinguished + 10 * HighestLevelAmbulanceMission + CriminalsCaught + LivesSavedWithAmbulance
|
||||
+ 30 * HelisDestroyed + TotalLegitimateKills - 3 * TimesArrested - 3 * TimesDied
|
||||
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney / 5000;
|
||||
if (rating <= 0) rating = 0;
|
||||
|
||||
if (InstantHitsFiredByPlayer > 100)
|
||||
rating += (float)CStats::InstantHitsHitByPlayer / (float)CStats::InstantHitsFiredByPlayer * 500.0f;
|
||||
if (TotalProgressInGame)
|
||||
rating += (float)CStats::ProgressMade / (float)CStats::TotalProgressInGame * 1000.0f;
|
||||
if (!IndustrialPassed && rating >= 3521)
|
||||
rating = 3521;
|
||||
if (!CommercialPassed && rating >= 4552)
|
||||
rating = 4552;
|
||||
return rating;
|
||||
}
|
||||
|
||||
void CStats::SaveStats(uint8 *buf, uint32 *size)
|
||||
{
|
||||
CheckPointReachedSuccessfully();
|
||||
uint8 *buf_start = buf;
|
||||
*size = sizeof(PeopleKilledByPlayer) +
|
||||
sizeof(PeopleKilledByOthers) +
|
||||
sizeof(CarsExploded) +
|
||||
sizeof(RoundsFiredByPlayer) +
|
||||
sizeof(PedsKilledOfThisType) +
|
||||
sizeof(HelisDestroyed) +
|
||||
sizeof(ProgressMade) +
|
||||
sizeof(TotalProgressInGame) +
|
||||
sizeof(KgsOfExplosivesUsed) +
|
||||
sizeof(InstantHitsFiredByPlayer) +
|
||||
sizeof(InstantHitsHitByPlayer) +
|
||||
sizeof(CarsCrushed) +
|
||||
sizeof(HeadsPopped) +
|
||||
sizeof(TimesArrested) +
|
||||
sizeof(TimesDied) +
|
||||
sizeof(DaysPassed) +
|
||||
sizeof(mmRain) +
|
||||
sizeof(MaximumJumpDistance) +
|
||||
sizeof(MaximumJumpHeight) +
|
||||
sizeof(MaximumJumpFlips) +
|
||||
sizeof(MaximumJumpSpins) +
|
||||
sizeof(BestStuntJump) +
|
||||
sizeof(NumberOfUniqueJumpsFound) +
|
||||
sizeof(TotalNumberOfUniqueJumps) +
|
||||
sizeof(MissionsGiven) +
|
||||
sizeof(MissionsPassed) +
|
||||
sizeof(PassengersDroppedOffWithTaxi) +
|
||||
sizeof(MoneyMadeWithTaxi) +
|
||||
sizeof(IndustrialPassed) +
|
||||
sizeof(CommercialPassed) +
|
||||
sizeof(SuburbanPassed) +
|
||||
sizeof(ElBurroTime) +
|
||||
sizeof(DistanceTravelledOnFoot) +
|
||||
sizeof(DistanceTravelledInVehicle) +
|
||||
sizeof(Record4x4One) +
|
||||
sizeof(Record4x4Two) +
|
||||
sizeof(Record4x4Three) +
|
||||
sizeof(Record4x4Mayhem) +
|
||||
sizeof(LivesSavedWithAmbulance) +
|
||||
sizeof(CriminalsCaught) +
|
||||
sizeof(HighestLevelAmbulanceMission) +
|
||||
sizeof(FiresExtinguished) +
|
||||
sizeof(LongestFlightInDodo) +
|
||||
sizeof(TimeTakenDefuseMission) +
|
||||
sizeof(NumberKillFrenziesPassed) +
|
||||
sizeof(TotalNumberKillFrenzies) +
|
||||
sizeof(TotalNumberMissions) +
|
||||
sizeof(FastestTimes) +
|
||||
sizeof(HighestScores) +
|
||||
sizeof(KillsSinceLastCheckpoint) +
|
||||
sizeof(TotalLegitimateKills) +
|
||||
sizeof(LastMissionPassedName);
|
||||
|
||||
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data);
|
||||
CopyToBuf(buf, PeopleKilledByPlayer);
|
||||
CopyToBuf(buf, PeopleKilledByOthers);
|
||||
CopyToBuf(buf, CarsExploded);
|
||||
CopyToBuf(buf, RoundsFiredByPlayer);
|
||||
CopyToBuf(buf, PedsKilledOfThisType);
|
||||
CopyToBuf(buf, HelisDestroyed);
|
||||
CopyToBuf(buf, ProgressMade);
|
||||
CopyToBuf(buf, TotalProgressInGame);
|
||||
CopyToBuf(buf, KgsOfExplosivesUsed);
|
||||
CopyToBuf(buf, InstantHitsFiredByPlayer);
|
||||
CopyToBuf(buf, InstantHitsHitByPlayer);
|
||||
CopyToBuf(buf, CarsCrushed);
|
||||
CopyToBuf(buf, HeadsPopped);
|
||||
CopyToBuf(buf, TimesArrested);
|
||||
CopyToBuf(buf, TimesDied);
|
||||
CopyToBuf(buf, DaysPassed);
|
||||
CopyToBuf(buf, mmRain);
|
||||
CopyToBuf(buf, MaximumJumpDistance);
|
||||
CopyToBuf(buf, MaximumJumpHeight);
|
||||
CopyToBuf(buf, MaximumJumpFlips);
|
||||
CopyToBuf(buf, MaximumJumpSpins);
|
||||
CopyToBuf(buf, BestStuntJump);
|
||||
CopyToBuf(buf, NumberOfUniqueJumpsFound);
|
||||
CopyToBuf(buf, TotalNumberOfUniqueJumps);
|
||||
CopyToBuf(buf, MissionsGiven);
|
||||
CopyToBuf(buf, MissionsPassed);
|
||||
CopyToBuf(buf, PassengersDroppedOffWithTaxi);
|
||||
CopyToBuf(buf, MoneyMadeWithTaxi);
|
||||
CopyToBuf(buf, IndustrialPassed);
|
||||
CopyToBuf(buf, CommercialPassed);
|
||||
CopyToBuf(buf, SuburbanPassed);
|
||||
CopyToBuf(buf, ElBurroTime);
|
||||
CopyToBuf(buf, DistanceTravelledOnFoot);
|
||||
CopyToBuf(buf, DistanceTravelledInVehicle);
|
||||
CopyToBuf(buf, Record4x4One);
|
||||
CopyToBuf(buf, Record4x4Two);
|
||||
CopyToBuf(buf, Record4x4Three);
|
||||
CopyToBuf(buf, Record4x4Mayhem);
|
||||
CopyToBuf(buf, LivesSavedWithAmbulance);
|
||||
CopyToBuf(buf, CriminalsCaught);
|
||||
CopyToBuf(buf, HighestLevelAmbulanceMission);
|
||||
CopyToBuf(buf, FiresExtinguished);
|
||||
CopyToBuf(buf, LongestFlightInDodo);
|
||||
CopyToBuf(buf, TimeTakenDefuseMission);
|
||||
CopyToBuf(buf, NumberKillFrenziesPassed);
|
||||
CopyToBuf(buf, TotalNumberKillFrenzies);
|
||||
CopyToBuf(buf, TotalNumberMissions);
|
||||
CopyToBuf(buf, FastestTimes);
|
||||
CopyToBuf(buf, HighestScores);
|
||||
CopyToBuf(buf, KillsSinceLastCheckpoint);
|
||||
CopyToBuf(buf, TotalLegitimateKills);
|
||||
CopyToBuf(buf, LastMissionPassedName);
|
||||
|
||||
assert(buf - buf_start == *size);
|
||||
#undef CopyToBuf
|
||||
}
|
||||
|
||||
void CStats::LoadStats(uint8 *buf, uint32 size)
|
||||
{
|
||||
uint8* buf_start = buf;
|
||||
|
||||
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data);
|
||||
|
||||
CopyFromBuf(buf, PeopleKilledByPlayer);
|
||||
CopyFromBuf(buf, PeopleKilledByOthers);
|
||||
CopyFromBuf(buf, CarsExploded);
|
||||
CopyFromBuf(buf, RoundsFiredByPlayer);
|
||||
CopyFromBuf(buf, PedsKilledOfThisType);
|
||||
CopyFromBuf(buf, HelisDestroyed);
|
||||
CopyFromBuf(buf, ProgressMade);
|
||||
CopyFromBuf(buf, TotalProgressInGame);
|
||||
CopyFromBuf(buf, KgsOfExplosivesUsed);
|
||||
CopyFromBuf(buf, InstantHitsFiredByPlayer);
|
||||
CopyFromBuf(buf, InstantHitsHitByPlayer);
|
||||
CopyFromBuf(buf, CarsCrushed);
|
||||
CopyFromBuf(buf, HeadsPopped);
|
||||
CopyFromBuf(buf, TimesArrested);
|
||||
CopyFromBuf(buf, TimesDied);
|
||||
CopyFromBuf(buf, DaysPassed);
|
||||
CopyFromBuf(buf, mmRain);
|
||||
CopyFromBuf(buf, MaximumJumpDistance);
|
||||
CopyFromBuf(buf, MaximumJumpHeight);
|
||||
CopyFromBuf(buf, MaximumJumpFlips);
|
||||
CopyFromBuf(buf, MaximumJumpSpins);
|
||||
CopyFromBuf(buf, BestStuntJump);
|
||||
CopyFromBuf(buf, NumberOfUniqueJumpsFound);
|
||||
CopyFromBuf(buf, TotalNumberOfUniqueJumps);
|
||||
CopyFromBuf(buf, MissionsGiven);
|
||||
CopyFromBuf(buf, MissionsPassed);
|
||||
CopyFromBuf(buf, PassengersDroppedOffWithTaxi);
|
||||
CopyFromBuf(buf, MoneyMadeWithTaxi);
|
||||
CopyFromBuf(buf, IndustrialPassed);
|
||||
CopyFromBuf(buf, CommercialPassed);
|
||||
CopyFromBuf(buf, SuburbanPassed);
|
||||
CopyFromBuf(buf, ElBurroTime);
|
||||
CopyFromBuf(buf, DistanceTravelledOnFoot);
|
||||
CopyFromBuf(buf, DistanceTravelledInVehicle);
|
||||
CopyFromBuf(buf, Record4x4One);
|
||||
CopyFromBuf(buf, Record4x4Two);
|
||||
CopyFromBuf(buf, Record4x4Three);
|
||||
CopyFromBuf(buf, Record4x4Mayhem);
|
||||
CopyFromBuf(buf, LivesSavedWithAmbulance);
|
||||
CopyFromBuf(buf, CriminalsCaught);
|
||||
CopyFromBuf(buf, HighestLevelAmbulanceMission);
|
||||
CopyFromBuf(buf, FiresExtinguished);
|
||||
CopyFromBuf(buf, LongestFlightInDodo);
|
||||
CopyFromBuf(buf, TimeTakenDefuseMission);
|
||||
CopyFromBuf(buf, NumberKillFrenziesPassed);
|
||||
CopyFromBuf(buf, TotalNumberKillFrenzies);
|
||||
CopyFromBuf(buf, TotalNumberMissions);
|
||||
CopyFromBuf(buf, FastestTimes);
|
||||
CopyFromBuf(buf, HighestScores);
|
||||
CopyFromBuf(buf, KillsSinceLastCheckpoint);
|
||||
CopyFromBuf(buf, TotalLegitimateKills);
|
||||
CopyFromBuf(buf, LastMissionPassedName);
|
||||
|
||||
assert(buf - buf_start == size);
|
||||
#undef CopyFromBuf
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x48C5A3, CStats::Init, PATCH_JUMP); // CGame::ReInitGameObjectVariables
|
||||
InjectHook(0x4AB3E0, CStats::SaveStats, PATCH_JUMP);
|
||||
InjectHook(0x4AB670, CStats::LoadStats, PATCH_JUMP);
|
||||
InjectHook(0x4AB090, CStats::FindCriminalRatingString, PATCH_JUMP);
|
||||
InjectHook(0x4AB2A0, CStats::FindCriminalRatingNumber, PATCH_JUMP);
|
||||
ENDPATCHES
|
@ -11,9 +11,9 @@ public:
|
||||
};
|
||||
static int32 &DaysPassed;
|
||||
static int32 &HeadsPopped;
|
||||
static bool& CommercialPassed;
|
||||
static bool& IndustrialPassed;
|
||||
static bool& SuburbanPassed;
|
||||
static int32& CommercialPassed;
|
||||
static int32& IndustrialPassed;
|
||||
static int32& SuburbanPassed;
|
||||
static int32 &NumberKillFrenziesPassed;
|
||||
static int32 &PeopleKilledByOthers;
|
||||
static int32 &HelisDestroyed;
|
||||
@ -53,7 +53,7 @@ public:
|
||||
static int32 &TimeTakenDefuseMission;
|
||||
static int32 &TotalNumberKillFrenzies;
|
||||
static int32 &TotalNumberMissions;
|
||||
static int32 &ShotsMade;
|
||||
static int32 &RoundsFiredByPlayer;
|
||||
static int32 &KgsOfExplosivesUsed;
|
||||
static int32 &InstantHitsFiredByPlayer;
|
||||
static int32 &InstantHitsHitByPlayer;
|
||||
@ -64,24 +64,27 @@ public:
|
||||
static int32(&HighestScores)[TOTAL_HIGHEST_SCORES];
|
||||
|
||||
public:
|
||||
static void Init(void);
|
||||
static void RegisterFastestTime(int32, int32);
|
||||
static void RegisterHighestScore(int32, int32);
|
||||
static void AnotherKillFrenzyPassed();
|
||||
static void AnotherLifeSavedWithAmbulance();
|
||||
static void AnotherCriminalCaught();
|
||||
static void RegisterLevelAmbulanceMission(int32);
|
||||
static void AnotherFireExtinguished();
|
||||
static void RegisterElBurroTime(int32);
|
||||
static void Register4x4OneTime(int32);
|
||||
static void Register4x4TwoTime(int32);
|
||||
static void Register4x4ThreeTime(int32);
|
||||
static void Register4x4MayhemTime(int32);
|
||||
static void AnotherLifeSavedWithAmbulance();
|
||||
static void AnotherCriminalCaught();
|
||||
static void RegisterLevelAmbulanceMission(int32);
|
||||
static void AnotherFireExtinguished();
|
||||
static wchar *FindCriminalRatingString();
|
||||
static void RegisterLongestFlightInDodo(int32);
|
||||
static void RegisterTimeTakenDefuseMission(int32);
|
||||
static void AnotherKillFrenzyPassed();
|
||||
static void SetTotalNumberKillFrenzies(int32);
|
||||
static void SetTotalNumberMissions(int32);
|
||||
static void CheckPointReachedUnsuccessfully() { KillsSinceLastCheckpoint = 0; };
|
||||
static void CheckPointReachedSuccessfully() { TotalLegitimateKills += KillsSinceLastCheckpoint; KillsSinceLastCheckpoint = 0; };
|
||||
static void RegisterElBurroTime(int32);
|
||||
static void CheckPointReachedUnsuccessfully() { KillsSinceLastCheckpoint = 0; };
|
||||
static int32 FindCriminalRatingNumber();
|
||||
static void SaveStats(uint8 *buf, uint32 *size);
|
||||
static void Init(void);
|
||||
static void LoadStats(uint8 *buf, uint32 size);
|
||||
};
|
||||
|
@ -56,6 +56,8 @@ WRAPPER void CWorld::FindMissionEntitiesIntersectingCube(const CVector&, const C
|
||||
WRAPPER void CWorld::ClearCarsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B50E0); }
|
||||
WRAPPER void CWorld::ClearPedsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B52B0); }
|
||||
WRAPPER void CWorld::CallOffChaseForArea(float, float, float, float) { EAXJMP(0x4B5530); }
|
||||
WRAPPER void CWorld::TriggerExplosion(const CVector& a1, float a2, float a3, CEntity *a4, bool a5) { EAXJMP(0x4B1140); }
|
||||
WRAPPER void CWorld::SetPedsOnFire(float, float, float, float, CEntity*) { EAXJMP(0x4B3D30); }
|
||||
|
||||
void
|
||||
CWorld::Initialise()
|
||||
|
@ -132,6 +132,7 @@ public:
|
||||
static void SetAllCarsCanBeDamaged(bool);
|
||||
static void ExtinguishAllCarFiresInArea(CVector, float);
|
||||
static void SetCarsOnFire(float, float, float, float, CEntity*);
|
||||
static void SetPedsOnFire(float, float, float, float, CEntity*);
|
||||
|
||||
static void Initialise();
|
||||
static void AddParticles();
|
||||
@ -140,6 +141,7 @@ public:
|
||||
static void RepositionCertainDynamicObjects();
|
||||
static void RemoveStaticObjects();
|
||||
static void Process();
|
||||
static void TriggerExplosion(const CVector &, float, float, CEntity*, bool);
|
||||
};
|
||||
|
||||
extern CColPoint *gaTempSphereColPoints;
|
||||
|
@ -84,12 +84,14 @@ extern void **rwengine;
|
||||
#define DEFAULT_SCREEN_WIDTH (640)
|
||||
#define DEFAULT_SCREEN_HEIGHT (448)
|
||||
#define DEFAULT_ASPECT_RATIO (4.0f/3.0f)
|
||||
#define DEFAULT_VIEWWINDOW (0.7f)
|
||||
|
||||
// game uses maximumWidth/Height, but this probably won't work
|
||||
// with RW windowed mode
|
||||
#define SCREEN_WIDTH ((float)RsGlobal.width)
|
||||
#define SCREEN_HEIGHT ((float)RsGlobal.height)
|
||||
#define SCREEN_ASPECT_RATIO (CDraw::GetAspectRatio())
|
||||
#define SCREEN_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetFOV() * 0.5f)))
|
||||
|
||||
// This scales from PS2 pixel coordinates to the real resolution
|
||||
#define SCREEN_STRETCH_X(a) ((a) * (float) SCREEN_WIDTH / DEFAULT_SCREEN_WIDTH)
|
||||
@ -105,10 +107,8 @@ extern void **rwengine;
|
||||
|
||||
#ifdef ASPECT_RATIO_SCALE
|
||||
#define SCREEN_SCALE_AR(a) ((a) * DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO)
|
||||
#define SCREEN_SCALE_AR2(a) ((a) / (DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO))
|
||||
#else
|
||||
#define SCREEN_SCALE_AR(a) (a)
|
||||
#define SCREEN_SCALE_AR2(a) (a)
|
||||
#endif
|
||||
|
||||
#include "maths.h"
|
||||
|
@ -79,6 +79,7 @@ enum Config {
|
||||
NUMPICKUPMESSAGES = 16,
|
||||
NUMBULLETTRACES = 16,
|
||||
NUMMBLURSTREAKS = 4,
|
||||
NUMSKIDMARKS = 32,
|
||||
|
||||
NUMONSCREENTIMERENTRIES = 1,
|
||||
NUMRADARBLIPS = 32,
|
||||
@ -125,7 +126,9 @@ enum Config {
|
||||
|
||||
NUM_GARAGE_STORED_CARS = 6,
|
||||
|
||||
NUM_CRANES = 8
|
||||
NUM_CRANES = 8,
|
||||
|
||||
NUM_EXPLOSIONS = 48,
|
||||
};
|
||||
|
||||
// We'll use this once we're ready to become independent of the game
|
||||
@ -150,6 +153,7 @@ enum Config {
|
||||
//#define MASTER
|
||||
|
||||
#if defined GTA_PS2
|
||||
# define GTA_PS2_STUFF
|
||||
# define RANDOMSPLASH
|
||||
#elif defined GTA_PC
|
||||
# define GTA3_1_1_PATCH
|
||||
|
2094
src/core/main.cpp
2094
src/core/main.cpp
File diff suppressed because it is too large
Load Diff
@ -1,119 +1,119 @@
|
||||
#include "common.h"
|
||||
#include "Debug.h"
|
||||
#include "obrstr.h"
|
||||
|
||||
char obrstr[128];
|
||||
char obrstr2[128];
|
||||
|
||||
void ObrInt(int32 n1)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void ObrInt2(int32 n1, int32 n2)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n2, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void ObrInt3(int32 n1, int32 n2, int32 n3)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n2, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n3, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void ObrInt4(int32 n1, int32 n2, int32 n3, int32 n4)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n2, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n3, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n4, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void ObrInt5(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n2, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n3, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n4, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n5, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void ObrInt6(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n2, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n3, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n4, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n5, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n6, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void IntToStr(int32 inNum, char *outStr)
|
||||
{
|
||||
bool isNeg = inNum < 0;
|
||||
|
||||
if (isNeg) {
|
||||
inNum = -inNum;
|
||||
*outStr = '-';
|
||||
}
|
||||
|
||||
int16 digits = 1;
|
||||
|
||||
if (inNum > 9) {
|
||||
int32 _inNum = inNum;
|
||||
do {
|
||||
digits++;
|
||||
_inNum /= 10;
|
||||
} while (_inNum > 9);
|
||||
}
|
||||
|
||||
int32 strSize = digits;
|
||||
if (isNeg)
|
||||
strSize++;
|
||||
|
||||
char *pStr = &outStr[strSize];
|
||||
int32 i = 0;
|
||||
do {
|
||||
*(pStr-- - 1) = (inNum % 10) + '0';
|
||||
inNum /= 10;
|
||||
} while (++i < strSize);
|
||||
outStr[strSize] = '\0';
|
||||
#include "common.h"
|
||||
#include "Debug.h"
|
||||
#include "obrstr.h"
|
||||
|
||||
char obrstr[128];
|
||||
char obrstr2[128];
|
||||
|
||||
void ObrInt(int32 n1)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void ObrInt2(int32 n1, int32 n2)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n2, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void ObrInt3(int32 n1, int32 n2, int32 n3)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n2, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n3, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void ObrInt4(int32 n1, int32 n2, int32 n3, int32 n4)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n2, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n3, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n4, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void ObrInt5(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n2, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n3, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n4, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n5, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void ObrInt6(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n2, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n3, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n4, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n5, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n6, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void IntToStr(int32 inNum, char *outStr)
|
||||
{
|
||||
bool isNeg = inNum < 0;
|
||||
|
||||
if (isNeg) {
|
||||
inNum = -inNum;
|
||||
*outStr = '-';
|
||||
}
|
||||
|
||||
int16 digits = 1;
|
||||
|
||||
if (inNum > 9) {
|
||||
int32 _inNum = inNum;
|
||||
do {
|
||||
digits++;
|
||||
_inNum /= 10;
|
||||
} while (_inNum > 9);
|
||||
}
|
||||
|
||||
int32 strSize = digits;
|
||||
if (isNeg)
|
||||
strSize++;
|
||||
|
||||
char *pStr = &outStr[strSize];
|
||||
int32 i = 0;
|
||||
do {
|
||||
*(pStr-- - 1) = (inNum % 10) + '0';
|
||||
inNum /= 10;
|
||||
} while (++i < strSize);
|
||||
outStr[strSize] = '\0';
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
void ObrInt(int32 n1);
|
||||
void ObrInt2(int32 n1, int32 n2);
|
||||
void ObrInt3(int32 n1, int32 n2, int32 n3);
|
||||
void ObrInt4(int32 n1, int32 n2, int32 n3, int32 n4);
|
||||
void ObrInt5(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5);
|
||||
void ObrInt6(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6);
|
||||
#pragma once
|
||||
|
||||
void ObrInt(int32 n1);
|
||||
void ObrInt2(int32 n1, int32 n2);
|
||||
void ObrInt3(int32 n1, int32 n2, int32 n3);
|
||||
void ObrInt4(int32 n1, int32 n2, int32 n3, int32 n4);
|
||||
void ObrInt5(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5);
|
||||
void ObrInt6(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6);
|
||||
void IntToStr(int32 inNum, char *outStr);
|
@ -1,121 +1,121 @@
|
||||
#ifndef MASTER
|
||||
#include "common.h"
|
||||
#include "Font.h"
|
||||
#include "Frontend.h"
|
||||
#include "Timer.h"
|
||||
#include "Text.h"
|
||||
|
||||
#define MAX_TIMERS (50)
|
||||
#define MAX_MS_COLLECTED (40)
|
||||
|
||||
// enables frame time output
|
||||
#define FRAMETIME
|
||||
|
||||
struct sTimeBar
|
||||
{
|
||||
char name[20];
|
||||
float startTime;
|
||||
float endTime;
|
||||
int32 unk;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
sTimeBar Timers[MAX_TIMERS];
|
||||
uint32 count;
|
||||
} TimerBar;
|
||||
float MaxTimes[MAX_TIMERS];
|
||||
float MaxFrameTime;
|
||||
|
||||
uint32 curMS;
|
||||
uint32 msCollected[MAX_MS_COLLECTED];
|
||||
#ifdef FRAMETIME
|
||||
float FrameInitTime;
|
||||
#endif
|
||||
|
||||
void tbInit()
|
||||
{
|
||||
TimerBar.count = 0;
|
||||
uint32 i = CTimer::GetFrameCounter() & 0x7F;
|
||||
if (i == 0) {
|
||||
do
|
||||
MaxTimes[i++] = 0.0f;
|
||||
while (i != MAX_TIMERS);
|
||||
#ifdef FRAMETIME
|
||||
MaxFrameTime = 0.0f;
|
||||
#endif
|
||||
}
|
||||
#ifdef FRAMETIME
|
||||
FrameInitTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
|
||||
#endif
|
||||
}
|
||||
|
||||
void tbStartTimer(int32 unk, char *name)
|
||||
{
|
||||
strcpy(TimerBar.Timers[TimerBar.count].name, name);
|
||||
TimerBar.Timers[TimerBar.count].unk = unk;
|
||||
TimerBar.Timers[TimerBar.count].startTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
|
||||
TimerBar.count++;
|
||||
}
|
||||
|
||||
void tbEndTimer(char* name)
|
||||
{
|
||||
uint32 n = 1500;
|
||||
for (uint32 i = 0; i < TimerBar.count; i++) {
|
||||
if (strcmp(name, TimerBar.Timers[i].name) == 0)
|
||||
n = i;
|
||||
}
|
||||
assert(n != 1500);
|
||||
TimerBar.Timers[n].endTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
|
||||
}
|
||||
|
||||
float Diag_GetFPS()
|
||||
{
|
||||
return 39000.0f / (msCollected[(curMS - 1) % MAX_MS_COLLECTED] - msCollected[curMS % MAX_MS_COLLECTED]);
|
||||
}
|
||||
|
||||
void tbDisplay()
|
||||
{
|
||||
char temp[200];
|
||||
wchar wtemp[200];
|
||||
|
||||
#ifdef FRAMETIME
|
||||
float FrameEndTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
|
||||
#endif
|
||||
|
||||
msCollected[(curMS++) % MAX_MS_COLLECTED] = RsTimer();
|
||||
CFont::SetBackgroundOff();
|
||||
CFont::SetBackgroundColor(CRGBA(0, 0, 0, 128));
|
||||
CFont::SetScale(0.48f, 1.12f);
|
||||
CFont::SetCentreOff();
|
||||
CFont::SetJustifyOff();
|
||||
CFont::SetWrapx(640.0f);
|
||||
CFont::SetRightJustifyOff();
|
||||
CFont::SetPropOn();
|
||||
CFont::SetFontStyle(FONT_BANK);
|
||||
sprintf(temp, "FPS: %.2f", Diag_GetFPS());
|
||||
AsciiToUnicode(temp, wtemp);
|
||||
CFont::SetColor(CRGBA(255, 255, 255, 255));
|
||||
if (!CMenuManager::m_PrefsMarketing || !CMenuManager::m_PrefsDisableTutorials) {
|
||||
CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * (4.0f / DEFAULT_SCREEN_HEIGHT), wtemp);
|
||||
|
||||
#ifndef FINAL
|
||||
// Timers output (my own implementation)
|
||||
for (uint32 i = 0; i < TimerBar.count; i++) {
|
||||
MaxTimes[i] = max(MaxTimes[i], TimerBar.Timers[i].endTime - TimerBar.Timers[i].startTime);
|
||||
sprintf(temp, "%s: %.2f", &TimerBar.Timers[i].name[0], MaxTimes[i]);
|
||||
AsciiToUnicode(temp, wtemp);
|
||||
CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * ((8.0f * (i + 2)) / DEFAULT_SCREEN_HEIGHT), wtemp);
|
||||
}
|
||||
|
||||
#ifdef FRAMETIME
|
||||
MaxFrameTime = max(MaxFrameTime, FrameEndTime - FrameInitTime);
|
||||
sprintf(temp, "Frame Time: %.2f", MaxFrameTime);
|
||||
AsciiToUnicode(temp, wtemp);
|
||||
|
||||
CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * ((8.0f * (TimerBar.count + 4)) / DEFAULT_SCREEN_HEIGHT), wtemp);
|
||||
#endif // FRAMETIME
|
||||
#endif // !FINAL
|
||||
}
|
||||
}
|
||||
#ifndef MASTER
|
||||
#include "common.h"
|
||||
#include "Font.h"
|
||||
#include "Frontend.h"
|
||||
#include "Timer.h"
|
||||
#include "Text.h"
|
||||
|
||||
#define MAX_TIMERS (50)
|
||||
#define MAX_MS_COLLECTED (40)
|
||||
|
||||
// enables frame time output
|
||||
#define FRAMETIME
|
||||
|
||||
struct sTimeBar
|
||||
{
|
||||
char name[20];
|
||||
float startTime;
|
||||
float endTime;
|
||||
int32 unk;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
sTimeBar Timers[MAX_TIMERS];
|
||||
uint32 count;
|
||||
} TimerBar;
|
||||
float MaxTimes[MAX_TIMERS];
|
||||
float MaxFrameTime;
|
||||
|
||||
uint32 curMS;
|
||||
uint32 msCollected[MAX_MS_COLLECTED];
|
||||
#ifdef FRAMETIME
|
||||
float FrameInitTime;
|
||||
#endif
|
||||
|
||||
void tbInit()
|
||||
{
|
||||
TimerBar.count = 0;
|
||||
uint32 i = CTimer::GetFrameCounter() & 0x7F;
|
||||
if (i == 0) {
|
||||
do
|
||||
MaxTimes[i++] = 0.0f;
|
||||
while (i != MAX_TIMERS);
|
||||
#ifdef FRAMETIME
|
||||
MaxFrameTime = 0.0f;
|
||||
#endif
|
||||
}
|
||||
#ifdef FRAMETIME
|
||||
FrameInitTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
|
||||
#endif
|
||||
}
|
||||
|
||||
void tbStartTimer(int32 unk, char *name)
|
||||
{
|
||||
strcpy(TimerBar.Timers[TimerBar.count].name, name);
|
||||
TimerBar.Timers[TimerBar.count].unk = unk;
|
||||
TimerBar.Timers[TimerBar.count].startTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
|
||||
TimerBar.count++;
|
||||
}
|
||||
|
||||
void tbEndTimer(char* name)
|
||||
{
|
||||
uint32 n = 1500;
|
||||
for (uint32 i = 0; i < TimerBar.count; i++) {
|
||||
if (strcmp(name, TimerBar.Timers[i].name) == 0)
|
||||
n = i;
|
||||
}
|
||||
assert(n != 1500);
|
||||
TimerBar.Timers[n].endTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
|
||||
}
|
||||
|
||||
float Diag_GetFPS()
|
||||
{
|
||||
return 39000.0f / (msCollected[(curMS - 1) % MAX_MS_COLLECTED] - msCollected[curMS % MAX_MS_COLLECTED]);
|
||||
}
|
||||
|
||||
void tbDisplay()
|
||||
{
|
||||
char temp[200];
|
||||
wchar wtemp[200];
|
||||
|
||||
#ifdef FRAMETIME
|
||||
float FrameEndTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
|
||||
#endif
|
||||
|
||||
msCollected[(curMS++) % MAX_MS_COLLECTED] = RsTimer();
|
||||
CFont::SetBackgroundOff();
|
||||
CFont::SetBackgroundColor(CRGBA(0, 0, 0, 128));
|
||||
CFont::SetScale(0.48f, 1.12f);
|
||||
CFont::SetCentreOff();
|
||||
CFont::SetJustifyOff();
|
||||
CFont::SetWrapx(640.0f);
|
||||
CFont::SetRightJustifyOff();
|
||||
CFont::SetPropOn();
|
||||
CFont::SetFontStyle(FONT_BANK);
|
||||
sprintf(temp, "FPS: %.2f", Diag_GetFPS());
|
||||
AsciiToUnicode(temp, wtemp);
|
||||
CFont::SetColor(CRGBA(255, 255, 255, 255));
|
||||
if (!CMenuManager::m_PrefsMarketing || !CMenuManager::m_PrefsDisableTutorials) {
|
||||
CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * (4.0f / DEFAULT_SCREEN_HEIGHT), wtemp);
|
||||
|
||||
#ifndef FINAL
|
||||
// Timers output (my own implementation)
|
||||
for (uint32 i = 0; i < TimerBar.count; i++) {
|
||||
MaxTimes[i] = max(MaxTimes[i], TimerBar.Timers[i].endTime - TimerBar.Timers[i].startTime);
|
||||
sprintf(temp, "%s: %.2f", &TimerBar.Timers[i].name[0], MaxTimes[i]);
|
||||
AsciiToUnicode(temp, wtemp);
|
||||
CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * ((8.0f * (i + 2)) / DEFAULT_SCREEN_HEIGHT), wtemp);
|
||||
}
|
||||
|
||||
#ifdef FRAMETIME
|
||||
MaxFrameTime = max(MaxFrameTime, FrameEndTime - FrameInitTime);
|
||||
sprintf(temp, "Frame Time: %.2f", MaxFrameTime);
|
||||
AsciiToUnicode(temp, wtemp);
|
||||
|
||||
CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * ((8.0f * (TimerBar.count + 4)) / DEFAULT_SCREEN_HEIGHT), wtemp);
|
||||
#endif // FRAMETIME
|
||||
#endif // !FINAL
|
||||
}
|
||||
}
|
||||
#endif // !MASTER
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
void tbInit();
|
||||
void tbStartTimer(int32, char*);
|
||||
void tbEndTimer(char*);
|
||||
#pragma once
|
||||
|
||||
void tbInit();
|
||||
void tbStartTimer(int32, char*);
|
||||
void tbEndTimer(char*);
|
||||
void tbDisplay();
|
@ -275,9 +275,9 @@ CEntity::CreateRwObject(void)
|
||||
if(IsBuilding())
|
||||
gBuildings++;
|
||||
if(RwObjectGetType(m_rwObject) == rpATOMIC)
|
||||
m_matrix.AttachRW(RwFrameGetMatrix(RpAtomicGetFrame(m_rwObject)), false);
|
||||
m_matrix.AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false);
|
||||
else if(RwObjectGetType(m_rwObject) == rpCLUMP)
|
||||
m_matrix.AttachRW(RwFrameGetMatrix(RpClumpGetFrame(m_rwObject)), false);
|
||||
m_matrix.AttachRW(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false);
|
||||
mi->AddRef();
|
||||
}
|
||||
}
|
||||
@ -290,7 +290,7 @@ CEntity::DeleteRwObject(void)
|
||||
m_matrix.Detach();
|
||||
if(m_rwObject){
|
||||
if(RwObjectGetType(m_rwObject) == rpATOMIC){
|
||||
f = RpAtomicGetFrame(m_rwObject);
|
||||
f = RpAtomicGetFrame((RpAtomic*)m_rwObject);
|
||||
RpAtomicDestroy((RpAtomic*)m_rwObject);
|
||||
RwFrameDestroy(f);
|
||||
}else if(RwObjectGetType(m_rwObject) == rpCLUMP)
|
||||
@ -307,9 +307,9 @@ CEntity::UpdateRwFrame(void)
|
||||
{
|
||||
if(m_rwObject){
|
||||
if(RwObjectGetType(m_rwObject) == rpATOMIC)
|
||||
RwFrameUpdateObjects(RpAtomicGetFrame(m_rwObject));
|
||||
RwFrameUpdateObjects(RpAtomicGetFrame((RpAtomic*)m_rwObject));
|
||||
else if(RwObjectGetType(m_rwObject) == rpCLUMP)
|
||||
RwFrameUpdateObjects(RpClumpGetFrame(m_rwObject));
|
||||
RwFrameUpdateObjects(RpClumpGetFrame((RpClump*)m_rwObject));
|
||||
}
|
||||
}
|
||||
|
||||
@ -482,9 +482,9 @@ CEntity::AttachToRwObject(RwObject *obj)
|
||||
m_rwObject = obj;
|
||||
if(m_rwObject){
|
||||
if(RwObjectGetType(m_rwObject) == rpATOMIC)
|
||||
m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame(m_rwObject)), false);
|
||||
m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false);
|
||||
else if(RwObjectGetType(m_rwObject) == rpCLUMP)
|
||||
m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame(m_rwObject)), false);
|
||||
m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false);
|
||||
CModelInfo::GetModelInfo(m_modelIndex)->AddRef();
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
class CSolid : public CEntity
|
||||
{
|
||||
public:
|
||||
CSolid(void) {
|
||||
m_type = ENTITY_TYPE_BUILDING;
|
||||
bUsesCollision = true;
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
class CSolid : public CEntity
|
||||
{
|
||||
public:
|
||||
CSolid(void) {
|
||||
m_type = ENTITY_TYPE_BUILDING;
|
||||
bUsesCollision = true;
|
||||
}
|
||||
};
|
@ -1,14 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "ClumpModelInfo.h"
|
||||
|
||||
class CMloModelInfo : public CClumpModelInfo
|
||||
{
|
||||
public:
|
||||
float field_34; // draw distance?
|
||||
int firstInstance;
|
||||
int lastInstance;
|
||||
public:
|
||||
CMloModelInfo(void) : CClumpModelInfo(MITYPE_MLO) {}
|
||||
void ConstructClump();
|
||||
#pragma once
|
||||
|
||||
#include "ClumpModelInfo.h"
|
||||
|
||||
class CMloModelInfo : public CClumpModelInfo
|
||||
{
|
||||
public:
|
||||
float field_34; // draw distance?
|
||||
int firstInstance;
|
||||
int lastInstance;
|
||||
public:
|
||||
CMloModelInfo(void) : CClumpModelInfo(MITYPE_MLO) {}
|
||||
void ConstructClump();
|
||||
};
|
@ -216,7 +216,7 @@ CPedModelInfo::AnimatePedColModel(CColModel* colmodel, RwFrame* frame)
|
||||
RwMatrixCopy(mat, RwFrameGetMatrix(f));
|
||||
|
||||
for (f = RwFrameGetParent(f); f; f = RwFrameGetParent(f)) {
|
||||
RwMatrixTransform(mat, &f->modelling, rwCOMBINEPOSTCONCAT);
|
||||
RwMatrixTransform(mat, RwFrameGetMatrix(f), rwCOMBINEPOSTCONCAT);
|
||||
if (RwFrameGetParent(f) == frame)
|
||||
break;
|
||||
}
|
||||
|
@ -707,7 +707,7 @@ RpMaterial*
|
||||
CVehicleModelInfo::GetEditableMaterialListCB(RpMaterial *material, void *data)
|
||||
{
|
||||
static RwRGBA white = { 255, 255, 255, 255 };
|
||||
RwRGBA *col;
|
||||
const RwRGBA *col;
|
||||
editableMatCBData *cbdata;
|
||||
|
||||
cbdata = (editableMatCBData*)data;
|
||||
@ -758,8 +758,8 @@ CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2)
|
||||
col = ms_vehicleColourTable[c1];
|
||||
coltex = ms_colourTextureTable[c1];
|
||||
for(matp = m_materials1; *matp; matp++){
|
||||
if(RpMaterialGetTexture(*matp) && RpMaterialGetTexture(*matp)->name[0] != '@'){
|
||||
colp = RpMaterialGetColor(*matp);
|
||||
if(RpMaterialGetTexture(*matp) && RwTextureGetName(RpMaterialGetTexture(*matp))[0] != '@'){
|
||||
colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
|
||||
colp->red = col.red;
|
||||
colp->green = col.green;
|
||||
colp->blue = col.blue;
|
||||
@ -773,8 +773,8 @@ CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2)
|
||||
col = ms_vehicleColourTable[c2];
|
||||
coltex = ms_colourTextureTable[c2];
|
||||
for(matp = m_materials2; *matp; matp++){
|
||||
if(RpMaterialGetTexture(*matp) && RpMaterialGetTexture(*matp)->name[0] != '@'){
|
||||
colp = RpMaterialGetColor(*matp);
|
||||
if(RpMaterialGetTexture(*matp) && RwTextureGetName(RpMaterialGetTexture(*matp))[0] != '@'){
|
||||
colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
|
||||
colp->red = col.red;
|
||||
colp->green = col.green;
|
||||
colp->blue = col.blue;
|
||||
@ -861,7 +861,7 @@ CreateCarColourTexture(uint8 r, uint8 g, uint8 b)
|
||||
RwImageDestroy(img);
|
||||
RwFree(pixels);
|
||||
tex = RwTextureCreate(ras);
|
||||
tex->name[0] = '@';
|
||||
RwTextureGetName(tex)[0] = '@';
|
||||
return tex;
|
||||
}
|
||||
|
||||
@ -1058,7 +1058,7 @@ CVehicleModelInfo::LoadEnvironmentMaps(void)
|
||||
}
|
||||
if(gpWhiteTexture == nil){
|
||||
gpWhiteTexture = RwTextureRead("white", nil);
|
||||
gpWhiteTexture->name[0] = '@';
|
||||
RwTextureGetName(gpWhiteTexture)[0] = '@';
|
||||
RwTextureSetFilterMode(gpWhiteTexture, rwFILTERLINEAR);
|
||||
}
|
||||
CTxdStore::PopCurrentTxd();
|
||||
|
@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "ClumpModelInfo.h"
|
||||
|
||||
class CXtraCompsModelInfo : public CClumpModelInfo
|
||||
{
|
||||
int field_34;
|
||||
public:
|
||||
CXtraCompsModelInfo(void) : CClumpModelInfo(MITYPE_XTRACOMPS) { field_34 = 0; }
|
||||
void SetClump(RpClump*) {};
|
||||
void Shutdown(void) {};
|
||||
#pragma once
|
||||
|
||||
#include "ClumpModelInfo.h"
|
||||
|
||||
class CXtraCompsModelInfo : public CClumpModelInfo
|
||||
{
|
||||
int field_34;
|
||||
public:
|
||||
CXtraCompsModelInfo(void) : CClumpModelInfo(MITYPE_XTRACOMPS) { field_34 = 0; }
|
||||
void SetClump(RpClump*) {};
|
||||
void Shutdown(void) {};
|
||||
};
|
@ -20,7 +20,7 @@ CCutsceneHead::CCutsceneHead(CObject *obj)
|
||||
m_pHeadNode = RpAnimBlendClumpFindFrame((RpClump*)obj->m_rwObject, "Shead")->frame;
|
||||
atm = (RpAtomic*)GetFirstObject(m_pHeadNode);
|
||||
if(atm){
|
||||
assert(RwObjectGetType(atm) == rpATOMIC);
|
||||
assert(RwObjectGetType((RwObject*)atm) == rpATOMIC);
|
||||
RpAtomicSetFlags(atm, RpAtomicGetFlags(atm) & ~rpATOMICRENDER);
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
|
||||
pobj->m_nRemoveTimer = 0;
|
||||
|
||||
if ( color.alpha != 0 )
|
||||
RwRGBAAssign(&pobj->m_Color, &color);
|
||||
pobj->m_Color, color;
|
||||
else
|
||||
pobj->m_Color.alpha = 0;
|
||||
|
||||
|
@ -676,7 +676,7 @@ RemoveAllModelCB(RwObject *object, void *data)
|
||||
{
|
||||
RpAtomic *atomic = (RpAtomic*)object;
|
||||
if (CVisibilityPlugins::GetAtomicModelInfo(atomic)) {
|
||||
RpClumpRemoveAtomic(atomic->clump, atomic);
|
||||
RpClumpRemoveAtomic(RpAtomicGetClump(atomic), atomic);
|
||||
RpAtomicDestroy(atomic);
|
||||
}
|
||||
return object;
|
||||
@ -902,7 +902,7 @@ static RwObject*
|
||||
SetPedAtomicVisibilityCB(RwObject* object, void* data)
|
||||
{
|
||||
if (data == nil)
|
||||
RpAtomicSetFlags(object, 0);
|
||||
RpAtomicSetFlags((RpAtomic*)object, 0);
|
||||
return object;
|
||||
}
|
||||
|
||||
|
@ -340,7 +340,7 @@ CPedIK::RestoreLookAt(void)
|
||||
}
|
||||
|
||||
void
|
||||
CPedIK::ExtractYawAndPitchWorld(RwMatrixTag *mat, float *yaw, float *pitch)
|
||||
CPedIK::ExtractYawAndPitchWorld(RwMatrix *mat, float *yaw, float *pitch)
|
||||
{
|
||||
float f = clamp(DotProduct(mat->up, CVector(0.0f, 1.0f, 0.0f)), -1.0f, 1.0f);
|
||||
*yaw = Acos(f);
|
||||
@ -352,7 +352,7 @@ CPedIK::ExtractYawAndPitchWorld(RwMatrixTag *mat, float *yaw, float *pitch)
|
||||
}
|
||||
|
||||
void
|
||||
CPedIK::ExtractYawAndPitchLocal(RwMatrixTag *mat, float *yaw, float *pitch)
|
||||
CPedIK::ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch)
|
||||
{
|
||||
float f = clamp(DotProduct(mat->at, CVector(0.0f, 0.0f, 1.0f)), -1.0f, 1.0f);
|
||||
*yaw = Acos(f);
|
||||
|
@ -54,8 +54,8 @@ public:
|
||||
void GetComponentPosition(RwV3d *pos, uint32 node);
|
||||
static RwMatrix *GetWorldMatrix(RwFrame *source, RwMatrix *destination);
|
||||
void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll);
|
||||
void ExtractYawAndPitchLocal(RwMatrixTag *mat, float *yaw, float *pitch);
|
||||
void ExtractYawAndPitchWorld(RwMatrixTag *mat, float *yaw, float *pitch);
|
||||
void ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch);
|
||||
void ExtractYawAndPitchWorld(RwMatrix *mat, float *yaw, float *pitch);
|
||||
LimbMoveStatus MoveLimb(LimbOrientation &limb, float approxPhi, float approxTheta, LimbMovementInfo &moveInfo);
|
||||
bool RestoreGunPosn(void);
|
||||
bool LookInDirection(float phi, float theta);
|
||||
|
@ -85,6 +85,7 @@ public:
|
||||
static uint32 GetFlag(int type) { return ms_apPedType[type]->m_flag; }
|
||||
static uint32 GetAvoid(int type) { return ms_apPedType[type]->m_avoid; }
|
||||
static uint32 GetThreats(int type) { return ms_apPedType[type]->m_threats; }
|
||||
static void SetThreats(int type, uint32 threat) { ms_apPedType[type]->m_threats = threat; }
|
||||
static void AddThreat(int type, int threat) { ms_apPedType[type]->m_threats |= threat; }
|
||||
static void RemoveThreat(int type, int threat) { ms_apPedType[type]->m_threats &= ~threat; }
|
||||
static bool IsThreat(int type, int threat) { return ms_apPedType[type]->m_threats & threat; }
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -704,12 +704,15 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
|
||||
if (i != 0) {
|
||||
// Gang member
|
||||
newPed->SetLeader(gangLeader);
|
||||
#ifndef FIX_BUGS
|
||||
// seems to be a miami leftover (this code is not on PS2) but gang peds end up just being frozen
|
||||
newPed->m_nPedState = PED_UNKNOWN;
|
||||
gangLeader->m_nPedState = PED_UNKNOWN;
|
||||
newPed->m_fRotationCur = CGeneral::GetRadianAngleBetweenPoints(
|
||||
gangLeader->GetPosition().x, gangLeader->GetPosition().y,
|
||||
newPed->GetPosition().x, newPed->GetPosition().y);
|
||||
newPed->m_fRotationDest = newPed->m_fRotationCur;
|
||||
#endif
|
||||
} else {
|
||||
gangLeader = newPed;
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ CClouds::Render(void)
|
||||
RwV3d pos = { 0.0f, -100.0f, 15.0f };
|
||||
RwV3dAdd(&worldpos, &campos, &pos);
|
||||
if(CSprite::CalcScreenCoors(worldpos, &screenpos, &szx, &szy, false)){
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[2]->raster);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[2]));
|
||||
if(CCoronas::bSmallMoon){
|
||||
szx *= 4.0f;
|
||||
szy *= 4.0f;
|
||||
@ -116,7 +116,7 @@ CClouds::Render(void)
|
||||
static float StarCoorsY[9] = { 0.0f, 0.45f, 0.9f, 1.0f, 0.85f, 0.52f, 0.48f, 0.35f, 0.2f };
|
||||
static float StarSizes[9] = { 1.0f, 1.4f, 0.9f, 1.0f, 0.6f, 1.5f, 1.3f, 1.0f, 0.8f };
|
||||
int brightness = (1.0f - coverage) * starintens;
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
|
||||
for(i = 0; i < 11; i++){
|
||||
RwV3d pos = { 100.0f, 0.0f, 10.0f };
|
||||
if(i >= 9) pos.x = -pos.x;
|
||||
@ -132,7 +132,7 @@ CClouds::Render(void)
|
||||
CSprite::FlushSpriteBuffer();
|
||||
|
||||
// *
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
|
||||
RwV3d pos = { 100.0f, 0.0f, 10.0f };
|
||||
RwV3dAdd(&worldpos, &campos, &pos);
|
||||
worldpos.y -= 90.0f;
|
||||
@ -156,7 +156,7 @@ CClouds::Render(void)
|
||||
int b = CTimeCycle::GetLowCloudsBlue() * lowcloudintensity;
|
||||
for(int cloudtype = 0; cloudtype < 3; cloudtype++){
|
||||
for(i = cloudtype; i < 12; i += 3){
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[cloudtype]->raster);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[cloudtype]));
|
||||
RwV3d pos = { 800.0f*LowCloudsX[i], 800.0f*LowCloudsY[i], 60.0f*LowCloudsZ[i] };
|
||||
worldpos.x = campos.x + pos.x;
|
||||
worldpos.y = campos.y + pos.y;
|
||||
@ -202,7 +202,7 @@ CClouds::Render(void)
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[4]->raster);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[4]));
|
||||
for(i = 0; i < 37; i++){
|
||||
RwV3d pos = { 2.0f*CoorsOffsetX[i], 2.0f*CoorsOffsetY[i], 40.0f*CoorsOffsetZ[i] + 40.0f };
|
||||
worldpos.x = pos.x*rot_cos + pos.y*rot_sin + campos.x;
|
||||
@ -244,7 +244,7 @@ CClouds::Render(void)
|
||||
// Highlights
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[3]->raster);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[3]));
|
||||
|
||||
for(i = 0; i < 37; i++){
|
||||
RwV3d pos = { 2.0f*CoorsOffsetX[i], 2.0f*CoorsOffsetY[i], 40.0f*CoorsOffsetZ[i] + 40.0f };
|
||||
@ -269,7 +269,7 @@ CClouds::Render(void)
|
||||
static uint8 BowRed[6] = { 30, 30, 30, 10, 0, 15 };
|
||||
static uint8 BowGreen[6] = { 0, 15, 30, 30, 0, 0 };
|
||||
static uint8 BowBlue[6] = { 0, 0, 0, 10, 30, 30 };
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
|
||||
for(i = 0; i < 6; i++){
|
||||
RwV3d pos = { i*1.5f, 100.0f, 5.0f };
|
||||
RwV3dAdd(&worldpos, &campos, &pos);
|
||||
|
@ -320,7 +320,7 @@ CCoronas::Render(void)
|
||||
|
||||
CSprite::RenderOneXLUSprite(spriteCoors.x, spriteCoors.y, spriteCoors.z,
|
||||
spritew * aCoronas[i].size * wscale,
|
||||
spriteh * SCREEN_SCALE_AR2(aCoronas[i].size * fogscale * hscale),
|
||||
spriteh * aCoronas[i].size * fogscale * hscale,
|
||||
CCoronas::aCoronas[i].red / fogscale,
|
||||
CCoronas::aCoronas[i].green / fogscale,
|
||||
CCoronas::aCoronas[i].blue / fogscale,
|
||||
@ -331,7 +331,7 @@ CCoronas::Render(void)
|
||||
CSprite::RenderOneXLUSprite_Rotate_Aspect(
|
||||
spriteCoors.x, spriteCoors.y, spriteCoors.z,
|
||||
spritew * aCoronas[i].size * fogscale,
|
||||
spriteh * SCREEN_SCALE_AR2(aCoronas[i].size * fogscale),
|
||||
spriteh * aCoronas[i].size * fogscale,
|
||||
CCoronas::aCoronas[i].red / fogscale,
|
||||
CCoronas::aCoronas[i].green / fogscale,
|
||||
CCoronas::aCoronas[i].blue / fogscale,
|
||||
|
@ -755,14 +755,14 @@ void CTowerClock::Render()
|
||||
&TempV[1],
|
||||
m_Position.x + Sin(angleMinute) * m_fScale * m_Size.x,
|
||||
m_Position.y + Sin(angleMinute) * m_fScale * m_Size.y,
|
||||
m_Position.z + Cos(angleMinute) * m_fScale;
|
||||
m_Position.z + Cos(angleMinute) * m_fScale
|
||||
);
|
||||
RwIm3DVertexSetPos(&TempV[2], m_Position.x, m_Position.y, m_Position.z);
|
||||
RwIm3DVertexSetPos(
|
||||
&TempV[3],
|
||||
m_Position.x + Sin(angleHour) * 0.75f * m_fScale * m_Size.x,
|
||||
m_Position.y + Sin(angleHour) * 0.75f * m_fScale * m_Size.y,
|
||||
m_Position.z + Cos(angleHour) * 0.75f * m_fScale;
|
||||
m_Position.z + Cos(angleHour) * 0.75f * m_fScale
|
||||
);
|
||||
|
||||
LittleTest();
|
||||
|
1272
src/render/Font.cpp
1272
src/render/Font.cpp
File diff suppressed because it is too large
Load Diff
@ -815,7 +815,7 @@ void CHud::Draw()
|
||||
DrawScriptText
|
||||
*/
|
||||
if (!CTimer::GetIsUserPaused()) {
|
||||
CTextLine* IntroText = CTheScripts::IntroTextLines;
|
||||
intro_text_line* IntroText = CTheScripts::IntroTextLines;
|
||||
|
||||
for (int i = 0; i < MAX_NUM_INTRO_TEXT_LINES; i++) {
|
||||
if (CTheScripts::IntroTextLines[i].m_Text[0] && CTheScripts::IntroTextLines[i].m_bTextBeforeFade) {
|
||||
@ -862,7 +862,7 @@ void CHud::Draw()
|
||||
}
|
||||
}
|
||||
|
||||
CScriptRectangle* IntroRect = CTheScripts::IntroRectangles;
|
||||
intro_script_rectangle* IntroRect = CTheScripts::IntroRectangles;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (CTheScripts::IntroRectangles[i].m_bIsUsed && CTheScripts::IntroRectangles[i].m_bBeforeFade) {
|
||||
|
@ -4,12 +4,13 @@
|
||||
#include "Camera.h"
|
||||
#include "MBlur.h"
|
||||
|
||||
// Originally taken from RW example 'mblur'
|
||||
|
||||
RwRaster *&CMBlur::pFrontBuffer = *(RwRaster**)0x8E2C48;
|
||||
bool &CMBlur::ms_bJustInitialised = *(bool*)0x95CDAB;
|
||||
bool &CMBlur::BlurOn = *(bool*)0x95CDAD;
|
||||
|
||||
static RwIm2DVertex Vertex[4];
|
||||
//static RwIm2DVertex *Vertex = (RwIm2DVertex*)0x62F780;
|
||||
static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 };
|
||||
|
||||
void
|
||||
|
@ -1,169 +1,174 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "main.h"
|
||||
#include "PlayerSkin.h"
|
||||
#include "TxdStore.h"
|
||||
#include "rtbmp.h"
|
||||
#include "ClumpModelInfo.h"
|
||||
#include "VisibilityPlugins.h"
|
||||
#include "World.h"
|
||||
#include "PlayerInfo.h"
|
||||
#include "CdStream.h"
|
||||
#include "FileMgr.h"
|
||||
#include "Directory.h"
|
||||
#include "RwHelper.h"
|
||||
#include "Timer.h"
|
||||
#include "Lights.h"
|
||||
|
||||
int CPlayerSkin::m_txdSlot;
|
||||
|
||||
void
|
||||
FindPlayerDff(uint32 &offset, uint32 &size)
|
||||
{
|
||||
int file;
|
||||
CDirectory::DirectoryInfo info;
|
||||
|
||||
file = CFileMgr::OpenFile("models\\gta3.dir", "rb");
|
||||
|
||||
do {
|
||||
if (!CFileMgr::Read(file, (char*)&info, sizeof(CDirectory::DirectoryInfo)))
|
||||
return;
|
||||
} while (strcasecmp("player.dff", info.name) != 0);
|
||||
|
||||
offset = info.offset;
|
||||
size = info.size;
|
||||
}
|
||||
|
||||
void
|
||||
LoadPlayerDff(void)
|
||||
{
|
||||
RwStream *stream;
|
||||
RwMemory mem;
|
||||
uint32 offset, size;
|
||||
uint8 *buffer;
|
||||
bool streamWasAdded = false;
|
||||
|
||||
if (CdStreamGetNumImages() == 0) {
|
||||
CdStreamAddImage("models\\gta3.img");
|
||||
streamWasAdded = true;
|
||||
}
|
||||
|
||||
FindPlayerDff(offset, size);
|
||||
buffer = (uint8*)RwMallocAlign(size << 11, 2048);
|
||||
CdStreamRead(0, buffer, offset, size);
|
||||
CdStreamSync(0);
|
||||
|
||||
mem.start = buffer;
|
||||
mem.length = size << 11;
|
||||
stream = RwStreamOpen(rwSTREAMMEMORY, rwSTREAMREAD, &mem);
|
||||
|
||||
if (RwStreamFindChunk(stream, rwID_CLUMP, nil, nil))
|
||||
gpPlayerClump = RpClumpStreamRead(stream);
|
||||
|
||||
RwStreamClose(stream, &mem);
|
||||
RwFreeAlign(buffer);
|
||||
|
||||
if (streamWasAdded)
|
||||
CdStreamRemoveImages();
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerSkin::Initialise(void)
|
||||
{
|
||||
m_txdSlot = CTxdStore::AddTxdSlot("skin");
|
||||
CTxdStore::Create(m_txdSlot);
|
||||
CTxdStore::AddRef(m_txdSlot);
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerSkin::Shutdown(void)
|
||||
{
|
||||
CTxdStore::RemoveTxdSlot(m_txdSlot);
|
||||
}
|
||||
|
||||
RwTexture *
|
||||
CPlayerSkin::GetSkinTexture(const char *texName)
|
||||
{
|
||||
RwTexture *tex;
|
||||
RwRaster *raster;
|
||||
int32 width, height, depth, format;
|
||||
|
||||
CTxdStore::PushCurrentTxd();
|
||||
CTxdStore::SetCurrentTxd(m_txdSlot);
|
||||
tex = RwTextureRead(texName, NULL);
|
||||
CTxdStore::PopCurrentTxd();
|
||||
if (tex) return tex;
|
||||
|
||||
if (strcmp(DEFAULT_SKIN_NAME, texName) == 0)
|
||||
sprintf(gString, "models\\generic\\player.bmp");
|
||||
else
|
||||
sprintf(gString, "skins\\%s.bmp", texName);
|
||||
|
||||
if (RwImage *image = RtBMPImageRead(gString)) {
|
||||
RwImageFindRasterFormat(image, rwRASTERTYPETEXTURE, &width, &height, &depth, &format);
|
||||
raster = RwRasterCreate(width, height, depth, format);
|
||||
RwRasterSetFromImage(raster, image);
|
||||
|
||||
tex = RwTextureCreate(raster);
|
||||
RwTextureSetName(tex, texName);
|
||||
RwTextureSetFilterMode(tex, rwFILTERLINEAR); // filtering bugfix from VC
|
||||
RwTexDictionaryAddTexture(CTxdStore::GetSlot(m_txdSlot)->texDict, tex);
|
||||
|
||||
RwImageDestroy(image);
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerSkin::BeginFrontendSkinEdit(void)
|
||||
{
|
||||
LoadPlayerDff();
|
||||
RpClumpForAllAtomics(gpPlayerClump, CClumpModelInfo::SetAtomicRendererCB, CVisibilityPlugins::RenderPlayerCB);
|
||||
CWorld::Players[0].LoadPlayerSkin();
|
||||
gOldFov = CDraw::GetFOV();
|
||||
CDraw::SetFOV(30.0f);
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerSkin::EndFrontendSkinEdit(void)
|
||||
{
|
||||
RpClumpDestroy(gpPlayerClump);
|
||||
gpPlayerClump = NULL;
|
||||
CDraw::SetFOV(gOldFov);
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerSkin::RenderFrontendSkinEdit(void)
|
||||
{
|
||||
static float rotation = 0.0f;
|
||||
RwRGBAReal AmbientColor = { 0.65f, 0.65f, 0.65f, 1.0f };
|
||||
RwV3d pos = { 1.35f, 0.35f, 7.725f };
|
||||
const RwV3d axis1 = { 1.0f, 0.0f, 0.0f };
|
||||
const RwV3d axis2 = { 0.0f, 0.0f, 1.0f };
|
||||
static uint32 LastFlash = 0;
|
||||
|
||||
RwFrame *frame = RpClumpGetFrame(gpPlayerClump);
|
||||
|
||||
if (CTimer::GetTimeInMillisecondsPauseMode() - LastFlash > 7) {
|
||||
rotation += 2.0f;
|
||||
if (rotation > 360.0f)
|
||||
rotation -= 360.0f;
|
||||
LastFlash = CTimer::GetTimeInMillisecondsPauseMode();
|
||||
}
|
||||
RwFrameTransform(frame, RwFrameGetMatrix(RwCameraGetFrame(Scene.camera)), rwCOMBINEREPLACE);
|
||||
RwFrameTranslate(frame, &pos, rwCOMBINEPRECONCAT);
|
||||
RwFrameRotate(frame, &axis1, -90.0f, rwCOMBINEPRECONCAT);
|
||||
RwFrameRotate(frame, &axis2, rotation, rwCOMBINEPRECONCAT);
|
||||
RwFrameUpdateObjects(frame);
|
||||
SetAmbientColours(&AmbientColor);
|
||||
RpClumpRender(gpPlayerClump);
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x59B9B0, &CPlayerSkin::Initialise, PATCH_JUMP);
|
||||
InjectHook(0x59B9E0, &CPlayerSkin::Shutdown, PATCH_JUMP);
|
||||
InjectHook(0x59B9F0, &CPlayerSkin::GetSkinTexture, PATCH_JUMP);
|
||||
InjectHook(0x59BC70, &CPlayerSkin::BeginFrontendSkinEdit, PATCH_JUMP);
|
||||
InjectHook(0x59BCB0, &CPlayerSkin::EndFrontendSkinEdit, PATCH_JUMP);
|
||||
InjectHook(0x59BCE0, &CPlayerSkin::RenderFrontendSkinEdit, PATCH_JUMP);
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "main.h"
|
||||
#include "PlayerSkin.h"
|
||||
#include "TxdStore.h"
|
||||
#include "rtbmp.h"
|
||||
#include "ClumpModelInfo.h"
|
||||
#include "VisibilityPlugins.h"
|
||||
#include "World.h"
|
||||
#include "PlayerInfo.h"
|
||||
#include "CdStream.h"
|
||||
#include "FileMgr.h"
|
||||
#include "Directory.h"
|
||||
#include "RwHelper.h"
|
||||
#include "Timer.h"
|
||||
#include "Lights.h"
|
||||
|
||||
RpClump *gpPlayerClump;
|
||||
float gOldFov;
|
||||
|
||||
int CPlayerSkin::m_txdSlot;
|
||||
|
||||
void
|
||||
FindPlayerDff(uint32 &offset, uint32 &size)
|
||||
{
|
||||
int file;
|
||||
CDirectory::DirectoryInfo info;
|
||||
|
||||
file = CFileMgr::OpenFile("models\\gta3.dir", "rb");
|
||||
|
||||
do {
|
||||
if (!CFileMgr::Read(file, (char*)&info, sizeof(CDirectory::DirectoryInfo)))
|
||||
return;
|
||||
} while (strcasecmp("player.dff", info.name) != 0);
|
||||
|
||||
offset = info.offset;
|
||||
size = info.size;
|
||||
}
|
||||
|
||||
void
|
||||
LoadPlayerDff(void)
|
||||
{
|
||||
RwStream *stream;
|
||||
RwMemory mem;
|
||||
uint32 offset, size;
|
||||
uint8 *buffer;
|
||||
bool streamWasAdded = false;
|
||||
|
||||
if (CdStreamGetNumImages() == 0) {
|
||||
CdStreamAddImage("models\\gta3.img");
|
||||
streamWasAdded = true;
|
||||
}
|
||||
|
||||
FindPlayerDff(offset, size);
|
||||
buffer = (uint8*)RwMallocAlign(size << 11, 2048);
|
||||
CdStreamRead(0, buffer, offset, size);
|
||||
CdStreamSync(0);
|
||||
|
||||
mem.start = buffer;
|
||||
mem.length = size << 11;
|
||||
stream = RwStreamOpen(rwSTREAMMEMORY, rwSTREAMREAD, &mem);
|
||||
|
||||
if (RwStreamFindChunk(stream, rwID_CLUMP, nil, nil))
|
||||
gpPlayerClump = RpClumpStreamRead(stream);
|
||||
|
||||
RwStreamClose(stream, &mem);
|
||||
RwFreeAlign(buffer);
|
||||
|
||||
if (streamWasAdded)
|
||||
CdStreamRemoveImages();
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerSkin::Initialise(void)
|
||||
{
|
||||
m_txdSlot = CTxdStore::AddTxdSlot("skin");
|
||||
CTxdStore::Create(m_txdSlot);
|
||||
CTxdStore::AddRef(m_txdSlot);
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerSkin::Shutdown(void)
|
||||
{
|
||||
CTxdStore::RemoveTxdSlot(m_txdSlot);
|
||||
}
|
||||
|
||||
RwTexture *
|
||||
CPlayerSkin::GetSkinTexture(const char *texName)
|
||||
{
|
||||
RwTexture *tex;
|
||||
RwRaster *raster;
|
||||
int32 width, height, depth, format;
|
||||
|
||||
CTxdStore::PushCurrentTxd();
|
||||
CTxdStore::SetCurrentTxd(m_txdSlot);
|
||||
tex = RwTextureRead(texName, NULL);
|
||||
CTxdStore::PopCurrentTxd();
|
||||
if (tex != nil) return tex;
|
||||
|
||||
if (strcmp(DEFAULT_SKIN_NAME, texName) == 0)
|
||||
sprintf(gString, "models\\generic\\player.bmp");
|
||||
else
|
||||
sprintf(gString, "skins\\%s.bmp", texName);
|
||||
|
||||
if (RwImage *image = RtBMPImageRead(gString)) {
|
||||
RwImageFindRasterFormat(image, rwRASTERTYPETEXTURE, &width, &height, &depth, &format);
|
||||
raster = RwRasterCreate(width, height, depth, format);
|
||||
RwRasterSetFromImage(raster, image);
|
||||
|
||||
tex = RwTextureCreate(raster);
|
||||
RwTextureSetName(tex, texName);
|
||||
#ifdef FIX_BUGS
|
||||
RwTextureSetFilterMode(tex, rwFILTERLINEAR); // filtering bugfix from VC
|
||||
#endif
|
||||
RwTexDictionaryAddTexture(CTxdStore::GetSlot(m_txdSlot)->texDict, tex);
|
||||
|
||||
RwImageDestroy(image);
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerSkin::BeginFrontendSkinEdit(void)
|
||||
{
|
||||
LoadPlayerDff();
|
||||
RpClumpForAllAtomics(gpPlayerClump, CClumpModelInfo::SetAtomicRendererCB, CVisibilityPlugins::RenderPlayerCB);
|
||||
CWorld::Players[0].LoadPlayerSkin();
|
||||
gOldFov = CDraw::GetFOV();
|
||||
CDraw::SetFOV(30.0f);
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerSkin::EndFrontendSkinEdit(void)
|
||||
{
|
||||
RpClumpDestroy(gpPlayerClump);
|
||||
gpPlayerClump = NULL;
|
||||
CDraw::SetFOV(gOldFov);
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerSkin::RenderFrontendSkinEdit(void)
|
||||
{
|
||||
static float rotation = 0.0f;
|
||||
RwRGBAReal AmbientColor = { 0.65f, 0.65f, 0.65f, 1.0f };
|
||||
const RwV3d pos = { 1.35f, 0.35f, 7.725f };
|
||||
const RwV3d axis1 = { 1.0f, 0.0f, 0.0f };
|
||||
const RwV3d axis2 = { 0.0f, 0.0f, 1.0f };
|
||||
static uint32 LastFlash = 0;
|
||||
|
||||
RwFrame *frame = RpClumpGetFrame(gpPlayerClump);
|
||||
|
||||
if (CTimer::GetTimeInMillisecondsPauseMode() - LastFlash > 7) {
|
||||
rotation += 2.0f;
|
||||
if (rotation > 360.0f)
|
||||
rotation -= 360.0f;
|
||||
LastFlash = CTimer::GetTimeInMillisecondsPauseMode();
|
||||
}
|
||||
RwFrameTransform(frame, RwFrameGetMatrix(RwCameraGetFrame(Scene.camera)), rwCOMBINEREPLACE);
|
||||
RwFrameTranslate(frame, &pos, rwCOMBINEPRECONCAT);
|
||||
RwFrameRotate(frame, &axis1, -90.0f, rwCOMBINEPRECONCAT);
|
||||
RwFrameRotate(frame, &axis2, rotation, rwCOMBINEPRECONCAT);
|
||||
RwFrameUpdateObjects(frame);
|
||||
SetAmbientColours(&AmbientColor);
|
||||
RpClumpRender(gpPlayerClump);
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x59B9B0, &CPlayerSkin::Initialise, PATCH_JUMP);
|
||||
InjectHook(0x59B9E0, &CPlayerSkin::Shutdown, PATCH_JUMP);
|
||||
InjectHook(0x59B9F0, &CPlayerSkin::GetSkinTexture, PATCH_JUMP);
|
||||
InjectHook(0x59BC70, &CPlayerSkin::BeginFrontendSkinEdit, PATCH_JUMP);
|
||||
InjectHook(0x59BCB0, &CPlayerSkin::EndFrontendSkinEdit, PATCH_JUMP);
|
||||
InjectHook(0x59BCE0, &CPlayerSkin::RenderFrontendSkinEdit, PATCH_JUMP);
|
||||
ENDPATCHES
|
@ -2,12 +2,6 @@
|
||||
|
||||
#define DEFAULT_SKIN_NAME "$$\"\""
|
||||
|
||||
static RpClump *gpPlayerClump;// = *(RpClump**)0x660FF8;
|
||||
static float gOldFov;// = *(float*)0x660FFC;
|
||||
|
||||
void LoadPlayerDff(void);
|
||||
void FindPlayerDff(uint32 &offset, uint32 &size);
|
||||
|
||||
class CPlayerSkin
|
||||
{
|
||||
static int m_txdSlot;
|
@ -1,12 +1,247 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "main.h"
|
||||
#include "TxdStore.h"
|
||||
#include "Timer.h"
|
||||
#include "Replay.h"
|
||||
#include "Skidmarks.h"
|
||||
|
||||
WRAPPER void CSkidmarks::Clear(void) { EAXJMP(0x518130); }
|
||||
WRAPPER void CSkidmarks::Update() { EAXJMP(0x518200); }
|
||||
CSkidmark CSkidmarks::aSkidmarks[NUMSKIDMARKS];
|
||||
|
||||
WRAPPER void CSkidmarks::Render(void) { EAXJMP(0x5182E0); }
|
||||
WRAPPER void CSkidmarks::RegisterOne(uint32 id, CVector pos, float fwdx, float fwdY, bool *isMuddy, bool *isBloddy) { EAXJMP(0x5185C0); }
|
||||
RwImVertexIndex SkidmarkIndexList[SKIDMARK_LENGTH * 6];
|
||||
RwIm3DVertex SkidmarkVertices[SKIDMARK_LENGTH * 2];
|
||||
RwTexture *gpSkidTex;
|
||||
RwTexture *gpSkidBloodTex;
|
||||
RwTexture *gpSkidMudTex;
|
||||
|
||||
WRAPPER void CSkidmarks::Init(void) { EAXJMP(0x517D70); }
|
||||
WRAPPER void CSkidmarks::Shutdown(void) { EAXJMP(0x518100); }
|
||||
void
|
||||
CSkidmarks::Init(void)
|
||||
{
|
||||
int i, ix, slot;
|
||||
CTxdStore::PushCurrentTxd();
|
||||
slot = CTxdStore::FindTxdSlot("particle");
|
||||
CTxdStore::SetCurrentTxd(slot);
|
||||
gpSkidTex = RwTextureRead("particleskid", nil);
|
||||
gpSkidBloodTex = RwTextureRead("particleskidblood", nil);
|
||||
gpSkidMudTex = RwTextureRead("particleskidmud", nil);
|
||||
CTxdStore::PopCurrentTxd();
|
||||
|
||||
for(i = 0; i < NUMSKIDMARKS; i++){
|
||||
aSkidmarks[i].m_state = 0;
|
||||
aSkidmarks[i].m_wasUpdated = false;
|
||||
}
|
||||
|
||||
ix = 0;
|
||||
for(i = 0; i < SKIDMARK_LENGTH; i++){
|
||||
SkidmarkIndexList[i*6+0] = ix+0;
|
||||
SkidmarkIndexList[i*6+1] = ix+2;
|
||||
SkidmarkIndexList[i*6+2] = ix+1;
|
||||
SkidmarkIndexList[i*6+3] = ix+1;
|
||||
SkidmarkIndexList[i*6+4] = ix+2;
|
||||
SkidmarkIndexList[i*6+5] = ix+3;
|
||||
ix += 2;
|
||||
}
|
||||
|
||||
for(i = 0; i < SKIDMARK_LENGTH; i++){
|
||||
RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 0], 0.0f);
|
||||
RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 0], i*5.01f);
|
||||
RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 1], 1.0f);
|
||||
RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 1], i*5.01f);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CSkidmarks::Shutdown(void)
|
||||
{
|
||||
RwTextureDestroy(gpSkidTex);
|
||||
RwTextureDestroy(gpSkidBloodTex);
|
||||
RwTextureDestroy(gpSkidMudTex);
|
||||
}
|
||||
|
||||
void
|
||||
CSkidmarks::Clear(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < NUMSKIDMARKS; i++){
|
||||
aSkidmarks[i].m_state = 0;
|
||||
aSkidmarks[i].m_wasUpdated = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CSkidmarks::Update(void)
|
||||
{
|
||||
int i;
|
||||
uint32 t1 = CTimer::GetTimeInMilliseconds() + 2500;
|
||||
uint32 t2 = CTimer::GetTimeInMilliseconds() + 5000;
|
||||
uint32 t3 = CTimer::GetTimeInMilliseconds() + 10000;
|
||||
uint32 t4 = CTimer::GetTimeInMilliseconds() + 20000;
|
||||
for(i = 0; i < NUMSKIDMARKS; i++){
|
||||
switch(aSkidmarks[i].m_state){
|
||||
case 1:
|
||||
if(!aSkidmarks[i].m_wasUpdated){
|
||||
// Didn't continue this one last time, so finish it and set fade times
|
||||
aSkidmarks[i].m_state = 2;
|
||||
if(aSkidmarks[i].m_last < 4){
|
||||
aSkidmarks[i].m_fadeStart = t1;
|
||||
aSkidmarks[i].m_fadeEnd = t2;
|
||||
}else if(aSkidmarks[i].m_last < 9){
|
||||
aSkidmarks[i].m_fadeStart = t2;
|
||||
aSkidmarks[i].m_fadeEnd = t3;
|
||||
}else{
|
||||
aSkidmarks[i].m_fadeStart = t3;
|
||||
aSkidmarks[i].m_fadeEnd = t4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(CTimer::GetTimeInMilliseconds() > aSkidmarks[i].m_fadeEnd)
|
||||
aSkidmarks[i].m_state = 0;
|
||||
break;
|
||||
}
|
||||
aSkidmarks[i].m_wasUpdated = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CSkidmarks::Render(void)
|
||||
{
|
||||
int i, j;
|
||||
RwTexture *lastTex = nil;
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||
|
||||
for(i = 0; i < NUMSKIDMARKS; i++){
|
||||
if(aSkidmarks[i].m_state == 0 || aSkidmarks[i].m_last < 1)
|
||||
continue;
|
||||
|
||||
if(aSkidmarks[i].m_isBloody){
|
||||
if(lastTex != gpSkidBloodTex){
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidBloodTex));
|
||||
lastTex = gpSkidBloodTex;
|
||||
}
|
||||
}else if(aSkidmarks[i].m_isMuddy){
|
||||
if(lastTex != gpSkidMudTex){
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidMudTex));
|
||||
lastTex = gpSkidMudTex;
|
||||
}
|
||||
}else{
|
||||
if(lastTex != gpSkidTex){
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidTex));
|
||||
lastTex = gpSkidTex;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 fade, alpha;
|
||||
if(aSkidmarks[i].m_state == 1 || CTimer::GetTimeInMilliseconds() < aSkidmarks[i].m_fadeStart)
|
||||
fade = 255;
|
||||
else
|
||||
fade = 255*(aSkidmarks[i].m_fadeEnd - CTimer::GetTimeInMilliseconds()) / (aSkidmarks[i].m_fadeEnd - aSkidmarks[i].m_fadeStart);
|
||||
|
||||
for(j = 0; j <= aSkidmarks[i].m_last; j++){
|
||||
alpha = 128;
|
||||
if(j == 0 || j == aSkidmarks[i].m_last && aSkidmarks[i].m_state == 2)
|
||||
alpha = 0;
|
||||
alpha = alpha*fade/256;
|
||||
|
||||
CVector p1 = aSkidmarks[i].m_pos[j] + aSkidmarks[i].m_side[j];
|
||||
CVector p2 = aSkidmarks[i].m_pos[j] - aSkidmarks[i].m_side[j];
|
||||
RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+0], 255, 255, 255, alpha);
|
||||
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+0], p1.x, p1.y, p1.z+0.1f);
|
||||
RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+1], 255, 255, 255, alpha);
|
||||
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+1], p2.x, p2.y, p2.z+0.1f);
|
||||
}
|
||||
|
||||
LittleTest();
|
||||
if(RwIm3DTransform(SkidmarkVertices, 2*(aSkidmarks[i].m_last+1), nil, rwIM3D_VERTEXUV)){
|
||||
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, SkidmarkIndexList, 6*aSkidmarks[i].m_last);
|
||||
RwIm3DEnd();
|
||||
}
|
||||
}
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
CSkidmarks::RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody)
|
||||
{
|
||||
int i;
|
||||
CVector2D fwd(fwdX, fwdY);
|
||||
|
||||
if(CReplay::IsPlayingBack())
|
||||
return;
|
||||
|
||||
// Find a skidmark to continue
|
||||
for(i = 0; i < NUMSKIDMARKS; i++)
|
||||
if(aSkidmarks[i].m_state == 1 && aSkidmarks[i].m_id == id)
|
||||
break;
|
||||
|
||||
if(i < NUMSKIDMARKS){
|
||||
// Continue this one
|
||||
|
||||
if(aSkidmarks[i].m_isBloody != *isBloody){
|
||||
// Blood-status changed, end this one
|
||||
aSkidmarks[i].m_state = 2;
|
||||
aSkidmarks[i].m_fadeStart = CTimer::GetTimeInMilliseconds() + 10000;
|
||||
aSkidmarks[i].m_fadeEnd = CTimer::GetTimeInMilliseconds() + 20000;
|
||||
return;
|
||||
}
|
||||
|
||||
aSkidmarks[i].m_wasUpdated = true;
|
||||
|
||||
if(CTimer::GetTimeInMilliseconds() - aSkidmarks[i].m_lastUpdate <= 100){
|
||||
// Last update was recently, just change last coords
|
||||
aSkidmarks[i].m_pos[aSkidmarks[i].m_last] = pos;
|
||||
return;
|
||||
}
|
||||
aSkidmarks[i].m_lastUpdate = CTimer::GetTimeInMilliseconds();
|
||||
|
||||
if(aSkidmarks[i].m_last >= SKIDMARK_LENGTH-1){
|
||||
// No space to continue, end it
|
||||
aSkidmarks[i].m_state = 2;
|
||||
aSkidmarks[i].m_fadeStart = CTimer::GetTimeInMilliseconds() + 10000;
|
||||
aSkidmarks[i].m_fadeEnd = CTimer::GetTimeInMilliseconds() + 20000;
|
||||
*isBloody = false; // stpo blood marks at end
|
||||
return;
|
||||
}
|
||||
aSkidmarks[i].m_last++;
|
||||
|
||||
aSkidmarks[i].m_pos[aSkidmarks[i].m_last] = pos;
|
||||
|
||||
CVector2D dist = aSkidmarks[i].m_pos[aSkidmarks[i].m_last] - aSkidmarks[i].m_pos[aSkidmarks[i].m_last-1];
|
||||
dist.Normalise();
|
||||
CVector2D right(dist.y, -dist.x);
|
||||
float turn = DotProduct2D(fwd, right);
|
||||
turn = Abs(turn) + 1.0f;
|
||||
aSkidmarks[i].m_side[aSkidmarks[i].m_last] = CVector(right.x, right.y, 0.0f) * turn * 0.125f;
|
||||
if(aSkidmarks[i].m_last == 1)
|
||||
aSkidmarks[i].m_side[0] = aSkidmarks[i].m_side[1];
|
||||
|
||||
if(aSkidmarks[i].m_last > 8)
|
||||
*isBloody = false; // stop blood marks after 8
|
||||
return;
|
||||
}
|
||||
|
||||
// Start a new one
|
||||
for(i = 0; i < NUMSKIDMARKS; i++)
|
||||
if(aSkidmarks[i].m_state == 0)
|
||||
break;
|
||||
if(i < NUMSKIDMARKS){
|
||||
// Found a free slot
|
||||
aSkidmarks[i].m_state = 1;
|
||||
aSkidmarks[i].m_id = id;
|
||||
aSkidmarks[i].m_pos[0] = pos;
|
||||
aSkidmarks[i].m_side[0] = CVector(0.0f, 0.0f, 0.0f);
|
||||
aSkidmarks[i].m_wasUpdated = true;
|
||||
aSkidmarks[i].m_last = 0;
|
||||
aSkidmarks[i].m_lastUpdate = CTimer::GetTimeInMilliseconds() - 1000;
|
||||
aSkidmarks[i].m_isBloody = *isBloody;
|
||||
aSkidmarks[i].m_isMuddy = *isMuddy;
|
||||
}else
|
||||
*isBloody = false; // stop blood marks if no space
|
||||
}
|
||||
|
@ -1,12 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
enum { SKIDMARK_LENGTH = 16 };
|
||||
|
||||
class CSkidmark
|
||||
{
|
||||
public:
|
||||
uint8 m_state;
|
||||
bool m_wasUpdated;
|
||||
bool m_isBloody;
|
||||
bool m_isMuddy;
|
||||
uintptr m_id;
|
||||
int16 m_last;
|
||||
uint32 m_lastUpdate;;
|
||||
uint32 m_fadeStart;
|
||||
uint32 m_fadeEnd;
|
||||
CVector m_pos[SKIDMARK_LENGTH];
|
||||
CVector m_side[SKIDMARK_LENGTH];
|
||||
};
|
||||
|
||||
class CSkidmarks
|
||||
{
|
||||
static CSkidmark aSkidmarks[NUMSKIDMARKS];
|
||||
public:
|
||||
|
||||
static void Init(void);
|
||||
static void Shutdown(void);
|
||||
static void Clear(void);
|
||||
static void Update(void);
|
||||
static void Render(void);
|
||||
static void RegisterOne(uint32 id, CVector pos, float fwdx, float fwdY, bool *isMuddy, bool *isBloddy);
|
||||
static void Init(void);
|
||||
static void Shutdown(void);
|
||||
static void RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody);
|
||||
};
|
||||
|
@ -22,10 +22,10 @@
|
||||
#include "Shadows.h"
|
||||
#include "main.h"
|
||||
|
||||
RxObjSpace3DVertex StreakVertices[4];
|
||||
RwIm3DVertex StreakVertices[4];
|
||||
RwImVertexIndex StreakIndexList[12];
|
||||
|
||||
RxObjSpace3DVertex TraceVertices[6];
|
||||
RwIm3DVertex TraceVertices[6];
|
||||
RwImVertexIndex TraceIndexList[12];
|
||||
|
||||
|
||||
@ -34,60 +34,60 @@ CSpecialFX::Init(void)
|
||||
{
|
||||
CBulletTraces::Init();
|
||||
|
||||
RwIm3DVertexSetU(&StreakVertices[0], 0.0f);
|
||||
RwIm3DVertexSetV(&StreakVertices[0], 0.0f);
|
||||
RwIm3DVertexSetU(&StreakVertices[1], 1.0f);
|
||||
RwIm3DVertexSetV(&StreakVertices[1], 0.0f);
|
||||
RwIm3DVertexSetU(&StreakVertices[2], 0.0f);
|
||||
RwIm3DVertexSetV(&StreakVertices[2], 0.0f);
|
||||
RwIm3DVertexSetU(&StreakVertices[3], 1.0f);
|
||||
RwIm3DVertexSetV(&StreakVertices[3], 0.0f);
|
||||
|
||||
StreakIndexList[0] = 0;
|
||||
StreakIndexList[1] = 1;
|
||||
StreakIndexList[2] = 2;
|
||||
StreakIndexList[3] = 1;
|
||||
StreakIndexList[4] = 3;
|
||||
StreakIndexList[5] = 2;
|
||||
StreakIndexList[6] = 0;
|
||||
StreakIndexList[7] = 2;
|
||||
StreakIndexList[8] = 1;
|
||||
StreakIndexList[9] = 1;
|
||||
StreakIndexList[10] = 2;
|
||||
StreakIndexList[11] = 3;
|
||||
|
||||
RwIm3DVertexSetRGBA(&TraceVertices[0], 20, 20, 20, 255);
|
||||
RwIm3DVertexSetRGBA(&TraceVertices[1], 20, 20, 20, 255);
|
||||
RwIm3DVertexSetRGBA(&TraceVertices[2], 70, 70, 70, 255);
|
||||
RwIm3DVertexSetRGBA(&TraceVertices[3], 70, 70, 70, 255);
|
||||
RwIm3DVertexSetRGBA(&TraceVertices[4], 10, 10, 10, 255);
|
||||
RwIm3DVertexSetRGBA(&TraceVertices[5], 10, 10, 10, 255);
|
||||
RwIm3DVertexSetU(&TraceVertices[0], 0.0);
|
||||
RwIm3DVertexSetV(&TraceVertices[0], 0.0);
|
||||
RwIm3DVertexSetU(&TraceVertices[1], 1.0);
|
||||
RwIm3DVertexSetV(&TraceVertices[1], 0.0);
|
||||
RwIm3DVertexSetU(&TraceVertices[2], 0.0);
|
||||
RwIm3DVertexSetV(&TraceVertices[2], 0.5);
|
||||
RwIm3DVertexSetU(&TraceVertices[3], 1.0);
|
||||
RwIm3DVertexSetV(&TraceVertices[3], 0.5);
|
||||
RwIm3DVertexSetU(&TraceVertices[4], 0.0);
|
||||
RwIm3DVertexSetV(&TraceVertices[4], 1.0);
|
||||
RwIm3DVertexSetU(&TraceVertices[5], 1.0);
|
||||
RwIm3DVertexSetV(&TraceVertices[5], 1.0);
|
||||
RwIm3DVertexSetU(&StreakVertices[0], 0.0f);
|
||||
RwIm3DVertexSetV(&StreakVertices[0], 0.0f);
|
||||
RwIm3DVertexSetU(&StreakVertices[1], 1.0f);
|
||||
RwIm3DVertexSetV(&StreakVertices[1], 0.0f);
|
||||
RwIm3DVertexSetU(&StreakVertices[2], 0.0f);
|
||||
RwIm3DVertexSetV(&StreakVertices[2], 0.0f);
|
||||
RwIm3DVertexSetU(&StreakVertices[3], 1.0f);
|
||||
RwIm3DVertexSetV(&StreakVertices[3], 0.0f);
|
||||
|
||||
StreakIndexList[0] = 0;
|
||||
StreakIndexList[1] = 1;
|
||||
StreakIndexList[2] = 2;
|
||||
StreakIndexList[3] = 1;
|
||||
StreakIndexList[4] = 3;
|
||||
StreakIndexList[5] = 2;
|
||||
StreakIndexList[6] = 0;
|
||||
StreakIndexList[7] = 2;
|
||||
StreakIndexList[8] = 1;
|
||||
StreakIndexList[9] = 1;
|
||||
StreakIndexList[10] = 2;
|
||||
StreakIndexList[11] = 3;
|
||||
|
||||
RwIm3DVertexSetRGBA(&TraceVertices[0], 20, 20, 20, 255);
|
||||
RwIm3DVertexSetRGBA(&TraceVertices[1], 20, 20, 20, 255);
|
||||
RwIm3DVertexSetRGBA(&TraceVertices[2], 70, 70, 70, 255);
|
||||
RwIm3DVertexSetRGBA(&TraceVertices[3], 70, 70, 70, 255);
|
||||
RwIm3DVertexSetRGBA(&TraceVertices[4], 10, 10, 10, 255);
|
||||
RwIm3DVertexSetRGBA(&TraceVertices[5], 10, 10, 10, 255);
|
||||
RwIm3DVertexSetU(&TraceVertices[0], 0.0);
|
||||
RwIm3DVertexSetV(&TraceVertices[0], 0.0);
|
||||
RwIm3DVertexSetU(&TraceVertices[1], 1.0);
|
||||
RwIm3DVertexSetV(&TraceVertices[1], 0.0);
|
||||
RwIm3DVertexSetU(&TraceVertices[2], 0.0);
|
||||
RwIm3DVertexSetV(&TraceVertices[2], 0.5);
|
||||
RwIm3DVertexSetU(&TraceVertices[3], 1.0);
|
||||
RwIm3DVertexSetV(&TraceVertices[3], 0.5);
|
||||
RwIm3DVertexSetU(&TraceVertices[4], 0.0);
|
||||
RwIm3DVertexSetV(&TraceVertices[4], 1.0);
|
||||
RwIm3DVertexSetU(&TraceVertices[5], 1.0);
|
||||
RwIm3DVertexSetV(&TraceVertices[5], 1.0);
|
||||
|
||||
TraceIndexList[0] = 0;
|
||||
TraceIndexList[1] = 2;
|
||||
TraceIndexList[2] = 1;
|
||||
TraceIndexList[3] = 1;
|
||||
TraceIndexList[4] = 2;
|
||||
TraceIndexList[5] = 3;
|
||||
TraceIndexList[6] = 2;
|
||||
TraceIndexList[7] = 4;
|
||||
TraceIndexList[8] = 3;
|
||||
TraceIndexList[9] = 3;
|
||||
TraceIndexList[10] = 4;
|
||||
TraceIndexList[11] = 5;
|
||||
|
||||
TraceIndexList[0] = 0;
|
||||
TraceIndexList[1] = 2;
|
||||
TraceIndexList[2] = 1;
|
||||
TraceIndexList[3] = 1;
|
||||
TraceIndexList[4] = 2;
|
||||
TraceIndexList[5] = 3;
|
||||
TraceIndexList[6] = 2;
|
||||
TraceIndexList[7] = 4;
|
||||
TraceIndexList[8] = 3;
|
||||
TraceIndexList[9] = 3;
|
||||
TraceIndexList[10] = 4;
|
||||
TraceIndexList[11] = 5;
|
||||
|
||||
CMotionBlurStreaks::Init();
|
||||
CBrightLights::Init();
|
||||
CShinyTexts::Init();
|
||||
@ -112,13 +112,13 @@ LookForBatCB(RwObject *object, void *data)
|
||||
void
|
||||
CSpecialFX::Update(void)
|
||||
{
|
||||
CMotionBlurStreaks::Update();
|
||||
CBulletTraces::Update();
|
||||
|
||||
if(FindPlayerPed() &&
|
||||
FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT &&
|
||||
FindPlayerPed()->GetWeapon()->m_eWeaponState == WEAPONSTATE_FIRING)
|
||||
RwFrameForAllObjects(FindPlayerPed()->GetNodeFrame(PED_HANDR), LookForBatCB, CModelInfo::GetModelInfo(MI_BASEBALL_BAT));
|
||||
CMotionBlurStreaks::Update();
|
||||
CBulletTraces::Update();
|
||||
|
||||
if(FindPlayerPed() &&
|
||||
FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT &&
|
||||
FindPlayerPed()->GetWeapon()->m_eWeaponState == WEAPONSTATE_FIRING)
|
||||
RwFrameForAllObjects(FindPlayerPed()->GetNodeFrame(PED_HANDR), LookForBatCB, CModelInfo::GetModelInfo(MI_BASEBALL_BAT));
|
||||
}
|
||||
|
||||
void
|
||||
@ -130,78 +130,78 @@ CSpecialFX::Shutdown(void)
|
||||
void
|
||||
CSpecialFX::Render(void)
|
||||
{
|
||||
CMotionBlurStreaks::Render();
|
||||
CBulletTraces::Render();
|
||||
CBrightLights::Render();
|
||||
CShinyTexts::Render();
|
||||
CMoneyMessages::Render();
|
||||
C3dMarkers::Render();
|
||||
CMotionBlurStreaks::Render();
|
||||
CBulletTraces::Render();
|
||||
CBrightLights::Render();
|
||||
CShinyTexts::Render();
|
||||
CMoneyMessages::Render();
|
||||
C3dMarkers::Render();
|
||||
}
|
||||
|
||||
CRegisteredMotionBlurStreak CMotionBlurStreaks::aStreaks[NUMMBLURSTREAKS];
|
||||
|
||||
void
|
||||
CRegisteredMotionBlurStreak::Update(void)
|
||||
{
|
||||
int i;
|
||||
bool wasUpdated;
|
||||
bool lastWasUpdated = false;
|
||||
for(i = 2; i > 0; i--){
|
||||
m_pos1[i] = m_pos1[i-1];
|
||||
m_pos2[i] = m_pos2[i-1];
|
||||
m_isValid[i] = m_isValid[i-1];
|
||||
wasUpdated = true;
|
||||
if(!lastWasUpdated && !m_isValid[i])
|
||||
wasUpdated = false;
|
||||
lastWasUpdated = wasUpdated;
|
||||
}
|
||||
m_isValid[0] = false;
|
||||
if(!wasUpdated)
|
||||
m_id = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CRegisteredMotionBlurStreak::Render(void)
|
||||
{
|
||||
int i;
|
||||
int a1, a2;
|
||||
for(i = 0; i < 2; i++)
|
||||
if(m_isValid[i] && m_isValid[i+1]){
|
||||
a1 = (255/3)*(3-i)/3;
|
||||
RwIm3DVertexSetRGBA(&StreakVertices[0], m_red, m_green, m_blue, a1);
|
||||
RwIm3DVertexSetRGBA(&StreakVertices[1], m_red, m_green, m_blue, a1);
|
||||
a2 = (255/3)*(3-(i+1))/3;
|
||||
RwIm3DVertexSetRGBA(&StreakVertices[2], m_red, m_green, m_blue, a2);
|
||||
RwIm3DVertexSetRGBA(&StreakVertices[3], m_red, m_green, m_blue, a2);
|
||||
RwIm3DVertexSetPos(&StreakVertices[0], m_pos1[i].x, m_pos1[i].y, m_pos1[i].z);
|
||||
RwIm3DVertexSetPos(&StreakVertices[1], m_pos2[i].x, m_pos2[i].y, m_pos2[i].z);
|
||||
RwIm3DVertexSetPos(&StreakVertices[2], m_pos1[i+1].x, m_pos1[i+1].y, m_pos1[i+1].z);
|
||||
RwIm3DVertexSetPos(&StreakVertices[3], m_pos2[i+1].x, m_pos2[i+1].y, m_pos2[i+1].z);
|
||||
void
|
||||
CRegisteredMotionBlurStreak::Update(void)
|
||||
{
|
||||
int i;
|
||||
bool wasUpdated;
|
||||
bool lastWasUpdated = false;
|
||||
for(i = 2; i > 0; i--){
|
||||
m_pos1[i] = m_pos1[i-1];
|
||||
m_pos2[i] = m_pos2[i-1];
|
||||
m_isValid[i] = m_isValid[i-1];
|
||||
wasUpdated = true;
|
||||
if(!lastWasUpdated && !m_isValid[i])
|
||||
wasUpdated = false;
|
||||
lastWasUpdated = wasUpdated;
|
||||
}
|
||||
m_isValid[0] = false;
|
||||
if(!wasUpdated)
|
||||
m_id = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CRegisteredMotionBlurStreak::Render(void)
|
||||
{
|
||||
int i;
|
||||
int a1, a2;
|
||||
for(i = 0; i < 2; i++)
|
||||
if(m_isValid[i] && m_isValid[i+1]){
|
||||
a1 = (255/3)*(3-i)/3;
|
||||
RwIm3DVertexSetRGBA(&StreakVertices[0], m_red, m_green, m_blue, a1);
|
||||
RwIm3DVertexSetRGBA(&StreakVertices[1], m_red, m_green, m_blue, a1);
|
||||
a2 = (255/3)*(3-(i+1))/3;
|
||||
RwIm3DVertexSetRGBA(&StreakVertices[2], m_red, m_green, m_blue, a2);
|
||||
RwIm3DVertexSetRGBA(&StreakVertices[3], m_red, m_green, m_blue, a2);
|
||||
RwIm3DVertexSetPos(&StreakVertices[0], m_pos1[i].x, m_pos1[i].y, m_pos1[i].z);
|
||||
RwIm3DVertexSetPos(&StreakVertices[1], m_pos2[i].x, m_pos2[i].y, m_pos2[i].z);
|
||||
RwIm3DVertexSetPos(&StreakVertices[2], m_pos1[i+1].x, m_pos1[i+1].y, m_pos1[i+1].z);
|
||||
RwIm3DVertexSetPos(&StreakVertices[3], m_pos2[i+1].x, m_pos2[i+1].y, m_pos2[i+1].z);
|
||||
LittleTest();
|
||||
if(RwIm3DTransform(StreakVertices, 4, nil, rwIM3D_VERTEXUV)){
|
||||
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, StreakIndexList, 12);
|
||||
RwIm3DEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CMotionBlurStreaks::Init(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < NUMMBLURSTREAKS; i++)
|
||||
aStreaks[i].m_id = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CMotionBlurStreaks::Update(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < NUMMBLURSTREAKS; i++)
|
||||
if(aStreaks[i].m_id)
|
||||
aStreaks[i].Update();
|
||||
}
|
||||
|
||||
void
|
||||
CMotionBlurStreaks::Init(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < NUMMBLURSTREAKS; i++)
|
||||
aStreaks[i].m_id = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CMotionBlurStreaks::Update(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < NUMMBLURSTREAKS; i++)
|
||||
if(aStreaks[i].m_id)
|
||||
aStreaks[i].Update();
|
||||
}
|
||||
|
||||
void
|
||||
CMotionBlurStreaks::RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2)
|
||||
{
|
||||
@ -234,32 +234,32 @@ CMotionBlurStreaks::RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVecto
|
||||
aStreaks[i].m_isValid[2] = false;
|
||||
}
|
||||
|
||||
void
|
||||
CMotionBlurStreaks::Render(void)
|
||||
{
|
||||
void
|
||||
CMotionBlurStreaks::Render(void)
|
||||
{
|
||||
bool setRenderStates = false;
|
||||
int i;
|
||||
for(i = 0; i < NUMMBLURSTREAKS; i++)
|
||||
if(aStreaks[i].m_id){
|
||||
if(!setRenderStates){
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE);
|
||||
for(i = 0; i < NUMMBLURSTREAKS; i++)
|
||||
if(aStreaks[i].m_id){
|
||||
if(!setRenderStates){
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEFOGCOLOR,
|
||||
(void*)RWRGBALONG(CTimeCycle::GetFogRed(), CTimeCycle::GetFogGreen(), CTimeCycle::GetFogBlue(), 255));
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE);
|
||||
setRenderStates = true;
|
||||
}
|
||||
aStreaks[i].Render();
|
||||
}
|
||||
if(setRenderStates){
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)FALSE);
|
||||
}
|
||||
}
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE);
|
||||
setRenderStates = true;
|
||||
}
|
||||
aStreaks[i].Render();
|
||||
}
|
||||
if(setRenderStates){
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CBulletTrace CBulletTraces::aTraces[NUMBULLETTRACES];
|
||||
@ -291,10 +291,10 @@ void CBulletTraces::Render(void)
|
||||
for (int i = 0; i < NUMBULLETTRACES; i++) {
|
||||
if (!aTraces[i].m_bInUse)
|
||||
continue;
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)0);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)2);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)2);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpShadowExplosionTex->raster);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpShadowExplosionTex));
|
||||
CVector inf = aTraces[i].m_vecCurrentPos;
|
||||
CVector sup = aTraces[i].m_vecTargetPos;
|
||||
CVector center = (inf + sup) / 2;
|
||||
@ -316,9 +316,9 @@ void CBulletTraces::Render(void)
|
||||
RwIm3DEnd();
|
||||
}
|
||||
}
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)1);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)5);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)6);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||
}
|
||||
|
||||
void CBulletTraces::Update(void)
|
||||
@ -414,8 +414,7 @@ C3dMarker::Render()
|
||||
{
|
||||
if (m_pAtomic == nil) return;
|
||||
|
||||
RwRGBA *color = RpMaterialGetColor(m_pMaterial);
|
||||
*color = m_Color;
|
||||
RpMaterialSetColor(m_pMaterial, &m_Color);
|
||||
|
||||
m_Matrix.UpdateRW();
|
||||
|
||||
@ -643,13 +642,13 @@ C3dMarkers::Update()
|
||||
|
||||
int CBrightLights::NumBrightLights;
|
||||
CBrightLight CBrightLights::aBrightLights[NUMBRIGHTLIGHTS];
|
||||
|
||||
void
|
||||
CBrightLights::Init(void)
|
||||
{
|
||||
NumBrightLights = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CBrightLights::Init(void)
|
||||
{
|
||||
NumBrightLights = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CBrightLights::RegisterOne(CVector pos, CVector up, CVector side, CVector front,
|
||||
uint8 type, uint8 red, uint8 green, uint8 blue)
|
||||
@ -661,13 +660,13 @@ CBrightLights::RegisterOne(CVector pos, CVector up, CVector side, CVector front,
|
||||
if(aBrightLights[NumBrightLights].m_camDist > BRIGHTLIGHTS_MAX_DIST)
|
||||
return;
|
||||
|
||||
aBrightLights[NumBrightLights].m_pos = pos;
|
||||
aBrightLights[NumBrightLights].m_up = up;
|
||||
aBrightLights[NumBrightLights].m_side = side;
|
||||
aBrightLights[NumBrightLights].m_front = front;
|
||||
aBrightLights[NumBrightLights].m_type = type;
|
||||
aBrightLights[NumBrightLights].m_red = red;
|
||||
aBrightLights[NumBrightLights].m_green = green;
|
||||
aBrightLights[NumBrightLights].m_pos = pos;
|
||||
aBrightLights[NumBrightLights].m_up = up;
|
||||
aBrightLights[NumBrightLights].m_side = side;
|
||||
aBrightLights[NumBrightLights].m_front = front;
|
||||
aBrightLights[NumBrightLights].m_type = type;
|
||||
aBrightLights[NumBrightLights].m_red = red;
|
||||
aBrightLights[NumBrightLights].m_green = green;
|
||||
aBrightLights[NumBrightLights].m_blue = blue;
|
||||
|
||||
NumBrightLights++;
|
||||
@ -696,22 +695,22 @@ static RwImVertexIndex CubeIndices[12*3] = {
|
||||
6, 0, 4, 6, 2, 0, 6, 5, 7, 6, 4, 5
|
||||
};
|
||||
|
||||
void
|
||||
CBrightLights::Render(void)
|
||||
{
|
||||
void
|
||||
CBrightLights::Render(void)
|
||||
{
|
||||
int i, j;
|
||||
CVector pos;
|
||||
|
||||
if(NumBrightLights == 0)
|
||||
return;
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
|
||||
|
||||
for(i = 0; i < NumBrightLights; i++){
|
||||
if(NumBrightLights == 0)
|
||||
return;
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
|
||||
|
||||
for(i = 0; i < NumBrightLights; i++){
|
||||
if(TempBufferIndicesStored > TEMPBUFFERINDEXSIZE-40 || TempBufferVerticesStored > TEMPBUFFERVERTSIZE-40)
|
||||
RenderOutGeometryBuffer();
|
||||
|
||||
@ -753,14 +752,14 @@ CBrightLights::Render(void)
|
||||
a = 255;
|
||||
else
|
||||
a = 255*(1.0f - (aBrightLights[i].m_camDist-BRIGHTLIGHTS_FADE_DIST)/(BRIGHTLIGHTS_MAX_DIST-BRIGHTLIGHTS_FADE_DIST));
|
||||
// fade car lights down to 31 as they come near
|
||||
if(aBrightLights[i].m_type >= BRIGHTLIGHT_FRONT_LONG && aBrightLights[i].m_type <= BRIGHTLIGHT_REAR_TALL){
|
||||
// fade car lights down to 31 as they come near
|
||||
if(aBrightLights[i].m_type >= BRIGHTLIGHT_FRONT_LONG && aBrightLights[i].m_type <= BRIGHTLIGHT_REAR_TALL){
|
||||
if(aBrightLights[i].m_camDist < CARLIGHTS_FADE_DIST)
|
||||
a = 31;
|
||||
else if(aBrightLights[i].m_camDist < CARLIGHTS_MAX_DIST)
|
||||
a = 31 + (255-31)*((aBrightLights[i].m_camDist-CARLIGHTS_FADE_DIST)/(CARLIGHTS_MAX_DIST-CARLIGHTS_FADE_DIST));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch(aBrightLights[i].m_type){
|
||||
case BRIGHTLIGHT_TRAFFIC_GREEN:
|
||||
case BRIGHTLIGHT_TRAFFIC_YELLOW:
|
||||
@ -793,7 +792,7 @@ CBrightLights::Render(void)
|
||||
TempBufferVerticesStored += 8;
|
||||
TempBufferIndicesStored += 12*3;
|
||||
break;
|
||||
|
||||
|
||||
case BRIGHTLIGHT_FRONT_SMALL:
|
||||
case BRIGHTLIGHT_REAR_SMALL:
|
||||
for(j = 0; j < 8; j++){
|
||||
@ -809,7 +808,7 @@ CBrightLights::Render(void)
|
||||
TempBufferVerticesStored += 8;
|
||||
TempBufferIndicesStored += 12*3;
|
||||
break;
|
||||
|
||||
|
||||
case BRIGHTLIGHT_FRONT_TALL:
|
||||
case BRIGHTLIGHT_REAR_TALL:
|
||||
for(j = 0; j < 8; j++){
|
||||
@ -840,17 +839,17 @@ CBrightLights::Render(void)
|
||||
TempBufferIndicesStored += 4*3;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
RenderOutGeometryBuffer();
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
NumBrightLights = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CBrightLights::RenderOutGeometryBuffer(void)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
RenderOutGeometryBuffer();
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
NumBrightLights = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CBrightLights::RenderOutGeometryBuffer(void)
|
||||
{
|
||||
if(TempBufferIndicesStored != 0){
|
||||
LittleTest();
|
||||
if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV)){
|
||||
@ -864,13 +863,13 @@ CBrightLights::RenderOutGeometryBuffer(void)
|
||||
|
||||
int CShinyTexts::NumShinyTexts;
|
||||
CShinyText CShinyTexts::aShinyTexts[NUMSHINYTEXTS];
|
||||
|
||||
void
|
||||
CShinyTexts::Init(void)
|
||||
{
|
||||
NumShinyTexts = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CShinyTexts::Init(void)
|
||||
{
|
||||
NumShinyTexts = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CShinyTexts::RegisterOne(CVector p0, CVector p1, CVector p2, CVector p3,
|
||||
float u0, float v0, float u1, float v1, float u2, float v2, float u3, float v3,
|
||||
@ -910,20 +909,20 @@ CShinyTexts::RegisterOne(CVector p0, CVector p1, CVector p2, CVector p3,
|
||||
NumShinyTexts++;
|
||||
}
|
||||
|
||||
void
|
||||
CShinyTexts::Render(void)
|
||||
{
|
||||
int i, ix, v;
|
||||
RwTexture *lastTex = nil;
|
||||
|
||||
if(NumShinyTexts == 0)
|
||||
return;
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
|
||||
|
||||
void
|
||||
CShinyTexts::Render(void)
|
||||
{
|
||||
int i, ix, v;
|
||||
RwTexture *lastTex = nil;
|
||||
|
||||
if(NumShinyTexts == 0)
|
||||
return;
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
|
||||
|
||||
TempBufferVerticesStored = 0;
|
||||
TempBufferIndicesStored = 0;
|
||||
|
||||
@ -984,15 +983,15 @@ CShinyTexts::Render(void)
|
||||
RenderOutGeometryBuffer();
|
||||
NumShinyTexts = 0;
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||
}
|
||||
|
||||
void
|
||||
CShinyTexts::RenderOutGeometryBuffer(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CShinyTexts::RenderOutGeometryBuffer(void)
|
||||
{
|
||||
if(TempBufferIndicesStored != 0){
|
||||
LittleTest();
|
||||
if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV)){
|
||||
@ -1002,8 +1001,8 @@ CShinyTexts::RenderOutGeometryBuffer(void)
|
||||
TempBufferVerticesStored = 0;
|
||||
TempBufferIndicesStored = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define MONEY_MESSAGE_LIFETIME_MS 2000
|
||||
|
@ -12,26 +12,26 @@ public:
|
||||
class CRegisteredMotionBlurStreak
|
||||
{
|
||||
public:
|
||||
uintptr m_id;
|
||||
uint8 m_red;
|
||||
uint8 m_green;
|
||||
uint8 m_blue;
|
||||
CVector m_pos1[3];
|
||||
CVector m_pos2[3];
|
||||
uintptr m_id;
|
||||
uint8 m_red;
|
||||
uint8 m_green;
|
||||
uint8 m_blue;
|
||||
CVector m_pos1[3];
|
||||
CVector m_pos2[3];
|
||||
bool m_isValid[3];
|
||||
|
||||
void Update(void);
|
||||
void Render(void);
|
||||
void Update(void);
|
||||
void Render(void);
|
||||
};
|
||||
|
||||
class CMotionBlurStreaks
|
||||
{
|
||||
static CRegisteredMotionBlurStreak aStreaks[NUMMBLURSTREAKS];
|
||||
public:
|
||||
static void Init(void);
|
||||
static void Update(void);
|
||||
static void Init(void);
|
||||
static void Update(void);
|
||||
static void RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2);
|
||||
static void Render(void);
|
||||
static void Render(void);
|
||||
};
|
||||
|
||||
struct CBulletTrace
|
||||
@ -133,18 +133,18 @@ enum
|
||||
BRIGHTLIGHT_REAR = BRIGHTLIGHT_REAR_LONG,
|
||||
};
|
||||
|
||||
class CBrightLight
|
||||
{
|
||||
public:
|
||||
CVector m_pos;
|
||||
CVector m_up;
|
||||
CVector m_side;
|
||||
CVector m_front;
|
||||
float m_camDist;
|
||||
uint8 m_type;
|
||||
uint8 m_red;
|
||||
uint8 m_green;
|
||||
uint8 m_blue;
|
||||
class CBrightLight
|
||||
{
|
||||
public:
|
||||
CVector m_pos;
|
||||
CVector m_up;
|
||||
CVector m_side;
|
||||
CVector m_front;
|
||||
float m_camDist;
|
||||
uint8 m_type;
|
||||
uint8 m_red;
|
||||
uint8 m_green;
|
||||
uint8 m_blue;
|
||||
};
|
||||
|
||||
class CBrightLights
|
||||
@ -152,11 +152,11 @@ class CBrightLights
|
||||
static int NumBrightLights;
|
||||
static CBrightLight aBrightLights[NUMBRIGHTLIGHTS];
|
||||
public:
|
||||
static void Init(void);
|
||||
static void Init(void);
|
||||
static void RegisterOne(CVector pos, CVector up, CVector side, CVector front,
|
||||
uint8 type, uint8 red = 0, uint8 green = 0, uint8 blue = 0);
|
||||
static void Render(void);
|
||||
static void RenderOutGeometryBuffer(void);
|
||||
static void Render(void);
|
||||
static void RenderOutGeometryBuffer(void);
|
||||
};
|
||||
|
||||
|
||||
@ -169,12 +169,12 @@ enum
|
||||
class CShinyText
|
||||
{
|
||||
public:
|
||||
CVector m_verts[4];
|
||||
CVector2D m_texCoords[4];
|
||||
float m_camDist;
|
||||
uint8 m_type;
|
||||
uint8 m_red;
|
||||
uint8 m_green;
|
||||
CVector m_verts[4];
|
||||
CVector2D m_texCoords[4];
|
||||
float m_camDist;
|
||||
uint8 m_type;
|
||||
uint8 m_red;
|
||||
uint8 m_green;
|
||||
uint8 m_blue;
|
||||
};
|
||||
|
||||
@ -183,12 +183,12 @@ class CShinyTexts
|
||||
static int NumShinyTexts;
|
||||
static CShinyText aShinyTexts[NUMSHINYTEXTS];
|
||||
public:
|
||||
static void Init(void);
|
||||
static void Init(void);
|
||||
static void RegisterOne(CVector p0, CVector p1, CVector p2, CVector p3,
|
||||
float u0, float v0, float u1, float v1, float u2, float v2, float u3, float v3,
|
||||
uint8 type, uint8 red, uint8 green, uint8 blue, float maxDist);
|
||||
static void Render(void);
|
||||
static void RenderOutGeometryBuffer(void);
|
||||
static void Render(void);
|
||||
static void RenderOutGeometryBuffer(void);
|
||||
};
|
||||
|
||||
class CMoneyMessage
|
||||
|
@ -30,10 +30,12 @@ CSprite::CalcScreenCoors(const RwV3d &in, RwV3d *out, float *outw, float *outh,
|
||||
out->x *= SCREEN_WIDTH * recip;
|
||||
out->y *= SCREEN_HEIGHT * recip;
|
||||
// What is this? size?
|
||||
*outw = 70.0f/CDraw::GetFOV();
|
||||
*outh = 70.0f/CDraw::GetFOV();
|
||||
*outw *= SCREEN_WIDTH * recip;
|
||||
*outh *= SCREEN_HEIGHT * recip;
|
||||
*outw = 70.0f/CDraw::GetFOV() * SCREEN_WIDTH * recip;
|
||||
#ifdef ASPECT_RATIO_SCALE
|
||||
*outh = 70.0f/CDraw::GetFOV() / (DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO) * SCREEN_HEIGHT * recip;
|
||||
#else
|
||||
*outh = 70.0f/CDraw::GetFOV() * SCREEN_HEIGHT * recip;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -432,6 +434,7 @@ void
|
||||
CSprite::Set6Vertices2D(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
|
||||
{
|
||||
float screenz, recipz;
|
||||
float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
|
||||
|
||||
screenz = m_f2DNearScreenZ;
|
||||
recipz = m_fRecipNearClipPlane;
|
||||
@ -496,6 +499,7 @@ CSprite::Set6Vertices2D(RwIm2DVertex *verts, float x1, float y1, float x2, float
|
||||
const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
|
||||
{
|
||||
float screenz, recipz;
|
||||
float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
|
||||
|
||||
screenz = m_f2DNearScreenZ;
|
||||
recipz = m_fRecipNearClipPlane;
|
||||
|
@ -267,6 +267,7 @@ CSprite2d::SetVertices(float x1, float y1, float x2, float y2, float x3, float y
|
||||
const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
|
||||
{
|
||||
float screenz, recipz;
|
||||
float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
|
||||
|
||||
screenz = RwIm2DGetNearScreenZ();
|
||||
recipz = RecipNearClip;
|
||||
@ -312,10 +313,11 @@ void
|
||||
CSprite2d::SetVertices(int n, float *positions, float *uvs, const CRGBA &col)
|
||||
{
|
||||
int i;
|
||||
float screenz, recipz;
|
||||
float screenz, recipz, z;
|
||||
|
||||
screenz = RwIm2DGetNearScreenZ();
|
||||
recipz = RecipNearClip;
|
||||
z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
|
||||
|
||||
|
||||
for(i = 0; i < n; i++){
|
||||
@ -334,10 +336,11 @@ void
|
||||
CSprite2d::SetMaskVertices(int n, float *positions)
|
||||
{
|
||||
int i;
|
||||
float screenz, recipz;
|
||||
float screenz, recipz, z;
|
||||
|
||||
screenz = RwIm2DGetNearScreenZ();
|
||||
recipz = RecipNearClip;
|
||||
z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
|
||||
|
||||
for(i = 0; i < n; i++){
|
||||
RwIm2DVertexSetScreenX(&maVertices[i], positions[i*2 + 0]);
|
||||
@ -345,7 +348,7 @@ CSprite2d::SetMaskVertices(int n, float *positions)
|
||||
RwIm2DVertexSetScreenZ(&maVertices[i], screenz);
|
||||
RwIm2DVertexSetCameraZ(&maVertices[i], z);
|
||||
RwIm2DVertexSetRecipCameraZ(&maVertices[i], recipz);
|
||||
RwIm2DVertexSetIntRGBA(&maVertices[i], 0, 0, 0, 0);
|
||||
RwIm2DVertexSetIntRGBA(&maVertices[i], 255, 255, 255, 255); // 0, 0, 0, 0 on PC
|
||||
}
|
||||
}
|
||||
|
||||
@ -353,10 +356,11 @@ void
|
||||
CSprite2d::SetVertices(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3,
|
||||
float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2)
|
||||
{
|
||||
float screenz, recipz;
|
||||
float screenz, recipz, z;
|
||||
|
||||
screenz = RwIm2DGetNearScreenZ();
|
||||
recipz = RecipNearClip;
|
||||
z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
|
||||
|
||||
RwIm2DVertexSetScreenX(&verts[0], r.left);
|
||||
RwIm2DVertexSetScreenY(&verts[0], r.top);
|
||||
@ -459,15 +463,15 @@ CSprite2d::DrawRectXLU(const CRect &r, const CRGBA &c0, const CRGBA &c1, const C
|
||||
|
||||
void CSprite2d::Draw2DPolygon(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, const CRGBA &color)
|
||||
{
|
||||
SetVertices(x1, y1, x2, y2, x3, y3, x4, y4, color, color, color, color);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, 0);
|
||||
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)(color.a != 255));
|
||||
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
SetVertices(x1, y1, x2, y2, x3, y3, x4, y4, color, color, color, color);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, 0);
|
||||
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)(color.a != 255));
|
||||
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEGOURAUD);
|
||||
}
|
||||
|
||||
|
41
src/render/TexList.cpp
Normal file
41
src/render/TexList.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include "common.h"
|
||||
#include "TexList.h"
|
||||
#include "rtbmp.h"
|
||||
#include "FileMgr.h"
|
||||
|
||||
bool CTexList::ms_nTexUsed[MAX_TEXUSED];
|
||||
|
||||
void
|
||||
CTexList::Initialise()
|
||||
{}
|
||||
|
||||
void
|
||||
CTexList::Shutdown()
|
||||
{}
|
||||
|
||||
RwTexture *
|
||||
CTexList::SetTexture(int32 slot, char *name)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
int32
|
||||
CTexList::GetFirstFreeTexture()
|
||||
{
|
||||
for (int32 i = 0; i < MAX_TEXUSED; i++)
|
||||
if (!ms_nTexUsed[i])
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
RwTexture *
|
||||
CTexList::LoadFileNameTexture(char *name)
|
||||
{
|
||||
return SetTexture(GetFirstFreeTexture(), name);
|
||||
}
|
||||
|
||||
void
|
||||
CTexList::LoadGlobalTextureList()
|
||||
{
|
||||
CFileMgr::SetDir("TEXTURES");
|
||||
}
|
14
src/render/TexList.h
Normal file
14
src/render/TexList.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
class CTexList
|
||||
{
|
||||
enum { MAX_TEXUSED = 400, };
|
||||
static bool ms_nTexUsed[MAX_TEXUSED];
|
||||
public:
|
||||
static void Initialise();
|
||||
static void Shutdown();
|
||||
static RwTexture *SetTexture(int32 slot, char *name);
|
||||
static int32 GetFirstFreeTexture();
|
||||
static RwTexture *LoadFileNameTexture(char *name);
|
||||
static void LoadGlobalTextureList();
|
||||
};
|
@ -117,7 +117,7 @@ CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera)
|
||||
RpMaterial*
|
||||
SetAlphaCB(RpMaterial *material, void *data)
|
||||
{
|
||||
material->color.alpha = (uint8)(uint32)data;
|
||||
((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uint32)data;
|
||||
return material;
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ CWeaponEffects::Render(void)
|
||||
{
|
||||
float recipz = 1.0f / pos.z;
|
||||
CSprite::RenderOneXLUSprite(pos.x, pos.y, pos.z,
|
||||
gCrossHair.m_fSize * w, gCrossHair.m_fSize * SCREEN_SCALE_AR2(h),
|
||||
gCrossHair.m_fSize * w, gCrossHair.m_fSize * h,
|
||||
gCrossHair.m_nRed, gCrossHair.m_nGreen, gCrossHair.m_nBlue, 255,
|
||||
recipz, 255);
|
||||
}
|
||||
|
@ -71,8 +71,8 @@ const int16 WeatherTypesList[] = {
|
||||
|
||||
const float Windiness[] = {
|
||||
0.0f, // WEATHER_SUNNY
|
||||
0.7f, // WEATHER_RAINY
|
||||
1.0f, // WEATHER_CLOUDY
|
||||
0.7f, // WEATHER_CLOUDY
|
||||
1.0f, // WEATHER_RAINY
|
||||
0.5f // WEATHER_FOGGY
|
||||
};
|
||||
|
||||
@ -106,7 +106,7 @@ void CWeather::Init(void)
|
||||
{
|
||||
NewWeatherType = WEATHER_SUNNY;
|
||||
bScriptsForceRain = false;
|
||||
OldWeatherType = WEATHER_RAINY;
|
||||
OldWeatherType = WEATHER_CLOUDY;
|
||||
Stored_StateStored = false;
|
||||
InterpolationValue = 0.0f;
|
||||
WhenToPlayLightningSound = 0;
|
||||
@ -475,7 +475,7 @@ void CWeather::RenderRainStreaks(void)
|
||||
// 1/16 probability
|
||||
Streaks[i].direction = CVector(4.0f, 4.0f, -4.0f);
|
||||
Streaks[i].position = 6.0f * TheCamera.GetForward() + TheCamera.GetPosition() + CVector(-1.8f * Streaks[i].direction.x, -1.8f * Streaks[i].direction.y, 8.0f);
|
||||
if (!CCutsceneMgr::IsCutsceneProcessing()) {
|
||||
if (!CCutsceneMgr::IsRunning()) {
|
||||
Streaks[i].position.x += 2.0f * FindPlayerSpeed().x * 60.0f;
|
||||
Streaks[i].position.y += 2.0f * FindPlayerSpeed().y * 60.0f;
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
class CDate
|
||||
{
|
||||
public:
|
||||
int m_nSecond;
|
||||
int m_nMinute;
|
||||
int m_nHour;
|
||||
int m_nDay;
|
||||
int m_nMonth;
|
||||
int m_nYear;
|
||||
|
||||
CDate();
|
||||
bool operator>(const CDate &right);
|
||||
bool operator<(const CDate &right);
|
||||
bool operator==(const CDate &right);
|
||||
void PopulateDateFields(int8 &second, int8 &minute, int8 &hour, int8 &day, int8 &month, int16 year);
|
||||
#pragma once
|
||||
|
||||
class CDate
|
||||
{
|
||||
public:
|
||||
int m_nSecond;
|
||||
int m_nMinute;
|
||||
int m_nHour;
|
||||
int m_nDay;
|
||||
int m_nMonth;
|
||||
int m_nYear;
|
||||
|
||||
CDate();
|
||||
bool operator>(const CDate &right);
|
||||
bool operator<(const CDate &right);
|
||||
bool operator==(const CDate &right);
|
||||
void PopulateDateFields(int8 &second, int8 &minute, int8 &hour, int8 &day, int8 &month, int16 year);
|
||||
};
|
@ -48,6 +48,13 @@ char SaveFileNameJustSaved[260];
|
||||
int (&Slots)[SLOT_COUNT+1] = *(int(*)[SLOT_COUNT+1])*(uintptr*)0x72803C;
|
||||
CDate &CompileDateAndTime = *(CDate*)0x72BCB8;
|
||||
|
||||
|
||||
bool &b_FoundRecentSavedGameWantToLoad = *(bool*)0x95CDA8;
|
||||
bool &JustLoadedDontFadeInYet = *(bool*)0x95CDB4;
|
||||
bool &StillToFadeOut = *(bool*)0x95CD99;
|
||||
uint32 &TimeStartedCountingForFade = *(uint32*)0x9430EC;
|
||||
uint32 &TimeToStayFadedBeforeFadeOut = *(uint32*)0x611564;
|
||||
|
||||
#define ReadDataFromBufferPointer(buf, to) memcpy(&to, buf, sizeof(to)); buf += align4bytes(sizeof(to));
|
||||
#define WriteDataToBufferPointer(buf, from) memcpy(buf, &from, sizeof(from)); buf += align4bytes(sizeof(from));
|
||||
|
||||
|
@ -1,37 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include "PCSave.h"
|
||||
|
||||
#define SLOT_COUNT (8)
|
||||
|
||||
bool GenericSave(int file);
|
||||
bool GenericLoad();
|
||||
bool ReadInSizeofSaveFileBuffer(int32 &file, uint32 &size);
|
||||
bool ReadDataFromFile(int32 file, uint8 *buf, uint32 size);
|
||||
bool CloseFile(int32 file);
|
||||
void DoGameSpecificStuffAfterSucessLoad();
|
||||
bool CheckSlotDataValid(int32 slot);
|
||||
void MakeSpaceForSizeInBufferPointer(uint8 *&presize, uint8 *&buf, uint8 *&postsize);
|
||||
void CopySizeAndPreparePointer(uint8 *&buf, uint8 *&postbuf, uint8 *&postbuf2, uint32 &unused, uint32 &size);
|
||||
void DoGameSpecificStuffBeforeSave();
|
||||
void MakeValidSaveName(int32 slot);
|
||||
wchar *GetSavedGameDateAndTime(int32 slot);
|
||||
wchar *GetNameOfSavedGame(int32 slot);
|
||||
bool CheckDataNotCorrupt(int32 slot, char *name);
|
||||
bool RestoreForStartLoad();
|
||||
int align4bytes(int32 size);
|
||||
|
||||
extern class CDate& CompileDateAndTime;
|
||||
|
||||
extern char (&DefaultPCSaveFileName)[260];
|
||||
extern char (&ValidSaveName)[260];
|
||||
extern char (&LoadFileName)[256];
|
||||
extern wchar (&SlotFileName)[SLOT_COUNT][260];
|
||||
extern wchar (&SlotSaveDate)[SLOT_COUNT][70];
|
||||
extern int &CheckSum;
|
||||
extern enum eLevelName &m_LevelToLoad;
|
||||
extern int (&Slots)[SLOT_COUNT+1];
|
||||
|
||||
extern char SaveFileNameJustSaved[260]; // 8F2570
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PCSave.h"
|
||||
|
||||
#define SLOT_COUNT (8)
|
||||
|
||||
bool GenericSave(int file);
|
||||
bool GenericLoad();
|
||||
bool ReadInSizeofSaveFileBuffer(int32 &file, uint32 &size);
|
||||
bool ReadDataFromFile(int32 file, uint8 *buf, uint32 size);
|
||||
bool CloseFile(int32 file);
|
||||
void DoGameSpecificStuffAfterSucessLoad();
|
||||
bool CheckSlotDataValid(int32 slot);
|
||||
void MakeSpaceForSizeInBufferPointer(uint8 *&presize, uint8 *&buf, uint8 *&postsize);
|
||||
void CopySizeAndPreparePointer(uint8 *&buf, uint8 *&postbuf, uint8 *&postbuf2, uint32 &unused, uint32 &size);
|
||||
void DoGameSpecificStuffBeforeSave();
|
||||
void MakeValidSaveName(int32 slot);
|
||||
wchar *GetSavedGameDateAndTime(int32 slot);
|
||||
wchar *GetNameOfSavedGame(int32 slot);
|
||||
bool CheckDataNotCorrupt(int32 slot, char *name);
|
||||
bool RestoreForStartLoad();
|
||||
int align4bytes(int32 size);
|
||||
|
||||
extern class CDate& CompileDateAndTime;
|
||||
|
||||
extern char (&DefaultPCSaveFileName)[260];
|
||||
extern char (&ValidSaveName)[260];
|
||||
extern char (&LoadFileName)[256];
|
||||
extern wchar (&SlotFileName)[SLOT_COUNT][260];
|
||||
extern wchar (&SlotSaveDate)[SLOT_COUNT][70];
|
||||
extern int &CheckSum;
|
||||
extern enum eLevelName &m_LevelToLoad;
|
||||
extern int (&Slots)[SLOT_COUNT+1];
|
||||
|
||||
extern bool &b_FoundRecentSavedGameWantToLoad;
|
||||
extern bool &JustLoadedDontFadeInYet;
|
||||
extern bool &StillToFadeOut;
|
||||
extern uint32 &TimeStartedCountingForFade;
|
||||
extern uint32 &TimeToStayFadedBeforeFadeOut;
|
||||
|
||||
extern char SaveFileNameJustSaved[260]; // 8F2570
|
||||
|
||||
const char TopLineEmptyFile[] = "THIS FILE IS NOT VALID YET";
|
@ -1927,7 +1927,7 @@ _WinMain(HINSTANCE instance,
|
||||
* Enter the message processing loop...
|
||||
*/
|
||||
|
||||
while( !RsGlobal.quit && !FrontEndMenuManager.m_bStartGameLoading )
|
||||
while( !RsGlobal.quit && !FrontEndMenuManager.m_bWantToRestart )
|
||||
{
|
||||
if( PeekMessage(&message, nil, 0U, 0U, PM_REMOVE|PM_NOYIELD) )
|
||||
{
|
||||
@ -2059,13 +2059,13 @@ _WinMain(HINSTANCE instance,
|
||||
if (wp.showCmd != SW_SHOWMINIMIZED)
|
||||
RsEventHandler(rsFRONTENDIDLE, nil);
|
||||
|
||||
if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bLoadingSavedGame )
|
||||
if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bWantToLoad )
|
||||
{
|
||||
gGameState = GS_INIT_PLAYING_GAME;
|
||||
TRACE("gGameState = GS_INIT_PLAYING_GAME;");
|
||||
}
|
||||
|
||||
if ( FrontEndMenuManager.m_bLoadingSavedGame )
|
||||
if ( FrontEndMenuManager.m_bWantToLoad )
|
||||
{
|
||||
InitialiseGame();
|
||||
FrontEndMenuManager.m_bGameNotLoaded = false;
|
||||
@ -2128,7 +2128,7 @@ _WinMain(HINSTANCE instance,
|
||||
RwInitialised = FALSE;
|
||||
|
||||
FrontEndMenuManager.UnloadTextures();
|
||||
if ( !FrontEndMenuManager.m_bStartGameLoading )
|
||||
if ( !FrontEndMenuManager.m_bWantToRestart )
|
||||
break;
|
||||
|
||||
CPad::ResetCheats();
|
||||
@ -2138,13 +2138,13 @@ _WinMain(HINSTANCE instance,
|
||||
|
||||
CTimer::Stop();
|
||||
|
||||
if ( FrontEndMenuManager.m_bLoadingSavedGame )
|
||||
if ( FrontEndMenuManager.m_bWantToLoad )
|
||||
{
|
||||
CGame::ShutDownForRestart();
|
||||
CGame::InitialiseWhenRestarting();
|
||||
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
|
||||
LoadSplash(GetLevelSplashScreen(CGame::currLevel));
|
||||
FrontEndMenuManager.m_bLoadingSavedGame = false;
|
||||
FrontEndMenuManager.m_bWantToLoad = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2168,7 +2168,7 @@ _WinMain(HINSTANCE instance,
|
||||
}
|
||||
|
||||
FrontEndMenuManager.m_bFirstTime = false;
|
||||
FrontEndMenuManager.m_bStartGameLoading = false;
|
||||
FrontEndMenuManager.m_bWantToRestart = false;
|
||||
}
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,194 +1,194 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Pager.h"
|
||||
#include "Timer.h"
|
||||
#include "Messages.h"
|
||||
#include "Hud.h"
|
||||
#include "Camera.h"
|
||||
|
||||
void
|
||||
CPager::Init()
|
||||
{
|
||||
ClearMessages();
|
||||
m_nNumDisplayLetters = 8;
|
||||
}
|
||||
|
||||
void
|
||||
CPager::Process()
|
||||
{
|
||||
if (m_messages[0].m_pText != nil && m_messages[0].m_nCurrentPosition >= (int32)m_messages[0].m_nStringLength) {
|
||||
m_messages[0].m_pText = nil;
|
||||
uint16 i = 0;
|
||||
while (i < NUMPAGERMESSAGES-1) {
|
||||
if (m_messages[i + 1].m_pText == nil) break;
|
||||
m_messages[i] = m_messages[i + 1];
|
||||
i++;
|
||||
}
|
||||
m_messages[i].m_pText = nil;
|
||||
if (m_messages[0].m_pText != nil)
|
||||
CMessages::AddToPreviousBriefArray(
|
||||
m_messages[0].m_pText,
|
||||
m_messages[0].m_nNumber[0],
|
||||
m_messages[0].m_nNumber[1],
|
||||
m_messages[0].m_nNumber[2],
|
||||
m_messages[0].m_nNumber[3],
|
||||
m_messages[0].m_nNumber[4],
|
||||
m_messages[0].m_nNumber[5],
|
||||
0);
|
||||
}
|
||||
Display();
|
||||
if (m_messages[0].m_pText != nil) {
|
||||
if (TheCamera.m_WideScreenOn || !CHud::m_Wants_To_Draw_Hud || CHud::m_BigMessage[0][0] || CHud::m_BigMessage[2][0]) {
|
||||
RestartCurrentMessage();
|
||||
} else {
|
||||
if (CTimer::GetTimeInMilliseconds() > m_messages[0].m_nTimeToChangePosition) {
|
||||
m_messages[0].m_nCurrentPosition++;
|
||||
m_messages[0].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + m_messages[0].m_nSpeedMs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CPager::Display()
|
||||
{
|
||||
wchar outstr1[256];
|
||||
wchar outstr2[260];
|
||||
|
||||
wchar *pText = m_messages[0].m_pText;
|
||||
uint16 i = 0;
|
||||
if (pText != nil) {
|
||||
CMessages::InsertNumberInString(
|
||||
pText,
|
||||
m_messages[0].m_nNumber[0],
|
||||
m_messages[0].m_nNumber[1],
|
||||
m_messages[0].m_nNumber[2],
|
||||
m_messages[0].m_nNumber[3],
|
||||
m_messages[0].m_nNumber[4],
|
||||
m_messages[0].m_nNumber[5],
|
||||
outstr1);
|
||||
for (; i < m_nNumDisplayLetters; i++) {
|
||||
int pos = m_messages[0].m_nCurrentPosition + i;
|
||||
if (pos >= 0) {
|
||||
if (!outstr1[pos]) break;
|
||||
|
||||
outstr2[i] = outstr1[pos];
|
||||
} else {
|
||||
outstr2[i] = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
outstr2[i] = '\0';
|
||||
CHud::SetPagerMessage(outstr2);
|
||||
}
|
||||
|
||||
void
|
||||
CPager::AddMessage(wchar *str, uint16 speed, uint16 priority, uint16 a5)
|
||||
{
|
||||
uint16 size = CMessages::GetWideStringLength(str);
|
||||
for (int32 i = 0; i < NUMPAGERMESSAGES; i++) {
|
||||
if (m_messages[i].m_pText) {
|
||||
if (m_messages[i].m_nPriority >= priority)
|
||||
continue;
|
||||
|
||||
for (int j = NUMPAGERMESSAGES-1; j > i; j--)
|
||||
m_messages[j] = m_messages[j-1];
|
||||
|
||||
}
|
||||
m_messages[i].m_pText = str;
|
||||
m_messages[i].m_nSpeedMs = speed;
|
||||
m_messages[i].m_nPriority = priority;
|
||||
m_messages[i].field_10 = a5;
|
||||
m_messages[i].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
|
||||
m_messages[i].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + speed;
|
||||
m_messages[i].m_nStringLength = size;
|
||||
m_messages[i].m_nNumber[0] = -1;
|
||||
m_messages[i].m_nNumber[1] = -1;
|
||||
m_messages[i].m_nNumber[2] = -1;
|
||||
m_messages[i].m_nNumber[3] = -1;
|
||||
m_messages[i].m_nNumber[4] = -1;
|
||||
m_messages[i].m_nNumber[5] = -1;
|
||||
|
||||
if (i == 0)
|
||||
CMessages::AddToPreviousBriefArray(
|
||||
m_messages[0].m_pText,
|
||||
m_messages[0].m_nNumber[0],
|
||||
m_messages[0].m_nNumber[1],
|
||||
m_messages[0].m_nNumber[2],
|
||||
m_messages[0].m_nNumber[3],
|
||||
m_messages[0].m_nNumber[4],
|
||||
m_messages[0].m_nNumber[5],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CPager::AddMessageWithNumber(wchar *str, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, uint16 speed, uint16 priority, uint16 a11)
|
||||
{
|
||||
wchar nstr[520];
|
||||
|
||||
CMessages::InsertNumberInString(str, n1, n2, n3, n4, n5, n6, nstr);
|
||||
uint16 size = CMessages::GetWideStringLength(nstr);
|
||||
for (int32 i = 0; i < NUMPAGERMESSAGES; i++) {
|
||||
if (m_messages[i].m_pText) {
|
||||
if (m_messages[i].m_nPriority >= priority)
|
||||
continue;
|
||||
|
||||
for (int j = NUMPAGERMESSAGES-1; j > i; j--)
|
||||
m_messages[j] = m_messages[j - 1];
|
||||
|
||||
}
|
||||
m_messages[i].m_pText = str;
|
||||
m_messages[i].m_nSpeedMs = speed;
|
||||
m_messages[i].m_nPriority = priority;
|
||||
m_messages[i].field_10 = a11;
|
||||
m_messages[i].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
|
||||
m_messages[i].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + speed;
|
||||
m_messages[i].m_nStringLength = size;
|
||||
m_messages[i].m_nNumber[0] = n1;
|
||||
m_messages[i].m_nNumber[1] = n2;
|
||||
m_messages[i].m_nNumber[2] = n3;
|
||||
m_messages[i].m_nNumber[3] = n4;
|
||||
m_messages[i].m_nNumber[4] = n5;
|
||||
m_messages[i].m_nNumber[5] = n6;
|
||||
|
||||
if (i == 0)
|
||||
CMessages::AddToPreviousBriefArray(
|
||||
m_messages[0].m_pText,
|
||||
m_messages[0].m_nNumber[0],
|
||||
m_messages[0].m_nNumber[1],
|
||||
m_messages[0].m_nNumber[2],
|
||||
m_messages[0].m_nNumber[3],
|
||||
m_messages[0].m_nNumber[4],
|
||||
m_messages[0].m_nNumber[5],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CPager::ClearMessages()
|
||||
{
|
||||
for (int32 i = 0; i < NUMPAGERMESSAGES; i++)
|
||||
m_messages[i].m_pText = nil;
|
||||
}
|
||||
|
||||
void
|
||||
CPager::RestartCurrentMessage()
|
||||
{
|
||||
if (m_messages[0].m_pText != nil) {
|
||||
m_messages[0].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
|
||||
m_messages[0].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + m_messages[0].m_nSpeedMs;
|
||||
}
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x52B6F0, &CPager::Init, PATCH_JUMP);
|
||||
InjectHook(0x52B740, &CPager::Process, PATCH_JUMP);
|
||||
InjectHook(0x52B890, &CPager::Display, PATCH_JUMP);
|
||||
InjectHook(0x52B940, &CPager::AddMessage, PATCH_JUMP);
|
||||
InjectHook(0x52BB50, &CPager::AddMessageWithNumber, PATCH_JUMP);
|
||||
InjectHook(0x52BE50, &CPager::RestartCurrentMessage, PATCH_JUMP);
|
||||
InjectHook(0x52BE00, &CPager::ClearMessages, PATCH_JUMP);
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Pager.h"
|
||||
#include "Timer.h"
|
||||
#include "Messages.h"
|
||||
#include "Hud.h"
|
||||
#include "Camera.h"
|
||||
|
||||
void
|
||||
CPager::Init()
|
||||
{
|
||||
ClearMessages();
|
||||
m_nNumDisplayLetters = 8;
|
||||
}
|
||||
|
||||
void
|
||||
CPager::Process()
|
||||
{
|
||||
if (m_messages[0].m_pText != nil && m_messages[0].m_nCurrentPosition >= (int32)m_messages[0].m_nStringLength) {
|
||||
m_messages[0].m_pText = nil;
|
||||
uint16 i = 0;
|
||||
while (i < NUMPAGERMESSAGES-1) {
|
||||
if (m_messages[i + 1].m_pText == nil) break;
|
||||
m_messages[i] = m_messages[i + 1];
|
||||
i++;
|
||||
}
|
||||
m_messages[i].m_pText = nil;
|
||||
if (m_messages[0].m_pText != nil)
|
||||
CMessages::AddToPreviousBriefArray(
|
||||
m_messages[0].m_pText,
|
||||
m_messages[0].m_nNumber[0],
|
||||
m_messages[0].m_nNumber[1],
|
||||
m_messages[0].m_nNumber[2],
|
||||
m_messages[0].m_nNumber[3],
|
||||
m_messages[0].m_nNumber[4],
|
||||
m_messages[0].m_nNumber[5],
|
||||
0);
|
||||
}
|
||||
Display();
|
||||
if (m_messages[0].m_pText != nil) {
|
||||
if (TheCamera.m_WideScreenOn || !CHud::m_Wants_To_Draw_Hud || CHud::m_BigMessage[0][0] || CHud::m_BigMessage[2][0]) {
|
||||
RestartCurrentMessage();
|
||||
} else {
|
||||
if (CTimer::GetTimeInMilliseconds() > m_messages[0].m_nTimeToChangePosition) {
|
||||
m_messages[0].m_nCurrentPosition++;
|
||||
m_messages[0].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + m_messages[0].m_nSpeedMs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CPager::Display()
|
||||
{
|
||||
wchar outstr1[256];
|
||||
wchar outstr2[260];
|
||||
|
||||
wchar *pText = m_messages[0].m_pText;
|
||||
uint16 i = 0;
|
||||
if (pText != nil) {
|
||||
CMessages::InsertNumberInString(
|
||||
pText,
|
||||
m_messages[0].m_nNumber[0],
|
||||
m_messages[0].m_nNumber[1],
|
||||
m_messages[0].m_nNumber[2],
|
||||
m_messages[0].m_nNumber[3],
|
||||
m_messages[0].m_nNumber[4],
|
||||
m_messages[0].m_nNumber[5],
|
||||
outstr1);
|
||||
for (; i < m_nNumDisplayLetters; i++) {
|
||||
int pos = m_messages[0].m_nCurrentPosition + i;
|
||||
if (pos >= 0) {
|
||||
if (!outstr1[pos]) break;
|
||||
|
||||
outstr2[i] = outstr1[pos];
|
||||
} else {
|
||||
outstr2[i] = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
outstr2[i] = '\0';
|
||||
CHud::SetPagerMessage(outstr2);
|
||||
}
|
||||
|
||||
void
|
||||
CPager::AddMessage(wchar *str, uint16 speed, uint16 priority, uint16 a5)
|
||||
{
|
||||
uint16 size = CMessages::GetWideStringLength(str);
|
||||
for (int32 i = 0; i < NUMPAGERMESSAGES; i++) {
|
||||
if (m_messages[i].m_pText) {
|
||||
if (m_messages[i].m_nPriority >= priority)
|
||||
continue;
|
||||
|
||||
for (int j = NUMPAGERMESSAGES-1; j > i; j--)
|
||||
m_messages[j] = m_messages[j-1];
|
||||
|
||||
}
|
||||
m_messages[i].m_pText = str;
|
||||
m_messages[i].m_nSpeedMs = speed;
|
||||
m_messages[i].m_nPriority = priority;
|
||||
m_messages[i].field_10 = a5;
|
||||
m_messages[i].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
|
||||
m_messages[i].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + speed;
|
||||
m_messages[i].m_nStringLength = size;
|
||||
m_messages[i].m_nNumber[0] = -1;
|
||||
m_messages[i].m_nNumber[1] = -1;
|
||||
m_messages[i].m_nNumber[2] = -1;
|
||||
m_messages[i].m_nNumber[3] = -1;
|
||||
m_messages[i].m_nNumber[4] = -1;
|
||||
m_messages[i].m_nNumber[5] = -1;
|
||||
|
||||
if (i == 0)
|
||||
CMessages::AddToPreviousBriefArray(
|
||||
m_messages[0].m_pText,
|
||||
m_messages[0].m_nNumber[0],
|
||||
m_messages[0].m_nNumber[1],
|
||||
m_messages[0].m_nNumber[2],
|
||||
m_messages[0].m_nNumber[3],
|
||||
m_messages[0].m_nNumber[4],
|
||||
m_messages[0].m_nNumber[5],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CPager::AddMessageWithNumber(wchar *str, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, uint16 speed, uint16 priority, uint16 a11)
|
||||
{
|
||||
wchar nstr[520];
|
||||
|
||||
CMessages::InsertNumberInString(str, n1, n2, n3, n4, n5, n6, nstr);
|
||||
uint16 size = CMessages::GetWideStringLength(nstr);
|
||||
for (int32 i = 0; i < NUMPAGERMESSAGES; i++) {
|
||||
if (m_messages[i].m_pText) {
|
||||
if (m_messages[i].m_nPriority >= priority)
|
||||
continue;
|
||||
|
||||
for (int j = NUMPAGERMESSAGES-1; j > i; j--)
|
||||
m_messages[j] = m_messages[j - 1];
|
||||
|
||||
}
|
||||
m_messages[i].m_pText = str;
|
||||
m_messages[i].m_nSpeedMs = speed;
|
||||
m_messages[i].m_nPriority = priority;
|
||||
m_messages[i].field_10 = a11;
|
||||
m_messages[i].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
|
||||
m_messages[i].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + speed;
|
||||
m_messages[i].m_nStringLength = size;
|
||||
m_messages[i].m_nNumber[0] = n1;
|
||||
m_messages[i].m_nNumber[1] = n2;
|
||||
m_messages[i].m_nNumber[2] = n3;
|
||||
m_messages[i].m_nNumber[3] = n4;
|
||||
m_messages[i].m_nNumber[4] = n5;
|
||||
m_messages[i].m_nNumber[5] = n6;
|
||||
|
||||
if (i == 0)
|
||||
CMessages::AddToPreviousBriefArray(
|
||||
m_messages[0].m_pText,
|
||||
m_messages[0].m_nNumber[0],
|
||||
m_messages[0].m_nNumber[1],
|
||||
m_messages[0].m_nNumber[2],
|
||||
m_messages[0].m_nNumber[3],
|
||||
m_messages[0].m_nNumber[4],
|
||||
m_messages[0].m_nNumber[5],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CPager::ClearMessages()
|
||||
{
|
||||
for (int32 i = 0; i < NUMPAGERMESSAGES; i++)
|
||||
m_messages[i].m_pText = nil;
|
||||
}
|
||||
|
||||
void
|
||||
CPager::RestartCurrentMessage()
|
||||
{
|
||||
if (m_messages[0].m_pText != nil) {
|
||||
m_messages[0].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
|
||||
m_messages[0].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + m_messages[0].m_nSpeedMs;
|
||||
}
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x52B6F0, &CPager::Init, PATCH_JUMP);
|
||||
InjectHook(0x52B740, &CPager::Process, PATCH_JUMP);
|
||||
InjectHook(0x52B890, &CPager::Display, PATCH_JUMP);
|
||||
InjectHook(0x52B940, &CPager::AddMessage, PATCH_JUMP);
|
||||
InjectHook(0x52BB50, &CPager::AddMessageWithNumber, PATCH_JUMP);
|
||||
InjectHook(0x52BE50, &CPager::RestartCurrentMessage, PATCH_JUMP);
|
||||
InjectHook(0x52BE00, &CPager::ClearMessages, PATCH_JUMP);
|
||||
ENDPATCHES
|
@ -1,28 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
struct PagerMessage {
|
||||
wchar *m_pText;
|
||||
uint16 m_nSpeedMs;
|
||||
int16 m_nCurrentPosition;
|
||||
uint16 m_nStringLength;
|
||||
uint16 m_nPriority;
|
||||
uint32 m_nTimeToChangePosition;
|
||||
int16 field_10;
|
||||
int32 m_nNumber[6];
|
||||
};
|
||||
|
||||
#define NUMPAGERMESSAGES 8
|
||||
|
||||
class CPager
|
||||
{
|
||||
int16 m_nNumDisplayLetters;
|
||||
PagerMessage m_messages[NUMPAGERMESSAGES];
|
||||
public:
|
||||
void Init();
|
||||
void Process();
|
||||
void Display();
|
||||
void AddMessage(wchar*, uint16, uint16, uint16);
|
||||
void AddMessageWithNumber(wchar *str, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, uint16 speed, uint16 priority, uint16 a11);
|
||||
void ClearMessages();
|
||||
void RestartCurrentMessage();
|
||||
#pragma once
|
||||
|
||||
struct PagerMessage {
|
||||
wchar *m_pText;
|
||||
uint16 m_nSpeedMs;
|
||||
int16 m_nCurrentPosition;
|
||||
uint16 m_nStringLength;
|
||||
uint16 m_nPriority;
|
||||
uint32 m_nTimeToChangePosition;
|
||||
int16 field_10;
|
||||
int32 m_nNumber[6];
|
||||
};
|
||||
|
||||
#define NUMPAGERMESSAGES 8
|
||||
|
||||
class CPager
|
||||
{
|
||||
int16 m_nNumDisplayLetters;
|
||||
PagerMessage m_messages[NUMPAGERMESSAGES];
|
||||
public:
|
||||
void Init();
|
||||
void Process();
|
||||
void Display();
|
||||
void AddMessage(wchar*, uint16, uint16, uint16);
|
||||
void AddMessageWithNumber(wchar *str, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, uint16 speed, uint16 priority, uint16 a11);
|
||||
void ClearMessages();
|
||||
void RestartCurrentMessage();
|
||||
};
|
@ -1,324 +1,324 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "FileMgr.h"
|
||||
#include "Frontend.h"
|
||||
#include "Messages.h"
|
||||
#include "Text.h"
|
||||
|
||||
static wchar WideErrorString[25];
|
||||
|
||||
CText &TheText = *(CText*)0x941520;
|
||||
|
||||
CText::CText(void)
|
||||
{
|
||||
encoding = 'e';
|
||||
memset(WideErrorString, 0, sizeof(WideErrorString));
|
||||
}
|
||||
|
||||
void
|
||||
CText::Load(void)
|
||||
{
|
||||
uint8 *filedata;
|
||||
char filename[32], type[4];
|
||||
int length;
|
||||
int offset, sectlen;
|
||||
|
||||
Unload();
|
||||
filedata = new uint8[0x40000];
|
||||
|
||||
CFileMgr::SetDir("TEXT");
|
||||
switch(CMenuManager::m_PrefsLanguage){
|
||||
case LANGUAGE_AMERICAN:
|
||||
sprintf(filename, "AMERICAN.GXT");
|
||||
break;
|
||||
case LANGUAGE_FRENCH:
|
||||
sprintf(filename, "FRENCH.GXT");
|
||||
break;
|
||||
case LANGUAGE_GERMAN:
|
||||
sprintf(filename, "GERMAN.GXT");
|
||||
break;
|
||||
case LANGUAGE_ITALIAN:
|
||||
sprintf(filename, "ITALIAN.GXT");
|
||||
break;
|
||||
case LANGUAGE_SPANISH:
|
||||
sprintf(filename, "SPANISH.GXT");
|
||||
break;
|
||||
#ifdef MORE_LANGUAGES
|
||||
case LANGUAGE_RUSSIAN:
|
||||
sprintf(filename, "RUSSIAN.GXT");
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
length = CFileMgr::LoadFile(filename, filedata, 0x40000, "rb");
|
||||
CFileMgr::SetDir("");
|
||||
|
||||
offset = 0;
|
||||
while(offset < length){
|
||||
type[0] = filedata[offset++];
|
||||
type[1] = filedata[offset++];
|
||||
type[2] = filedata[offset++];
|
||||
type[3] = filedata[offset++];
|
||||
sectlen = (int)filedata[offset+3]<<24 | (int)filedata[offset+2]<<16 |
|
||||
(int)filedata[offset+1]<<8 | (int)filedata[offset+0];
|
||||
offset += 4;
|
||||
if(sectlen != 0){
|
||||
if(strncmp(type, "TKEY", 4) == 0)
|
||||
keyArray.Load(sectlen, filedata, &offset);
|
||||
else if(strncmp(type, "TDAT", 4) == 0)
|
||||
data.Load(sectlen, filedata, &offset);
|
||||
else
|
||||
offset += sectlen;
|
||||
}
|
||||
}
|
||||
|
||||
keyArray.Update(data.chars);
|
||||
|
||||
delete[] filedata;
|
||||
}
|
||||
|
||||
void
|
||||
CText::Unload(void)
|
||||
{
|
||||
CMessages::ClearAllMessagesDisplayedByGame();
|
||||
data.Unload();
|
||||
keyArray.Unload();
|
||||
}
|
||||
|
||||
wchar*
|
||||
CText::Get(const char *key)
|
||||
{
|
||||
return keyArray.Search(key);
|
||||
}
|
||||
|
||||
wchar UpperCaseTable[128] = {
|
||||
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
|
||||
139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
|
||||
150, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137,
|
||||
138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
|
||||
149, 173, 173, 175, 176, 177, 178, 179, 180, 181, 182,
|
||||
183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
|
||||
194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204,
|
||||
205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215,
|
||||
216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,
|
||||
227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
|
||||
238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248,
|
||||
249, 250, 251, 252, 253, 254, 255
|
||||
};
|
||||
|
||||
wchar FrenchUpperCaseTable[128] = {
|
||||
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
|
||||
139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
|
||||
150, 65, 65, 65, 65, 132, 133, 69, 69, 69, 69, 73, 73,
|
||||
73, 73, 79, 79, 79, 79, 85, 85, 85, 85, 173, 173, 175,
|
||||
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186,
|
||||
187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
|
||||
198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208,
|
||||
209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
|
||||
220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230,
|
||||
231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
|
||||
242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
|
||||
253, 254, 255
|
||||
};
|
||||
|
||||
wchar
|
||||
CText::GetUpperCase(wchar c)
|
||||
{
|
||||
switch (encoding)
|
||||
{
|
||||
case 'e':
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return c - 32;
|
||||
break;
|
||||
case 'f':
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return c - 32;
|
||||
|
||||
if (c >= 128 && c <= 255)
|
||||
return FrenchUpperCaseTable[c-128];
|
||||
break;
|
||||
case 'g':
|
||||
case 'i':
|
||||
case 's':
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return c - 32;
|
||||
|
||||
if (c >= 128 && c <= 255)
|
||||
return UpperCaseTable[c-128];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
CText::UpperCase(wchar *s)
|
||||
{
|
||||
while(*s){
|
||||
*s = GetUpperCase(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CKeyArray::Load(uint32 length, uint8 *data, int *offset)
|
||||
{
|
||||
uint32 i;
|
||||
uint8 *rawbytes;
|
||||
|
||||
numEntries = length / sizeof(CKeyEntry);
|
||||
entries = new CKeyEntry[numEntries];
|
||||
rawbytes = (uint8*)entries;
|
||||
|
||||
for(i = 0; i < length; i++)
|
||||
rawbytes[i] = data[(*offset)++];
|
||||
}
|
||||
|
||||
void
|
||||
CKeyArray::Unload(void)
|
||||
{
|
||||
delete[] entries;
|
||||
entries = nil;
|
||||
numEntries = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CKeyArray::Update(wchar *chars)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < numEntries; i++)
|
||||
entries[i].value = (wchar*)((uint8*)chars + (uintptr)entries[i].value);
|
||||
}
|
||||
|
||||
CKeyEntry*
|
||||
CKeyArray::BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 high)
|
||||
{
|
||||
int mid;
|
||||
int diff;
|
||||
|
||||
if(low > high)
|
||||
return nil;
|
||||
|
||||
mid = (low + high)/2;
|
||||
diff = strcmp(key, entries[mid].key);
|
||||
if(diff == 0)
|
||||
return &entries[mid];
|
||||
if(diff < 0)
|
||||
return BinarySearch(key, entries, low, mid-1);
|
||||
if(diff > 0)
|
||||
return BinarySearch(key, entries, mid+1, high);
|
||||
return nil;
|
||||
}
|
||||
|
||||
wchar*
|
||||
CKeyArray::Search(const char *key)
|
||||
{
|
||||
CKeyEntry *found;
|
||||
char errstr[25];
|
||||
int i;
|
||||
|
||||
found = BinarySearch(key, entries, 0, numEntries-1);
|
||||
if(found)
|
||||
return found->value;
|
||||
sprintf(errstr, "%s missing", key);
|
||||
for(i = 0; i < 25; i++)
|
||||
WideErrorString[i] = errstr[i];
|
||||
return WideErrorString;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CData::Load(uint32 length, uint8 *data, int *offset)
|
||||
{
|
||||
uint32 i;
|
||||
uint8 *rawbytes;
|
||||
|
||||
numChars = length / sizeof(wchar);
|
||||
chars = new wchar[numChars];
|
||||
rawbytes = (uint8*)chars;
|
||||
|
||||
for(i = 0; i < length; i++)
|
||||
rawbytes[i] = data[(*offset)++];
|
||||
}
|
||||
|
||||
void
|
||||
CData::Unload(void)
|
||||
{
|
||||
delete[] chars;
|
||||
chars = nil;
|
||||
numChars = 0;
|
||||
}
|
||||
|
||||
void
|
||||
AsciiToUnicode(const char *src, wchar *dst)
|
||||
{
|
||||
while((*dst++ = *src++) != '\0');
|
||||
}
|
||||
|
||||
char*
|
||||
UnicodeToAscii(wchar *src)
|
||||
{
|
||||
static char aStr[256];
|
||||
int len;
|
||||
for(len = 0; *src != '\0' && len < 256-1; len++, src++)
|
||||
if(*src < 128)
|
||||
aStr[len] = *src;
|
||||
else
|
||||
aStr[len] = '#';
|
||||
aStr[len] = '\0';
|
||||
return aStr;
|
||||
}
|
||||
|
||||
char*
|
||||
UnicodeToAsciiForSaveLoad(wchar *src)
|
||||
{
|
||||
static char aStr[256];
|
||||
int len;
|
||||
for(len = 0; *src != '\0' && len < 256-1; len++, src++)
|
||||
if(*src < 256)
|
||||
aStr[len] = *src;
|
||||
else
|
||||
aStr[len] = '#';
|
||||
aStr[len] = '\0';
|
||||
return aStr;
|
||||
}
|
||||
|
||||
void
|
||||
UnicodeStrcpy(wchar *dst, const wchar *src)
|
||||
{
|
||||
while((*dst++ = *src++) != '\0');
|
||||
}
|
||||
|
||||
int
|
||||
UnicodeStrlen(const wchar *str)
|
||||
{
|
||||
int len;
|
||||
for(len = 0; *str != '\0'; len++, str++);
|
||||
return len;
|
||||
}
|
||||
|
||||
void
|
||||
TextCopy(wchar *dst, const wchar *src)
|
||||
{
|
||||
while((*dst++ = *src++) != '\0');
|
||||
}
|
||||
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x52C3C0, &CText::Load, PATCH_JUMP);
|
||||
InjectHook(0x52C580, &CText::Unload, PATCH_JUMP);
|
||||
InjectHook(0x52C5A0, &CText::Get, PATCH_JUMP);
|
||||
InjectHook(0x52C220, &CText::GetUpperCase, PATCH_JUMP);
|
||||
InjectHook(0x52C2C0, &CText::UpperCase, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x52BE70, &CKeyArray::Load, PATCH_JUMP);
|
||||
InjectHook(0x52BF60, &CKeyArray::Unload, PATCH_JUMP);
|
||||
InjectHook(0x52BF80, &CKeyArray::Update, PATCH_JUMP);
|
||||
InjectHook(0x52C060, &CKeyArray::BinarySearch, PATCH_JUMP);
|
||||
InjectHook(0x52BFB0, &CKeyArray::Search, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x52C120, &CData::Load, PATCH_JUMP);
|
||||
InjectHook(0x52C200, &CData::Unload, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "FileMgr.h"
|
||||
#include "Frontend.h"
|
||||
#include "Messages.h"
|
||||
#include "Text.h"
|
||||
|
||||
static wchar WideErrorString[25];
|
||||
|
||||
CText &TheText = *(CText*)0x941520;
|
||||
|
||||
CText::CText(void)
|
||||
{
|
||||
encoding = 'e';
|
||||
memset(WideErrorString, 0, sizeof(WideErrorString));
|
||||
}
|
||||
|
||||
void
|
||||
CText::Load(void)
|
||||
{
|
||||
uint8 *filedata;
|
||||
char filename[32], type[4];
|
||||
int length;
|
||||
int offset, sectlen;
|
||||
|
||||
Unload();
|
||||
filedata = new uint8[0x40000];
|
||||
|
||||
CFileMgr::SetDir("TEXT");
|
||||
switch(CMenuManager::m_PrefsLanguage){
|
||||
case LANGUAGE_AMERICAN:
|
||||
sprintf(filename, "AMERICAN.GXT");
|
||||
break;
|
||||
case LANGUAGE_FRENCH:
|
||||
sprintf(filename, "FRENCH.GXT");
|
||||
break;
|
||||
case LANGUAGE_GERMAN:
|
||||
sprintf(filename, "GERMAN.GXT");
|
||||
break;
|
||||
case LANGUAGE_ITALIAN:
|
||||
sprintf(filename, "ITALIAN.GXT");
|
||||
break;
|
||||
case LANGUAGE_SPANISH:
|
||||
sprintf(filename, "SPANISH.GXT");
|
||||
break;
|
||||
#ifdef MORE_LANGUAGES
|
||||
case LANGUAGE_RUSSIAN:
|
||||
sprintf(filename, "RUSSIAN.GXT");
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
length = CFileMgr::LoadFile(filename, filedata, 0x40000, "rb");
|
||||
CFileMgr::SetDir("");
|
||||
|
||||
offset = 0;
|
||||
while(offset < length){
|
||||
type[0] = filedata[offset++];
|
||||
type[1] = filedata[offset++];
|
||||
type[2] = filedata[offset++];
|
||||
type[3] = filedata[offset++];
|
||||
sectlen = (int)filedata[offset+3]<<24 | (int)filedata[offset+2]<<16 |
|
||||
(int)filedata[offset+1]<<8 | (int)filedata[offset+0];
|
||||
offset += 4;
|
||||
if(sectlen != 0){
|
||||
if(strncmp(type, "TKEY", 4) == 0)
|
||||
keyArray.Load(sectlen, filedata, &offset);
|
||||
else if(strncmp(type, "TDAT", 4) == 0)
|
||||
data.Load(sectlen, filedata, &offset);
|
||||
else
|
||||
offset += sectlen;
|
||||
}
|
||||
}
|
||||
|
||||
keyArray.Update(data.chars);
|
||||
|
||||
delete[] filedata;
|
||||
}
|
||||
|
||||
void
|
||||
CText::Unload(void)
|
||||
{
|
||||
CMessages::ClearAllMessagesDisplayedByGame();
|
||||
data.Unload();
|
||||
keyArray.Unload();
|
||||
}
|
||||
|
||||
wchar*
|
||||
CText::Get(const char *key)
|
||||
{
|
||||
return keyArray.Search(key);
|
||||
}
|
||||
|
||||
wchar UpperCaseTable[128] = {
|
||||
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
|
||||
139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
|
||||
150, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137,
|
||||
138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
|
||||
149, 173, 173, 175, 176, 177, 178, 179, 180, 181, 182,
|
||||
183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
|
||||
194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204,
|
||||
205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215,
|
||||
216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,
|
||||
227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
|
||||
238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248,
|
||||
249, 250, 251, 252, 253, 254, 255
|
||||
};
|
||||
|
||||
wchar FrenchUpperCaseTable[128] = {
|
||||
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
|
||||
139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
|
||||
150, 65, 65, 65, 65, 132, 133, 69, 69, 69, 69, 73, 73,
|
||||
73, 73, 79, 79, 79, 79, 85, 85, 85, 85, 173, 173, 175,
|
||||
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186,
|
||||
187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
|
||||
198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208,
|
||||
209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
|
||||
220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230,
|
||||
231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
|
||||
242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
|
||||
253, 254, 255
|
||||
};
|
||||
|
||||
wchar
|
||||
CText::GetUpperCase(wchar c)
|
||||
{
|
||||
switch (encoding)
|
||||
{
|
||||
case 'e':
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return c - 32;
|
||||
break;
|
||||
case 'f':
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return c - 32;
|
||||
|
||||
if (c >= 128 && c <= 255)
|
||||
return FrenchUpperCaseTable[c-128];
|
||||
break;
|
||||
case 'g':
|
||||
case 'i':
|
||||
case 's':
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return c - 32;
|
||||
|
||||
if (c >= 128 && c <= 255)
|
||||
return UpperCaseTable[c-128];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
CText::UpperCase(wchar *s)
|
||||
{
|
||||
while(*s){
|
||||
*s = GetUpperCase(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CKeyArray::Load(uint32 length, uint8 *data, int *offset)
|
||||
{
|
||||
uint32 i;
|
||||
uint8 *rawbytes;
|
||||
|
||||
numEntries = length / sizeof(CKeyEntry);
|
||||
entries = new CKeyEntry[numEntries];
|
||||
rawbytes = (uint8*)entries;
|
||||
|
||||
for(i = 0; i < length; i++)
|
||||
rawbytes[i] = data[(*offset)++];
|
||||
}
|
||||
|
||||
void
|
||||
CKeyArray::Unload(void)
|
||||
{
|
||||
delete[] entries;
|
||||
entries = nil;
|
||||
numEntries = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CKeyArray::Update(wchar *chars)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < numEntries; i++)
|
||||
entries[i].value = (wchar*)((uint8*)chars + (uintptr)entries[i].value);
|
||||
}
|
||||
|
||||
CKeyEntry*
|
||||
CKeyArray::BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 high)
|
||||
{
|
||||
int mid;
|
||||
int diff;
|
||||
|
||||
if(low > high)
|
||||
return nil;
|
||||
|
||||
mid = (low + high)/2;
|
||||
diff = strcmp(key, entries[mid].key);
|
||||
if(diff == 0)
|
||||
return &entries[mid];
|
||||
if(diff < 0)
|
||||
return BinarySearch(key, entries, low, mid-1);
|
||||
if(diff > 0)
|
||||
return BinarySearch(key, entries, mid+1, high);
|
||||
return nil;
|
||||
}
|
||||
|
||||
wchar*
|
||||
CKeyArray::Search(const char *key)
|
||||
{
|
||||
CKeyEntry *found;
|
||||
char errstr[25];
|
||||
int i;
|
||||
|
||||
found = BinarySearch(key, entries, 0, numEntries-1);
|
||||
if(found)
|
||||
return found->value;
|
||||
sprintf(errstr, "%s missing", key);
|
||||
for(i = 0; i < 25; i++)
|
||||
WideErrorString[i] = errstr[i];
|
||||
return WideErrorString;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CData::Load(uint32 length, uint8 *data, int *offset)
|
||||
{
|
||||
uint32 i;
|
||||
uint8 *rawbytes;
|
||||
|
||||
numChars = length / sizeof(wchar);
|
||||
chars = new wchar[numChars];
|
||||
rawbytes = (uint8*)chars;
|
||||
|
||||
for(i = 0; i < length; i++)
|
||||
rawbytes[i] = data[(*offset)++];
|
||||
}
|
||||
|
||||
void
|
||||
CData::Unload(void)
|
||||
{
|
||||
delete[] chars;
|
||||
chars = nil;
|
||||
numChars = 0;
|
||||
}
|
||||
|
||||
void
|
||||
AsciiToUnicode(const char *src, wchar *dst)
|
||||
{
|
||||
while((*dst++ = *src++) != '\0');
|
||||
}
|
||||
|
||||
char*
|
||||
UnicodeToAscii(wchar *src)
|
||||
{
|
||||
static char aStr[256];
|
||||
int len;
|
||||
for(len = 0; *src != '\0' && len < 256-1; len++, src++)
|
||||
if(*src < 128)
|
||||
aStr[len] = *src;
|
||||
else
|
||||
aStr[len] = '#';
|
||||
aStr[len] = '\0';
|
||||
return aStr;
|
||||
}
|
||||
|
||||
char*
|
||||
UnicodeToAsciiForSaveLoad(wchar *src)
|
||||
{
|
||||
static char aStr[256];
|
||||
int len;
|
||||
for(len = 0; *src != '\0' && len < 256-1; len++, src++)
|
||||
if(*src < 256)
|
||||
aStr[len] = *src;
|
||||
else
|
||||
aStr[len] = '#';
|
||||
aStr[len] = '\0';
|
||||
return aStr;
|
||||
}
|
||||
|
||||
void
|
||||
UnicodeStrcpy(wchar *dst, const wchar *src)
|
||||
{
|
||||
while((*dst++ = *src++) != '\0');
|
||||
}
|
||||
|
||||
int
|
||||
UnicodeStrlen(const wchar *str)
|
||||
{
|
||||
int len;
|
||||
for(len = 0; *str != '\0'; len++, str++);
|
||||
return len;
|
||||
}
|
||||
|
||||
void
|
||||
TextCopy(wchar *dst, const wchar *src)
|
||||
{
|
||||
while((*dst++ = *src++) != '\0');
|
||||
}
|
||||
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x52C3C0, &CText::Load, PATCH_JUMP);
|
||||
InjectHook(0x52C580, &CText::Unload, PATCH_JUMP);
|
||||
InjectHook(0x52C5A0, &CText::Get, PATCH_JUMP);
|
||||
InjectHook(0x52C220, &CText::GetUpperCase, PATCH_JUMP);
|
||||
InjectHook(0x52C2C0, &CText::UpperCase, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x52BE70, &CKeyArray::Load, PATCH_JUMP);
|
||||
InjectHook(0x52BF60, &CKeyArray::Unload, PATCH_JUMP);
|
||||
InjectHook(0x52BF80, &CKeyArray::Update, PATCH_JUMP);
|
||||
InjectHook(0x52C060, &CKeyArray::BinarySearch, PATCH_JUMP);
|
||||
InjectHook(0x52BFB0, &CKeyArray::Search, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x52C120, &CData::Load, PATCH_JUMP);
|
||||
InjectHook(0x52C200, &CData::Unload, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -182,17 +182,17 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
|
||||
m_weaponDoorTimerRight = m_weaponDoorTimerLeft;
|
||||
|
||||
if(GetModelIndex() == MI_DODO){
|
||||
RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
|
||||
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
|
||||
CMatrix mat1;
|
||||
mat1.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF]));
|
||||
CMatrix mat2(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LF]));
|
||||
mat1.GetPosition() += CVector(mat2.GetPosition().x + 0.1f, 0.0f, mat2.GetPosition().z);
|
||||
mat1.UpdateRW();
|
||||
}else if(GetModelIndex() == MI_MIAMI_SPARROW || GetModelIndex() == MI_MIAMI_RCRAIDER){
|
||||
RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
|
||||
RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]), 0);
|
||||
RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0);
|
||||
RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0);
|
||||
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
|
||||
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]), 0);
|
||||
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0);
|
||||
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0);
|
||||
}else if(GetModelIndex() == MI_RHINO){
|
||||
bExplosionProof = true;
|
||||
bBulletProof = true;
|
||||
|
15
src/vehicles/Bike.h
Normal file
15
src/vehicles/Bike.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
// some miami bike leftovers
|
||||
|
||||
enum eBikeNodes {
|
||||
BIKE_NODE_NONE,
|
||||
BIKE_CHASSIS,
|
||||
BIKE_FORKS_FRONT,
|
||||
BIKE_FORKS_REAR,
|
||||
BIKE_WHEEL_FRONT,
|
||||
BIKE_WHEEL_REAR,
|
||||
BIKE_MUDGUARD,
|
||||
BIKE_HANDLEBARS,
|
||||
BIKE_NUM_NODES
|
||||
};
|
@ -94,7 +94,7 @@ CBoat::GetComponentWorldPosition(int32 component, CVector &pos)
|
||||
pos = *RwMatrixGetPos(RwFrameGetLTM(m_aBoatNodes[component]));
|
||||
}
|
||||
|
||||
RxObjSpace3DVertex KeepWaterOutVertices[4];
|
||||
RwIm3DVertex KeepWaterOutVertices[4];
|
||||
RwImVertexIndex KeepWaterOutIndices[6];
|
||||
|
||||
void
|
||||
@ -103,7 +103,7 @@ CBoat::Render()
|
||||
CMatrix matrix;
|
||||
|
||||
if (m_aBoatNodes[1] != nil) {
|
||||
matrix.Attach(&m_aBoatNodes[1]->modelling);
|
||||
matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[1]));
|
||||
|
||||
CVector pos = matrix.GetPosition();
|
||||
matrix.SetRotateZ(m_fMovingHiRotation);
|
||||
@ -111,7 +111,7 @@ CBoat::Render()
|
||||
|
||||
matrix.UpdateRW();
|
||||
if (CVehicle::bWheelsOnlyCheat) {
|
||||
RpAtomicRenderMacro((RpAtomic*)GetFirstObject(m_aBoatNodes[1]));
|
||||
RpAtomicRender((RpAtomic*)GetFirstObject(m_aBoatNodes[1]));
|
||||
}
|
||||
}
|
||||
m_fMovingHiRotation += 0.05f;
|
||||
@ -130,47 +130,23 @@ CBoat::Render()
|
||||
KeepWaterOutIndices[5] = 3;
|
||||
switch (GetModelIndex()) {
|
||||
case MI_SPEEDER:
|
||||
KeepWaterOutVertices[0].objVertex.x = -1.15f;
|
||||
KeepWaterOutVertices[0].objVertex.y = 3.61f;
|
||||
KeepWaterOutVertices[0].objVertex.z = 1.03f;
|
||||
KeepWaterOutVertices[1].objVertex.x = 1.15f;
|
||||
KeepWaterOutVertices[1].objVertex.y = 3.61f;
|
||||
KeepWaterOutVertices[1].objVertex.z = 1.03f;
|
||||
KeepWaterOutVertices[2].objVertex.x = -1.15f;
|
||||
KeepWaterOutVertices[2].objVertex.y = 0.06f;
|
||||
KeepWaterOutVertices[2].objVertex.z = 1.03f;
|
||||
KeepWaterOutVertices[3].objVertex.x = 1.15f;
|
||||
KeepWaterOutVertices[3].objVertex.y = 0.06f;
|
||||
KeepWaterOutVertices[3].objVertex.z = 1.03f;
|
||||
RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.15f, 3.61f, 1.03f);
|
||||
RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.15f, 3.61f, 1.03f);
|
||||
RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.15f, 0.06f, 1.03f);
|
||||
RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.15f, 0.06f, 1.03f);
|
||||
break;
|
||||
case MI_REEFER:
|
||||
KeepWaterOutVertices[2].objVertex.x = -1.9f;
|
||||
KeepWaterOutVertices[2].objVertex.y = 2.83f;
|
||||
KeepWaterOutVertices[2].objVertex.z = 1.0f;
|
||||
KeepWaterOutVertices[3].objVertex.x = 1.9f;
|
||||
KeepWaterOutVertices[3].objVertex.y = 2.83f;
|
||||
KeepWaterOutVertices[3].objVertex.z = 1.0f;
|
||||
KeepWaterOutVertices[0].objVertex.x = -1.66f;
|
||||
KeepWaterOutVertices[0].objVertex.y = -4.48f;
|
||||
KeepWaterOutVertices[0].objVertex.z = 0.83f;
|
||||
KeepWaterOutVertices[1].objVertex.x = 1.66f;
|
||||
KeepWaterOutVertices[1].objVertex.y = -4.48f;
|
||||
KeepWaterOutVertices[1].objVertex.z = 0.83f;
|
||||
RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.9f, 2.83f, 1.0f);
|
||||
RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.9f, 2.83f, 1.0f);
|
||||
RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.66f, -4.48f, 0.83f);
|
||||
RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.66f, -4.48f, 0.83f);
|
||||
break;
|
||||
case MI_PREDATOR:
|
||||
default:
|
||||
KeepWaterOutVertices[0].objVertex.x = -1.45f;
|
||||
KeepWaterOutVertices[0].objVertex.y = 1.9f;
|
||||
KeepWaterOutVertices[0].objVertex.z = 0.96f;
|
||||
KeepWaterOutVertices[1].objVertex.x = 1.45f;
|
||||
KeepWaterOutVertices[1].objVertex.y = 1.9f;
|
||||
KeepWaterOutVertices[1].objVertex.z = 0.96f;
|
||||
KeepWaterOutVertices[2].objVertex.x = -1.45f;
|
||||
KeepWaterOutVertices[2].objVertex.y = -3.75f;
|
||||
KeepWaterOutVertices[2].objVertex.z = 0.96f;
|
||||
KeepWaterOutVertices[3].objVertex.x = 1.45f;
|
||||
KeepWaterOutVertices[3].objVertex.y = -3.75f;
|
||||
KeepWaterOutVertices[3].objVertex.z = 0.96f;
|
||||
RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.45f, 1.9f, 0.96f);
|
||||
RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.45f, 1.9f, 0.96f);
|
||||
RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.45f, -3.75f, 0.96f);
|
||||
RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.45f, -3.75f, 0.96f);
|
||||
break;
|
||||
}
|
||||
KeepWaterOutVertices[0].u = 0.0f;
|
||||
|
@ -238,6 +238,7 @@ public:
|
||||
bool IsTrain(void) { return m_vehType == VEHICLE_TYPE_TRAIN; }
|
||||
bool IsHeli(void) { return m_vehType == VEHICLE_TYPE_HELI; }
|
||||
bool IsPlane(void) { return m_vehType == VEHICLE_TYPE_PLANE; }
|
||||
bool IsBike(void) { return m_vehType == VEHICLE_TYPE_BIKE; }
|
||||
|
||||
void FlyingControl(eFlightModel flightModel);
|
||||
void ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint,
|
||||
|
@ -1,11 +1,29 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Automobile.h"
|
||||
#include "Bike.h"
|
||||
#include "Camera.h"
|
||||
#include "Coronas.h"
|
||||
#include "DMAudio.h"
|
||||
#include "Entity.h"
|
||||
#include "EventList.h"
|
||||
#include "Explosion.h"
|
||||
#include "General.h"
|
||||
#include "Fire.h"
|
||||
#include "Pad.h"
|
||||
#include "Particle.h"
|
||||
#include "PointLights.h"
|
||||
#include "Shadows.h"
|
||||
#include "Timer.h"
|
||||
#include "Vehicle.h"
|
||||
#include "WaterLevel.h"
|
||||
#include "World.h"
|
||||
|
||||
CExplosion(&gaExplosion)[48] = *(CExplosion(*)[48])*(uintptr*)0x64E208;
|
||||
CExplosion(&gaExplosion)[NUM_EXPLOSIONS] = *(CExplosion(*)[NUM_EXPLOSIONS])*(uintptr*)0x64E208;
|
||||
|
||||
WRAPPER void CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32) { EAXJMP(0x5591C0); }
|
||||
// these two were not initialised in original code, I'm really not sure what were they meant to be
|
||||
RwRGBA colMedExpl = { 0, 0, 0, 0 };
|
||||
RwRGBA colUpdate = { 0, 0, 0, 0 };
|
||||
|
||||
int AudioHandle = AEHANDLE_NONE;
|
||||
|
||||
@ -15,26 +33,25 @@ CExplosion::Initialise()
|
||||
debug("Initialising CExplosion...\n");
|
||||
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
|
||||
gaExplosion[i].m_ExplosionType = EXPLOSION_GRENADE;
|
||||
gaExplosion[i].m_vecPosition.x = 0.0f;
|
||||
gaExplosion[i].m_vecPosition.y = 0.0f;
|
||||
gaExplosion[i].m_vecPosition.z = 0.0f;
|
||||
gaExplosion[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
|
||||
gaExplosion[i].m_fRadius = 1.0f;
|
||||
gaExplosion[i].m_fPropagationRate = 0.0f;
|
||||
gaExplosion[i].field_38 = 0;
|
||||
gaExplosion[i].m_fZshift = 0.0f;
|
||||
gaExplosion[i].m_pCreatorEntity = nil;
|
||||
gaExplosion[i].m_pVictimEntity = nil;
|
||||
gaExplosion[i].m_fStopTime = 0.0f;
|
||||
gaExplosion[i].m_bActive = false;
|
||||
gaExplosion[i].m_nStartTime = 0;
|
||||
gaExplosion[i].field_34 = 0;
|
||||
gaExplosion[i].m_nIteration = 0;
|
||||
gaExplosion[i].m_fStartTime = 0.0f;
|
||||
gaExplosion[i].m_bIsBoat = false;
|
||||
}
|
||||
AudioHandle = DMAudio.CreateEntity(AUDIOTYPE_EXPLOSION, (void*)1);
|
||||
if (AudioHandle >= 0)
|
||||
DMAudio.SetEntityStatus(AudioHandle, 1);
|
||||
DMAudio.SetEntityStatus(AudioHandle, true);
|
||||
debug("CExplosion ready\n");
|
||||
}
|
||||
|
||||
void CExplosion::Shutdown()
|
||||
void
|
||||
CExplosion::Shutdown()
|
||||
{
|
||||
debug("Shutting down CExplosion...\n");
|
||||
if (AudioHandle >= 0) {
|
||||
@ -44,27 +61,16 @@ void CExplosion::Shutdown()
|
||||
debug("CExplosion shut down\n");
|
||||
}
|
||||
|
||||
void
|
||||
CExplosion::RemoveAllExplosionsInArea(CVector pos, float radius)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
|
||||
if (gaExplosion[i].m_bActive) {
|
||||
if ((pos - gaExplosion[i].m_vecPosition).MagnitudeSqr() < SQR(radius))
|
||||
gaExplosion[i].m_bActive = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int8
|
||||
CExplosion::GetExplosionActiveCounter(uint8 id)
|
||||
{
|
||||
return gaExplosion[id].m_bActiveCounter;
|
||||
return gaExplosion[id].m_nActiveCounter;
|
||||
}
|
||||
|
||||
CVector *
|
||||
CExplosion::GetExplosionPosition(uint8 id)
|
||||
void
|
||||
CExplosion::ResetExplosionActiveCounter(uint8 id)
|
||||
{
|
||||
return &gaExplosion[id].m_vecPosition;
|
||||
gaExplosion[id].m_nActiveCounter = 0;
|
||||
}
|
||||
|
||||
uint8
|
||||
@ -73,18 +79,363 @@ CExplosion::GetExplosionType(uint8 id)
|
||||
return gaExplosion[id].m_ExplosionType;
|
||||
}
|
||||
|
||||
void
|
||||
CExplosion::ResetExplosionActiveCounter(uint8 id)
|
||||
CVector *
|
||||
CExplosion::GetExplosionPosition(uint8 id)
|
||||
{
|
||||
gaExplosion[id].m_bActiveCounter = 0;
|
||||
return &gaExplosion[id].m_vecPosition;
|
||||
}
|
||||
|
||||
bool
|
||||
CExplosion::TestForExplosionInArea(eExplosionType a1, float x1, float x2, float y1, float y2, float z1, float z2)
|
||||
CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32 lifetime)
|
||||
{
|
||||
CVector pPosn;
|
||||
CVector posGround;
|
||||
|
||||
RwRGBA colorMedium = colMedExpl;
|
||||
bool bDontExplode = false;
|
||||
const RwRGBA color = { 160, 160, 160, 255 };
|
||||
pPosn = pos;
|
||||
pPosn.z += 5.0f;
|
||||
#ifdef FIX_BUGS
|
||||
CShadows::AddPermanentShadow(SHADOWTEX_CAR, gpShadowHeliTex, &pPosn, 8.0f, 0.0f, 0.0f, -8.0f, 200, 0, 0, 0, 10.0f, 30000, 1.0f);
|
||||
#else
|
||||
// last two arguments are swapped resulting in no shadow
|
||||
CShadows::AddPermanentShadow(SHADOWTEX_CAR, gpShadowHeliTex, &pPosn, 8.0f, 0.0f, 0.0f, -8.0f, 200, 0, 0, 0, 10.0f, 1, 30000.0f);
|
||||
#endif
|
||||
|
||||
int n = 0;
|
||||
while (gaExplosion[n].m_nIteration != 0 && n < ARRAY_SIZE(gaExplosion))
|
||||
n++;
|
||||
if (n == ARRAY_SIZE(gaExplosion))
|
||||
return false;
|
||||
|
||||
CExplosion &explosion = gaExplosion[n];
|
||||
explosion.m_ExplosionType = type;
|
||||
explosion.m_vecPosition = pos;
|
||||
explosion.m_fRadius = 1.0f;
|
||||
explosion.m_fZshift = 0.0f;
|
||||
explosion.m_pCreatorEntity = culprit;
|
||||
if (culprit != nil)
|
||||
culprit->RegisterReference(&explosion.m_pCreatorEntity);
|
||||
explosion.m_pVictimEntity = explodingEntity;
|
||||
if (explodingEntity != nil)
|
||||
explodingEntity->RegisterReference(&explosion.m_pVictimEntity);
|
||||
explosion.m_nIteration = 1;
|
||||
explosion.m_nActiveCounter = 1;
|
||||
explosion.m_bIsBoat = false;
|
||||
explosion.m_nParticlesExpireTime = lifetime != 0 ? CTimer::GetTimeInMilliseconds() + lifetime : 0;
|
||||
switch (type)
|
||||
{
|
||||
case EXPLOSION_GRENADE:
|
||||
explosion.m_fRadius = 9.0f;
|
||||
explosion.m_fPower = 300.0f;
|
||||
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
|
||||
explosion.m_fPropagationRate = 0.5f;
|
||||
posGround = pos;
|
||||
posGround.z = CWorld::FindGroundZFor3DCoord(posGround.x, posGround.y, posGround.z + 3.0f, nil);
|
||||
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
|
||||
if (Distance(explosion.m_vecPosition, TheCamera.GetPosition()) < 40.0f)
|
||||
CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
|
||||
break;
|
||||
case EXPLOSION_MOLOTOV:
|
||||
{
|
||||
explosion.m_fRadius = 6.0f;
|
||||
explosion.m_fPower = 0.0f;
|
||||
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 3000;
|
||||
explosion.m_fPropagationRate = 0.5f;
|
||||
posGround = pos;
|
||||
bool found;
|
||||
posGround.z = CWorld::FindGroundZFor3DCoord(posGround.x, posGround.y, posGround.z + 3.0f, &found);
|
||||
if (found) {
|
||||
float waterLevel;
|
||||
if (CWaterLevel::GetWaterLevelNoWaves(posGround.x, posGround.y, posGround.z, &waterLevel)
|
||||
&& posGround.z < waterLevel
|
||||
&& waterLevel - 6.0f < posGround.z) // some subway/tunnels check?
|
||||
bDontExplode = true;
|
||||
else
|
||||
gFireManager.StartFire(posGround, 1.8f, false);
|
||||
}
|
||||
else
|
||||
bDontExplode = true;
|
||||
break;
|
||||
}
|
||||
case EXPLOSION_ROCKET:
|
||||
explosion.m_fRadius = 10.0f;
|
||||
explosion.m_fPower = 300.0f;
|
||||
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
|
||||
explosion.m_fPropagationRate = 0.5f;
|
||||
CEventList::RegisterEvent(EVENT_EXPLOSION, pos, 250);
|
||||
if (Distance(explosion.m_vecPosition, TheCamera.GetPosition()) < 40.0f)
|
||||
CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
|
||||
break;
|
||||
case EXPLOSION_CAR:
|
||||
case EXPLOSION_CAR_QUICK:
|
||||
explosion.m_fRadius = 9.0f;
|
||||
explosion.m_fPower = 300.0f;
|
||||
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 4250;
|
||||
explosion.m_fPropagationRate = 0.5f;
|
||||
explosion.m_fStartTime = CTimer::GetTimeInMilliseconds();
|
||||
if (explosion.m_pVictimEntity != nil) {
|
||||
if (explosion.m_pVictimEntity->IsVehicle() && ((CVehicle*)explosion.m_pVictimEntity)->IsBoat())
|
||||
explosion.m_bIsBoat = true;
|
||||
CEventList::RegisterEvent(EVENT_EXPLOSION, EVENT_ENTITY_VEHICLE, explosion.m_pVictimEntity, nil, 1000);
|
||||
} else
|
||||
CEventList::RegisterEvent(EVENT_EXPLOSION, pos, 1000);
|
||||
|
||||
if (explosion.m_pVictimEntity != nil && !explosion.m_bIsBoat) {
|
||||
int rn = (CGeneral::GetRandomNumber() & 1) + 2;
|
||||
for (int i = 0; i < rn; i++) {
|
||||
CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, explosion.m_pVictimEntity->GetPosition(), CVector(0.0f, 0.0f, 0.0f), nil, 3.5f, colMedExpl);
|
||||
CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, explosion.m_pVictimEntity->GetPosition(), CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
|
||||
}
|
||||
CVehicle *veh = (CVehicle*)explosion.m_pVictimEntity;
|
||||
int32 component = CAR_WING_LR;
|
||||
|
||||
// miami leftover
|
||||
if (veh->IsBike())
|
||||
component = BIKE_FORKS_REAR;
|
||||
|
||||
if (veh->IsComponentPresent(component)) {
|
||||
CVector componentPos;
|
||||
veh->GetComponentWorldPosition(component, componentPos);
|
||||
rn = (CGeneral::GetRandomNumber() & 1) + 1;
|
||||
for (int i = 0; i < rn; i++)
|
||||
CParticle::AddJetExplosion(componentPos, 1.4f, 0.0f);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EXPLOSION_HELI:
|
||||
explosion.m_fRadius = 6.0f;
|
||||
explosion.m_fPower = 300.0f;
|
||||
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
|
||||
explosion.m_fPropagationRate = 0.5f;
|
||||
explosion.m_fStartTime = CTimer::GetTimeInMilliseconds();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
CVector randpos;
|
||||
uint8 x, y, z;
|
||||
|
||||
x = CGeneral::GetRandomNumber();
|
||||
y = CGeneral::GetRandomNumber();
|
||||
z = CGeneral::GetRandomNumber();
|
||||
randpos = pos + CVector(x - 128, y - 128, z - 128) / 20.0f;
|
||||
|
||||
CParticle::AddParticle(PARTICLE_EXPLOSION_MFAST, randpos, CVector(0.0f, 0.0f, 0.0f), nil, 2.5f, color);
|
||||
|
||||
x = CGeneral::GetRandomNumber();
|
||||
y = CGeneral::GetRandomNumber();
|
||||
z = CGeneral::GetRandomNumber();
|
||||
randpos = pos + CVector(x - 128, y - 128, z - 128) / 20.0f;
|
||||
|
||||
CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, randpos, CVector(0.0f, 0.0f, 0.0f), nil, 5.0f, color);
|
||||
|
||||
x = CGeneral::GetRandomNumber();
|
||||
y = CGeneral::GetRandomNumber();
|
||||
z = CGeneral::GetRandomNumber();
|
||||
randpos = pos + CVector(x - 128, y - 128, z - 128) / 20.0f;
|
||||
|
||||
CParticle::AddJetExplosion(randpos, 1.4f, 3.0f);
|
||||
}
|
||||
CEventList::RegisterEvent(EVENT_EXPLOSION, pos, 1000);
|
||||
break;
|
||||
case EXPLOSION_MINE:
|
||||
explosion.m_fRadius = 10.0f;
|
||||
explosion.m_fPower = 150.0f;
|
||||
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
|
||||
explosion.m_fPropagationRate = 0.5f;
|
||||
posGround = pos;
|
||||
//posGround.z =
|
||||
CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
|
||||
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
|
||||
break;
|
||||
case EXPLOSION_BARREL:
|
||||
explosion.m_fRadius = 7.0f;
|
||||
explosion.m_fPower = 150.0f;
|
||||
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
|
||||
explosion.m_fPropagationRate = 0.5f;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
CVector randpos;
|
||||
uint8 x, y, z;
|
||||
|
||||
x = CGeneral::GetRandomNumber();
|
||||
y = CGeneral::GetRandomNumber();
|
||||
z = CGeneral::GetRandomNumber();
|
||||
randpos = CVector(x - 128, y - 128, z - 128);
|
||||
|
||||
randpos.x /= 50.0f;
|
||||
randpos.y /= 50.0f;
|
||||
randpos.z /= 25.0f;
|
||||
randpos += pos;
|
||||
CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, randpos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colorMedium);
|
||||
}
|
||||
posGround = pos;
|
||||
//posGround.z =
|
||||
CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
|
||||
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
|
||||
break;
|
||||
case EXPLOSION_TANK_GRENADE:
|
||||
explosion.m_fRadius = 10.0f;
|
||||
explosion.m_fPower = 150.0f;
|
||||
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
|
||||
explosion.m_fPropagationRate = 0.5f;
|
||||
posGround = pos;
|
||||
//posGround.z =
|
||||
CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
|
||||
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
|
||||
break;
|
||||
case EXPLOSION_HELI_BOMB:
|
||||
explosion.m_fRadius = 8.0f;
|
||||
explosion.m_fPower = 50.0f;
|
||||
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
|
||||
explosion.m_fPropagationRate = 0.5f;
|
||||
posGround = pos;
|
||||
//posGround.z =
|
||||
CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
|
||||
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
|
||||
break;
|
||||
}
|
||||
if (bDontExplode) {
|
||||
explosion.m_nIteration = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (explosion.m_fPower != 0.0f && explosion.m_nParticlesExpireTime == 0)
|
||||
CWorld::TriggerExplosion(pos, explosion.m_fRadius, explosion.m_fPower, culprit, (type == EXPLOSION_ROCKET || type == EXPLOSION_CAR_QUICK || type == EXPLOSION_MINE || type == EXPLOSION_BARREL || type == EXPLOSION_TANK_GRENADE || type == EXPLOSION_HELI_BOMB));
|
||||
|
||||
TheCamera.CamShake(0.6f, pos.x, pos.y, pos.z);
|
||||
CPad::GetPad(0)->StartShake_Distance(300, 128, pos.x, pos.y, pos.z);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CExplosion::Update()
|
||||
{
|
||||
RwRGBA color = colUpdate;
|
||||
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
|
||||
CExplosion &explosion = gaExplosion[i];
|
||||
if (explosion.m_nIteration == 0) continue;
|
||||
|
||||
if (explosion.m_nParticlesExpireTime != 0) {
|
||||
if (CTimer::GetTimeInMilliseconds() > explosion.m_nParticlesExpireTime) {
|
||||
explosion.m_nParticlesExpireTime = 0;
|
||||
if (explosion.m_fPower != 0.0f)
|
||||
CWorld::TriggerExplosion(explosion.m_vecPosition, explosion.m_fRadius, explosion.m_fPower, explosion.m_pCreatorEntity, (explosion.m_ExplosionType == EXPLOSION_ROCKET || explosion.m_ExplosionType == EXPLOSION_CAR_QUICK || explosion.m_ExplosionType == EXPLOSION_MINE || explosion.m_ExplosionType == EXPLOSION_BARREL || explosion.m_ExplosionType == EXPLOSION_TANK_GRENADE || explosion.m_ExplosionType == EXPLOSION_HELI_BOMB));
|
||||
}
|
||||
} else {
|
||||
explosion.m_fRadius += explosion.m_fPropagationRate * CTimer::GetTimeStep();
|
||||
int32 someTime = explosion.m_fStopTime - CTimer::GetTimeInMilliseconds();
|
||||
switch (explosion.m_ExplosionType)
|
||||
{
|
||||
case EXPLOSION_GRENADE:
|
||||
case EXPLOSION_ROCKET:
|
||||
case EXPLOSION_HELI:
|
||||
case EXPLOSION_MINE:
|
||||
case EXPLOSION_BARREL:
|
||||
if (CTimer::GetFrameCounter() & 1) {
|
||||
CPointLights::AddLight(CPointLights::LIGHT_POINT, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), 20.0f, 1.0f, 1.0f, 0.5f, CPointLights::FOG_NONE, true);
|
||||
CCoronas::RegisterCorona((uintptr)&explosion, 255, 255, 200, 255, explosion.m_vecPosition, 8.0f, 120.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
|
||||
} else
|
||||
CCoronas::RegisterCorona((uintptr)&explosion, 128, 128, 100, 255, explosion.m_vecPosition, 8.0f, 120.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
|
||||
CCoronas::RegisterCorona((uintptr)&explosion + 1, 30, 30, 25, 255, explosion.m_vecPosition, explosion.m_fRadius, 120.0f, gpCoronaTexture[7], CCoronas::TYPE_STAR, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
|
||||
break;
|
||||
case EXPLOSION_MOLOTOV:
|
||||
CWorld::SetPedsOnFire(explosion.m_vecPosition.x, explosion.m_vecPosition.y, explosion.m_vecPosition.z, 6.0f, explosion.m_pCreatorEntity);
|
||||
CWorld::SetCarsOnFire(explosion.m_vecPosition.x, explosion.m_vecPosition.y, explosion.m_vecPosition.z, 6.0f, explosion.m_pCreatorEntity);
|
||||
if (explosion.m_nIteration < 10) {
|
||||
if (explosion.m_nIteration == 1) {
|
||||
CVector point1 = explosion.m_vecPosition;
|
||||
point1.z += 5.0f;
|
||||
CColPoint colPoint;
|
||||
CEntity *pEntity;
|
||||
CWorld::ProcessVerticalLine(point1, -1000.0f, colPoint, pEntity, true, false, false, false, true, false, nil);
|
||||
explosion.m_fZshift = colPoint.point.z;
|
||||
}
|
||||
float ff = ((float)explosion.m_nIteration * 0.55f);
|
||||
for (int i = 0; i < 5 * ff; i++) {
|
||||
float angle = CGeneral::GetRandomNumber() / 256.0f * 6.28f;
|
||||
|
||||
CVector pos = explosion.m_vecPosition;
|
||||
pos.x += ff * Sin(angle);
|
||||
pos.y += ff * Cos(angle);
|
||||
pos.z += 5.0f; // what is the point of this?
|
||||
|
||||
pos.z = explosion.m_fZshift + 0.5f;
|
||||
CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, CGeneral::GetRandomNumberInRange(-3.0f, 3.0f), CGeneral::GetRandomNumberInRange(-180.0f, 180.0f));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EXPLOSION_CAR:
|
||||
case EXPLOSION_CAR_QUICK:
|
||||
if (someTime >= 3500) {
|
||||
if (explosion.m_pVictimEntity != nil && !explosion.m_bIsBoat) {
|
||||
if ((CGeneral::GetRandomNumber() & 0xF) == 0) {
|
||||
CVehicle *veh = (CVehicle*)explosion.m_pVictimEntity;
|
||||
uint8 component = CAR_WING_LR;
|
||||
|
||||
// miami leftover
|
||||
if (veh->IsBike())
|
||||
component = BIKE_FORKS_REAR;
|
||||
|
||||
if (veh->IsComponentPresent(component)) {
|
||||
CVector componentPos;
|
||||
veh->GetComponentWorldPosition(component, componentPos);
|
||||
CParticle::AddJetExplosion(componentPos, 1.5f, 0.0f);
|
||||
}
|
||||
}
|
||||
if (CTimer::GetTimeInMilliseconds() > explosion.m_fStartTime) {
|
||||
explosion.m_fStartTime = CTimer::GetTimeInMilliseconds() + 125 + (CGeneral::GetRandomNumber() & 0x7F);
|
||||
CVector pos = explosion.m_pVictimEntity->GetPosition();
|
||||
for (int i = 0; i < (CGeneral::GetRandomNumber() & 1) + 1; i++) {
|
||||
CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, CVector(0.0f, 0.0f, 0.0f), nil, 3.5f, color);
|
||||
CParticle::AddParticle(PARTICLE_EXPLOSION_LARGE, pos, CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CTimer::GetFrameCounter() & 1) {
|
||||
CPointLights::AddLight(CPointLights::LIGHT_POINT, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), 15.0f, 1.0f, 0.0f, 0.0f, CPointLights::FOG_NONE, true);
|
||||
CCoronas::RegisterCorona((uintptr)&explosion, 200, 100, 0, 255, explosion.m_vecPosition, 6.0f, 80.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
|
||||
} else
|
||||
CCoronas::RegisterCorona((uintptr)&explosion, 128, 0, 0, 255, explosion.m_vecPosition, 8.0f, 80.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
|
||||
|
||||
CCoronas::RegisterCorona((uintptr)&explosion + 1, 30, 15, 0, 255, explosion.m_vecPosition, explosion.m_fRadius, 80.0f, gpCoronaTexture[7], CCoronas::TYPE_STAR, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
|
||||
} else if (explosion.m_nIteration & 1) {
|
||||
if (explosion.m_pVictimEntity != nil)
|
||||
CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, explosion.m_pVictimEntity->GetPosition(), CVector(0.0f, 0.0f, 0.0f), nil, CGeneral::GetRandomNumberInRange(0.5f, 0.8f), color);
|
||||
CVector pos = explosion.m_vecPosition;
|
||||
pos.z += 1.0f;
|
||||
CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, pos, CVector(0.0f, 0.0f, 0.11f), nil, CGeneral::GetRandomNumberInRange(0.5f, 2.0f), color);
|
||||
}
|
||||
break;
|
||||
case EXPLOSION_TANK_GRENADE:
|
||||
case EXPLOSION_HELI_BOMB:
|
||||
if (explosion.m_nIteration < 5) {
|
||||
float ff = ((float)explosion.m_nIteration * 0.65f);
|
||||
for (int i = 0; i < 10 * ff; i++) {
|
||||
uint8 x = CGeneral::GetRandomNumber(), y = CGeneral::GetRandomNumber(), z = CGeneral::GetRandomNumber();
|
||||
CVector pos(x - 128, y - 128, (z % 128) + 1);
|
||||
|
||||
pos.Normalise();
|
||||
pos *= ff / 5.0f;
|
||||
pos += explosion.m_vecPosition;
|
||||
pos.z += 0.5f;
|
||||
CParticle::AddParticle(PARTICLE_EXPLOSION_LARGE, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, CGeneral::GetRandomNumberInRange(-3.0f, 3.0f), CGeneral::GetRandomNumberInRange(-180.0f, 180.0f));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (someTime > 0)
|
||||
explosion.m_nIteration++;
|
||||
else
|
||||
explosion.m_nIteration = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CExplosion::TestForExplosionInArea(eExplosionType type, float x1, float x2, float y1, float y2, float z1, float z2)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
|
||||
if (gaExplosion[i].m_bActive) {
|
||||
if (a1 == gaExplosion[i].m_ExplosionType) {
|
||||
if (gaExplosion[i].m_nIteration != 0) {
|
||||
if (type == gaExplosion[i].m_ExplosionType) {
|
||||
if (gaExplosion[i].m_vecPosition.x >= x1 && gaExplosion[i].m_vecPosition.x <= x2) {
|
||||
if (gaExplosion[i].m_vecPosition.y >= y1 && gaExplosion[i].m_vecPosition.y <= y2) {
|
||||
if (gaExplosion[i].m_vecPosition.z >= z1 && gaExplosion[i].m_vecPosition.z <= z2)
|
||||
@ -97,13 +448,26 @@ CExplosion::TestForExplosionInArea(eExplosionType a1, float x1, float x2, float
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CExplosion::RemoveAllExplosionsInArea(CVector pos, float radius)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
|
||||
if (gaExplosion[i].m_nIteration != 0) {
|
||||
if ((pos - gaExplosion[i].m_vecPosition).MagnitudeSqr() < SQR(radius))
|
||||
gaExplosion[i].m_nIteration = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x559030, &CExplosion::Initialise, PATCH_JUMP);
|
||||
InjectHook(0x559100, &CExplosion::Shutdown, PATCH_JUMP);
|
||||
InjectHook(0x55AD40, &CExplosion::RemoveAllExplosionsInArea, PATCH_JUMP);
|
||||
InjectHook(0x559140, &CExplosion::GetExplosionActiveCounter, PATCH_JUMP);
|
||||
InjectHook(0x5591A0, &CExplosion::GetExplosionPosition, PATCH_JUMP);
|
||||
InjectHook(0x559180, &CExplosion::GetExplosionType, PATCH_JUMP);
|
||||
InjectHook(0x559160, &CExplosion::ResetExplosionActiveCounter, PATCH_JUMP);
|
||||
InjectHook(0x559180, &CExplosion::GetExplosionType, PATCH_JUMP);
|
||||
InjectHook(0x5591A0, &CExplosion::GetExplosionPosition, PATCH_JUMP);
|
||||
InjectHook(0x5591C0, &CExplosion::AddExplosion, PATCH_JUMP);
|
||||
InjectHook(0x55A0C0, &CExplosion::Update, PATCH_JUMP);
|
||||
InjectHook(0x55AC80, &CExplosion::TestForExplosionInArea, PATCH_JUMP);
|
||||
InjectHook(0x55AD40, &CExplosion::RemoveAllExplosionsInArea, PATCH_JUMP);
|
||||
ENDPATCHES
|
@ -26,25 +26,24 @@ class CExplosion
|
||||
CEntity *m_pCreatorEntity;
|
||||
CEntity *m_pVictimEntity;
|
||||
float m_fStopTime;
|
||||
bool m_bActive;
|
||||
int8 m_bActiveCounter;
|
||||
int32 m_nStartTime;
|
||||
uint8 m_nIteration;
|
||||
uint8 m_nActiveCounter;
|
||||
float m_fStartTime;
|
||||
uint32 m_nParticlesExpireTime;
|
||||
float m_fPower;
|
||||
int32 field_34;
|
||||
int32 field_38;
|
||||
bool m_bIsBoat;
|
||||
float m_fZshift;
|
||||
public:
|
||||
static void Initialise();
|
||||
static void Shutdown();
|
||||
static void AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type,
|
||||
const CVector &pos, uint32);
|
||||
|
||||
static int8 GetExplosionActiveCounter(uint8 id);
|
||||
static CVector *GetExplosionPosition(uint8 id);
|
||||
static uint8 GetExplosionType(uint8 id);
|
||||
static void ResetExplosionActiveCounter(uint8 id);
|
||||
static void RemoveAllExplosionsInArea(CVector, float);
|
||||
static bool TestForExplosionInArea(eExplosionType, float, float, float, float, float, float);
|
||||
static uint8 GetExplosionType(uint8 id);
|
||||
static CVector *GetExplosionPosition(uint8 id);
|
||||
static bool AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32 lifetime);
|
||||
static void Update();
|
||||
static bool TestForExplosionInArea(eExplosionType type, float x1, float x2, float y1, float y2, float z1, float z2);
|
||||
static void RemoveAllExplosionsInArea(CVector pos, float radius);
|
||||
};
|
||||
|
||||
extern CExplosion (&gaExplosion)[48];
|
||||
extern CExplosion (&gaExplosion)[NUM_EXPLOSIONS];
|
@ -1,32 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
class CEntity;
|
||||
class CObject;
|
||||
class CProjectile;
|
||||
enum eWeaponType;
|
||||
|
||||
class CProjectileInfo
|
||||
{
|
||||
public:
|
||||
eWeaponType m_eWeaponType;
|
||||
CEntity* m_pSource;
|
||||
uint32 m_nExplosionTime;
|
||||
bool m_bInUse;
|
||||
CVector m_vecPos;
|
||||
|
||||
public:
|
||||
static CProjectileInfo* GetProjectileInfo(int32 id);
|
||||
static CProjectile* (&ms_apProjectile)[NUM_PROJECTILES];
|
||||
|
||||
static void Initialise();
|
||||
static void Shutdown();
|
||||
static bool AddProjectile(CEntity *ped, eWeaponType weapon, CVector pos, float speed);
|
||||
static void RemoveProjectile(CProjectileInfo *info, CProjectile *projectile);
|
||||
static void RemoveNotAdd(CEntity *entity, eWeaponType weaponType, CVector pos);
|
||||
static bool RemoveIfThisIsAProjectile(CObject *pObject);
|
||||
static void RemoveAllProjectiles();
|
||||
static void Update();
|
||||
static bool IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove);
|
||||
};
|
||||
|
||||
#pragma once
|
||||
|
||||
class CEntity;
|
||||
class CObject;
|
||||
class CProjectile;
|
||||
enum eWeaponType;
|
||||
|
||||
class CProjectileInfo
|
||||
{
|
||||
public:
|
||||
eWeaponType m_eWeaponType;
|
||||
CEntity* m_pSource;
|
||||
uint32 m_nExplosionTime;
|
||||
bool m_bInUse;
|
||||
CVector m_vecPos;
|
||||
|
||||
public:
|
||||
static CProjectileInfo* GetProjectileInfo(int32 id);
|
||||
static CProjectile* (&ms_apProjectile)[NUM_PROJECTILES];
|
||||
|
||||
static void Initialise();
|
||||
static void Shutdown();
|
||||
static bool AddProjectile(CEntity *ped, eWeaponType weapon, CVector pos, float speed);
|
||||
static void RemoveProjectile(CProjectileInfo *info, CProjectile *projectile);
|
||||
static void RemoveNotAdd(CEntity *entity, eWeaponType weaponType, CVector pos);
|
||||
static bool RemoveIfThisIsAProjectile(CObject *pObject);
|
||||
static void RemoveAllProjectiles();
|
||||
static void Update();
|
||||
static bool IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove);
|
||||
};
|
||||
|
||||
extern CProjectileInfo (&gaProjectileInfo)[NUM_PROJECTILES];
|
Loading…
Reference in New Issue
Block a user