mirror of
https://gitlab.com/GaryOderNichts/re3-wiiu.git
synced 2024-12-27 10:11:49 +01:00
Merge branch 'master' into master
This commit is contained in:
commit
aa449b6fe1
@ -125,8 +125,8 @@ CAnimBlendNode::CalcDeltas(void)
|
||||
float cos = DotProduct(kfA->rotation, kfB->rotation);
|
||||
if(cos > 1.0f)
|
||||
cos = 1.0f;
|
||||
theta = acos(cos);
|
||||
invSin = theta == 0.0f ? 0.0f : 1.0f/sin(theta);
|
||||
theta = Acos(cos);
|
||||
invSin = theta == 0.0f ? 0.0f : 1.0f/Sin(theta);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -10,7 +10,7 @@ class CAnimBlendNode
|
||||
public:
|
||||
// for slerp
|
||||
float theta; // angle between quaternions
|
||||
float invSin; // 1/sin(theta)
|
||||
float invSin; // 1/Sin(theta)
|
||||
// indices into array in sequence
|
||||
int32 frameA; // next key frame
|
||||
int32 frameB; // previous key frame
|
||||
|
@ -53,7 +53,7 @@ FrameUpdateCallBack(AnimBlendFrameData *frame, void *arg)
|
||||
if(norm == 0.0f)
|
||||
rot.w = 1.0f;
|
||||
else
|
||||
rot *= 1.0f/sqrt(norm);
|
||||
rot *= 1.0f/Sqrt(norm);
|
||||
rot.Get(mat);
|
||||
}
|
||||
|
||||
@ -127,7 +127,7 @@ FrameUpdateCallBackWithVelocityExtraction(AnimBlendFrameData *frame, void *arg)
|
||||
if(norm == 0.0f)
|
||||
rot.w = 1.0f;
|
||||
else
|
||||
rot *= 1.0f/sqrt(norm);
|
||||
rot *= 1.0f/Sqrt(norm);
|
||||
rot.Get(mat);
|
||||
}
|
||||
|
||||
@ -206,7 +206,7 @@ FrameUpdateCallBackWith3dVelocityExtraction(AnimBlendFrameData *frame, void *arg
|
||||
if(norm == 0.0f)
|
||||
rot.w = 1.0f;
|
||||
else
|
||||
rot *= 1.0f/sqrt(norm);
|
||||
rot *= 1.0f/Sqrt(norm);
|
||||
rot.Get(mat);
|
||||
}
|
||||
|
||||
|
@ -91,9 +91,249 @@ enum eVehicleModel
|
||||
cAudioManager &AudioManager = *(cAudioManager *)0x880FC0;
|
||||
|
||||
constexpr int totalAudioEntitiesSlots = 200;
|
||||
constexpr int maxVolume = 127;
|
||||
|
||||
char &g_nMissionAudioPlayingStatus = *(char *)0x60ED88;
|
||||
|
||||
void
|
||||
cAudioManager::AddSampleToRequestedQueue()
|
||||
{
|
||||
int32 calculatedVolume;
|
||||
tActiveSample *sample;
|
||||
int32 unknown1;
|
||||
uint8 unknown2;
|
||||
bool bReflections;
|
||||
|
||||
if(m_sQueueSample.m_nSampleIndex < TOTAL_AUDIO_SAMPLES) {
|
||||
calculatedVolume = m_sQueueSample.field_16 * (maxVolume - m_sQueueSample.m_bVolume);
|
||||
unknown2 = m_bSampleRequestQueuesStatus[m_bActiveSampleQueue];
|
||||
if(unknown2 >= m_bActiveSamples) {
|
||||
unknown1 = 27 * m_bActiveSampleQueue;
|
||||
unknown2 = *(&m_asSamples[53].field_91 + m_bActiveSamples + unknown1);
|
||||
if(m_asSamples[unknown1 + unknown2].calculatedVolume <= calculatedVolume)
|
||||
return;
|
||||
} else {
|
||||
++m_bSampleRequestQueuesStatus[m_bActiveSampleQueue];
|
||||
}
|
||||
m_sQueueSample.calculatedVolume = calculatedVolume;
|
||||
m_sQueueSample.m_bLoopEnded = 0;
|
||||
if(m_sQueueSample.m_bIsDistant) {
|
||||
m_sQueueSample.m_bRequireReflection = 0;
|
||||
m_sQueueSample.m_bLoopsRemaining = 0;
|
||||
}
|
||||
if(m_bDynamicAcousticModelingStatus && m_sQueueSample.m_nLoopCount) {
|
||||
bReflections = m_sQueueSample.m_bRequireReflection;
|
||||
} else {
|
||||
bReflections = false;
|
||||
m_sQueueSample.m_bLoopsRemaining = 0;
|
||||
}
|
||||
m_sQueueSample.m_bRequireReflection = 0;
|
||||
|
||||
if(!m_bDynamicAcousticModelingStatus) m_sQueueSample.m_bReverbFlag = 0;
|
||||
|
||||
sample = &m_asSamples[27 * m_bActiveSampleQueue + unknown2];
|
||||
sample->m_nEntityIndex = m_sQueueSample.m_nEntityIndex;
|
||||
sample->field_4 = m_sQueueSample.field_4;
|
||||
sample->m_nSampleIndex = m_sQueueSample.m_nSampleIndex;
|
||||
sample->m_bBankIndex = m_sQueueSample.m_bBankIndex;
|
||||
sample->m_bIsDistant = m_sQueueSample.m_bIsDistant;
|
||||
sample->field_16 = m_sQueueSample.field_16;
|
||||
sample->m_nFrequency = m_sQueueSample.m_nFrequency;
|
||||
sample->m_bVolume = m_sQueueSample.m_bVolume;
|
||||
sample->m_fDistance = m_sQueueSample.m_fDistance;
|
||||
sample->m_nLoopCount = m_sQueueSample.m_nLoopCount;
|
||||
sample->m_nLoopStart = m_sQueueSample.m_nLoopStart;
|
||||
sample->m_nLoopEnd = m_sQueueSample.m_nLoopEnd;
|
||||
sample->m_bEmittingVolume = m_sQueueSample.m_bEmittingVolume;
|
||||
sample->field_48 = m_sQueueSample.field_48;
|
||||
sample->m_fSoundIntensity = m_sQueueSample.m_fSoundIntensity;
|
||||
sample->field_56 = m_sQueueSample.field_56;
|
||||
sample->m_vecPos = m_sQueueSample.m_vecPos;
|
||||
sample->m_bReverbFlag = m_sQueueSample.m_bReverbFlag;
|
||||
sample->m_bLoopsRemaining = m_sQueueSample.m_bLoopsRemaining;
|
||||
sample->m_bRequireReflection = m_sQueueSample.m_bRequireReflection;
|
||||
sample->m_bOffset = m_sQueueSample.m_bOffset;
|
||||
sample->field_76 = m_sQueueSample.field_76;
|
||||
sample->m_bIsProcessed = m_sQueueSample.m_bIsProcessed;
|
||||
sample->m_bLoopEnded = m_sQueueSample.m_bLoopEnded;
|
||||
sample->calculatedVolume = m_sQueueSample.calculatedVolume;
|
||||
sample->field_88 = m_sQueueSample.field_88;
|
||||
|
||||
AddDetailsToRequestedOrderList(unknown2);
|
||||
if(bReflections) AddReflectionsToRequestedQueue();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cAudioManager::AddDetailsToRequestedOrderList(uint8 sample)
|
||||
{
|
||||
int32 offset;
|
||||
uint32 i = 0;
|
||||
if(sample != 0) {
|
||||
for(; i < sample; i++) {
|
||||
offset = 27 * m_bActiveSampleQueue;
|
||||
if(m_asSamples[offset + m_abSampleQueueIndexTable[i + offset]]
|
||||
.calculatedVolume > m_asSamples[offset + sample].calculatedVolume)
|
||||
break;
|
||||
}
|
||||
if(i < sample) {
|
||||
memmove(&m_abSampleQueueIndexTable[offset + 1 + i],
|
||||
&m_abSampleQueueIndexTable[offset + i], m_bActiveSamples - i - 1);
|
||||
}
|
||||
}
|
||||
m_abSampleQueueIndexTable[27 * m_bActiveSampleQueue + i] = sample;
|
||||
}
|
||||
|
||||
void
|
||||
cAudioManager::AddReflectionsToRequestedQueue()
|
||||
{
|
||||
float reflectionDistance;
|
||||
int32 noise;
|
||||
uint8 emittingVolume = emittingVolume =
|
||||
(m_sQueueSample.m_bVolume >> 1) + (m_sQueueSample.m_bVolume >> 3);
|
||||
|
||||
for(uint32 i = 0; i < 5u; i++) {
|
||||
reflectionDistance = m_afReflectionsDistances[i];
|
||||
if(reflectionDistance > 0.0f && reflectionDistance < 100.f &&
|
||||
reflectionDistance < m_sQueueSample.m_fSoundIntensity) {
|
||||
m_sQueueSample.m_bLoopsRemaining = (reflectionDistance * 0.38873f); // @todo assert value
|
||||
if(m_sQueueSample.m_bLoopsRemaining > 5u) {
|
||||
m_sQueueSample.m_fDistance = m_afReflectionsDistances[i];
|
||||
m_sQueueSample.m_bEmittingVolume = emittingVolume;
|
||||
m_sQueueSample.m_bVolume =
|
||||
ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity,
|
||||
m_sQueueSample.m_fDistance);
|
||||
if(m_sQueueSample.m_bVolume > emittingVolume >> 4) {
|
||||
m_sQueueSample.field_4 += ((i + 1) << 8);
|
||||
if(m_sQueueSample.m_nLoopCount) {
|
||||
noise = RandomDisplacement(
|
||||
m_sQueueSample.m_nFrequency >> 5);
|
||||
if(noise <= 0)
|
||||
m_sQueueSample.m_nFrequency += noise;
|
||||
else
|
||||
m_sQueueSample.m_nFrequency -= noise;
|
||||
}
|
||||
m_sQueueSample.field_16 += 20;
|
||||
m_sQueueSample.m_vecPos.x = m_avecReflectionsPos[i].x;
|
||||
m_sQueueSample.m_vecPos.y = m_avecReflectionsPos[i].y;
|
||||
m_sQueueSample.m_vecPos.z = m_avecReflectionsPos[i].z;
|
||||
AddSampleToRequestedQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32
|
||||
cAudioManager::ComputeVolume(int emittingVolume, float soundIntensity, float distance)
|
||||
{
|
||||
float newSoundIntensity;
|
||||
if(soundIntensity <= 0.0f) return 0;
|
||||
if((soundIntensity * 0.2f) <= distance) {
|
||||
newSoundIntensity = soundIntensity * 0.2f;
|
||||
emittingVolume =
|
||||
sq((soundIntensity - distance) / (soundIntensity - newSoundIntensity)) *
|
||||
emittingVolume;
|
||||
}
|
||||
return emittingVolume;
|
||||
}
|
||||
|
||||
void
|
||||
cAudioManager::Initialise()
|
||||
{
|
||||
if(!m_bIsInitialised) {
|
||||
PreInitialiseGameSpecificSetup();
|
||||
m_bIsInitialised = cSampleManager.Initialise();
|
||||
if(m_bIsInitialised) {
|
||||
m_bActiveSamples = cSampleManager.GetActiveSamples();
|
||||
if(m_bActiveSamples <= 1u) {
|
||||
Terminate();
|
||||
} else {
|
||||
--m_bActiveSamples;
|
||||
PostInitialiseGameSpecificSetup();
|
||||
InitialisePoliceRadioZones();
|
||||
InitialisePoliceRadio();
|
||||
MusicManager.Initialise();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cAudioManager::PostInitialiseGameSpecificSetup()
|
||||
{
|
||||
m_nFireAudioEntity = CreateEntity(
|
||||
AUDIOTYPE_FIRE, (CPhysical *)0x8F31D0); // last is addr of firemanager @todo change
|
||||
if(m_nFireAudioEntity >= 0) cAudioManager::SetEntityStatus(m_nFireAudioEntity, 1);
|
||||
|
||||
m_nCollisionEntity = CreateEntity(AUDIOTYPE_COLLISION, (CPhysical *)1);
|
||||
if(m_nCollisionEntity >= 0) cAudioManager::SetEntityStatus(m_nCollisionEntity, 1);
|
||||
|
||||
m_nFrontEndEntity = CreateEntity(AUDIOTYPE_FRONTEND, (CPhysical *)1);
|
||||
if(m_nFrontEndEntity >= 0) cAudioManager::SetEntityStatus(m_nFrontEndEntity, 1);
|
||||
|
||||
m_nProjectileEntity = CreateEntity(AUDIOTYPE_PROJECTILE, (CPhysical *)1);
|
||||
if(m_nProjectileEntity >= 0) cAudioManager::SetEntityStatus(m_nProjectileEntity, 1);
|
||||
|
||||
m_nWaterCannonEntity = CreateEntity(AUDIOTYPE_WATER_CANNON, (CPhysical *)1);
|
||||
if(m_nWaterCannonEntity >= 0) cAudioManager::SetEntityStatus(m_nWaterCannonEntity, 1);
|
||||
|
||||
m_nPoliceChannelEntity = CreateEntity(AUDIOTYPE_D, (CPhysical *)1);
|
||||
if(m_nPoliceChannelEntity >= 0) cAudioManager::SetEntityStatus(m_nPoliceChannelEntity, 1);
|
||||
|
||||
m_nBridgeEntity = CreateEntity(AUDIOTYPE_BRIDGE, (CPhysical *)1);
|
||||
if(m_nBridgeEntity >= 0) cAudioManager::SetEntityStatus(m_nBridgeEntity, 1);
|
||||
|
||||
m_sMissionAudio.m_nSampleIndex = NO_SAMPLE;
|
||||
m_sMissionAudio.m_bLoadingStatus = 0;
|
||||
m_sMissionAudio.m_bPlayStatus = 0;
|
||||
m_sMissionAudio.field_22 = 0;
|
||||
m_sMissionAudio.m_bIsPlayed = 0;
|
||||
m_sMissionAudio.field_12 = 1;
|
||||
m_sMissionAudio.field_24 = 0;
|
||||
ResetAudioLogicTimers((int32)CTimer::GetTimeInMilliseconds);
|
||||
}
|
||||
|
||||
WRAPPER
|
||||
void
|
||||
cAudioManager::InitialisePoliceRadioZones()
|
||||
{
|
||||
EAXJMP(0x57EAC0);
|
||||
}
|
||||
|
||||
WRAPPER
|
||||
void
|
||||
cAudioManager::ResetAudioLogicTimers(int32 timer)
|
||||
{
|
||||
EAXJMP(0x569650);
|
||||
}
|
||||
|
||||
void
|
||||
cAudioManager::Terminate()
|
||||
{
|
||||
if(m_bIsInitialised) {
|
||||
MusicManager.Terminate();
|
||||
|
||||
for(uint32 i = 0; i < totalAudioEntitiesSlots; i++) {
|
||||
m_asAudioEntities[i].m_bIsUsed = 0;
|
||||
m_anAudioEntityIndices[i] = 200;
|
||||
}
|
||||
|
||||
m_nAudioEntitiesTotal = 0;
|
||||
m_nScriptObjectEntityTotal = 0;
|
||||
PreTerminateGameSpecificShutdown();
|
||||
|
||||
for(uint32 i = 0; i < 2; i++) {
|
||||
if(cSampleManager.IsSampleBankLoaded(i)) cSampleManager.UnloadSampleBank(i);
|
||||
}
|
||||
|
||||
cSampleManager.Terminate();
|
||||
|
||||
m_bIsInitialised = 0;
|
||||
PostTerminateGameSpecificShutdown();
|
||||
}
|
||||
}
|
||||
|
||||
char
|
||||
cAudioManager::GetMissionScriptPoliceAudioPlayingStatus()
|
||||
{
|
||||
@ -205,7 +445,7 @@ void
|
||||
cAudioManager::CalculateDistance(bool *ptr, float dist)
|
||||
{
|
||||
if(*ptr == false) {
|
||||
m_sQueueSample.m_fDistance = sqrt(dist);
|
||||
m_sQueueSample.m_fDistance = Sqrt(dist);
|
||||
*ptr = true;
|
||||
}
|
||||
}
|
||||
@ -313,20 +553,16 @@ cAudioManager::ResetPoliceRadio()
|
||||
void
|
||||
cAudioManager::InterrogateAudioEntities()
|
||||
{
|
||||
int32 i = 0;
|
||||
int32 next;
|
||||
|
||||
while(i < m_nAudioEntitiesTotal) {
|
||||
for(int32 i = 0; i < m_nAudioEntitiesTotal; i++) {
|
||||
ProcessEntity(m_anAudioEntityIndices[i]);
|
||||
next = m_anAudioEntityIndices[i++];
|
||||
m_asAudioEntities[next].field_24 = 0;
|
||||
m_asAudioEntities[m_anAudioEntityIndices[i]].field_24 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cAudioManager::ClearRequestedQueue()
|
||||
{
|
||||
for(uint32 i = 0; i < m_bActiveSamples; i++) {
|
||||
for(int32 i = 0; i < m_bActiveSamples; i++) {
|
||||
m_abSampleQueueIndexTable[i + 27 * m_bActiveSampleQueue] = m_bActiveSamples;
|
||||
}
|
||||
m_bSampleRequestQueuesStatus[m_bActiveSampleQueue] = 0;
|
||||
@ -340,14 +576,14 @@ cAudioManager::ClearRequestedQueue()
|
||||
bool
|
||||
cAudioManager::UsesReverseWarning(int32 model)
|
||||
{
|
||||
return model == LINERUN || fabs(model - FIRETRUK) <= 1 || model == BUS ||
|
||||
return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS ||
|
||||
model == COACH; // fix
|
||||
}
|
||||
|
||||
bool
|
||||
cAudioManager::HasAirBrakes(int32 model)
|
||||
{
|
||||
return model == LINERUN || fabs(model - FIRETRUK) <= 1 || model == BUS ||
|
||||
return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS ||
|
||||
model == COACH; // fix
|
||||
}
|
||||
|
||||
@ -436,7 +672,7 @@ cAudioManager::RandomDisplacement(uint32 seed)
|
||||
int32 value;
|
||||
|
||||
static bool bIsEven = true;
|
||||
static uint8 base = 0;
|
||||
static uint32 base = 0;
|
||||
|
||||
if(!seed) return 0;
|
||||
|
||||
@ -473,17 +709,17 @@ cAudioManager::IsAudioInitialised() const
|
||||
}
|
||||
|
||||
int32
|
||||
cAudioManager::CreateEntity(int32 type, CPhysical *memory)
|
||||
cAudioManager::CreateEntity(int32 type, CPhysical *entity)
|
||||
{
|
||||
if(!m_bIsInitialised) return -4;
|
||||
if(!memory) return -2;
|
||||
if(!entity) return -2;
|
||||
if(type >= TOTAL_AUDIO_TYPES) return -1;
|
||||
for(uint32 i = 0; i < 200; i++) {
|
||||
if(!m_asAudioEntities[i].m_bIsUsed) {
|
||||
m_asAudioEntities[i].m_bIsUsed = true;
|
||||
m_asAudioEntities[i].m_bStatus = 0;
|
||||
m_asAudioEntities[i].m_nType = (eAudioType)type;
|
||||
m_asAudioEntities[i].m_pEntity = memory;
|
||||
m_asAudioEntities[i].m_pEntity = entity;
|
||||
m_asAudioEntities[i].m_awAudioEvent[0] = SOUND_TOTAL_PED_SOUNDS;
|
||||
m_asAudioEntities[i].m_awAudioEvent[1] = SOUND_TOTAL_PED_SOUNDS;
|
||||
m_asAudioEntities[i].m_awAudioEvent[2] = SOUND_TOTAL_PED_SOUNDS;
|
||||
@ -502,7 +738,7 @@ cAudioManager::DestroyEntity(int32 id)
|
||||
if(m_bIsInitialised && id >= 0 && id < totalAudioEntitiesSlots &&
|
||||
m_asAudioEntities[id].m_bIsUsed) {
|
||||
m_asAudioEntities[id].m_bIsUsed = 0;
|
||||
for(uint32 i = 0; i < m_nAudioEntitiesTotal; ++i) {
|
||||
for(int32 i = 0; i < m_nAudioEntitiesTotal; ++i) {
|
||||
if(id == m_anAudioEntityIndices[i]) {
|
||||
if(i < totalAudioEntitiesSlots - 1)
|
||||
memmove(&m_anAudioEntityIndices[i],
|
||||
@ -2724,6 +2960,17 @@ cAudioManager::Service()
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x57B070, &cAudioManager::AddSampleToRequestedQueue, PATCH_JUMP);
|
||||
InjectHook(0x57B210, &cAudioManager::AddDetailsToRequestedOrderList, PATCH_JUMP);
|
||||
InjectHook(0x57B300, &cAudioManager::AddReflectionsToRequestedQueue, PATCH_JUMP);
|
||||
InjectHook(0x57ABB0, &cAudioManager::ComputeVolume, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x57A0E0, &cAudioManager::Initialise, PATCH_JUMP);
|
||||
InjectHook(0x569420, &cAudioManager::PostInitialiseGameSpecificSetup, PATCH_JUMP);
|
||||
//InjectHook(0x57EAC0, &cAudioManager::InitialisePoliceRadioZones, PATCH_JUMP);
|
||||
//InjectHook(0x569650, &cAudioManager::ResetAudioLogicTimers, PATCH_JUMP);
|
||||
InjectHook(0x57A150, &cAudioManager::Terminate, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x57F050, &cAudioManager::GetMissionScriptPoliceAudioPlayingStatus, PATCH_JUMP);
|
||||
InjectHook(0x5795D0, &cAudioManager::GetMissionAudioLoadingStatus, PATCH_JUMP);
|
||||
|
||||
|
@ -44,7 +44,7 @@ public:
|
||||
char m_bLoopEnded;
|
||||
char field_82;
|
||||
char field_83;
|
||||
int field_84;
|
||||
int calculatedVolume;
|
||||
char field_88;
|
||||
char field_89;
|
||||
char field_90;
|
||||
@ -218,6 +218,20 @@ public:
|
||||
char field_19195;
|
||||
int m_nTimeOfRecentCrime;
|
||||
|
||||
void AddSampleToRequestedQueue();
|
||||
|
||||
void AddDetailsToRequestedOrderList(uint8 sample);
|
||||
void AddReflectionsToRequestedQueue();
|
||||
|
||||
uint32 ComputeVolume(int emittingVolume, float soundIntensity, float distance);
|
||||
|
||||
void Initialise();
|
||||
void PostInitialiseGameSpecificSetup();
|
||||
void InitialisePoliceRadioZones(); // @todo
|
||||
void ResetAudioLogicTimers(int32 timer); // @todo
|
||||
|
||||
void Terminate();
|
||||
|
||||
char GetMissionScriptPoliceAudioPlayingStatus();
|
||||
bool GetMissionAudioLoadingStatus();
|
||||
|
||||
@ -261,7 +275,7 @@ public:
|
||||
void InterrogateAudioEntities();
|
||||
|
||||
void ClearRequestedQueue();
|
||||
// void AgeCrimes();
|
||||
// void AgeCrimes(); //todo
|
||||
|
||||
bool UsesReverseWarning(int32 model);
|
||||
bool HasAirBrakes(int32 model);
|
||||
@ -274,7 +288,7 @@ public:
|
||||
void ProcessPlane(void *); // todo
|
||||
|
||||
void ClearMissionAudio();
|
||||
// void ProcessReverb();
|
||||
// void ProcessReverb(); // todo
|
||||
|
||||
bool IsMissionAudioSampleFinished();
|
||||
|
||||
@ -282,8 +296,6 @@ public:
|
||||
|
||||
void InitialisePoliceRadio();
|
||||
|
||||
// done
|
||||
|
||||
int32 RandomDisplacement(uint32 seed);
|
||||
|
||||
void ReleaseDigitalHandle();
|
||||
@ -292,7 +304,7 @@ public:
|
||||
|
||||
bool IsAudioInitialised() const;
|
||||
|
||||
int32 CreateEntity(int32 type, CPhysical *memory);
|
||||
int32 CreateEntity(int32 type, CPhysical *entity);
|
||||
void DestroyEntity(int32 id);
|
||||
void SetEntityStatus(int32 id, bool status);
|
||||
|
||||
|
@ -19,7 +19,7 @@ WRAPPER void cDMAudio::ChangeMusicMode(uint8 mode) { EAXJMP(0x57CCF0); }
|
||||
WRAPPER void cDMAudio::PlayFrontEndSound(uint32, uint32) { EAXJMP(0x57CC20); }
|
||||
WRAPPER void cDMAudio::PlayFrontEndTrack(uint32, uint32) { EAXJMP(0x57CC80); }
|
||||
WRAPPER void cDMAudio::StopFrontEndTrack() { EAXJMP(0x57CCB0); }
|
||||
WRAPPER void cDMAudio::PlayOneShot(int32, uint16, float) { EAXJMP(0x57C840); }
|
||||
WRAPPER void cDMAudio::PlayOneShot(int32 audioentity, uint16 sound/*eSound*/, float) { EAXJMP(0x57C840); }
|
||||
WRAPPER void cDMAudio::SetMusicMasterVolume(int8) { EAXJMP(0x57C8C0); }
|
||||
WRAPPER void cDMAudio::SetEffectsMasterVolume(int8) { EAXJMP(0x57C890); }
|
||||
WRAPPER int8 cDMAudio::SetCurrent3DProvider(int8) { EAXJMP(0x57C9B0); }
|
||||
|
@ -190,7 +190,7 @@ public:
|
||||
void PlayFrontEndSound(uint32, uint32);
|
||||
void PlayFrontEndTrack(uint32, uint32);
|
||||
void StopFrontEndTrack();
|
||||
void PlayOneShot(int32, uint16, float);
|
||||
void PlayOneShot(int32 audioentity, uint16 sound/*eSound*/, float);
|
||||
void SetMusicMasterVolume(int8);
|
||||
void SetEffectsMasterVolume(int8);
|
||||
int8 SetCurrent3DProvider(int8);
|
||||
|
@ -174,3 +174,17 @@ void cMusicManager::DisplayRadioStationName()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
WRAPPER
|
||||
void
|
||||
cMusicManager::Initialise()
|
||||
{
|
||||
EAXJMP(0x57CF70);
|
||||
}
|
||||
|
||||
WRAPPER
|
||||
void
|
||||
cMusicManager::Terminate()
|
||||
{
|
||||
EAXJMP(0x57D140);
|
||||
}
|
||||
|
@ -264,6 +264,9 @@ public:
|
||||
uint8 field_2395;
|
||||
|
||||
public:
|
||||
void Initialise();
|
||||
void Terminate();
|
||||
|
||||
char *Get3DProviderName(char);
|
||||
bool PlayerInCar();
|
||||
void DisplayRadioStationName();
|
||||
|
@ -12,6 +12,33 @@ bool CSampleManager::IsMP3RadioChannelAvailable() {
|
||||
return nNumOfMp3Files != 0;
|
||||
}
|
||||
|
||||
WRAPPER
|
||||
bool CSampleManager::IsSampleBankLoaded(uint8) { EAXJMP(0x567130); }
|
||||
|
||||
WRAPPER
|
||||
void CSampleManager::UnloadSampleBank(uint8) { EAXJMP(0x567110); }
|
||||
|
||||
WRAPPER
|
||||
void
|
||||
CSampleManager::Terminate()
|
||||
{
|
||||
EAXJMP(0x566DC0);
|
||||
}
|
||||
|
||||
WRAPPER
|
||||
bool
|
||||
CSampleManager::Initialise()
|
||||
{
|
||||
EAXJMP(0x566530);
|
||||
}
|
||||
|
||||
WRAPPER
|
||||
int32
|
||||
CSampleManager::GetActiveSamples()
|
||||
{
|
||||
EAXJMP(0x565970);
|
||||
}
|
||||
|
||||
WRAPPER void
|
||||
CSampleManager::ReleaseDigitalHandle()
|
||||
{
|
||||
@ -87,6 +114,7 @@ CSampleManager::StopChannel(int32 id)
|
||||
{
|
||||
EAXJMP(0x567BE0);
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x566490, CSampleManager::IsMP3RadioChannelAvailable, PATCH_JUMP);
|
||||
ENDPATCHES
|
@ -11,6 +11,13 @@ struct tSample {
|
||||
class CSampleManager
|
||||
{
|
||||
public:
|
||||
bool IsSampleBankLoaded(uint8);
|
||||
void UnloadSampleBank(uint8);
|
||||
void Terminate();
|
||||
|
||||
bool Initialise();
|
||||
int32 GetActiveSamples();
|
||||
|
||||
void ReleaseDigitalHandle();
|
||||
void RequireDigitalHandle();
|
||||
|
||||
|
@ -59,9 +59,9 @@ enum eCarDrivingStyle : uint8
|
||||
|
||||
class CAutoPilot {
|
||||
public:
|
||||
void *m_currentAddress;
|
||||
void *m_startingRouteNode;
|
||||
void *m_PreviousRouteNode;
|
||||
uint32 m_nCurrentRouteNode;
|
||||
uint32 m_nNextRouteNode;
|
||||
uint32 m_nPrevRouteNode;
|
||||
uint32 m_nTotalSpeedScaleFactor;
|
||||
uint32 m_nSpeedScaleFactor;
|
||||
uint32 m_nCurrentPathNodeInfo;
|
||||
@ -80,10 +80,41 @@ public:
|
||||
uint8 m_nAnimationTime;
|
||||
float m_fMaxTrafficSpeed;
|
||||
uint8 m_nCruiseSpeed;
|
||||
uint8 m_nCarCtrlFlags;
|
||||
uint8 m_flag1 : 1;
|
||||
uint8 m_flag2 : 1;
|
||||
uint8 m_flag4 : 1;
|
||||
uint8 m_flag8 : 1;
|
||||
uint8 m_flag10 : 1;
|
||||
CVector m_vecDestinationCoors;
|
||||
void *m_aPathFindNodesInfo[8];
|
||||
uint16 m_nPathFindNodesCount;
|
||||
CVehicle *m_pTargetCar;
|
||||
|
||||
CAutoPilot(void) {
|
||||
m_nPrevRouteNode = 0;
|
||||
m_nNextRouteNode = m_nPrevRouteNode;
|
||||
m_nCurrentRouteNode = m_nNextRouteNode;
|
||||
m_nTotalSpeedScaleFactor = 0;
|
||||
m_nSpeedScaleFactor = 1000;
|
||||
m_nPreviousPathNodeInfo = 0;
|
||||
m_nNextPathNodeInfo = m_nPreviousPathNodeInfo;
|
||||
m_nCurrentPathNodeInfo = m_nNextPathNodeInfo;
|
||||
m_nNextDirection = 1;
|
||||
m_nCurrentDirecton = m_nNextDirection;
|
||||
m_nCurrentPathDirection = 0;
|
||||
m_nPreviousPathDirection = m_nCurrentPathDirection;
|
||||
m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
|
||||
m_nCarMission = MISSION_NONE;
|
||||
m_nAnimationId = TEMPACT_NONE;
|
||||
m_nCruiseSpeed = 10;
|
||||
m_fMaxTrafficSpeed = 10.0f;
|
||||
m_flag2 = false;
|
||||
m_flag1 = false;
|
||||
m_nPathFindNodesCount = 0;
|
||||
m_pTargetCar = 0;
|
||||
m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
|
||||
m_nTimeSwitchedToRealPhysics = m_nTimeToStartMission;
|
||||
m_flag8 = false;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(CAutoPilot) == 0x70, "CAutoPilot: error");
|
||||
|
@ -1,12 +1,338 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "main.h"
|
||||
#include "Darkel.h"
|
||||
#include "Timer.h"
|
||||
#include "DMAudio.h"
|
||||
#include "Population.h"
|
||||
#include "Weapon.h"
|
||||
#include "World.h"
|
||||
#include "PlayerPed.h"
|
||||
#include "Stats.h"
|
||||
#include "Font.h"
|
||||
#include "Text.h"
|
||||
|
||||
int32 &CDarkel::TimeLimit = *(int32*)0x885BAC;
|
||||
int32 &CDarkel::PreviousTime = *(int32*)0x885B00;
|
||||
int32 &CDarkel::TimeOfFrenzyStart = *(int32*)0x9430D8;
|
||||
int32 &CDarkel::WeaponType = *(int32*)0x9430F0;
|
||||
int32 &CDarkel::AmmoInterruptedWeapon = *(int32*)0x8E29C8;
|
||||
int32 &CDarkel::KillsNeeded = *(int32*)0x8F1AB8;
|
||||
int8 &CDarkel::InterruptedWeapon = *(int8*)0x95CD60;
|
||||
int8 &CDarkel::bStandardSoundAndMessages = *(int8*)0x95CDB6;
|
||||
int8 &CDarkel::bNeedHeadShot = *(int8*)0x95CDCA;
|
||||
int8 &CDarkel::bProperKillFrenzy = *(int8*)0x95CD98;
|
||||
eKillFrenzyStatus &CDarkel::Status = *(eKillFrenzyStatus*)0x95CCB4;
|
||||
int16 *CDarkel::RegisteredKills = (int16*)0x6EDBE0;
|
||||
int32 &CDarkel::ModelToKill = *(int32*)0x8F2C78;
|
||||
int32 &CDarkel::ModelToKill2 = *(int32*)0x885B40;
|
||||
int32 &CDarkel::ModelToKill3 = *(int32*)0x885B3C;
|
||||
int32 &CDarkel::ModelToKill4 = *(int32*)0x885B34;
|
||||
wchar *CDarkel::pStartMessage = (wchar*)0x8F2C08;
|
||||
|
||||
int32 CDarkel::CalcFade(uint32 time, int32 start, uint32 end) {
|
||||
if (time >= start && time <= end) {
|
||||
if (time >= start + 500) {
|
||||
if (time <= end - 500)
|
||||
return 255;
|
||||
else
|
||||
return 255 * (end - time) / 500;
|
||||
}
|
||||
else
|
||||
return 255 * (time - start) / 500;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This function has been cleaned up from unused stuff.
|
||||
#if 0
|
||||
WRAPPER void CDarkel::DrawMessages(void) { EAXJMP(0x420920); }
|
||||
#else
|
||||
void CDarkel::DrawMessages()
|
||||
{
|
||||
bool DisplayTimers = false;
|
||||
|
||||
switch (Status) {
|
||||
case KILLFRENZY_ONGOING:
|
||||
assert(pStartMessage != nil);
|
||||
DisplayTimers = true;
|
||||
break;
|
||||
case KILLFRENZY_PASSED:
|
||||
case KILLFRENZY_FAILED:
|
||||
DisplayTimers = false;
|
||||
break;
|
||||
};
|
||||
|
||||
if (DisplayTimers) {
|
||||
CFont::SetPropOn();
|
||||
CFont::SetBackgroundOff();
|
||||
CFont::SetBackGroundOnlyTextOn();
|
||||
CFont::SetAlignment(ALIGN_RIGHT);
|
||||
CFont::SetRightJustifyWrap(-SCREEN_WIDTH);
|
||||
CFont::SetFontStyle(FONT_HEADING);
|
||||
CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
|
||||
|
||||
float AlignToHUD = SCREEN_SCALE_X(-10.0f);
|
||||
int32 a = (TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart));
|
||||
if (CTimer::GetFrameCounter() & 8 || a > 4000) {
|
||||
sprintf(gString, "%d:%02d", a / 60000, a % 60000 / 1000);
|
||||
AsciiToUnicode(gString, gUString);
|
||||
CFont::SetColor(CRGBA(0, 0, 0, 255));
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(25.0f) + AlignToHUD, SCREEN_SCALE_Y(112.0f), gUString);
|
||||
|
||||
CFont::SetColor(CRGBA(150, 100, 255, 255));
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(27.0f) + AlignToHUD, SCREEN_SCALE_Y(110.0f), gUString);
|
||||
}
|
||||
|
||||
if (KillsNeeded <= 0)
|
||||
KillsNeeded = 0;
|
||||
|
||||
sprintf((char *)gString, "%d", KillsNeeded);
|
||||
AsciiToUnicode(gString, gUString);
|
||||
|
||||
CFont::SetColor(CRGBA(0, 0, 0, 255));
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(25.0f) + AlignToHUD, SCREEN_SCALE_Y(134.0f), gUString);
|
||||
|
||||
CFont::SetColor(CRGBA(255, 128, 128, 255));
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(27.0f) + AlignToHUD, SCREEN_SCALE_Y(132.0f), gUString);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void CDarkel::Init()
|
||||
{
|
||||
Status = KILLFRENZY_NONE;
|
||||
}
|
||||
|
||||
int16 CDarkel::QueryModelsKilledByPlayer(int32 modelId)
|
||||
{
|
||||
return RegisteredKills[modelId];
|
||||
}
|
||||
|
||||
bool CDarkel::Status = *(bool*)0x95CCB4;
|
||||
|
||||
bool CDarkel::FrenzyOnGoing()
|
||||
{
|
||||
return Status == 1;
|
||||
}
|
||||
return Status == KILLFRENZY_ONGOING;
|
||||
}
|
||||
|
||||
|
||||
eKillFrenzyStatus CDarkel::ReadStatus()
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
#if 1
|
||||
WRAPPER void CDarkel::RegisterCarBlownUpByPlayer(CVehicle *vehicle) { EAXJMP(0x421070); }
|
||||
#else
|
||||
int32 CDarkel::RegisterCarBlownUpByPlayer(CVehicle *vehicle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
WRAPPER void CDarkel::RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot) { EAXJMP(0x420F60); }
|
||||
#else
|
||||
void CDarkel::RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void CDarkel::RegisterKillNotByPlayer()
|
||||
{
|
||||
++CStats::NumberKillFrenziesPassed;
|
||||
}
|
||||
|
||||
void CDarkel::ResetModelsKilledByPlayer()
|
||||
{
|
||||
for (int i = 0; i < 200; i++)
|
||||
RegisteredKills[i] = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
WRAPPER void CDarkel::ResetOnPlayerDeath() { EAXJMP(0x420E70); }
|
||||
#else
|
||||
void CDarkel::ResetOnPlayerDeath()
|
||||
{
|
||||
if (Status != KILLFRENZY_ONGOING)
|
||||
return;
|
||||
|
||||
CPopulation::m_AllRandomPedsThisType = -1;
|
||||
Status = KILLFRENZY_FAILED;
|
||||
TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds();
|
||||
|
||||
if (WeaponType == WEAPONTYPE_UZI_DRIVEBY)
|
||||
WeaponType = WEAPONTYPE_UZI;
|
||||
|
||||
if (WeaponType < WEAPONTYPE_TOTALWEAPONS) {
|
||||
FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon;
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon;
|
||||
}
|
||||
|
||||
if (FindPlayerVehicle()) {
|
||||
FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId);
|
||||
FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType;
|
||||
FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon);
|
||||
}
|
||||
|
||||
|
||||
CPopulation::m_AllRandomPedsThisType = -1;
|
||||
Status = KILLFRENZY_FAILED;
|
||||
TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds();
|
||||
|
||||
if (WeaponType == WEAPONTYPE_UZI_DRIVEBY)
|
||||
WeaponType = WEAPONTYPE_UZI;
|
||||
|
||||
if (WeaponType < WEAPONTYPE_TOTALWEAPONS) {
|
||||
FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon;
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon;
|
||||
}
|
||||
|
||||
if (FindPlayerVehicle()) {
|
||||
FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId);
|
||||
FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType;
|
||||
FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
WRAPPER void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot) { EAXJMP(0x4210E0); }
|
||||
#else
|
||||
void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot)
|
||||
{
|
||||
if (weaponType == WEAPONTYPE_UZI_DRIVEBY)
|
||||
weaponType = WEAPONTYPE_UZI;
|
||||
|
||||
WeaponType = weaponType;
|
||||
Status = KILLFRENZY_ONGOING;
|
||||
KillsNeeded = kill;
|
||||
ModelToKill = modelId0;
|
||||
ModelToKill2 = modelId2;
|
||||
ModelToKill3 = modelId3;
|
||||
ModelToKill4 = modelId4;
|
||||
pStartMessage = text;
|
||||
|
||||
if (text == TheText.Get("PAGE_00")) {
|
||||
CDarkel::bProperKillFrenzy = 1;
|
||||
CDarkel::pStartMessage = 0;
|
||||
}
|
||||
else
|
||||
bProperKillFrenzy = 0;
|
||||
|
||||
bStandardSoundAndMessages = standardSound;
|
||||
bNeedHeadShot = needHeadShot;
|
||||
TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds();
|
||||
TimeLimit = time;
|
||||
PreviousTime = time / 1000;
|
||||
|
||||
if (weaponType < WEAPONTYPE_TOTALWEAPONS) {
|
||||
InterruptedWeapon = FindPlayerPed()->m_currentWeapon;
|
||||
FindPlayerPed()->GiveWeapon(weaponType, 0);
|
||||
AmmoInterruptedWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal;
|
||||
FindPlayerPed()->GiveWeapon(weaponType, 30000);
|
||||
FindPlayerPed()->m_bWeaponSlot = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType;
|
||||
FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_bWeaponSlot);
|
||||
|
||||
if (FindPlayerVehicle()) {
|
||||
FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType;
|
||||
if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal <= CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoInClip)
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoInClip = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal;
|
||||
|
||||
FindPlayerPed()->ClearWeaponTarget();
|
||||
}
|
||||
}
|
||||
if (CDarkel::bStandardSoundAndMessages)
|
||||
DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_START, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void CDarkel::Update()
|
||||
{
|
||||
if (Status != KILLFRENZY_ONGOING)
|
||||
return;
|
||||
|
||||
int32 FrameTime = TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart);
|
||||
if ((TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart)) > 0 || TimeLimit < 0) {
|
||||
DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_ONGOING, FrameTime);
|
||||
|
||||
int32 PrevTime = FrameTime / 1000;
|
||||
|
||||
if (PrevTime != PreviousTime) {
|
||||
if (PreviousTime < 12)
|
||||
DMAudio.PlayFrontEndSound(SOUND_CLOCK_TICK, PrevTime);
|
||||
PreviousTime = PrevTime;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
CPopulation::m_AllRandomPedsThisType = -1;
|
||||
Status = KILLFRENZY_FAILED;
|
||||
TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds();
|
||||
|
||||
if (WeaponType == WEAPONTYPE_UZI_DRIVEBY)
|
||||
WeaponType = WEAPONTYPE_UZI;
|
||||
|
||||
if (WeaponType < WEAPONTYPE_TOTALWEAPONS) {
|
||||
FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon;
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon;
|
||||
}
|
||||
|
||||
if (FindPlayerVehicle()) {
|
||||
FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId);
|
||||
FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType;
|
||||
FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon);
|
||||
}
|
||||
|
||||
if (bStandardSoundAndMessages)
|
||||
DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_FAILED, 0);
|
||||
}
|
||||
|
||||
if (KillsNeeded <= 0) {
|
||||
CPopulation::m_AllRandomPedsThisType = -1;
|
||||
Status = KILLFRENZY_PASSED;
|
||||
|
||||
if (bProperKillFrenzy)
|
||||
CStats::AnotherKillFrenzyPassed();
|
||||
|
||||
TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds();
|
||||
|
||||
FindPlayerPed()->m_pWanted->SetWantedLevel(NOTWANTED);
|
||||
|
||||
if (WeaponType == WEAPONTYPE_UZI_DRIVEBY)
|
||||
WeaponType = WEAPONTYPE_UZI;
|
||||
|
||||
if (WeaponType < WEAPONTYPE_TOTALWEAPONS) {
|
||||
FindPlayerPed()->m_bWeaponSlot = InterruptedWeapon;
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon;
|
||||
}
|
||||
|
||||
if (FindPlayerVehicle()) {
|
||||
FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId);
|
||||
FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType;
|
||||
FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon);
|
||||
}
|
||||
|
||||
if (bStandardSoundAndMessages)
|
||||
DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_PASSED, 0);
|
||||
}
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
/*InjectHook(0x421380, CDarkel::CalcFade, PATCH_JUMP);
|
||||
InjectHook(0x420920, CDarkel::DrawMessages, PATCH_JUMP);
|
||||
InjectHook(0x420E60, CDarkel::FrenzyOnGoing, PATCH_JUMP);
|
||||
InjectHook(0x420650, CDarkel::Init, PATCH_JUMP);
|
||||
InjectHook(0x421370, CDarkel::QueryModelsKilledByPlayer, PATCH_JUMP);
|
||||
InjectHook(0x420E50, CDarkel::ReadStatus, PATCH_JUMP);
|
||||
InjectHook(0x421070, CDarkel::RegisterCarBlownUpByPlayer, PATCH_JUMP);
|
||||
InjectHook(0x420F60, CDarkel::RegisterKillByPlayer, PATCH_JUMP);
|
||||
InjectHook(0x421060, CDarkel::RegisterKillNotByPlayer, PATCH_JUMP);
|
||||
InjectHook(0x421310, CDarkel::ResetModelsKilledByPlayer, PATCH_JUMP);
|
||||
InjectHook(0x420E70, CDarkel::ResetOnPlayerDeath, PATCH_JUMP);
|
||||
InjectHook(0x4210E0, CDarkel::StartFrenzy, PATCH_JUMP);
|
||||
InjectHook(0x420660, CDarkel::Update, PATCH_JUMP);*/
|
||||
ENDPATCHES
|
@ -1,11 +1,51 @@
|
||||
#pragma once
|
||||
#include "Weapon.h"
|
||||
|
||||
class CVehicle;
|
||||
class CPed;
|
||||
|
||||
enum eKillFrenzyStatus
|
||||
{
|
||||
KILLFRENZY_NONE,
|
||||
KILLFRENZY_ONGOING,
|
||||
KILLFRENZY_PASSED,
|
||||
KILLFRENZY_FAILED,
|
||||
};
|
||||
|
||||
class CDarkel
|
||||
{
|
||||
private:
|
||||
static bool Status;
|
||||
static int32 &TimeLimit;
|
||||
static int32 &PreviousTime;
|
||||
static int32 &TimeOfFrenzyStart;
|
||||
static int32 &WeaponType;
|
||||
static int32 &AmmoInterruptedWeapon;
|
||||
static int32 &KillsNeeded;
|
||||
static int8 &InterruptedWeapon;
|
||||
static int8 &bStandardSoundAndMessages;
|
||||
static int8 &bNeedHeadShot;
|
||||
static int8 &bProperKillFrenzy;
|
||||
static eKillFrenzyStatus &Status;
|
||||
static int16 *RegisteredKills;
|
||||
static int32 &ModelToKill;
|
||||
static int32 &ModelToKill2;
|
||||
static int32 &ModelToKill3;
|
||||
static int32 &ModelToKill4;
|
||||
static wchar *pStartMessage;
|
||||
|
||||
public:
|
||||
static int32 CalcFade(uint32 time, int32 min, uint32 max);
|
||||
static void DrawMessages(void);
|
||||
static bool FrenzyOnGoing();
|
||||
static void Init();
|
||||
static int16 QueryModelsKilledByPlayer(int32 modelId);
|
||||
static eKillFrenzyStatus ReadStatus();
|
||||
static void RegisterCarBlownUpByPlayer(CVehicle *vehicle);
|
||||
static void RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot = false);
|
||||
static void RegisterKillNotByPlayer();
|
||||
static void ResetModelsKilledByPlayer();
|
||||
static void ResetOnPlayerDeath();
|
||||
static void StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot);
|
||||
static void Update();
|
||||
|
||||
};
|
||||
|
@ -146,8 +146,8 @@ CPathFind::PreparePathData(void)
|
||||
numExtern++;
|
||||
if(InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes > numLanes)
|
||||
numLanes = InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes;
|
||||
maxX = max(maxX, fabs(InfoForTileCars[k].x));
|
||||
maxY = max(maxY, fabs(InfoForTileCars[k].y));
|
||||
maxX = max(maxX, Abs(InfoForTileCars[k].x));
|
||||
maxY = max(maxY, Abs(InfoForTileCars[k].y));
|
||||
}else if(InfoForTileCars[k].type == NodeTypeIntern)
|
||||
numIntern++;
|
||||
}
|
||||
@ -327,10 +327,10 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
|
||||
if(tempnodes[k].linkState != 1)
|
||||
continue;
|
||||
dx = tempnodes[k].pos.x - CoorsXFormed.x;
|
||||
if(fabs(dx) < nearestDist){
|
||||
if(Abs(dx) < nearestDist){
|
||||
dy = tempnodes[k].pos.y - CoorsXFormed.y;
|
||||
if(fabs(dy) < nearestDist){
|
||||
nearestDist = max(fabs(dx), fabs(dy));
|
||||
if(Abs(dy) < nearestDist){
|
||||
nearestDist = max(Abs(dx), Abs(dy));
|
||||
nearestId = k;
|
||||
}
|
||||
}
|
||||
@ -369,7 +369,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
|
||||
dx = m_pathNodes[tempnodes[nearestId].link1].pos.x - m_pathNodes[tempnodes[nearestId].link2].pos.x;
|
||||
dy = m_pathNodes[tempnodes[nearestId].link1].pos.y - m_pathNodes[tempnodes[nearestId].link2].pos.y;
|
||||
tempnodes[nearestId].pos = (tempnodes[nearestId].pos + CoorsXFormed)*0.5f;
|
||||
mag = sqrt(dx*dx + dy*dy);
|
||||
mag = Sqrt(dx*dx + dy*dy);
|
||||
tempnodes[nearestId].dirX = dx/mag;
|
||||
tempnodes[nearestId].dirY = dy/mag;
|
||||
// do something when number of lanes doesn't agree
|
||||
@ -464,7 +464,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
|
||||
posy = (m_pathNodes[i].pos.y + m_pathNodes[j].pos.y)*0.5f;
|
||||
dx = m_pathNodes[j].pos.x - m_pathNodes[i].pos.x;
|
||||
dy = m_pathNodes[j].pos.y - m_pathNodes[i].pos.y;
|
||||
mag = sqrt(dx*dx + dy*dy);
|
||||
mag = Sqrt(dx*dx + dy*dy);
|
||||
dx /= mag;
|
||||
dy /= mag;
|
||||
if(i < j){
|
||||
|
@ -1,6 +1,130 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Phones.h"
|
||||
#include "Pools.h"
|
||||
|
||||
CPhoneInfo &gPhoneInfo = *(CPhoneInfo*)0x732A20;
|
||||
|
||||
bool &CPhoneInfo::isPhonePickedUp = *(bool*)0x6283AC;
|
||||
bool &CPhoneInfo::isPhoneBeingPickedUp = *(bool*)0x6283B4;
|
||||
CPhone *&CPhoneInfo::pickedUpPhone = *(CPhone**)0x6283B0;
|
||||
|
||||
int
|
||||
CPhoneInfo::FindNearestFreePhone(CVector *pos)
|
||||
{
|
||||
int nearestPhoneId = -1;
|
||||
float nearestPhoneDist = 60.0f;
|
||||
|
||||
for (int phoneId = 0; phoneId < m_nMax; phoneId++) {
|
||||
|
||||
if (gPhoneInfo.m_aPhones[phoneId].m_nState == PHONE_STATE_FREE) {
|
||||
float phoneDist = (m_aPhones[phoneId].m_vecPos - *pos).Magnitude2D();
|
||||
|
||||
if (phoneDist < nearestPhoneDist) {
|
||||
nearestPhoneDist = phoneDist;
|
||||
nearestPhoneId = phoneId;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nearestPhoneId;
|
||||
}
|
||||
|
||||
bool
|
||||
CPhoneInfo::PhoneAtThisPosition(CVector pos)
|
||||
{
|
||||
for (int phoneId = 0; phoneId < m_nMax; phoneId++) {
|
||||
if (pos.x == m_aPhones[phoneId].m_vecPos.x && pos.y == m_aPhones[phoneId].m_vecPos.y)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CPhoneInfo::HasMessageBeenDisplayed(int phoneId)
|
||||
{
|
||||
if (isPhonePickedUp)
|
||||
return false;
|
||||
|
||||
int state = m_aPhones[phoneId].m_nState;
|
||||
|
||||
return state == PHONE_STATE_REPEATED_MESSAGE_SHOWN_ONCE ||
|
||||
state == PHONE_STATE_ONETIME_MESSAGE_SHOWN ||
|
||||
state == PHONE_STATE_REPEATED_MESSAGE_SHOWN;
|
||||
}
|
||||
|
||||
bool
|
||||
CPhoneInfo::IsMessageBeingDisplayed(int phoneId)
|
||||
{
|
||||
return pickedUpPhone == &m_aPhones[phoneId];
|
||||
}
|
||||
|
||||
void
|
||||
CPhoneInfo::Load(CPhoneInfo *source, uint8 buffer)
|
||||
{
|
||||
// Buffer isn't used.
|
||||
|
||||
m_nMax = source->m_nMax;
|
||||
m_nNum = source->m_nNum;
|
||||
for (int phoneId = 0; phoneId < 50; phoneId++) {
|
||||
CPhone *phone = &source->m_aPhones[phoneId];
|
||||
|
||||
m_aPhones[phoneId].m_vecPos = phone->m_vecPos;
|
||||
memcpy(m_aPhones[phoneId].m_apMessages, phone->m_apMessages, sizeof(uint16*) * 6);
|
||||
m_aPhones[phoneId].m_pEntity = phone->m_pEntity;
|
||||
m_aPhones[phoneId].m_nState = phone->m_nState;
|
||||
m_aPhones[phoneId].field_30 = phone->field_30;
|
||||
|
||||
if (phone->m_pEntity) {
|
||||
// It's saved as building pool index in save file, convert it to true entity
|
||||
CBuilding *actualEntity = CPools::GetBuildingPool()->GetSlot((int)phone->m_pEntity - 1);
|
||||
m_aPhones[phoneId].m_pEntity = actualEntity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CPhoneInfo::SetPhoneMessage_JustOnce(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6)
|
||||
{
|
||||
// If there is at least one message, it should be msg1.
|
||||
if (msg1) {
|
||||
m_aPhones[phoneId].m_apMessages[0] = msg1;
|
||||
m_aPhones[phoneId].m_apMessages[1] = msg2;
|
||||
m_aPhones[phoneId].m_apMessages[2] = msg3;
|
||||
m_aPhones[phoneId].m_apMessages[3] = msg4;
|
||||
m_aPhones[phoneId].m_apMessages[4] = msg5;
|
||||
m_aPhones[phoneId].m_apMessages[5] = msg6;
|
||||
m_aPhones[phoneId].m_nState = PHONE_STATE_ONETIME_MESSAGE_SET;
|
||||
} else {
|
||||
m_aPhones[phoneId].m_nState = PHONE_STATE_MESSAGE_REMOVED;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CPhoneInfo::SetPhoneMessage_Repeatedly(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6)
|
||||
{
|
||||
// If there is at least one message, it should be msg1.
|
||||
if (msg1) {
|
||||
m_aPhones[phoneId].m_apMessages[0] = msg1;
|
||||
m_aPhones[phoneId].m_apMessages[1] = msg2;
|
||||
m_aPhones[phoneId].m_apMessages[2] = msg3;
|
||||
m_aPhones[phoneId].m_apMessages[3] = msg4;
|
||||
m_aPhones[phoneId].m_apMessages[4] = msg5;
|
||||
m_aPhones[phoneId].m_apMessages[5] = msg6;
|
||||
m_aPhones[phoneId].m_nState = PHONE_STATE_REPEATED_MESSAGE_SET;
|
||||
} else {
|
||||
m_aPhones[phoneId].m_nState = PHONE_STATE_MESSAGE_REMOVED;
|
||||
}
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x42F720, &CPhoneInfo::FindNearestFreePhone, PATCH_JUMP);
|
||||
InjectHook(0x42FD50, &CPhoneInfo::PhoneAtThisPosition, PATCH_JUMP);
|
||||
InjectHook(0x42FFF0, &CPhoneInfo::HasMessageBeenDisplayed, PATCH_JUMP);
|
||||
InjectHook(0x430030, &CPhoneInfo::IsMessageBeingDisplayed, PATCH_JUMP);
|
||||
InjectHook(0x430120, &CPhoneInfo::Load, PATCH_JUMP);
|
||||
InjectHook(0x42FF90, &CPhoneInfo::SetPhoneMessage_JustOnce, PATCH_JUMP);
|
||||
InjectHook(0x42FF30, &CPhoneInfo::SetPhoneMessage_Repeatedly, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
||||
WRAPPER void PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x42F570); }
|
||||
WRAPPER void PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x42F470); }
|
||||
|
@ -1,6 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include "Physical.h"
|
||||
#include "AnimBlendAssociation.h"
|
||||
|
||||
enum {
|
||||
PHONE_STATE_FREE,
|
||||
PHONE_STATE_1,
|
||||
PHONE_STATE_2,
|
||||
PHONE_STATE_MESSAGE_REMOVED,
|
||||
PHONE_STATE_ONETIME_MESSAGE_SET,
|
||||
PHONE_STATE_REPEATED_MESSAGE_SET,
|
||||
PHONE_STATE_REPEATED_MESSAGE_SHOWN_ONCE,
|
||||
PHONE_STATE_ONETIME_MESSAGE_SHOWN,
|
||||
PHONE_STATE_REPEATED_MESSAGE_SHOWN,
|
||||
PHONE_STATE_9
|
||||
};
|
||||
|
||||
struct CPhone
|
||||
{
|
||||
CVector m_vecPos;
|
||||
uint16 *m_apMessages[6];
|
||||
uint32 m_lastTimeRepeatedMsgShown;
|
||||
CEntity *m_pEntity; // it's building pool index in save files
|
||||
int32 m_nState;
|
||||
uint8 field_30;
|
||||
};
|
||||
|
||||
static_assert(sizeof(CPhone) == 0x34, "CPhone: error");
|
||||
|
||||
class CPhoneInfo {
|
||||
static bool &isPhonePickedUp;
|
||||
static bool &isPhoneBeingPickedUp;
|
||||
static CPhone *&pickedUpPhone;
|
||||
public:
|
||||
int32 m_nMax;
|
||||
int32 m_nNum;
|
||||
CPhone m_aPhones[50];
|
||||
|
||||
CPhoneInfo() { }
|
||||
~CPhoneInfo() { }
|
||||
|
||||
int FindNearestFreePhone(CVector*);
|
||||
bool PhoneAtThisPosition(CVector);
|
||||
bool HasMessageBeenDisplayed(int);
|
||||
bool IsMessageBeingDisplayed(int);
|
||||
void Load(CPhoneInfo *source, uint8 buffer);
|
||||
void SetPhoneMessage_JustOnce(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6);
|
||||
void SetPhoneMessage_Repeatedly(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6);
|
||||
};
|
||||
|
||||
extern CPhoneInfo &gPhoneInfo;
|
||||
|
||||
void PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg);
|
||||
void PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg);
|
@ -290,14 +290,14 @@ void CReplay::RecordThisFrame(void)
|
||||
CPed* p = peds->GetSlot(i);
|
||||
if (!p || !p->m_rwObject)
|
||||
continue;
|
||||
if (!p->bRecordedForReplay){
|
||||
if (!p->bHasAlreadyBeenRecorded){
|
||||
tPedHeaderPacket* ph = (tPedHeaderPacket*)&Record.m_pBase[Record.m_nOffset];
|
||||
ph->type = REPLAYPACKET_PED_HEADER;
|
||||
ph->index = i;
|
||||
ph->mi = p->GetModelIndex();
|
||||
ph->pedtype = p->m_nPedType;
|
||||
Record.m_nOffset += sizeof(*ph);
|
||||
p->bRecordedForReplay = true;
|
||||
p->bHasAlreadyBeenRecorded = true;
|
||||
}
|
||||
StorePedUpdate(p, i);
|
||||
}
|
||||
@ -469,7 +469,7 @@ void CReplay::ProcessPedUpdate(CPed *ped, float interpolation, CAddressInReplayB
|
||||
CMatrix ped_matrix;
|
||||
pp->matrix.DecompressIntoFullMatrix(ped_matrix);
|
||||
ped->GetMatrix() = ped->GetMatrix() * CMatrix(1.0f - interpolation);
|
||||
*ped->GetMatrix().GetPosition() *= (1.0f - interpolation);
|
||||
ped->GetMatrix().GetPosition() *= (1.0f - interpolation);
|
||||
ped->GetMatrix() += CMatrix(interpolation) * ped_matrix;
|
||||
if (pp->vehicle_index) {
|
||||
ped->m_pMyVehicle = CPools::GetVehiclePool()->GetSlot(pp->vehicle_index - 1);
|
||||
@ -666,7 +666,7 @@ void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressI
|
||||
CMatrix vehicle_matrix;
|
||||
vp->matrix.DecompressIntoFullMatrix(vehicle_matrix);
|
||||
vehicle->GetMatrix() = vehicle->GetMatrix() * CMatrix(1.0f - interpolation);
|
||||
*vehicle->GetMatrix().GetPosition() *= (1.0f - interpolation);
|
||||
vehicle->GetMatrix().GetPosition() *= (1.0f - interpolation);
|
||||
vehicle->GetMatrix() += CMatrix(interpolation) * vehicle_matrix;
|
||||
vehicle->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
|
||||
vehicle->m_fHealth = 4 * vp->health;
|
||||
@ -686,8 +686,8 @@ void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressI
|
||||
car->m_aSuspensionSpringRatio[i] = vp->wheel_susp_dist[i] / 50.0f;
|
||||
car->m_aWheelRotation[i] = vp->wheel_rotation[i] * M_PI / 128.0f;
|
||||
}
|
||||
car->Doors[2].m_fAngle = car->Doors[2].m_fPreviousAngle = vp->door_angles[0] * M_PI / 127.0f;
|
||||
car->Doors[3].m_fAngle = car->Doors[3].m_fPreviousAngle = vp->door_angles[1] * M_PI / 127.0f;
|
||||
car->Doors[2].m_fAngle = car->Doors[2].m_fPrevAngle = vp->door_angles[0] * M_PI / 127.0f;
|
||||
car->Doors[3].m_fAngle = car->Doors[3].m_fPrevAngle = vp->door_angles[1] * M_PI / 127.0f;
|
||||
if (vp->door_angles[0])
|
||||
car->Damage.SetDoorStatus(2, 2);
|
||||
if (vp->door_angles[1])
|
||||
@ -847,7 +847,7 @@ bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, flo
|
||||
{
|
||||
tGeneralPacket* pg = (tGeneralPacket*)&ptr[offset];
|
||||
TheCamera.GetMatrix() = TheCamera.GetMatrix() * CMatrix(split);
|
||||
*TheCamera.GetMatrix().GetPosition() *= split;
|
||||
TheCamera.GetMatrix().GetPosition() *= split;
|
||||
TheCamera.GetMatrix() += CMatrix(interpolation) * pg->camera_pos;
|
||||
RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera));
|
||||
pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition();
|
||||
@ -979,40 +979,40 @@ void CReplay::ProcessReplayCamera(void)
|
||||
switch (CameraMode) {
|
||||
case REPLAYCAMMODE_TOPDOWN:
|
||||
{
|
||||
*TheCamera.GetMatrix().GetPosition() = CVector(CameraFocusX, CameraFocusY, CameraFocusZ + 15.0f);
|
||||
*TheCamera.GetMatrix().GetForward() = CVector(0.0f, 0.0f, -1.0f);
|
||||
*TheCamera.GetMatrix().GetUp() = CVector(0.0f, 1.0f, 0.0f);
|
||||
*TheCamera.GetMatrix().GetRight() = CVector(1.0f, 0.0f, 0.0f);
|
||||
TheCamera.GetMatrix().GetPosition() = CVector(CameraFocusX, CameraFocusY, CameraFocusZ + 15.0f);
|
||||
TheCamera.GetMatrix().GetForward() = CVector(0.0f, 0.0f, -1.0f);
|
||||
TheCamera.GetMatrix().GetUp() = CVector(0.0f, 1.0f, 0.0f);
|
||||
TheCamera.GetMatrix().GetRight() = CVector(1.0f, 0.0f, 0.0f);
|
||||
RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera));
|
||||
pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition();
|
||||
pm->at = *(RwV3d*)TheCamera.GetMatrix().GetForward();
|
||||
pm->up = *(RwV3d*)TheCamera.GetMatrix().GetUp();
|
||||
pm->right = *(RwV3d*)TheCamera.GetMatrix().GetRight();
|
||||
pm->pos = *(RwV3d*)&TheCamera.GetMatrix().GetPosition();
|
||||
pm->at = *(RwV3d*)&TheCamera.GetMatrix().GetForward();
|
||||
pm->up = *(RwV3d*)&TheCamera.GetMatrix().GetUp();
|
||||
pm->right = *(RwV3d*)&TheCamera.GetMatrix().GetRight();
|
||||
break;
|
||||
}
|
||||
case REPLAYCAMMODE_FIXED:
|
||||
{
|
||||
*TheCamera.GetMatrix().GetPosition() = CVector(CameraFixedX, CameraFixedY, CameraFixedZ);
|
||||
TheCamera.GetMatrix().GetPosition() = CVector(CameraFixedX, CameraFixedY, CameraFixedZ);
|
||||
CVector forward(CameraFocusX - CameraFixedX, CameraFocusY - CameraFixedY, CameraFocusZ - CameraFixedZ);
|
||||
forward.Normalise();
|
||||
CVector right = CrossProduct(CVector(0.0f, 0.0f, 1.0f), forward);
|
||||
right.Normalise();
|
||||
CVector up = CrossProduct(forward, right);
|
||||
up.Normalise();
|
||||
*TheCamera.GetMatrix().GetForward() = forward;
|
||||
*TheCamera.GetMatrix().GetUp() = up;
|
||||
*TheCamera.GetMatrix().GetRight() = right;
|
||||
TheCamera.GetMatrix().GetForward() = forward;
|
||||
TheCamera.GetMatrix().GetUp() = up;
|
||||
TheCamera.GetMatrix().GetRight() = right;
|
||||
RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera));
|
||||
pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition();
|
||||
pm->at = *(RwV3d*)TheCamera.GetMatrix().GetForward();
|
||||
pm->up = *(RwV3d*)TheCamera.GetMatrix().GetUp();
|
||||
pm->right = *(RwV3d*)TheCamera.GetMatrix().GetRight();
|
||||
pm->pos = *(RwV3d*)&TheCamera.GetMatrix().GetPosition();
|
||||
pm->at = *(RwV3d*)&TheCamera.GetMatrix().GetForward();
|
||||
pm->up = *(RwV3d*)&TheCamera.GetMatrix().GetUp();
|
||||
pm->right = *(RwV3d*)&TheCamera.GetMatrix().GetRight();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
TheCamera.m_vecGameCamPos = *TheCamera.GetMatrix().GetPosition();
|
||||
TheCamera.m_vecGameCamPos = TheCamera.GetMatrix().GetPosition();
|
||||
TheCamera.CalculateDerivedValues();
|
||||
RwMatrixUpdate(RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)));
|
||||
RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera));
|
||||
@ -1189,7 +1189,7 @@ void CReplay::RestoreStuffFromMem(void)
|
||||
CMatrix tmp1;
|
||||
tmp1.Attach(RwFrameGetMatrix(dodo->m_aCarNodes[CAR_WHEEL_RF]), false);
|
||||
CMatrix tmp2(RwFrameGetMatrix(dodo->m_aCarNodes[CAR_WHEEL_LF]), false);
|
||||
*tmp1.GetPosition() += CVector(tmp2.GetPosition()->x + 0.1f, 0.0f, tmp2.GetPosition()->z);
|
||||
tmp1.GetPosition() += CVector(tmp2.GetPosition().x + 0.1f, 0.0f, tmp2.GetPosition().z);
|
||||
tmp1.UpdateRW();
|
||||
}
|
||||
if (vehicle->IsCar()){
|
||||
@ -1346,14 +1346,14 @@ void CReplay::MarkEverythingAsNew(void)
|
||||
CVehicle* v = CPools::GetVehiclePool()->GetSlot(i);
|
||||
if (!v)
|
||||
continue;
|
||||
v->bRecordedForReplay = false;
|
||||
v->bHasAlreadyBeenRecorded = false;
|
||||
}
|
||||
i = CPools::GetPedPool()->GetSize();
|
||||
while (i--) {
|
||||
CPed* p = CPools::GetPedPool()->GetSlot(i);
|
||||
if (!p)
|
||||
continue;
|
||||
p->bRecordedForReplay = false;
|
||||
p->bHasAlreadyBeenRecorded = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1505,9 +1505,9 @@ void CReplay::ProcessLookAroundCam(void)
|
||||
else
|
||||
fAlphaAngleLookAroundCam = max(0.1f, min(1.5f, fAlphaAngleLookAroundCam + y_moved));
|
||||
CVector camera_pt(
|
||||
fDistanceLookAroundCam * sin(fBetaAngleLookAroundCam) * cos(fAlphaAngleLookAroundCam),
|
||||
fDistanceLookAroundCam * cos(fBetaAngleLookAroundCam) * cos(fAlphaAngleLookAroundCam),
|
||||
fDistanceLookAroundCam * sin(fAlphaAngleLookAroundCam)
|
||||
fDistanceLookAroundCam * Sin(fBetaAngleLookAroundCam) * Cos(fAlphaAngleLookAroundCam),
|
||||
fDistanceLookAroundCam * Cos(fBetaAngleLookAroundCam) * Cos(fAlphaAngleLookAroundCam),
|
||||
fDistanceLookAroundCam * Sin(fAlphaAngleLookAroundCam)
|
||||
);
|
||||
CVector focus = CVector(CameraFocusX, CameraFocusY, CameraFocusZ);
|
||||
camera_pt += focus;
|
||||
@ -1525,15 +1525,15 @@ void CReplay::ProcessLookAroundCam(void)
|
||||
right.Normalise();
|
||||
CVector up = CrossProduct(forward, right);
|
||||
up.Normalise();
|
||||
*TheCamera.GetMatrix().GetForward() = forward;
|
||||
*TheCamera.GetMatrix().GetUp() = up;
|
||||
*TheCamera.GetMatrix().GetRight() = right;
|
||||
*TheCamera.GetMatrix().GetPosition() = camera_pt;
|
||||
TheCamera.GetMatrix().GetForward() = forward;
|
||||
TheCamera.GetMatrix().GetUp() = up;
|
||||
TheCamera.GetMatrix().GetRight() = right;
|
||||
TheCamera.GetMatrix().GetPosition() = camera_pt;
|
||||
RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera));
|
||||
pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition();
|
||||
pm->at = *(RwV3d*)TheCamera.GetMatrix().GetForward();
|
||||
pm->up = *(RwV3d*)TheCamera.GetMatrix().GetUp();
|
||||
pm->right = *(RwV3d*)TheCamera.GetMatrix().GetRight();
|
||||
pm->pos = *(RwV3d*)&TheCamera.GetMatrix().GetPosition();
|
||||
pm->at = *(RwV3d*)&TheCamera.GetMatrix().GetForward();
|
||||
pm->up = *(RwV3d*)&TheCamera.GetMatrix().GetUp();
|
||||
pm->right = *(RwV3d*)&TheCamera.GetMatrix().GetRight();
|
||||
TheCamera.CalculateDerivedValues();
|
||||
RwMatrixUpdate(RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)));
|
||||
RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera));
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,18 +1,28 @@
|
||||
#pragma once
|
||||
#include "Ped.h"
|
||||
#include "Object.h"
|
||||
#include "common.h"
|
||||
#include "Sprite2d.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
class CEntity;
|
||||
class CBuilding;
|
||||
class CVehicle;
|
||||
class CPed;
|
||||
class CObject;
|
||||
|
||||
struct CScriptRectangle
|
||||
{
|
||||
bool m_bIsUsed;
|
||||
bool m_bIsAntialiased;
|
||||
uint16 m_wTextureId;
|
||||
int8 m_bIsUsed;
|
||||
bool m_bBeforeFade;
|
||||
int16 m_nTextureId;
|
||||
CRect m_sRect;
|
||||
CRGBA m_sColor;
|
||||
};
|
||||
|
||||
static_assert(sizeof(CScriptRectangle) == 0x18, "Script.h: error");
|
||||
|
||||
enum {
|
||||
SCRIPT_TEXT_MAX_LENGTH = 500
|
||||
};
|
||||
|
||||
struct CTextLine
|
||||
{
|
||||
float m_fScaleX;
|
||||
@ -26,33 +36,83 @@ struct CTextLine
|
||||
float m_fCenterSize;
|
||||
CRGBA m_sBackgroundColor;
|
||||
bool m_bTextProportional;
|
||||
int32 field_29;
|
||||
bool m_bTextBeforeFade;
|
||||
bool m_bRightJustify;
|
||||
int32 field_31;
|
||||
int32 m_nFont;
|
||||
float field_36;
|
||||
float field_40;
|
||||
wchar m_awText[500];
|
||||
float m_fAtX;
|
||||
float m_fAtY;
|
||||
wchar m_Text[SCRIPT_TEXT_MAX_LENGTH];
|
||||
|
||||
void Reset();
|
||||
};
|
||||
|
||||
struct CRunningScript
|
||||
static_assert(sizeof(CTextLine) == 0x414, "Script.h: error");
|
||||
|
||||
struct CScriptSphere
|
||||
{
|
||||
bool m_bInUse;
|
||||
uint16 m_Index;
|
||||
uint32 m_Id;
|
||||
CVector m_vecCenter;
|
||||
float m_fRadius;
|
||||
};
|
||||
|
||||
enum {
|
||||
MAX_STACK_DEPTH = 6,
|
||||
NUM_LOCAL_VARS = 16,
|
||||
NUM_TIMERS = 2
|
||||
};
|
||||
|
||||
class CRunningScript
|
||||
{
|
||||
CRunningScript *next;
|
||||
CRunningScript *prev;
|
||||
uint8 m_abScriptName[8];
|
||||
char m_abScriptName[8];
|
||||
uint32 m_nIp;
|
||||
uint32 m_anStack[6];
|
||||
uint32 m_anStack[MAX_STACK_DEPTH];
|
||||
uint16 m_nStackPointer;
|
||||
void* m_anLocalVariables[18];
|
||||
int32 m_anLocalVariables[NUM_LOCAL_VARS + NUM_TIMERS];
|
||||
bool m_bCondResult;
|
||||
bool m_bIsMissionThread;
|
||||
bool m_bIsMissionScript;
|
||||
bool m_bSkipWakeTime;
|
||||
uint32 m_nWakeTime;
|
||||
uint16 m_wIfOp;
|
||||
uint16 m_nAndOrState;
|
||||
bool m_bNotFlag;
|
||||
bool m_bWBCheck;
|
||||
bool m_bWastedOrBusted;
|
||||
bool m_bWBCheckEnabled;
|
||||
bool m_bWBChecked;
|
||||
bool m_bMissionFlag;
|
||||
|
||||
public:
|
||||
void SetIP(uint32 ip) { m_nIp = ip; }
|
||||
CRunningScript* GetNext() { return next; }
|
||||
void UpdateTimers(float timeStep){
|
||||
m_anLocalVariables[NUM_LOCAL_VARS] += timeStep;
|
||||
m_anLocalVariables[NUM_LOCAL_VARS + 1] += timeStep;
|
||||
}
|
||||
|
||||
void CollectParameters(uint32*, int16);
|
||||
int32 CollectNextParameterWithoutIncreasingPC(uint32);
|
||||
int32* GetPointerToScriptVariable(uint32*, int16);
|
||||
void StoreParameters(uint32*, int16);
|
||||
void Init();
|
||||
void RemoveScriptFromList(CRunningScript**);
|
||||
void AddScriptToList(CRunningScript**);
|
||||
void Process();
|
||||
int8 ProcessOneCommand();
|
||||
void DoDeatharrestCheck();
|
||||
int8 ProcessCommandsFrom0To99(int32);
|
||||
int8 ProcessCommandsFrom100To199(int32);
|
||||
int8 ProcessCommandsFrom200To299(int32);
|
||||
int8 ProcessCommandsFrom300To399(int32);
|
||||
int8 ProcessCommandsFrom400To499(int32);
|
||||
int8 ProcessCommandsFrom500To599(int32);
|
||||
int8 ProcessCommandsFrom600To699(int32);
|
||||
int8 ProcessCommandsFrom700To799(int32);
|
||||
int8 ProcessCommandsFrom800To899(int32);
|
||||
int8 ProcessCommandsFrom900To999(int32);
|
||||
int8 ProcessCommandsFrom1000To1099(int32);
|
||||
int8 ProcessCommandsFrom1100To1199(int32);
|
||||
void UpdateCompareFlag(bool);
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -133,13 +193,81 @@ public:
|
||||
bool HasCarBeenStuckForAWhile(int32);
|
||||
};
|
||||
|
||||
enum {
|
||||
ARGUMENT_END = 0,
|
||||
ARGUMENT_INT32,
|
||||
ARGUMENT_GLOBALVAR,
|
||||
ARGUMENT_LOCALVAR,
|
||||
ARGUMENT_INT8,
|
||||
ARGUMENT_INT16,
|
||||
ARGUMENT_FLOAT
|
||||
};
|
||||
|
||||
struct tCollectiveData
|
||||
{
|
||||
int32 index;
|
||||
uint32 unk_data;
|
||||
};
|
||||
|
||||
enum {
|
||||
USED_OBJECT_NAME_LENGTH = 24
|
||||
};
|
||||
|
||||
struct tUsedObject
|
||||
{
|
||||
char name[USED_OBJECT_NAME_LENGTH];
|
||||
int32 index;
|
||||
};
|
||||
|
||||
struct tBuildingSwap
|
||||
{
|
||||
CBuilding* m_pBuilding;
|
||||
int32 m_nNewModel;
|
||||
int32 m_nOldModel;
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
VAR_LOCAL = 1,
|
||||
VAR_GLOBAL = 2,
|
||||
};
|
||||
|
||||
enum {
|
||||
SIZE_MAIN_SCRIPT = 128 * 1024,
|
||||
SIZE_MISSION_SCRIPT = 32 * 1024,
|
||||
SIZE_SCRIPT_SPACE = SIZE_MAIN_SCRIPT + SIZE_MISSION_SCRIPT
|
||||
};
|
||||
|
||||
enum {
|
||||
MAX_NUM_SCRIPTS = 128,
|
||||
MAX_NUM_CONTACTS = 16,
|
||||
MAX_NUM_INTRO_TEXT_LINES = 2,
|
||||
MAX_NUM_INTRO_RECTANGLES = 16,
|
||||
MAX_NUM_SCRIPT_SRPITES = 16,
|
||||
MAX_NUM_SCRIPT_SPHERES = 16,
|
||||
MAX_NUM_COLLECTIVES = 32,
|
||||
MAX_NUM_USED_OBJECTS = 200,
|
||||
MAX_NUM_MISSION_SCRIPTS = 120,
|
||||
MAX_NUM_BUILDING_SWAPS = 25,
|
||||
MAX_NUM_INVISIBILITY_SETTINGS = 20
|
||||
};
|
||||
|
||||
class CTheScripts
|
||||
{
|
||||
public:
|
||||
static uint8(&ScriptSpace)[160 * 1024];
|
||||
static CTextLine(&IntroTextLines)[2];
|
||||
static CScriptRectangle(&IntroRectangles)[16];
|
||||
static CSprite2d(&ScriptSprites)[16];
|
||||
static uint8(&ScriptSpace)[SIZE_SCRIPT_SPACE];
|
||||
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 CSprite2d(&ScriptSprites)[MAX_NUM_SCRIPT_SRPITES];
|
||||
static CScriptSphere(&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];
|
||||
static tBuildingSwap(&BuildingSwapArray)[MAX_NUM_BUILDING_SWAPS];
|
||||
static CEntity*(&InvisibilitySettingArray)[MAX_NUM_INVISIBILITY_SETTINGS];
|
||||
static bool &DbgFlag;
|
||||
static uint32 &OnAMissionFlag;
|
||||
static CMissionCleanup &MissionCleanup;
|
||||
@ -147,11 +275,67 @@ public:
|
||||
static CUpsideDownCarCheck &UpsideDownCars;
|
||||
static int32 &StoreVehicleIndex;
|
||||
static bool &StoreVehicleWasRandom;
|
||||
|
||||
static CRunningScript *&pIdleScripts;
|
||||
static CRunningScript *&pActiveScripts;
|
||||
static uint32 &NextFreeCollectiveIndex;
|
||||
static int32 &LastRandomPedId;
|
||||
static uint16 &NumberOfUsedObjects;
|
||||
static bool &bAlreadyRunningAMissionScript;
|
||||
static bool &bUsingAMultiScriptFile;
|
||||
static uint16 &NumberOfMissionScripts;
|
||||
static uint32 &LargestMissionScriptSize;
|
||||
static uint32 &MainScriptSize;
|
||||
static uint8 &FailCurrentMission;
|
||||
static uint8 &CountdownToMakePlayerUnsafe;
|
||||
static uint8 &DelayMakingPlayerUnsafeThisTime;
|
||||
static uint16 &NumScriptDebugLines;
|
||||
static uint16 &NumberOfIntroRectanglesThisFrame;
|
||||
static uint16 &NumberOfIntroTextLinesThisFrame;
|
||||
static bool &UseTextCommands;
|
||||
static uint16 &CommandsExecuted;
|
||||
static uint16 &ScriptsUpdated;
|
||||
public:
|
||||
static bool IsPlayerOnAMission();
|
||||
static void ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2);
|
||||
static void CleanUpThisVehicle(CVehicle*);
|
||||
static void CleanUpThisPed(CPed*);
|
||||
static void CleanUpThisObject(CObject*);
|
||||
static void Init();
|
||||
static CRunningScript* StartNewScript(uint32);
|
||||
static void Process();
|
||||
static CRunningScript* StartTestScript();
|
||||
static bool IsPlayerOnAMission();
|
||||
|
||||
static void ReadObjectNamesFromScript();
|
||||
static void UpdateObjectIndices();
|
||||
static void ReadMultiScriptFileOffsetsFromScript();
|
||||
static void DrawScriptSpheres();
|
||||
static void ClearSpaceForMissionEntity(const CVector&, CEntity*);
|
||||
static void HighlightImportantArea(uint32, float, float, float, float, float);
|
||||
static void DrawDebugSquare(float, float, float, float);
|
||||
static void DrawDebugCube(float, float, float, float, float, float);
|
||||
|
||||
static int32 Read4BytesFromScript(uint32* pIp){
|
||||
int32 retval = 0;
|
||||
for (int i = 0; i < 4; i++){
|
||||
retval |= ScriptSpace[(*pIp)++] << (8 * i);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
static int16 Read2BytesFromScript(uint32* pIp){
|
||||
int16 retval = 0;
|
||||
for (int i = 0; i < 2; i++){
|
||||
retval |= ScriptSpace[(*pIp)++] << (8 * i);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
static int8 Read1ByteFromScript(uint32* pIp){
|
||||
int8 retval = 0;
|
||||
for (int i = 0; i < 1; i++){
|
||||
retval |= ScriptSpace[(*pIp)++] << (8 * i);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
static float ReadFloatFromScript(uint32* pIp){
|
||||
return Read2BytesFromScript(pIp) / 16.0f;
|
||||
}
|
||||
};
|
||||
|
1158
src/control/ScriptCommands.h
Normal file
1158
src/control/ScriptCommands.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -18,10 +18,12 @@ const float DefaultFOV = 70.0f; // beta: 80.0f
|
||||
CCamera &TheCamera = *(CCamera*)0x6FACF8;
|
||||
bool &CCamera::m_bUseMouse3rdPerson = *(bool *)0x5F03D8;
|
||||
|
||||
WRAPPER void CCamera::CamShake(float strength, float x, float y, float z) { EAXJMP(0x46B200); }
|
||||
WRAPPER void CCamera::DrawBordersForWideScreen(void) { EAXJMP(0x46B430); }
|
||||
WRAPPER void CCamera::CalculateDerivedValues(void) { EAXJMP(0x46EEA0); }
|
||||
WRAPPER void CCamera::Restore(void) { EAXJMP(0x46F990); }
|
||||
WRAPPER void CCamera::SetWidescreenOff(void) { EAXJMP(0x46FF10); }
|
||||
WRAPPER void CCamera::CamShake(float) { EAXJMP(0x46B100); }
|
||||
|
||||
bool
|
||||
CCamera::IsSphereVisible(const CVector ¢er, float radius, const CMatrix *mat)
|
||||
@ -136,6 +138,15 @@ CCamera::RenderMotionBlur(void)
|
||||
m_motionBlur, m_BlurType, m_imotionBlurAddAlpha);
|
||||
}
|
||||
|
||||
void
|
||||
CCamera::ClearPlayerWeaponMode()
|
||||
{
|
||||
PlayerWeaponMode.Mode = 0;
|
||||
PlayerWeaponMode.MaxZoom = 1;
|
||||
PlayerWeaponMode.MinZoom = -1;
|
||||
PlayerWeaponMode.Duration = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
@ -159,9 +170,9 @@ WellBufferMe(float Target, float *CurrentValue, float *CurrentSpeed, float MaxSp
|
||||
float TargetSpeed = Delta * MaxSpeed;
|
||||
// Add or subtract absolute depending on sign, genius!
|
||||
// if(TargetSpeed - *CurrentSpeed > 0.0f)
|
||||
// *CurrentSpeed += Acceleration * fabs(TargetSpeed - *CurrentSpeed) * CTimer::GetTimeStep();
|
||||
// *CurrentSpeed += Acceleration * Abs(TargetSpeed - *CurrentSpeed) * CTimer::GetTimeStep();
|
||||
// else
|
||||
// *CurrentSpeed -= Acceleration * fabs(TargetSpeed - *CurrentSpeed) * CTimer::GetTimeStep();
|
||||
// *CurrentSpeed -= Acceleration * Abs(TargetSpeed - *CurrentSpeed) * CTimer::GetTimeStep();
|
||||
// this is simpler:
|
||||
*CurrentSpeed += Acceleration * (TargetSpeed - *CurrentSpeed) * CTimer::GetTimeStep();
|
||||
|
||||
@ -238,14 +249,14 @@ CCam::GetPedBetaAngleForClearView(const CVector &Target, float Dist, float BetaO
|
||||
|
||||
for(a = 0.0f; a <= PI; a += DEGTORAD(5.0f)){
|
||||
if(BetaOffset <= 0.0f){
|
||||
ToSource = CVector(cos(Beta + BetaOffset + a), sin(Beta + BetaOffset + a), 0.0f)*Dist;
|
||||
ToSource = CVector(Cos(Beta + BetaOffset + a), Sin(Beta + BetaOffset + a), 0.0f)*Dist;
|
||||
if(!CWorld::ProcessLineOfSight(Target, Target + ToSource,
|
||||
point, ent, checkBuildings, checkVehicles, checkPeds,
|
||||
checkObjects, checkDummies, true, true))
|
||||
return a;
|
||||
}
|
||||
if(BetaOffset >= 0.0f){
|
||||
ToSource = CVector(cos(Beta + BetaOffset - a), sin(Beta + BetaOffset - a), 0.0f)*Dist;
|
||||
ToSource = CVector(Cos(Beta + BetaOffset - a), Sin(Beta + BetaOffset - a), 0.0f)*Dist;
|
||||
if(!CWorld::ProcessLineOfSight(Target, Target + ToSource,
|
||||
point, ent, checkBuildings, checkVehicles, checkPeds,
|
||||
checkObjects, checkDummies, true, true))
|
||||
@ -344,8 +355,8 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
|
||||
// TODO: what's transition beta?
|
||||
if(TheCamera.m_bUseTransitionBeta && ResetStatics){
|
||||
CVector VecDistance;
|
||||
IdealSource.x = TargetCoors.x + GroundDist*cos(m_fTransitionBeta);
|
||||
IdealSource.y = TargetCoors.y + GroundDist*sin(m_fTransitionBeta);
|
||||
IdealSource.x = TargetCoors.x + GroundDist*Cos(m_fTransitionBeta);
|
||||
IdealSource.y = TargetCoors.y + GroundDist*Sin(m_fTransitionBeta);
|
||||
Beta = CGeneral::GetATanOfXY(IdealSource.x - TargetCoors.x, IdealSource.y - TargetCoors.y);
|
||||
}else
|
||||
Beta = CGeneral::GetATanOfXY(Source.x - TargetCoors.x, Source.y - TargetCoors.y);
|
||||
@ -489,7 +500,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
|
||||
CVector PlayerPos = FindPlayerPed()->GetPosition();
|
||||
float RotationDist = (AngleToGoTo == Center ? CenterDist : LateralDist) * RealGroundDist;
|
||||
// What's going on here? - AngleToGoTo?
|
||||
CVector RotatedSource = PlayerPos + CVector(cos(Beta - AngleToGoTo), sin(Beta - AngleToGoTo), 0.0f) * RotationDist;
|
||||
CVector RotatedSource = PlayerPos + CVector(Cos(Beta - AngleToGoTo), Sin(Beta - AngleToGoTo), 0.0f) * RotationDist;
|
||||
|
||||
CColPoint colpoint;
|
||||
CEntity *entity;
|
||||
@ -573,9 +584,9 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
|
||||
float ReqSpeed = DeltaBeta * MaxSpeed;
|
||||
// Add or subtract absolute depending on sign, genius!
|
||||
if(ReqSpeed - BetaSpeed > 0.0f)
|
||||
BetaSpeed += SpeedStep * fabs(ReqSpeed - BetaSpeed) * CTimer::GetTimeStep();
|
||||
BetaSpeed += SpeedStep * Abs(ReqSpeed - BetaSpeed) * CTimer::GetTimeStep();
|
||||
else
|
||||
BetaSpeed -= SpeedStep * fabs(ReqSpeed - BetaSpeed) * CTimer::GetTimeStep();
|
||||
BetaSpeed -= SpeedStep * Abs(ReqSpeed - BetaSpeed) * CTimer::GetTimeStep();
|
||||
// this would be simpler:
|
||||
// BetaSpeed += SpeedStep * (ReqSpeed - BetaSpeed) * CTimer::ms_fTimeStep;
|
||||
|
||||
@ -593,14 +604,14 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
|
||||
BetaSpeed = 0.0f;
|
||||
}
|
||||
|
||||
Source.x = TargetCoors.x + Distance * cos(Beta);
|
||||
Source.y = TargetCoors.y + Distance * sin(Beta);
|
||||
Source.x = TargetCoors.x + Distance * Cos(Beta);
|
||||
Source.y = TargetCoors.y + Distance * Sin(Beta);
|
||||
|
||||
// Check if we can stop rotating
|
||||
DeltaBeta = FixedTargetOrientation - Beta;
|
||||
while(DeltaBeta >= PI) DeltaBeta -= 2*PI;
|
||||
while(DeltaBeta < -PI) DeltaBeta += 2*PI;
|
||||
if(fabs(DeltaBeta) < DEGTORAD(1.0f) && !bBehindPlayerDesired){
|
||||
if(Abs(DeltaBeta) < DEGTORAD(1.0f) && !bBehindPlayerDesired){
|
||||
// Stop rotation
|
||||
PickedASide = false;
|
||||
Rotating = false;
|
||||
@ -613,18 +624,18 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
|
||||
HackPlayerOnStoppingTrain || Rotating){
|
||||
if(TheCamera.m_bCamDirectlyBehind){
|
||||
Beta = TargetOrientation + PI;
|
||||
Source.x = TargetCoors.x + Distance * cos(Beta);
|
||||
Source.y = TargetCoors.y + Distance * sin(Beta);
|
||||
Source.x = TargetCoors.x + Distance * Cos(Beta);
|
||||
Source.y = TargetCoors.y + Distance * Sin(Beta);
|
||||
}
|
||||
if(TheCamera.m_bCamDirectlyInFront){
|
||||
Beta = TargetOrientation;
|
||||
Source.x = TargetCoors.x + Distance * cos(Beta);
|
||||
Source.y = TargetCoors.y + Distance * sin(Beta);
|
||||
Source.x = TargetCoors.x + Distance * Cos(Beta);
|
||||
Source.y = TargetCoors.y + Distance * Sin(Beta);
|
||||
}
|
||||
if(HackPlayerOnStoppingTrain){
|
||||
Beta = TargetOrientation + PI;
|
||||
Source.x = TargetCoors.x + Distance * cos(Beta);
|
||||
Source.y = TargetCoors.y + Distance * sin(Beta);
|
||||
Source.x = TargetCoors.x + Distance * Cos(Beta);
|
||||
Source.y = TargetCoors.y + Distance * Sin(Beta);
|
||||
m_fDimensionOfHighestNearCar = 0.0f;
|
||||
m_fCamBufferedHeight = 0.0f;
|
||||
m_fCamBufferedHeightSpeed = 0.0f;
|
||||
@ -669,9 +680,13 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
|
||||
else if(TargetZOffSet == m_fUnknownZOffSet && TargetZOffSet > m_fCamBufferedHeight){
|
||||
// TODO: figure this out
|
||||
bool foo = false;
|
||||
switch(((CPhysical*)CamTargetEntity)->m_nLastCollType)
|
||||
case 2: case 3: case 5:
|
||||
case 11: case 23: case 26:
|
||||
switch(((CPhysical*)CamTargetEntity)->m_nSurfaceTouched)
|
||||
case SURFACE_GRASS:
|
||||
case SURFACE_DIRT:
|
||||
case SURFACE_PAVEMENT:
|
||||
case SURFACE_STEEL:
|
||||
case SURFACE_TIRE:
|
||||
case SURFACE_STONE:
|
||||
foo = true;
|
||||
if(foo)
|
||||
WellBufferMe(TargetHeight, &m_fCamBufferedHeight, &m_fCamBufferedHeightSpeed, 0.4f, 0.05f, false);
|
||||
@ -784,7 +799,7 @@ CCam::WorkOutCamHeightWeeCar(CVector &TargetCoors, float TargetOrientation)
|
||||
if(CCullZones::CamNoRain() || CCullZones::PlayerNoRain())
|
||||
AlphaTarget = DEGTORAD(14.0f);
|
||||
WellBufferMe(AlphaTarget, &Alpha, &AlphaSpeed, 0.1f, 0.05f, true);
|
||||
Source.z = TargetCoors.z + CA_MAX_DISTANCE*sin(Alpha);
|
||||
Source.z = TargetCoors.z + CA_MAX_DISTANCE*Sin(Alpha);
|
||||
|
||||
if(FindPlayerVehicle()){
|
||||
m_fUnknownZOffSet = 0.0f;
|
||||
@ -889,7 +904,7 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa
|
||||
while(deltaBeta >= PI) deltaBeta -= 2*PI;
|
||||
while(deltaBeta < -PI) deltaBeta += 2*PI;
|
||||
|
||||
float BehindCarNess = cos(deltaBeta); // 1 if behind car, 0 if side, -1 if in front
|
||||
float BehindCarNess = Cos(deltaBeta); // 1 if behind car, 0 if side, -1 if in front
|
||||
CarAlpha = -CarAlpha * BehindCarNess;
|
||||
if(CarAlpha < -0.01f)
|
||||
CarAlpha = -0.01f;
|
||||
@ -924,13 +939,13 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa
|
||||
Forward = CamTargetEntity->GetForward(); // we actually still have that...
|
||||
Forward.Normalise(); // shouldn't be necessary
|
||||
float CarSideAngle = CGeneral::GetATanOfXY(Forward.x, Forward.y) + PI/2.0f;
|
||||
float SideX = 2.5f * cos(CarSideAngle);
|
||||
float SideY = 2.5f * sin(CarSideAngle);
|
||||
float SideX = 2.5f * Cos(CarSideAngle);
|
||||
float SideY = 2.5f * Sin(CarSideAngle);
|
||||
CWorld::FindRoofZFor3DCoord(TargetCoors.x + SideX, TargetCoors.y + SideY, CarBottom, &FoundRoofSide1);
|
||||
CWorld::FindRoofZFor3DCoord(TargetCoors.x - SideX, TargetCoors.y - SideY, CarBottom, &FoundRoofSide2);
|
||||
|
||||
// Now find out at what height we'd like to place the camera
|
||||
float CamGround = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, TargetCoors.z + Length*sin(Alpha + ModeAlpha) + m_fCloseInCarHeightOffset, &FoundCamGround);
|
||||
float CamGround = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, TargetCoors.z + Length*Sin(Alpha + ModeAlpha) + m_fCloseInCarHeightOffset, &FoundCamGround);
|
||||
float CamTargetZ = 0.0f;
|
||||
if(FoundCamGround){
|
||||
// This is the normal case
|
||||
@ -977,7 +992,7 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa
|
||||
}
|
||||
|
||||
// Now do things if CamClear...but what is that anyway?
|
||||
float CamZ = TargetCoors.z + Length*sin(Alpha + DeltaAlpha + ModeAlpha) + m_fCloseInCarHeightOffset;
|
||||
float CamZ = TargetCoors.z + Length*Sin(Alpha + DeltaAlpha + ModeAlpha) + m_fCloseInCarHeightOffset;
|
||||
bool FoundGround, FoundRoof;
|
||||
float CamGround2 = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, CamZ, &FoundGround);
|
||||
if(FoundGround){
|
||||
@ -1027,7 +1042,7 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa
|
||||
|
||||
WellBufferMe(LastTargetAlphaWithCollisionOn, &Alpha, &AlphaSpeed, LastTopAlphaSpeed, LastAlphaSpeedStep, true);
|
||||
|
||||
Source.z = TargetCoors.z + sin(Alpha + ModeAlpha)*Length + m_fCloseInCarHeightOffset;
|
||||
Source.z = TargetCoors.z + Sin(Alpha + ModeAlpha)*Length + m_fCloseInCarHeightOffset;
|
||||
}
|
||||
|
||||
// Rotate cam behind the car when the car is moving forward
|
||||
@ -1047,7 +1062,7 @@ CCam::RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation)
|
||||
while(DeltaBeta >= PI) DeltaBeta -= 2*PI;
|
||||
while(DeltaBeta < -PI) DeltaBeta += 2*PI;
|
||||
|
||||
if(fabs(DeltaBeta) > DEGTORAD(20.0f) && MovingForward && TheCamera.m_uiTransitionState == 0)
|
||||
if(Abs(DeltaBeta) > DEGTORAD(20.0f) && MovingForward && TheCamera.m_uiTransitionState == 0)
|
||||
m_bFixingBeta = true;
|
||||
|
||||
CPad *pad = CPad::GetPad(0);
|
||||
@ -1073,14 +1088,14 @@ CCam::RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation)
|
||||
if(TheCamera.m_bUseTransitionBeta && &TheCamera.Cams[TheCamera.ActiveCam] == this)
|
||||
Beta = m_fTransitionBeta;
|
||||
|
||||
Source.x = TargetCoors.x - cos(Beta)*Dist;
|
||||
Source.y = TargetCoors.y - sin(Beta)*Dist;
|
||||
Source.x = TargetCoors.x - Cos(Beta)*Dist;
|
||||
Source.y = TargetCoors.y - Sin(Beta)*Dist;
|
||||
|
||||
// Check if we're done
|
||||
DeltaBeta = TargetOrientation - Beta;
|
||||
while(DeltaBeta >= PI) DeltaBeta -= 2*PI;
|
||||
while(DeltaBeta < -PI) DeltaBeta += 2*PI;
|
||||
if(fabs(DeltaBeta) < DEGTORAD(2.0f))
|
||||
if(Abs(DeltaBeta) < DEGTORAD(2.0f))
|
||||
m_bFixingBeta = false;
|
||||
}
|
||||
TheCamera.m_bCamDirectlyBehind = false;
|
||||
@ -1123,8 +1138,8 @@ CCam::FixCamIfObscured(CVector &TargetCoors, float TargetHeight, float TargetOri
|
||||
Obscured1 = CWorld::ProcessLineOfSight(EntityPos, TempSource, colPoint, ent, true, false, false, true, false, true, true);
|
||||
}else if(m_bFixingBeta){
|
||||
float d = (TempSource - Target).Magnitude();
|
||||
TempSource.x = Target.x - d*cos(TargetOrientation);
|
||||
TempSource.y = Target.y - d*sin(TargetOrientation);
|
||||
TempSource.x = Target.x - d*Cos(TargetOrientation);
|
||||
TempSource.y = Target.y - d*Sin(TargetOrientation);
|
||||
|
||||
// same check again
|
||||
Obscured2 = CWorld::ProcessLineOfSight(Target, TempSource, colPoint, ent, true, false, false, true, false, true, true);
|
||||
@ -1142,14 +1157,14 @@ CCam::FixCamIfObscured(CVector &TargetCoors, float TargetHeight, float TargetOri
|
||||
return false;
|
||||
|
||||
if(Fix1){
|
||||
Source.x = Target.x - cos(Beta)*Dist1;
|
||||
Source.y = Target.y - sin(Beta)*Dist1;
|
||||
Source.x = Target.x - Cos(Beta)*Dist1;
|
||||
Source.y = Target.y - Sin(Beta)*Dist1;
|
||||
if(Mode == MODE_BEHINDCAR)
|
||||
Source = colPoint.point;
|
||||
}else{
|
||||
WellBufferMe(Dist2, &m_fDistanceBeforeChanges, &DistanceSpeed, 0.2f, 0.025f, false);
|
||||
Source.x = Target.x - cos(Beta)*m_fDistanceBeforeChanges;
|
||||
Source.y = Target.y - sin(Beta)*m_fDistanceBeforeChanges;
|
||||
Source.x = Target.x - Cos(Beta)*m_fDistanceBeforeChanges;
|
||||
Source.y = Target.y - Sin(Beta)*m_fDistanceBeforeChanges;
|
||||
}
|
||||
|
||||
if(ResetStatics){
|
||||
|
@ -454,14 +454,18 @@ int m_iModeObbeCamIsInForCar;
|
||||
void ProcessMusicFade(void);
|
||||
void SetFadeColour(uint8 r, uint8 g, uint8 b);
|
||||
|
||||
void CamShake(float strength, float x, float y, float z);
|
||||
|
||||
void SetMotionBlur(int r, int g, int b, int a, int type);
|
||||
void SetMotionBlurAlpha(int a);
|
||||
void RenderMotionBlur(void);
|
||||
void ClearPlayerWeaponMode();
|
||||
void CalculateDerivedValues(void);
|
||||
|
||||
void DrawBordersForWideScreen(void);
|
||||
void Restore(void);
|
||||
void SetWidescreenOff(void);
|
||||
void CamShake(float);
|
||||
|
||||
void dtor(void) { this->CCamera::~CCamera(); }
|
||||
};
|
||||
|
@ -457,7 +457,7 @@ CCollision::TestLineSphere(const CColLine &line, const CColSphere &sph)
|
||||
// I leave in the strange -2 factors even though they serve no real purpose
|
||||
float projline = -2.0f * DotProduct(v01, v0c); // project v0c onto line
|
||||
// Square of tangent from p0 multiplied by line length so we can compare with projline.
|
||||
// The length of the tangent would be this: sqrt((c-p0)^2 - r^2).
|
||||
// The length of the tangent would be this: Sqrt((c-p0)^2 - r^2).
|
||||
// Negative if p0 is inside the sphere! This breaks the test!
|
||||
float tansq = 4.0f * linesq *
|
||||
(sph.center.MagnitudeSqr() - 2.0f*DotProduct(sph.center, line.p0) + line.p0.MagnitudeSqr() - sph.radius*sph.radius);
|
||||
@ -467,10 +467,10 @@ CCollision::TestLineSphere(const CColLine &line, const CColSphere &sph)
|
||||
return false;
|
||||
// projline (negative in GTA for some reason) is the point on the line
|
||||
// in the middle of the two intersection points (startin from p0).
|
||||
// sqrt(diffsq) somehow works out to be the distance from that
|
||||
// Sqrt(diffsq) somehow works out to be the distance from that
|
||||
// midpoint to the intersection points.
|
||||
// So subtract that and get rid of the awkward scaling:
|
||||
float f = (-projline - sqrt(diffsq)) / (2.0f*linesq);
|
||||
float f = (-projline - Sqrt(diffsq)) / (2.0f*linesq);
|
||||
// f should now be in range [0, 1] for [p0, p1]
|
||||
return f >= 0.0f && f <= 1.0f;
|
||||
}
|
||||
@ -480,7 +480,7 @@ CCollision::TestSphereTriangle(const CColSphere &sphere,
|
||||
const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane)
|
||||
{
|
||||
// If sphere and plane don't intersect, no collision
|
||||
if(fabs(plane.CalcPoint(sphere.center)) > sphere.radius)
|
||||
if(Abs(plane.CalcPoint(sphere.center)) > sphere.radius)
|
||||
return false;
|
||||
|
||||
const CVector &va = verts[tri.a];
|
||||
@ -627,7 +627,7 @@ CCollision::ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoin
|
||||
dist = sph.center - p;
|
||||
float lensq = dist.MagnitudeSqr();
|
||||
if(lensq < mindistsq){
|
||||
point.normal = dist * (1.0f/sqrt(lensq));
|
||||
point.normal = dist * (1.0f/Sqrt(lensq));
|
||||
point.point = sph.center - point.normal;
|
||||
point.surfaceA = sph.surface;
|
||||
point.pieceA = sph.piece;
|
||||
@ -669,7 +669,7 @@ CCollision::ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoin
|
||||
dist = sph.center - p;
|
||||
float lensq = dist.MagnitudeSqr();
|
||||
if(lensq < mindistsq){
|
||||
float len = sqrt(lensq);
|
||||
float len = Sqrt(lensq);
|
||||
point.point = p;
|
||||
point.normal = dist * (1.0f/len);
|
||||
point.surfaceA = sph.surface;
|
||||
@ -816,7 +816,7 @@ CCollision::ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CC
|
||||
if(diffsq < 0.0f)
|
||||
return false;
|
||||
// point of first intersection, in range [0,1] between p0 and p1
|
||||
float t = (projline - sqrt(diffsq)) / linesq;
|
||||
float t = (projline - Sqrt(diffsq)) / linesq;
|
||||
// if not on line or beyond mindist, no intersection
|
||||
if(t < 0.0f || t > 1.0f || t >= mindist)
|
||||
return false;
|
||||
@ -1010,7 +1010,7 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere,
|
||||
// If sphere and plane don't intersect, no collision
|
||||
float planedist = plane.CalcPoint(sphere.center);
|
||||
float distsq = planedist*planedist;
|
||||
if(fabs(planedist) > sphere.radius || distsq > mindistsq)
|
||||
if(Abs(planedist) > sphere.radius || distsq > mindistsq)
|
||||
return false;
|
||||
|
||||
const CVector &va = verts[tri.a];
|
||||
@ -1057,7 +1057,7 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere,
|
||||
else assert(0);
|
||||
}else if(testcase == 3){
|
||||
// center is in triangle
|
||||
dist = fabs(planedist);
|
||||
dist = Abs(planedist);
|
||||
p = sphere.center - normal*planedist;
|
||||
}else
|
||||
assert(0); // front fell off
|
||||
@ -1173,7 +1173,7 @@ enum {
|
||||
// This checks model A's spheres and lines against model B's spheres, boxes and triangles.
|
||||
// Returns the number of A's spheres that collide.
|
||||
// Returned ColPoints are in world space.
|
||||
// NB: lines do not seem to be supported very well, use with caution
|
||||
// NB: only vehicles can have col models with lines, exactly 4, one for each wheel
|
||||
int32
|
||||
CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
|
||||
const CMatrix &matrixB, CColModel &modelB,
|
||||
@ -1333,7 +1333,7 @@ CCollision::DistToLine(const CVector *l0, const CVector *l1, const CVector *poin
|
||||
if(dot >= lensq)
|
||||
return (*point - *l1).Magnitude();
|
||||
// distance to line
|
||||
return sqrt((*point - *l0).MagnitudeSqr() - dot*dot/lensq);
|
||||
return Sqrt((*point - *l0).MagnitudeSqr() - dot*dot/lensq);
|
||||
}
|
||||
|
||||
// same as above but also return the point on the line
|
||||
@ -1641,7 +1641,7 @@ CColTrianglePlane::Set(const CVector *v, CColTriangle &tri)
|
||||
normal = CrossProduct(vc-va, vb-va);
|
||||
normal.Normalise();
|
||||
dist = DotProduct(normal, va);
|
||||
CVector an(fabs(normal.x), fabs(normal.y), fabs(normal.z));
|
||||
CVector an(Abs(normal.x), Abs(normal.y), Abs(normal.z));
|
||||
// find out largest component and its direction
|
||||
if(an.x > an.y && an.x > an.z)
|
||||
dir = normal.x < 0.0f ? DIR_X_NEG : DIR_X_POS;
|
||||
|
@ -147,7 +147,7 @@ public:
|
||||
static bool ProcessSphereTriangle(const CColSphere &sph, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindistsq);
|
||||
static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough);
|
||||
static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, CStoredCollPoly *poly);
|
||||
static int32 ProcessColModels(const CMatrix &matrix1, CColModel &model1, const CMatrix &matrix2, CColModel &model2, CColPoint *point1, CColPoint *point2, float *linedists);
|
||||
static int32 ProcessColModels(const CMatrix &matrixA, CColModel &modelA, const CMatrix &matrixB, CColModel &modelB, CColPoint *spherepoints, CColPoint *linepoints, float *linedists);
|
||||
|
||||
// TODO:
|
||||
// CCollision::IsStoredPolyStillValidVerticalLine
|
||||
|
@ -21,6 +21,7 @@ WRAPPER void CControllerConfigManager::InitDefaultControlConfigJoyPad(unsigned i
|
||||
WRAPPER void CControllerConfigManager::ClearSimButtonPressCheckers() { EAXJMP(0x58D220); }
|
||||
WRAPPER void CControllerConfigManager::AffectPadFromKeyBoard() { EAXJMP(0x58D0C0); }
|
||||
WRAPPER void CControllerConfigManager::AffectPadFromMouse() { EAXJMP(0x58D1A0); }
|
||||
WRAPPER void CControllerConfigManager::ClearSettingsAssociatedWithAction(int, int) { EAXJMP(0x58EB40); }
|
||||
|
||||
void CControllerConfigManager::LoadSettings(int32 file)
|
||||
{
|
||||
|
@ -50,7 +50,8 @@ public:
|
||||
void ClearSimButtonPressCheckers();
|
||||
void AffectPadFromKeyBoard();
|
||||
void AffectPadFromMouse();
|
||||
|
||||
void ClearSettingsAssociatedWithAction(int, int);
|
||||
|
||||
};
|
||||
|
||||
VALIDATE_SIZE(CControllerConfigManager, 0x143C);
|
||||
|
5
src/core/Explosion.cpp
Normal file
5
src/core/Explosion.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Explosion.h"
|
||||
|
||||
WRAPPER void CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32) { EAXJMP(0x5591C0); }
|
15
src/core/Explosion.h
Normal file
15
src/core/Explosion.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
class CEntity;
|
||||
|
||||
enum eExplosionType
|
||||
{
|
||||
EXPLOSION_3 = 3,
|
||||
EXPLOSION_4
|
||||
};
|
||||
|
||||
class CExplosion
|
||||
{
|
||||
public:
|
||||
static void AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32);
|
||||
};
|
@ -262,9 +262,9 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
|
||||
model.vertices = (CVector*)RwMalloc(numVertices*sizeof(CVector));
|
||||
for(i = 0; i < numVertices; i++){
|
||||
model.vertices[i] = *(CVector*)buf;
|
||||
if(fabs(model.vertices[i].x) >= 256.0f ||
|
||||
fabs(model.vertices[i].y) >= 256.0f ||
|
||||
fabs(model.vertices[i].z) >= 256.0f)
|
||||
if(Abs(model.vertices[i].x) >= 256.0f ||
|
||||
Abs(model.vertices[i].y) >= 256.0f ||
|
||||
Abs(model.vertices[i].z) >= 256.0f)
|
||||
printf("%s:Collision volume too big\n", modelname);
|
||||
buf += 12;
|
||||
}
|
||||
@ -813,6 +813,7 @@ CFileLoader::LoadPedObject(const char *line)
|
||||
if(strcmp(animGroup, CAnimManager::GetAnimGroupName((AssocGroupId)animGroupId)) == 0)
|
||||
break;
|
||||
mi->m_animGroup = animGroupId;
|
||||
mi->m_carsCanDrive = carsCanDrive;
|
||||
|
||||
// ???
|
||||
CModelInfo::GetModelInfo(MI_LOPOLYGUY)->SetColModel(&CTempColModels::ms_colModelPed1);
|
||||
|
@ -2,4 +2,8 @@
|
||||
#include "patcher.h"
|
||||
#include "Fire.h"
|
||||
|
||||
WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); }
|
||||
CFireManager &gFireManager = *(CFireManager*)0x8F31D0;
|
||||
|
||||
WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); }
|
||||
|
||||
WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); }
|
||||
|
@ -1,13 +1,13 @@
|
||||
#pragma once
|
||||
#include "common.h"
|
||||
#include "Entity.h"
|
||||
|
||||
class CEntity;
|
||||
|
||||
class CFire
|
||||
{
|
||||
char m_bIsOngoing;
|
||||
char m_bExists;
|
||||
char m_bPropogationFlag;
|
||||
char m_bAudioSet;
|
||||
bool m_bIsOngoing;
|
||||
bool m_bExists;
|
||||
bool m_bPropogationFlag;
|
||||
bool m_bAudioSet;
|
||||
CVector m_vecPos;
|
||||
CEntity *m_pEntity;
|
||||
CEntity *m_pSource;
|
||||
@ -20,4 +20,11 @@ class CFire
|
||||
|
||||
public:
|
||||
void Extinguish(void);
|
||||
};
|
||||
};
|
||||
|
||||
class CFireManager
|
||||
{
|
||||
public:
|
||||
void StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32);
|
||||
};
|
||||
extern CFireManager &gFireManager;
|
||||
|
@ -24,6 +24,10 @@
|
||||
#include "Vehicle.h"
|
||||
#include "MBlur.h"
|
||||
#include "PlayerSkin.h"
|
||||
#include "PlayerInfo.h"
|
||||
#include "World.h"
|
||||
|
||||
#define ALL_ORIGINAL_FRONTEND 1
|
||||
|
||||
int32 &CMenuManager::OS_Language = *(int32*)0x5F2F78;
|
||||
int8 &CMenuManager::m_PrefsUseVibration = *(int8*)0x95CD92;
|
||||
@ -50,7 +54,9 @@ int8 &CMenuManager::m_bFrontEnd_ReloadObrTxtGxt = *(int8*)0x628CFC;
|
||||
int32 &CMenuManager::m_PrefsMusicVolume = *(int32*)0x5F2E4C;
|
||||
int32 &CMenuManager::m_PrefsSfxVolume = *(int32*)0x5F2E48;
|
||||
|
||||
uint8 *CMenuManager::m_PrefsSkinFile = (uint8*)0x5F2E74;
|
||||
char *CMenuManager::m_PrefsSkinFile = (char*)0x5F2E74;
|
||||
|
||||
int32 &CMenuManager::m_KeyPressedCode = *(int32*)0x5F2E70;
|
||||
|
||||
CMenuManager &FrontEndMenuManager = *(CMenuManager*)0x8F59D8;
|
||||
|
||||
@ -58,14 +64,17 @@ CMenuManager &FrontEndMenuManager = *(CMenuManager*)0x8F59D8;
|
||||
float lodMultiplier = *(float*)0x5F726C;
|
||||
|
||||
// Stuff not in CMenuManager:
|
||||
int VibrationTime;
|
||||
char* pEditString;
|
||||
int32 pControlEdit;
|
||||
int8 DisplayComboButtonErrMsg;
|
||||
bool MouseButtonJustClicked;
|
||||
bool JoyButtonJustClicked;
|
||||
uint32 &VibrationTime = *(uint32*)0x628CF8;
|
||||
char* pEditString = (char*)0x628D00;
|
||||
int32 *&pControlEdit = *(int32**)0x628D08;
|
||||
bool &DisplayComboButtonErrMsg = *(bool*)0x628D14;
|
||||
int32 &MouseButtonJustClicked = *(int32*)0x628D0C;
|
||||
int32 &JoyButtonJustClicked = *(int32*)0x628D10;
|
||||
int32 &nTimeForSomething = *(int32*)0x628D54;
|
||||
//int32 *pControlTemp = 0;
|
||||
|
||||
// Frontend inputs.
|
||||
|
||||
bool GetPadBack();
|
||||
bool GetPadExitEnter();
|
||||
bool GetPadForward();
|
||||
@ -73,6 +82,11 @@ bool GetPadMoveUp();
|
||||
bool GetPadMoveDown();
|
||||
bool GetPadMoveLeft();
|
||||
bool GetPadMoveRight();
|
||||
bool GetMouseClickLeft();
|
||||
bool GetMouseClickRight();
|
||||
bool GetMouseClickMiddle();
|
||||
bool GetMouseWheelUp();
|
||||
bool GetMouseWheelDown();
|
||||
bool GetMouseForward();
|
||||
bool GetMouseBack();
|
||||
bool GetMousePos();
|
||||
@ -135,16 +149,35 @@ char *MenuFilenames[] = {
|
||||
nil, nil
|
||||
};
|
||||
|
||||
#if 1
|
||||
WRAPPER void CMenuManager::BuildStatLine(char *, void *, uint16, void *) { EAXJMP(0x483870); }
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::BuildStatLine(char *text, float *stat, bool aFloat, float* stat2) { EAXJMP(0x483870); }
|
||||
#else
|
||||
void CMenuManager::BuildStatLine(char *, void *, uint16, void *)
|
||||
void CMenuManager::BuildStatLine(char *text, float *stat, bool aFloat, float* stat2)
|
||||
{
|
||||
if (!text)
|
||||
return;
|
||||
|
||||
if (stat2) {
|
||||
if (aFloat)
|
||||
sprintf(gString2, " %.2f %s %.2f", *stat, UnicodeToAscii(TheText.Get("FEST_OO")), *stat2);
|
||||
else
|
||||
sprintf(gString2, " %d %s %d", *(int*)stat, UnicodeToAscii(TheText.Get("FEST_OO")), *(int*)stat2);
|
||||
}
|
||||
else if (stat) {
|
||||
if (aFloat)
|
||||
sprintf(gString2, " %.2f", *stat);
|
||||
else
|
||||
sprintf(gString2, " %d", *(int*)stat);
|
||||
}
|
||||
else
|
||||
gString2[0] = '\0';
|
||||
|
||||
UnicodeStrcpy(gUString, TheText.Get(text));
|
||||
AsciiToUnicode(gString2, gUString2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::CentreMousePointer() { EAXJMP(0x48ACE0); }
|
||||
#else
|
||||
void CMenuManager::CentreMousePointer()
|
||||
@ -164,15 +197,15 @@ void CMenuManager::CentreMousePointer()
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
WRAPPER void CMenuManager::CheckCodesForControls(int, int) { EAXJMP(0x48A950); }
|
||||
WRAPPER int CMenuManager::CheckCodesForControls(int32) { EAXJMP(0x48A950); }
|
||||
#else
|
||||
void CMenuManager::CheckCodesForControls()
|
||||
void CMenuManager::CheckCodesForControls(int, int)
|
||||
{
|
||||
|
||||
DisplayComboButtonErrMsg = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER bool CMenuManager::CheckHover(int, int, int, int) { EAXJMP(0x48ACA0); }
|
||||
#else
|
||||
bool CMenuManager::CheckHover(int x1, int x2, int y1, int y2)
|
||||
@ -251,7 +284,7 @@ void CMenuManager::CheckSliderMovement(int value)
|
||||
TheCamera.m_fMouseAccelVertical = fMouseSens;
|
||||
SaveSettings();
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
@ -263,7 +296,7 @@ int CMenuManager::CostructStatLine(int)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::DisplayHelperText() { EAXJMP(0x48B490); }
|
||||
#else
|
||||
void CMenuManager::DisplayHelperText()
|
||||
@ -303,7 +336,7 @@ void CMenuManager::DisplayHelperText()
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
CFont::SetAlignment(ALIGN_CENTER);
|
||||
CFont::SetScale(SCREEN_SCALE_X(0.4f), SCREEN_SCALE_Y(0.6f));
|
||||
@ -316,7 +349,7 @@ void CMenuManager::DisplayHelperText()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER float CMenuManager::DisplaySlider(float, float, float, float, float, float) { EAXJMP(0x488420); }
|
||||
#else
|
||||
float CMenuManager::DisplaySlider(float x, float y, float leftSize, float rightSize, float rectSize, float progress)
|
||||
@ -342,12 +375,12 @@ float CMenuManager::DisplaySlider(float x, float y, float leftSize, float rightS
|
||||
float _s = SCREEN_SCALE_X(2.0f);
|
||||
CSprite2d::DrawRect(CRect(_x + _s, _y + _s, _w + _s, _h + _s), CRGBA(0, 0, 0, FadeIn(255))); // Shadow
|
||||
CSprite2d::DrawRect(CRect(i * rectSize/16.0f + x, y + sizeRange - ((16 - i) * leftSize + i * rightSize)/16.0f, SCREEN_SCALE_X(10.0f) + i * rectSize/16.0f + x, y + sizeRange), color);
|
||||
};
|
||||
}
|
||||
return input;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::DoSettingsBeforeStartingAGame() { EAXJMP(0x48AB40); }
|
||||
#else
|
||||
void CMenuManager::DoSettingsBeforeStartingAGame()
|
||||
@ -366,7 +399,7 @@ void CMenuManager::DoSettingsBeforeStartingAGame()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::Draw() { EAXJMP(0x47AE00); }
|
||||
#else
|
||||
void CMenuManager::Draw()
|
||||
@ -427,7 +460,7 @@ void CMenuManager::Draw()
|
||||
default:
|
||||
str = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
CFont::SetDropShadowPosition(MENUDROP_COLOR_SIZE);
|
||||
CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(MENUDROP_COLOR_A)));
|
||||
@ -480,7 +513,7 @@ void CMenuManager::Draw()
|
||||
case 3:
|
||||
textToPrint[MENUCOLUMN_RIGHT] = TheText.Get("FEC_CF4");
|
||||
break;
|
||||
};
|
||||
}
|
||||
break;
|
||||
case MENUACTION_CTRLDISPLAY:
|
||||
break;
|
||||
@ -510,7 +543,7 @@ void CMenuManager::Draw()
|
||||
case AR_16_9:
|
||||
textToPrint[MENUCOLUMN_RIGHT] = (wchar*)L"16:9";
|
||||
break;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case MENUACTION_RADIO:
|
||||
@ -560,7 +593,7 @@ void CMenuManager::Draw()
|
||||
case 2:
|
||||
textToPrint[MENUCOLUMN_RIGHT] = TheText.Get("FEA_4SP");
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MENUACTION_CTRLMETHOD:
|
||||
@ -571,7 +604,7 @@ void CMenuManager::Draw()
|
||||
case 1:
|
||||
textToPrint[MENUCOLUMN_LEFT] = TheText.Get("FET_CCN");
|
||||
break;
|
||||
};
|
||||
}
|
||||
break;
|
||||
case MENUACTION_DYNAMICACOUSTIC:
|
||||
textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(m_PrefsDMA ? "FEM_ON" : "FEM_OFF");
|
||||
@ -579,7 +612,7 @@ void CMenuManager::Draw()
|
||||
case MENUACTION_MOUSESTEER:
|
||||
textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(m_bDisableMouseSteering ? "FEM_ON" : "FEM_OFF");
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
CFont::SetDropShadowPosition(MENUDROP_COLOR_SIZE);
|
||||
CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(MENUDROP_COLOR_A)));
|
||||
@ -667,7 +700,7 @@ void CMenuManager::Draw()
|
||||
default:
|
||||
vecPositions.y = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(MENUCOLUMN_MID_Y);
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (i > 0)
|
||||
@ -719,9 +752,9 @@ void CMenuManager::Draw()
|
||||
m_nPrevOption = m_nCurrOption;
|
||||
|
||||
if (GetMouseForward())
|
||||
m_nHoverOption = IGNORE_OPTION;
|
||||
m_nHoverOption = HOVEROPTION_NULL;
|
||||
else
|
||||
m_nHoverOption = ACTIVATE_OPTION;
|
||||
m_nHoverOption = HOVEROPTION_DEFAULT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -744,7 +777,7 @@ void CMenuManager::Draw()
|
||||
case MENUACTION_MOUSESENS:
|
||||
DisplaySlider(SCREEN_SCALE_FROM_RIGHT(MENUSLIDER_X), vecPositions.y - SCREEN_SCALE_Y(3.0f), SCREEN_SCALE_Y(2.0f), SCREEN_SCALE_Y(18.0f), SCREEN_SCALE_X(256.0f), TheCamera.m_fMouseAccelHorzntl * 200.0f);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
// Radio icons.
|
||||
float fIconSpacing = 59.52f;
|
||||
@ -793,9 +826,9 @@ void CMenuManager::Draw()
|
||||
case MENUPAGE_MOUSE_CONTROLS:
|
||||
DisplayHelperText();
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -826,7 +859,7 @@ void CMenuManager::DrawControllerSetupScreen()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::DrawFrontEnd(void) { EAXJMP(0x47A540); }
|
||||
#else
|
||||
void CMenuManager::DrawFrontEnd()
|
||||
@ -850,7 +883,7 @@ void CMenuManager::DrawFrontEnd()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::DrawFrontEndNormal(void) { EAXJMP(0x47A5B0); }
|
||||
#else
|
||||
void CMenuManager::DrawFrontEndNormal()
|
||||
@ -904,7 +937,7 @@ void CMenuManager::DrawFrontEndNormal()
|
||||
case MENUPAGE_OPTIONS:
|
||||
previousSprite = MENUSPRITE_PLAYERSET;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
if (m_nPrevScreen == MENUPAGE_NONE)
|
||||
CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, 255));
|
||||
@ -949,7 +982,7 @@ void CMenuManager::DrawFrontEndNormal()
|
||||
case MENUPAGE_OPTIONS:
|
||||
currentSprite = MENUSPRITE_PLAYERSET;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
uint32 savedShade;
|
||||
uint32 savedAlpha;
|
||||
@ -993,7 +1026,7 @@ void CMenuManager::DrawFrontEndNormal()
|
||||
default:
|
||||
CMenuManager::Draw();
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
CFont::DrawFonts();
|
||||
|
||||
@ -1012,7 +1045,7 @@ void CMenuManager::DrawPlayerSetupScreen()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER int CMenuManager::FadeIn(int alpha) { EAXJMP(0x48AC60); }
|
||||
#else
|
||||
int CMenuManager::FadeIn(int alpha)
|
||||
@ -1047,7 +1080,7 @@ int CMenuManager::GetStartOptionsCntrlConfigScreens()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::InitialiseChangedLanguageSettings() { EAXJMP(0x47A4D0); }
|
||||
#else
|
||||
void CMenuManager::InitialiseChangedLanguageSettings()
|
||||
@ -1069,12 +1102,12 @@ void CMenuManager::InitialiseChangedLanguageSettings()
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::LoadAllTextures() { EAXJMP(0x47A230); }
|
||||
#else
|
||||
void CMenuManager::LoadAllTextures()
|
||||
@ -1110,7 +1143,7 @@ void CMenuManager::LoadAllTextures()
|
||||
for (int i = 0; i < ARRAY_SIZE(FrontendFilenames); i++) {
|
||||
m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i]);
|
||||
m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
|
||||
};
|
||||
}
|
||||
|
||||
CTxdStore::PopCurrentTxd();
|
||||
|
||||
@ -1123,7 +1156,7 @@ void CMenuManager::LoadAllTextures()
|
||||
for (int i = 0; i < ARRAY_SIZE(MenuFilenames)/2; i++) {
|
||||
m_aMenuSprites[i].SetTexture(MenuFilenames[i*2], MenuFilenames[i*2+1]);
|
||||
m_aMenuSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
|
||||
};
|
||||
}
|
||||
|
||||
CTxdStore::PopCurrentTxd();
|
||||
|
||||
@ -1132,7 +1165,7 @@ void CMenuManager::LoadAllTextures()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::LoadSettings() { EAXJMP(0x488EE0); }
|
||||
#else
|
||||
void CMenuManager::LoadSettings()
|
||||
@ -1151,13 +1184,13 @@ void CMenuManager::LoadSettings()
|
||||
if (strncmp(&Ver, "THIS FILE IS NOT VALID YET", 26)) {
|
||||
CFileMgr::Seek(fileHandle, 0, 0);
|
||||
ControlsManager.LoadSettings(fileHandle);
|
||||
CFileMgr::Read(fileHandle, buf(&gString), 20);
|
||||
CFileMgr::Read(fileHandle, buf(&gString), 20);
|
||||
CFileMgr::Read(fileHandle, buf(&gString), 4);
|
||||
CFileMgr::Read(fileHandle, buf(&gString), 4);
|
||||
CFileMgr::Read(fileHandle, buf(&gString), 1);
|
||||
CFileMgr::Read(fileHandle, buf(&gString), 1);
|
||||
CFileMgr::Read(fileHandle, buf(&gString), 1);
|
||||
CFileMgr::Read(fileHandle, buf(gString), 20);
|
||||
CFileMgr::Read(fileHandle, buf(gString), 20);
|
||||
CFileMgr::Read(fileHandle, buf(gString), 4);
|
||||
CFileMgr::Read(fileHandle, buf(gString), 4);
|
||||
CFileMgr::Read(fileHandle, buf(gString), 1);
|
||||
CFileMgr::Read(fileHandle, buf(gString), 1);
|
||||
CFileMgr::Read(fileHandle, buf(gString), 1);
|
||||
CFileMgr::Read(fileHandle, buf(&TheCamera.m_bHeadBob), 1);
|
||||
CFileMgr::Read(fileHandle, buf(&TheCamera.m_fMouseAccelHorzntl), 4);
|
||||
CFileMgr::Read(fileHandle, buf(&TheCamera.m_fMouseAccelVertical), 4);
|
||||
@ -1253,7 +1286,7 @@ void CMenuManager::PrintBriefs()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::PrintErrorMessage() { EAXJMP(0x484F70); }
|
||||
#else
|
||||
void CMenuManager::PrintErrorMessage()
|
||||
@ -1286,22 +1319,31 @@ void CMenuManager::PrintStats()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::Process(void) { EAXJMP(0x485100); }
|
||||
#else
|
||||
void CMenuManager::Process(void)
|
||||
{
|
||||
if (m_bSaveMenuActive && TheCamera.GetScreenFadeStatus())
|
||||
field_112 = 0;
|
||||
|
||||
if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus() != FADE_0)
|
||||
return;
|
||||
|
||||
field_113 = 0;
|
||||
m_bStartGameLoading = false;
|
||||
InitialiseChangedLanguageSettings();
|
||||
|
||||
if (CPad::GetPad(0)->GetEscapeJustDown())
|
||||
RequestFrontEndStartUp();
|
||||
|
||||
SwitchMenuOnAndOff();
|
||||
|
||||
// Be able to re-open menu correctly.
|
||||
if (m_bMenuActive) {
|
||||
|
||||
// Load frontend textures.
|
||||
LoadAllTextures();
|
||||
|
||||
// Set save/delete game pages.
|
||||
if (m_nCurrScreen == MENUPAGE_DELETING) {
|
||||
bool SlotPopulated = false;
|
||||
|
||||
@ -1350,25 +1392,113 @@ void CMenuManager::Process(void)
|
||||
}
|
||||
|
||||
ProcessButtonPresses();
|
||||
|
||||
// Set binding keys.
|
||||
if (pEditString && CPad::EditString(pEditString, 0) == nil) {
|
||||
if (*pEditString == 0)
|
||||
strcpy(pEditString, "NoName");
|
||||
pEditString = nil;
|
||||
SaveSettings();
|
||||
}
|
||||
|
||||
if (field_113) {
|
||||
if (field_456)
|
||||
field_456 = 0;
|
||||
else {
|
||||
pControlEdit = CPad::EditCodesForControls(pControlEdit, 1);
|
||||
JoyButtonJustClicked = 0;
|
||||
MouseButtonJustClicked = 0;
|
||||
|
||||
if (GetMouseClickLeft())
|
||||
MouseButtonJustClicked = 1;
|
||||
else if (GetMouseClickRight())
|
||||
MouseButtonJustClicked = 3;
|
||||
else if (GetMouseClickMiddle())
|
||||
MouseButtonJustClicked = 2;
|
||||
else if (GetMouseWheelUp())
|
||||
MouseButtonJustClicked = 4;
|
||||
else if (GetMouseWheelDown())
|
||||
MouseButtonJustClicked = 5;
|
||||
//XXX two more buttons
|
||||
|
||||
JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown();
|
||||
|
||||
int32 TypeOfControl = 0;
|
||||
if (JoyButtonJustClicked)
|
||||
TypeOfControl = 3;
|
||||
if (MouseButtonJustClicked)
|
||||
TypeOfControl = 2;
|
||||
if (*pControlEdit != rsNULL)
|
||||
TypeOfControl = 0;
|
||||
|
||||
if (!field_534) {
|
||||
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
|
||||
pControlEdit = nil;
|
||||
field_113 = 0;
|
||||
m_KeyPressedCode = -1;
|
||||
field_456 = 0;
|
||||
}
|
||||
else if (!m_bKeyChangeNotProcessed) {
|
||||
if (*pControlEdit != rsNULL || MouseButtonJustClicked || JoyButtonJustClicked)
|
||||
CheckCodesForControls(TypeOfControl);
|
||||
|
||||
field_535 = 1;
|
||||
}
|
||||
else {
|
||||
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
|
||||
for (int i = 0; i < 4; i++)
|
||||
ControlsManager.ClearSettingsAssociatedWithAction(m_CurrCntrlAction, i);
|
||||
field_534 = false;
|
||||
m_bKeyChangeNotProcessed = false;
|
||||
pControlEdit = nil;
|
||||
field_113 = 0;
|
||||
m_KeyPressedCode = -1;
|
||||
field_456 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_nCurrScreen == MENUPAGE_13 || m_nCurrScreen == MENUPAGE_16) && CTimer::GetTimeInMillisecondsPauseMode() > field_558) {
|
||||
m_nCurrScreen = m_nPrevScreen;
|
||||
m_nCurrOption = 0;
|
||||
}
|
||||
|
||||
// Reset pad shaking.
|
||||
if (VibrationTime && CTimer::GetTimeInMillisecondsPauseMode() > VibrationTime) {
|
||||
CPad::StopPadsShaking();
|
||||
VibrationTime = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (GetPadExitEnter())
|
||||
RequestFrontEndStartUp();
|
||||
|
||||
UnloadTextures();
|
||||
m_nPrevScreen = MENUPAGE_NONE;
|
||||
field_452 = 0;
|
||||
*(bool*)0x5F33E4 = true;
|
||||
// byte_5F33E4 = 1; // unused
|
||||
m_nPrevScreen = 0;
|
||||
m_nCurrScreen = m_nPrevScreen;
|
||||
m_nCurrOption = MENUROW_0;
|
||||
m_nCurrOption = 0;
|
||||
pEditString = nil;
|
||||
field_113 = 0;
|
||||
}
|
||||
|
||||
if (!m_bStartGameLoading) {
|
||||
if (m_bGameNotLoaded)
|
||||
DMAudio.Service();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::ProcessButtonPresses() { EAXJMP(0x4856F0); }
|
||||
#else
|
||||
void CMenuManager::ProcessButtonPresses()
|
||||
{
|
||||
// Update Mouse Position
|
||||
if(pEditString)
|
||||
return;
|
||||
if(pControlEdit)
|
||||
return;
|
||||
|
||||
// Update mouse position
|
||||
m_nMouseOldPosX = m_nMousePosX;
|
||||
m_nMouseOldPosY = m_nMousePosY;
|
||||
|
||||
@ -1390,6 +1520,70 @@ void CMenuManager::ProcessButtonPresses()
|
||||
else if (GetPadInput())
|
||||
m_bShowMouse = false;
|
||||
|
||||
if (m_nCurrScreen == MENUPAGE_MULTIPLAYER_FIND_GAME || m_nCurrScreen == MENUPAGE_SKIN_SELECT || m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
|
||||
if (m_nCurrScreen == MENUPAGE_SKIN_SELECT)
|
||||
field_440 = m_nSkinsTotal;
|
||||
|
||||
if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
|
||||
field_440 = m_ControlMethod ? 30 : 25;
|
||||
|
||||
if (field_44C > field_440)
|
||||
field_44C = field_440 - 1;
|
||||
}
|
||||
|
||||
if (!GetPadBack() || m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS || field_535)
|
||||
field_535 = 0;
|
||||
else if (field_536 == 19) {
|
||||
m_nHoverOption = 42;
|
||||
field_113 = 1;
|
||||
field_456 = 1;
|
||||
m_bKeyChangeNotProcessed = 1;
|
||||
pControlEdit = &m_KeyPressedCode;
|
||||
}
|
||||
|
||||
if (GetPadForward()) {
|
||||
switch (field_536) {
|
||||
case 19:
|
||||
if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
|
||||
field_113 = 1;
|
||||
field_456 = 1;
|
||||
pControlEdit = &m_KeyPressedCode;
|
||||
}
|
||||
if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
|
||||
strcpy(m_PrefsSkinFile, m_aSkinName);
|
||||
CWorld::Players->SetPlayerSkin(m_PrefsSkinFile);
|
||||
field_536 = 9;
|
||||
}
|
||||
|
||||
m_nHoverOption = HOVEROPTION_NULL;
|
||||
SaveSettings();
|
||||
break;
|
||||
case 21:
|
||||
strcpy(m_PrefsSkinFile, m_aSkinName);
|
||||
CWorld::Players->SetPlayerSkin(m_PrefsSkinFile);
|
||||
field_536 = 9;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool once = false;
|
||||
if (!once) {
|
||||
once = true;
|
||||
nTimeForSomething = 0;
|
||||
}
|
||||
|
||||
if ((CTimer::GetTimeInMillisecondsPauseMode() - nTimeForSomething) > 200) {
|
||||
field_520 = 0;
|
||||
field_521 = 0;
|
||||
field_522 = 0;
|
||||
field_523 = 0;
|
||||
field_524 = 0;
|
||||
nTimeForSomething = CTimer::GetTimeInMillisecondsPauseMode();
|
||||
}
|
||||
}
|
||||
|
||||
// Get number of menu options.
|
||||
uint8 NumberOfMenuOptions = GetNumberOfMenuOptions();
|
||||
|
||||
@ -1436,29 +1630,54 @@ void CMenuManager::ProcessButtonPresses()
|
||||
RequestFrontEndShutdown();
|
||||
PlayEscSound = true;
|
||||
break;
|
||||
case MENUPAGE_KEYBOARD_CONTROLS:
|
||||
if (!m_bKeyChangeNotProcessed) {
|
||||
m_bKeyChangeNotProcessed = true;
|
||||
field_534 = 0;
|
||||
}
|
||||
else
|
||||
SwitchToNewScreen(aScreens[m_nCurrScreen].m_PreviousPage[0]);
|
||||
break;
|
||||
default:
|
||||
SwitchToNewScreen(aScreens[m_nCurrScreen].m_PreviousPage[0]);
|
||||
PlayEscSound = true;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
if (PlayEscSound)
|
||||
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_EXIT, 0);
|
||||
}
|
||||
|
||||
// TODO: finish hover options.
|
||||
// Set mouse buttons.
|
||||
// Set hover options, how it is supposed to be used isn't really clear yet.
|
||||
if (GetMouseForward()) {
|
||||
switch (m_nHoverOption) {
|
||||
case ACTIVATE_OPTION:
|
||||
case HOVEROPTION_DEFAULT:
|
||||
if (m_nCurrOption || m_nCurrScreen != MENUPAGE_PAUSE_MENU)
|
||||
m_nCurrOption = m_nPrevOption;
|
||||
|
||||
m_nHoverOption = ACTIVATE_OPTION;
|
||||
m_nHoverOption = HOVEROPTION_DEFAULT;
|
||||
break;
|
||||
case HOVEROPTION_12:
|
||||
m_nHoverOption = HOVEROPTION_14;
|
||||
break;
|
||||
case HOVEROPTION_13:
|
||||
m_nHoverOption = HOVEROPTION_15;
|
||||
break;
|
||||
case HOVEROPTION_19:
|
||||
m_nHoverOption = HOVEROPTION_20;
|
||||
break;
|
||||
case HOVEROPTION_CHANGESKIN:
|
||||
if (m_nSkinsTotal > 0) {
|
||||
m_pSelectedSkin = m_sSkin.field_304;
|
||||
strcpy(m_PrefsSkinFile, m_aSkinName);
|
||||
CWorld::Players->SetPlayerSkin(m_PrefsSkinFile);
|
||||
SaveSettings();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
m_nHoverOption = HOVEROPTION_NULL;
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Process all menu options here, but first check if it's an option or a redirect.
|
||||
@ -1494,19 +1713,11 @@ void CMenuManager::ProcessButtonPresses()
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
// Reset pad shaking.
|
||||
if (VibrationTime != 0) {
|
||||
if (CTimer::GetTimeInMillisecondsPauseMode() > VibrationTime) {
|
||||
CPad::GetPad(0)->StopShaking(0);
|
||||
VibrationTime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::ProcessOnOffMenuOptions() { EAXJMP(0x48AE60); }
|
||||
#else
|
||||
void CMenuManager::ProcessOnOffMenuOptions()
|
||||
@ -1567,7 +1778,7 @@ void CMenuManager::ProcessOnOffMenuOptions()
|
||||
case AR_16_9:
|
||||
m_PrefsUseWideScreen = AR_AUTO;
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (m_PrefsUseWideScreen) {
|
||||
@ -1580,7 +1791,7 @@ void CMenuManager::ProcessOnOffMenuOptions()
|
||||
case AR_16_9:
|
||||
m_PrefsUseWideScreen = AR_4_3;
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
SaveSettings();
|
||||
@ -1683,6 +1894,9 @@ void CMenuManager::ProcessOnOffMenuOptions()
|
||||
case MENUACTION_UPDATEMEMCARDSAVE:
|
||||
RequestFrontEndShutdown();
|
||||
break;
|
||||
case MENUACTION_GETKEY:
|
||||
//*pControlEdit = m_KeyPressedCode;
|
||||
break;
|
||||
case MENUACTION_INVVERT:
|
||||
MousePointerStateHelper.bInvertVertically = MousePointerStateHelper.bInvertVertically == false;
|
||||
return;
|
||||
@ -1823,7 +2037,7 @@ void CMenuManager::ProcessOnOffMenuOptions()
|
||||
case 2:
|
||||
m_PrefsSpeakers = 0;
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (m_PrefsSpeakers) {
|
||||
@ -1836,7 +2050,7 @@ void CMenuManager::ProcessOnOffMenuOptions()
|
||||
case 2:
|
||||
m_PrefsSpeakers = 1;
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
DMAudio.SetSpeakerConfig(m_PrefsSpeakers);
|
||||
@ -1864,11 +2078,11 @@ void CMenuManager::ProcessOnOffMenuOptions()
|
||||
case MENUACTION_MOUSESTEER:
|
||||
m_bDisableMouseSteering = m_bDisableMouseSteering == false;
|
||||
return;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::RequestFrontEndShutdown() { EAXJMP(0x488750); }
|
||||
#else
|
||||
void CMenuManager::RequestFrontEndShutdown()
|
||||
@ -1878,7 +2092,7 @@ void CMenuManager::RequestFrontEndShutdown()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::RequestFrontEndStartUp() { EAXJMP(0x488770); }
|
||||
#else
|
||||
void CMenuManager::RequestFrontEndStartUp()
|
||||
@ -1887,7 +2101,7 @@ void CMenuManager::RequestFrontEndStartUp()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::ResetHelperText() { EAXJMP(0x48B470); }
|
||||
#else
|
||||
void CMenuManager::ResetHelperText()
|
||||
@ -1897,7 +2111,7 @@ void CMenuManager::ResetHelperText()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::SaveLoadFileError_SetUpErrorScreen() { EAXJMP(0x488930); }
|
||||
#else
|
||||
void CMenuManager::SaveLoadFileError_SetUpErrorScreen()
|
||||
@ -1940,8 +2154,8 @@ void CMenuManager::SaveLoadFileError_SetUpErrorScreen()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
WRAPPER void CMenuManager::SetHelperText() { EAXJMP(0x48B450); }
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::SetHelperText(int text) { EAXJMP(0x48B450); }
|
||||
#else
|
||||
void CMenuManager::SetHelperText(int text)
|
||||
{
|
||||
@ -1950,7 +2164,7 @@ void CMenuManager::SetHelperText(int text)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::SaveSettings() { EAXJMP(0x488CC0); }
|
||||
#else
|
||||
void CMenuManager::SaveSettings()
|
||||
@ -1997,7 +2211,7 @@ void CMenuManager::SaveSettings()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::ShutdownJustMenu() { EAXJMP(0x488920); }
|
||||
#else
|
||||
void CMenuManager::ShutdownJustMenu()
|
||||
@ -2008,7 +2222,7 @@ void CMenuManager::ShutdownJustMenu()
|
||||
#endif
|
||||
|
||||
// We won't ever use this again.
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER float CMenuManager::StretchX(float) { EAXJMP(0x48ABE0); }
|
||||
#else
|
||||
float CMenuManager::StretchX(float x)
|
||||
@ -2020,7 +2234,7 @@ float CMenuManager::StretchX(float x)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER float CMenuManager::StretchY(float) { EAXJMP(0x48AC20); }
|
||||
#else
|
||||
float CMenuManager::StretchY(float y)
|
||||
@ -2032,7 +2246,7 @@ float CMenuManager::StretchY(float y)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::SwitchMenuOnAndOff() { EAXJMP(0x488790); }
|
||||
#else
|
||||
void CMenuManager::SwitchMenuOnAndOff()
|
||||
@ -2054,7 +2268,7 @@ void CMenuManager::SwitchMenuOnAndOff()
|
||||
ShutdownJustMenu();
|
||||
SaveSettings();
|
||||
m_bStartUpFrontEndRequested = false;
|
||||
pControlEdit = 0;
|
||||
pControlEdit = nil;
|
||||
m_bShutDownFrontEndRequested = false;
|
||||
DisplayComboButtonErrMsg = 0;
|
||||
CPad::GetPad(0)->Clear(0);
|
||||
@ -2078,7 +2292,7 @@ void CMenuManager::SwitchMenuOnAndOff()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::UnloadTextures() { EAXJMP(0x47A440); }
|
||||
#else
|
||||
void CMenuManager::UnloadTextures()
|
||||
@ -2103,7 +2317,7 @@ void CMenuManager::UnloadTextures()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if ALL_ORIGINAL_FRONTEND
|
||||
WRAPPER void CMenuManager::WaitForUserCD(void) { EAXJMP(0x48ADD0); }
|
||||
#else
|
||||
void CMenuManager::WaitForUserCD()
|
||||
@ -2131,7 +2345,7 @@ uint8 CMenuManager::GetNumberOfMenuOptions()
|
||||
break;
|
||||
|
||||
++Rows;
|
||||
};
|
||||
}
|
||||
return Rows;
|
||||
}
|
||||
|
||||
@ -2204,7 +2418,7 @@ void CMenuManager::SetDefaultPreferences(int8 screen)
|
||||
m_PrefsVsync = true;
|
||||
m_PrefsLOD = 1.2f;
|
||||
m_PrefsVsyncDisp = true;
|
||||
lodMultiplier = 1.2;
|
||||
lodMultiplier = 1.2f;
|
||||
CMBlur::BlurOn = true;
|
||||
CMBlur::MotionBlurOpen(Scene.camera);
|
||||
m_PrefsUseVibration = false;
|
||||
@ -2230,7 +2444,7 @@ void CMenuManager::SetDefaultPreferences(int8 screen)
|
||||
CVehicle::m_bDisableMouseSteering = true;
|
||||
TheCamera.m_bHeadBob = false;
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Frontend inputs.
|
||||
@ -2261,7 +2475,7 @@ bool GetPadMoveUp()
|
||||
return
|
||||
(CPad::GetPad(0)->NewState.DPadUp && !CPad::GetPad(0)->OldState.DPadUp) ||
|
||||
(CPad::GetPad(0)->NewKeyState.UP && !CPad::GetPad(0)->OldKeyState.UP) ||
|
||||
(CPad::GetPad(0)->NewState.LeftStickY < 0 && !CPad::GetPad(0)->OldState.LeftStickY < 0);
|
||||
(CPad::GetPad(0)->NewState.LeftStickY < 0 && !(CPad::GetPad(0)->OldState.LeftStickY < 0));
|
||||
}
|
||||
|
||||
bool GetPadMoveDown()
|
||||
@ -2269,7 +2483,7 @@ bool GetPadMoveDown()
|
||||
return
|
||||
(CPad::GetPad(0)->NewState.DPadDown && !CPad::GetPad(0)->OldState.DPadDown) ||
|
||||
(CPad::GetPad(0)->NewKeyState.DOWN && !CPad::GetPad(0)->OldKeyState.DOWN) ||
|
||||
(CPad::GetPad(0)->NewState.LeftStickY > 0 && !CPad::GetPad(0)->OldState.LeftStickY > 0);
|
||||
(CPad::GetPad(0)->NewState.LeftStickY > 0 && !(CPad::GetPad(0)->OldState.LeftStickY > 0));
|
||||
}
|
||||
|
||||
bool GetPadMoveLeft()
|
||||
@ -2277,7 +2491,7 @@ bool GetPadMoveLeft()
|
||||
return
|
||||
(CPad::GetPad(0)->NewState.DPadLeft && !CPad::GetPad(0)->OldState.DPadLeft) ||
|
||||
(CPad::GetPad(0)->NewKeyState.LEFT && !CPad::GetPad(0)->OldKeyState.LEFT) ||
|
||||
(CPad::GetPad(0)->NewState.LeftStickX < 0 && !CPad::GetPad(0)->OldState.LeftStickX < 0);
|
||||
(CPad::GetPad(0)->NewState.LeftStickX < 0 && !(CPad::GetPad(0)->OldState.LeftStickX < 0));
|
||||
}
|
||||
|
||||
bool GetPadMoveRight()
|
||||
@ -2285,21 +2499,50 @@ bool GetPadMoveRight()
|
||||
return
|
||||
(CPad::GetPad(0)->NewState.DPadRight && !CPad::GetPad(0)->OldState.DPadRight) ||
|
||||
(CPad::GetPad(0)->NewKeyState.RIGHT && !CPad::GetPad(0)->OldKeyState.RIGHT) ||
|
||||
(CPad::GetPad(0)->NewState.LeftStickX > 0 && !CPad::GetPad(0)->OldState.LeftStickX > 0);
|
||||
(CPad::GetPad(0)->NewState.LeftStickX > 0 && !(CPad::GetPad(0)->OldState.LeftStickX > 0));
|
||||
}
|
||||
|
||||
bool GetMouseForward()
|
||||
bool GetMouseClickLeft()
|
||||
{
|
||||
return
|
||||
(CPad::GetPad(0)->NewMouseControllerState.LMB && !CPad::GetPad(0)->OldMouseControllerState.LMB);
|
||||
}
|
||||
|
||||
bool GetMouseBack()
|
||||
bool GetMouseClickRight()
|
||||
{
|
||||
return
|
||||
(CPad::GetPad(0)->NewMouseControllerState.RMB && !CPad::GetPad(0)->OldMouseControllerState.RMB);
|
||||
}
|
||||
|
||||
bool GetMouseClickMiddle()
|
||||
{
|
||||
return
|
||||
(CPad::GetPad(0)->NewMouseControllerState.MMB && !CPad::GetPad(0)->OldMouseControllerState.MMB);
|
||||
}
|
||||
|
||||
bool GetMouseWheelUp()
|
||||
{
|
||||
return
|
||||
(CPad::GetPad(0)->NewMouseControllerState.WHEELUP && !CPad::GetPad(0)->OldMouseControllerState.WHEELUP);
|
||||
}
|
||||
|
||||
bool GetMouseWheelDown()
|
||||
{
|
||||
return
|
||||
(CPad::GetPad(0)->NewMouseControllerState.WHEELDN && !CPad::GetPad(0)->OldMouseControllerState.WHEELDN);
|
||||
}
|
||||
|
||||
|
||||
bool GetMouseForward()
|
||||
{
|
||||
return GetMouseClickLeft();
|
||||
}
|
||||
|
||||
bool GetMouseBack()
|
||||
{
|
||||
return GetMouseClickRight;
|
||||
}
|
||||
|
||||
bool GetMousePos()
|
||||
{
|
||||
return
|
||||
@ -2308,14 +2551,12 @@ bool GetMousePos()
|
||||
|
||||
bool GetMouseMoveLeft()
|
||||
{
|
||||
return
|
||||
(CPad::GetPad(0)->NewMouseControllerState.WHEELDN && !CPad::GetPad(0)->OldMouseControllerState.WHEELDN != 0.0f);
|
||||
return GetMouseWheelDown();
|
||||
}
|
||||
|
||||
bool GetMouseMoveRight()
|
||||
{
|
||||
return
|
||||
(CPad::GetPad(0)->NewMouseControllerState.WHEELUP && !CPad::GetPad(0)->OldMouseControllerState.WHEELUP != 0.0f);
|
||||
return GetMouseWheelUp();
|
||||
}
|
||||
|
||||
bool GetPadInput()
|
||||
@ -2340,6 +2581,7 @@ bool GetMouseInput()
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
#ifndef ALL_ORIGINAL_FRONTEND
|
||||
InjectHook(0x47A230, &CMenuManager::LoadAllTextures, PATCH_JUMP);
|
||||
InjectHook(0x47A440, &CMenuManager::UnloadTextures, PATCH_JUMP);
|
||||
InjectHook(0x485100, &CMenuManager::Process, PATCH_JUMP);
|
||||
@ -2350,4 +2592,5 @@ STARTPATCHES
|
||||
|
||||
for (int i = 1; i < ARRAY_SIZE(aScreens); i++)
|
||||
Patch(0x611930 + sizeof(CMenuScreen) * i, aScreens[i]);
|
||||
#endif
|
||||
ENDPATCHES
|
@ -306,8 +306,29 @@ enum eMenuAction
|
||||
|
||||
enum eCheckHover
|
||||
{
|
||||
ACTIVATE_OPTION = 2,
|
||||
IGNORE_OPTION = 42,
|
||||
HOVEROPTION_0,
|
||||
HOVEROPTION_1,
|
||||
HOVEROPTION_DEFAULT,
|
||||
HOVEROPTION_3,
|
||||
HOVEROPTION_4,
|
||||
HOVEROPTION_5,
|
||||
HOVEROPTION_6,
|
||||
HOVEROPTION_7,
|
||||
HOVEROPTION_8,
|
||||
HOVEROPTION_9,
|
||||
HOVEROPTION_10,
|
||||
HOVEROPTION_11,
|
||||
HOVEROPTION_12,
|
||||
HOVEROPTION_13,
|
||||
HOVEROPTION_14,
|
||||
HOVEROPTION_15,
|
||||
HOVEROPTION_16,
|
||||
HOVEROPTION_17,
|
||||
HOVEROPTION_18,
|
||||
HOVEROPTION_19,
|
||||
HOVEROPTION_20,
|
||||
HOVEROPTION_CHANGESKIN,
|
||||
HOVEROPTION_NULL = 42,
|
||||
};
|
||||
|
||||
enum eMenuColumns
|
||||
@ -348,7 +369,7 @@ struct tSkinInfo
|
||||
char skinName[256];
|
||||
char currSkinName[256];
|
||||
char date[256];
|
||||
int field_304;
|
||||
tSkinInfo *field_304;
|
||||
};
|
||||
|
||||
struct CMenuScreen
|
||||
@ -388,7 +409,7 @@ public:
|
||||
int32 m_nMouseTempPosX;
|
||||
int32 m_nMouseTempPosY;
|
||||
bool m_bShowMouse;
|
||||
tSkinInfo field_12C;
|
||||
tSkinInfo m_sSkin;
|
||||
tSkinInfo *m_pSelectedSkin;
|
||||
tSkinInfo *field_438;
|
||||
float field_43C;
|
||||
@ -427,7 +448,7 @@ public:
|
||||
int m_nCurrOption;
|
||||
int m_nPrevOption;
|
||||
int m_nPrevScreen;
|
||||
int field_558;
|
||||
uint32 field_558;
|
||||
int m_nCurrSaveSlot;
|
||||
int m_nScreenChangeDelayTimer;
|
||||
|
||||
@ -450,16 +471,17 @@ public:
|
||||
static int8 &m_bFrontEnd_ReloadObrTxtGxt;
|
||||
static int32 &m_PrefsMusicVolume;
|
||||
static int32 &m_PrefsSfxVolume;
|
||||
static uint8 *m_PrefsSkinFile;
|
||||
static char *m_PrefsSkinFile;
|
||||
static int32 &m_KeyPressedCode;
|
||||
|
||||
static bool &m_bStartUpFrontEndRequested;
|
||||
static bool &m_bShutDownFrontEndRequested;
|
||||
static bool &m_PrefsAllowNastyGame;
|
||||
|
||||
public:
|
||||
void BuildStatLine(char *, void *, uint16, void *);
|
||||
void BuildStatLine(char *text, float *stat, bool aFloat, float* stat2);
|
||||
static void CentreMousePointer();
|
||||
void CheckCodesForControls(int, int);
|
||||
int CheckCodesForControls(int32);
|
||||
bool CheckHover(int x1, int x2, int y1, int y2);
|
||||
void CheckSliderMovement(int);
|
||||
int CostructStatLine(int);
|
||||
|
@ -6,32 +6,32 @@ public:
|
||||
static float GetATanOfXY(float x, float y){
|
||||
if(x == 0.0f && y == 0.0f)
|
||||
return 0.0f;
|
||||
float xabs = fabs(x);
|
||||
float yabs = fabs(y);
|
||||
float xabs = Abs(x);
|
||||
float yabs = Abs(y);
|
||||
|
||||
if(xabs < yabs){
|
||||
if(y > 0.0f){
|
||||
if(x > 0.0f)
|
||||
return 0.5f*PI - atan2(x / y, 1.0f);
|
||||
return 0.5f*PI - Atan2(x / y, 1.0f);
|
||||
else
|
||||
return 0.5f*PI + atan2(-x / y, 1.0f);
|
||||
return 0.5f*PI + Atan2(-x / y, 1.0f);
|
||||
}else{
|
||||
if(x > 0.0f)
|
||||
return 1.5f*PI + atan2(x / -y, 1.0f);
|
||||
return 1.5f*PI + Atan2(x / -y, 1.0f);
|
||||
else
|
||||
return 1.5f*PI - atan2(-x / -y, 1.0f);
|
||||
return 1.5f*PI - Atan2(-x / -y, 1.0f);
|
||||
}
|
||||
}else{
|
||||
if(y > 0.0f){
|
||||
if(x > 0.0f)
|
||||
return atan2(y / x, 1.0f);
|
||||
return Atan2(y / x, 1.0f);
|
||||
else
|
||||
return PI - atan2(y / -x, 1.0f);
|
||||
return PI - Atan2(y / -x, 1.0f);
|
||||
}else{
|
||||
if(x > 0.0f)
|
||||
return 2.0f*PI - atan2(-y / x, 1.0f);
|
||||
return 2.0f*PI - Atan2(-y / x, 1.0f);
|
||||
else
|
||||
return PI + atan2(-y / -x, 1.0f);
|
||||
return PI + Atan2(-y / -x, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -68,14 +68,14 @@ public:
|
||||
|
||||
if (x > 0.0f) {
|
||||
if (y > 0.0f)
|
||||
return PI - atan2(x / y, 1.0f);
|
||||
return PI - Atan2(x / y, 1.0f);
|
||||
else
|
||||
return -atan2(x / y, 1.0f);
|
||||
return -Atan2(x / y, 1.0f);
|
||||
} else {
|
||||
if (y > 0.0f)
|
||||
return -(PI + atan2(x / y, 1.0f));
|
||||
return -(PI + Atan2(x / y, 1.0f));
|
||||
else
|
||||
return -atan2(x / y, 1.0f);
|
||||
return -Atan2(x / y, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
13
src/core/Instance.cpp
Normal file
13
src/core/Instance.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Instance.h"
|
||||
|
||||
class CInstance_ : public CInstance
|
||||
{
|
||||
public:
|
||||
void dtor() { CInstance::~CInstance(); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x50BE90, &CInstance_::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
10
src/core/Instance.h
Normal file
10
src/core/Instance.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Placeable.h"
|
||||
|
||||
// unused
|
||||
|
||||
class CInstance : CPlaceable
|
||||
{
|
||||
public:
|
||||
};
|
@ -43,7 +43,7 @@ const CMenuScreen aScreens[] = {
|
||||
{ "FET_DIS", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, MENUROW_2, MENUROW_2,
|
||||
MENUACTION_BRIGHTNESS, "FED_BRI", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS,
|
||||
MENUACTION_DRAWDIST, "FEM_LOD", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS,
|
||||
//MENUACTION_FRAMESYNC, "FEM_VSC", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS,
|
||||
MENUACTION_FRAMESYNC, "FEM_VSC", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS,
|
||||
MENUACTION_FRAMELIMIT, "FEM_FRM", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS,
|
||||
MENUACTION_TRAILS, "FED_TRA", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS,
|
||||
MENUACTION_SUBTITLES, "FED_SUB", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS,
|
||||
@ -273,7 +273,7 @@ const CMenuScreen aScreens[] = {
|
||||
MENUACTION_CHANGEMENU, "FET_AUD", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
|
||||
MENUACTION_CHANGEMENU, "FET_DIS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS,
|
||||
MENUACTION_CHANGEMENU, "FET_LAN", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS,
|
||||
//MENUACTION_CHANGEMENU, "FET_PSU", SAVESLOT_NONE, MENUPAGE_SKIN_SELECT,
|
||||
MENUACTION_CHANGEMENU, "FET_PSU", SAVESLOT_NONE, MENUPAGE_SKIN_SELECT,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
|
@ -670,7 +670,7 @@ int16 CPad::GetSteeringLeftRight(void)
|
||||
int16 axis = NewState.LeftStickX;
|
||||
int16 dpad = (NewState.DPadRight - NewState.DPadLeft) / 2;
|
||||
|
||||
if ( abs(axis) > abs(dpad) )
|
||||
if ( Abs(axis) > Abs(dpad) )
|
||||
return axis;
|
||||
else
|
||||
return dpad;
|
||||
@ -703,7 +703,7 @@ int16 CPad::GetSteeringUpDown(void)
|
||||
int16 axis = NewState.LeftStickY;
|
||||
int16 dpad = (NewState.DPadUp - NewState.DPadDown) / 2;
|
||||
|
||||
if ( abs(axis) > abs(dpad) )
|
||||
if ( Abs(axis) > Abs(dpad) )
|
||||
return axis;
|
||||
else
|
||||
return dpad;
|
||||
@ -790,7 +790,7 @@ int16 CPad::GetPedWalkLeftRight(void)
|
||||
int16 axis = NewState.LeftStickX;
|
||||
int16 dpad = (NewState.DPadRight - NewState.DPadLeft) / 2;
|
||||
|
||||
if ( abs(axis) > abs(dpad) )
|
||||
if ( Abs(axis) > Abs(dpad) )
|
||||
return axis;
|
||||
else
|
||||
return dpad;
|
||||
@ -824,7 +824,7 @@ int16 CPad::GetPedWalkUpDown(void)
|
||||
int16 axis = NewState.LeftStickY;
|
||||
int16 dpad = (NewState.DPadDown - NewState.DPadUp) / 2;
|
||||
|
||||
if ( abs(axis) > abs(dpad) )
|
||||
if ( Abs(axis) > Abs(dpad) )
|
||||
return axis;
|
||||
else
|
||||
return dpad;
|
||||
@ -854,7 +854,7 @@ int16 CPad::GetAnalogueUpDown(void)
|
||||
int16 axis = NewState.LeftStickY;
|
||||
int16 dpad = (NewState.DPadDown - NewState.DPadUp) / 2;
|
||||
|
||||
if ( abs(axis) > abs(dpad) )
|
||||
if ( Abs(axis) > Abs(dpad) )
|
||||
return axis;
|
||||
else
|
||||
return dpad;
|
||||
@ -1683,7 +1683,7 @@ int16 CPad::SniperModeLookLeftRight(void)
|
||||
int16 axis = NewState.LeftStickX;
|
||||
int16 dpad = (NewState.DPadRight - NewState.DPadLeft) / 2;
|
||||
|
||||
if ( abs(axis) > abs(dpad) )
|
||||
if ( Abs(axis) > Abs(dpad) )
|
||||
return axis;
|
||||
else
|
||||
return dpad;
|
||||
@ -1694,7 +1694,7 @@ int16 CPad::SniperModeLookUpDown(void)
|
||||
int16 axis = NewState.LeftStickY;
|
||||
int16 dpad = (NewState.DPadUp - NewState.DPadDown) / 2;
|
||||
|
||||
if ( abs(axis) > abs(dpad) )
|
||||
if ( Abs(axis) > Abs(dpad) )
|
||||
return axis;
|
||||
else
|
||||
return dpad;
|
||||
@ -1704,11 +1704,11 @@ int16 CPad::LookAroundLeftRight(void)
|
||||
{
|
||||
float axis = GetPad(0)->NewState.RightStickX;
|
||||
|
||||
if ( fabs(axis) > 85 && !GetLookBehindForPed() )
|
||||
if ( Abs(axis) > 85 && !GetLookBehindForPed() )
|
||||
return (int16) ( (axis + ( ( axis > 0 ) ? -85 : 85) )
|
||||
* (127.0f / 32.0f) ); // 3.96875f
|
||||
|
||||
else if ( TheCamera.Cams[0].Using3rdPersonMouseCam() && fabs(axis) > 10 )
|
||||
else if ( TheCamera.Cams[0].Using3rdPersonMouseCam() && Abs(axis) > 10 )
|
||||
return (int16) ( (axis + ( ( axis > 0 ) ? -10 : 10) )
|
||||
* (127.0f / 64.0f) ); // 1.984375f
|
||||
|
||||
@ -1719,11 +1719,11 @@ int16 CPad::LookAroundUpDown(void)
|
||||
{
|
||||
int16 axis = GetPad(0)->NewState.RightStickY;
|
||||
|
||||
if ( abs(axis) > 85 && !GetLookBehindForPed() )
|
||||
if ( Abs(axis) > 85 && !GetLookBehindForPed() )
|
||||
return (int16) ( (axis + ( ( axis > 0 ) ? -85 : 85) )
|
||||
* (127.0f / 32.0f) ); // 3.96875f
|
||||
|
||||
else if ( TheCamera.Cams[0].Using3rdPersonMouseCam() && abs(axis) > 40 )
|
||||
else if ( TheCamera.Cams[0].Using3rdPersonMouseCam() && Abs(axis) > 40 )
|
||||
return (int16) ( (axis + ( ( axis > 0 ) ? -40 : 40) )
|
||||
* (127.0f / 64.0f) ); // 1.984375f
|
||||
|
||||
|
@ -63,9 +63,17 @@ CPlaceable::IsWithinArea(float x1, float y1, float z1, float x2, float y2, float
|
||||
z1 <= GetPosition().z && GetPosition().z <= z2;
|
||||
}
|
||||
|
||||
class CPlaceable_ : public CPlaceable
|
||||
{
|
||||
public:
|
||||
CPlaceable *ctor(void) { return ::new (this) CPlaceable(); }
|
||||
void dtor(void) { CPlaceable::~CPlaceable(); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x49F9A0, &CPlaceable::ctor, PATCH_JUMP);
|
||||
InjectHook(0x49F9E0, &CPlaceable::dtor, PATCH_JUMP);
|
||||
InjectHook(0x49F9A0, &CPlaceable_::ctor, PATCH_JUMP);
|
||||
InjectHook(0x49F9E0, &CPlaceable_::dtor, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x49FA00, &CPlaceable::SetHeading, PATCH_JUMP);
|
||||
InjectHook(0x49FA50, (bool (CPlaceable::*)(float, float, float, float))&CPlaceable::IsWithinArea, PATCH_JUMP);
|
||||
InjectHook(0x49FAF0, (bool (CPlaceable::*)(float, float, float, float, float, float))&CPlaceable::IsWithinArea, PATCH_JUMP);
|
||||
|
@ -10,17 +10,19 @@ public:
|
||||
|
||||
CPlaceable(void);
|
||||
virtual ~CPlaceable(void);
|
||||
CVector &GetPosition(void) { return *m_matrix.GetPosition(); }
|
||||
CVector &GetRight(void) { return *m_matrix.GetRight(); }
|
||||
CVector &GetForward(void) { return *m_matrix.GetForward(); }
|
||||
CVector &GetUp(void) { return *m_matrix.GetUp(); }
|
||||
CVector &GetPosition(void) { return m_matrix.GetPosition(); }
|
||||
CVector &GetRight(void) { return m_matrix.GetRight(); }
|
||||
CVector &GetForward(void) { return m_matrix.GetForward(); }
|
||||
CVector &GetUp(void) { return m_matrix.GetUp(); }
|
||||
CMatrix &GetMatrix(void) { return m_matrix; }
|
||||
void SetTransform(RwMatrix *m) { m_matrix = CMatrix(m, false); }
|
||||
void SetHeading(float angle);
|
||||
void SetOrientation(float x, float y, float z){
|
||||
CVector pos = m_matrix.GetPosition();
|
||||
m_matrix.SetRotate(x, y, z);
|
||||
m_matrix.Translate(pos);
|
||||
}
|
||||
bool IsWithinArea(float x1, float y1, float x2, float y2);
|
||||
bool IsWithinArea(float x1, float y1, float z1, float x2, float y2, float z2);
|
||||
|
||||
CPlaceable *ctor(void) { return ::new (this) CPlaceable(); }
|
||||
void dtor(void) { this->CPlaceable::~CPlaceable(); }
|
||||
};
|
||||
static_assert(sizeof(CPlaceable) == 0x4C, "CPlaceable: error");
|
||||
|
@ -1,5 +1,14 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "PlayerInfo.h"
|
||||
#include "Frontend.h"
|
||||
|
||||
WRAPPER void CPlayerInfo::MakePlayerSafe(bool) { EAXJMP(0x4A1400); }
|
||||
WRAPPER void CPlayerInfo::MakePlayerSafe(bool) { EAXJMP(0x4A1400); }
|
||||
WRAPPER void CPlayerInfo::LoadPlayerSkin() { EAXJMP(0x4A1700); }
|
||||
WRAPPER void CPlayerInfo::AwardMoneyForExplosion(CVehicle *vehicle) { EAXJMP(0x4A15F0); }
|
||||
|
||||
void CPlayerInfo::SetPlayerSkin(char *skin)
|
||||
{
|
||||
strncpy(m_aSkinName, skin, 32);
|
||||
LoadPlayerSkin();
|
||||
}
|
||||
|
@ -63,10 +63,13 @@ public:
|
||||
bool m_bFastReload;
|
||||
bool m_bGetOutOfJailFree;
|
||||
bool m_bGetOutOfHospitalFree;
|
||||
uint8 m_aSkinName[32];
|
||||
char m_aSkinName[32];
|
||||
RwTexture *m_pSkinTexture;
|
||||
|
||||
void MakePlayerSafe(bool);
|
||||
void LoadPlayerSkin();
|
||||
void AwardMoneyForExplosion(CVehicle *vehicle);
|
||||
void SetPlayerSkin(char* skin);
|
||||
};
|
||||
|
||||
static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerInfo: error");
|
||||
|
@ -469,8 +469,8 @@ void CRadar::DrawRadarMask()
|
||||
|
||||
// Then generate a quarter of the circle
|
||||
for (int j = 0; j < 7; j++) {
|
||||
in.x = corners[i].x * cos(j * (PI / 2.0f / 6.0f));
|
||||
in.y = corners[i].y * sin(j * (PI / 2.0f / 6.0f));
|
||||
in.x = corners[i].x * Cos(j * (PI / 2.0f / 6.0f));
|
||||
in.y = corners[i].y * Sin(j * (PI / 2.0f / 6.0f));
|
||||
TransformRadarPointToScreenSpace(out[j + 1], in);
|
||||
};
|
||||
|
||||
@ -562,8 +562,8 @@ void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float
|
||||
for (uint32 i = 0; i < 4; i++) {
|
||||
oldPosn[i] = curPosn[i];
|
||||
|
||||
curPosn[i].x = x + (oldPosn[i].x - x) * cosf(angle) + (oldPosn[i].y - y) * sinf(angle);
|
||||
curPosn[i].y = y - (oldPosn[i].x - x) * sinf(angle) + (oldPosn[i].y - y) * cosf(angle);
|
||||
curPosn[i].x = x + (oldPosn[i].x - x) * Cos(angle) + (oldPosn[i].y - y) * Sin(angle);
|
||||
curPosn[i].y = y - (oldPosn[i].x - x) * Sin(angle) + (oldPosn[i].y - y) * Cos(angle);
|
||||
}
|
||||
|
||||
sprite->Draw(curPosn[2].x, curPosn[2].y, curPosn[3].x, curPosn[3].y, curPosn[0].x, curPosn[0].y, curPosn[1].x, curPosn[1].y, CRGBA(255, 255, 255, alpha));
|
||||
@ -868,8 +868,8 @@ void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D
|
||||
{
|
||||
float s, c;
|
||||
|
||||
s = -sin(TheCamera.GetForward().Heading());
|
||||
c = cos(TheCamera.GetForward().Heading());
|
||||
s = -Sin(TheCamera.GetForward().Heading());
|
||||
c = Cos(TheCamera.GetForward().Heading());
|
||||
|
||||
if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN1 || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWNPED) {
|
||||
s = 0.0f;
|
||||
@ -885,8 +885,8 @@ void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D
|
||||
else
|
||||
forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind;
|
||||
|
||||
s = -sin(forward.Heading());
|
||||
c = cos(forward.Heading());
|
||||
s = -Sin(forward.Heading());
|
||||
c = Cos(forward.Heading());
|
||||
}
|
||||
|
||||
out.x = s * in.y + c * in.x;
|
||||
@ -915,8 +915,8 @@ void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D
|
||||
c = 1.0f;
|
||||
}
|
||||
else if (TheCamera.GetLookDirection() == LOOKING_FORWARD) {
|
||||
s = sin(TheCamera.GetForward().Heading());
|
||||
c = cos(TheCamera.GetForward().Heading());
|
||||
s = Sin(TheCamera.GetForward().Heading());
|
||||
c = Cos(TheCamera.GetForward().Heading());
|
||||
}
|
||||
else {
|
||||
CVector forward;
|
||||
@ -928,8 +928,8 @@ void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D
|
||||
else
|
||||
forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind;
|
||||
|
||||
s = sin(forward.Heading());
|
||||
c = cos(forward.Heading());
|
||||
s = Sin(forward.Heading());
|
||||
c = Cos(forward.Heading());
|
||||
}
|
||||
|
||||
float x = (in.x - vec2DRadarOrigin.x) * (1.0f / m_RadarRange);
|
||||
|
@ -1,6 +1,13 @@
|
||||
#include "common.h"
|
||||
#include "Stats.h"
|
||||
|
||||
int32& CStats::DaysPassed = *(int32*)0x8F2BB8;
|
||||
int32& CStats::HeadShots = *(int32*)0x8F647C;
|
||||
bool& CStats::CommercialPassed = *(bool*)0x8F4334;
|
||||
int32 &CStats::DaysPassed = *(int32*)0x8F2BB8;
|
||||
int32 &CStats::HeadShots = *(int32*)0x8F647C;
|
||||
bool& CStats::CommercialPassed = *(bool*)0x8F4334;
|
||||
int32 &CStats::NumberKillFrenziesPassed = *(int32*)0x8E287C;
|
||||
int32 &CStats::PeopleKilledByOthers = *(int32*)0x8E2C50;
|
||||
|
||||
void CStats::AnotherKillFrenzyPassed()
|
||||
{
|
||||
++NumberKillFrenziesPassed;
|
||||
}
|
@ -3,7 +3,12 @@
|
||||
class CStats
|
||||
{
|
||||
public:
|
||||
static int32& DaysPassed;
|
||||
static int32& HeadShots;
|
||||
static int32 &DaysPassed;
|
||||
static int32 &HeadShots;
|
||||
static bool& CommercialPassed;
|
||||
static int32 &NumberKillFrenziesPassed;
|
||||
static int32 &PeopleKilledByOthers;
|
||||
|
||||
public:
|
||||
static void AnotherKillFrenzyPassed();
|
||||
};
|
@ -2131,8 +2131,8 @@ CStreaming::DeleteRwObjectsAfterDeath(const CVector &pos)
|
||||
|
||||
for(x = 0; x < NUMSECTORS_X; x++)
|
||||
for(y = 0; y < NUMSECTORS_Y; y++)
|
||||
if(fabs(ix - x) > 3.0f &&
|
||||
fabs(iy - y) > 3.0f){
|
||||
if(Abs(ix - x) > 3.0f &&
|
||||
Abs(iy - y) > 3.0f){
|
||||
sect = CWorld::GetSector(x, y);
|
||||
DeleteRwObjectsInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS]);
|
||||
DeleteRwObjectsInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]);
|
||||
@ -2158,7 +2158,7 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem)
|
||||
ix = CWorld::GetSectorIndexX(TheCamera.GetPosition().x);
|
||||
iy = CWorld::GetSectorIndexX(TheCamera.GetPosition().y);
|
||||
|
||||
if(fabs(TheCamera.GetForward().x) > fabs(TheCamera.GetForward().y)){
|
||||
if(Abs(TheCamera.GetForward().x) > Abs(TheCamera.GetForward().y)){
|
||||
// looking west/east
|
||||
|
||||
ymin = max(iy - 10, 0);
|
||||
@ -2312,13 +2312,13 @@ CStreaming::DeleteRwObjectsInOverlapSectorList(CPtrList &list, int32 x, int32 y)
|
||||
e = (CEntity*)node->item;
|
||||
if(e->m_rwObject && !e->bStreamingDontDelete && !e->bImBeingRendered){
|
||||
// Now this is pretty weird...
|
||||
if(fabs(CWorld::GetSectorIndexX(e->GetPosition().x) - x) >= 2.0f)
|
||||
if(Abs(CWorld::GetSectorIndexX(e->GetPosition().x) - x) >= 2.0f)
|
||||
// {
|
||||
e->DeleteRwObject();
|
||||
// return; // BUG?
|
||||
// }
|
||||
else // FIX?
|
||||
if(fabs(CWorld::GetSectorIndexY(e->GetPosition().y) - y) >= 2.0f)
|
||||
if(Abs(CWorld::GetSectorIndexY(e->GetPosition().y) - y) >= 2.0f)
|
||||
e->DeleteRwObject();
|
||||
}
|
||||
}
|
||||
|
@ -210,12 +210,56 @@ AsciiToUnicode(const char *src, uint16 *dst)
|
||||
while((*dst++ = *src++) != '\0');
|
||||
}
|
||||
|
||||
char*
|
||||
UnicodeToAscii(wchar *src)
|
||||
{
|
||||
static char aStr[256];
|
||||
int len;
|
||||
for(len = 0; src && *src != 0 && len < 256-1; len++, src++)
|
||||
if(*src < 256)
|
||||
aStr[len] = *src;
|
||||
else
|
||||
aStr[len] = '#';
|
||||
aStr[len] = '\0';
|
||||
return aStr;
|
||||
}
|
||||
|
||||
char*
|
||||
UnicodeToAsciiForSaveLoad(wchar *src)
|
||||
{
|
||||
// exact same code as above
|
||||
static char aStr[256];
|
||||
int len;
|
||||
for(len = 0; src && *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);
|
||||
|
@ -1,6 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
void AsciiToUnicode(const char *src, wchar *dst);
|
||||
char *UnicodeToAscii(wchar *src);
|
||||
char *UnicodeToAsciiForSaveLoad(wchar *src);
|
||||
void UnicodeStrcpy(wchar *dst, const wchar *src);
|
||||
int UnicodeStrlen(const wchar *str);
|
||||
void TextCopy(wchar *dst, const wchar *src);
|
||||
|
||||
struct CKeyEntry
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include "patcher.h"
|
||||
#include "Wanted.h"
|
||||
|
||||
int32 &CWanted::MaximumWantedLevel = *(int32*)0x5F7714;
|
||||
|
||||
bool CWanted::AreSwatRequired()
|
||||
{
|
||||
return m_nWantedLevel >= 4;
|
||||
@ -32,5 +34,102 @@ int CWanted::NumOfHelisRequired()
|
||||
return 2;
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void CWanted::SetWantedLevel(int32 level)
|
||||
{
|
||||
ClearQdCrimes();
|
||||
switch (level) {
|
||||
case NOTWANTED:
|
||||
m_nChaos = 0;
|
||||
break;
|
||||
case WANTEDLEVEL_1:
|
||||
m_nChaos = 60;
|
||||
break;
|
||||
case WANTEDLEVEL_2:
|
||||
m_nChaos = 220;
|
||||
break;
|
||||
case WANTEDLEVEL_3:
|
||||
m_nChaos = 420;
|
||||
break;
|
||||
case WANTEDLEVEL_4:
|
||||
m_nChaos = 820;
|
||||
break;
|
||||
case WANTEDLEVEL_5:
|
||||
m_nChaos = 1620;
|
||||
break;
|
||||
case WANTEDLEVEL_6:
|
||||
m_nChaos = 3220;
|
||||
break;
|
||||
default:
|
||||
if (level > MaximumWantedLevel)
|
||||
m_nChaos = MaximumWantedLevel;
|
||||
break;
|
||||
}
|
||||
UpdateWantedLevel();
|
||||
}
|
||||
|
||||
void CWanted::SetWantedLevelNoDrop(int32 level)
|
||||
{
|
||||
if (level > m_nWantedLevel)
|
||||
SetWantedLevel(level);
|
||||
}
|
||||
|
||||
void CWanted::ClearQdCrimes()
|
||||
{
|
||||
for (int i = 0; i < 16; i++) {
|
||||
m_sCrimes[i].m_eCrimeType = CRIME_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
void CWanted::UpdateWantedLevel()
|
||||
{
|
||||
int32 CurrWantedLevel = m_nWantedLevel;
|
||||
|
||||
if (m_nChaos >= 0 && m_nChaos < 40) {
|
||||
m_nWantedLevel = NOTWANTED;
|
||||
m_MaximumLawEnforcerVehicles = 0;
|
||||
m_MaxCops = 0;
|
||||
m_RoadblockDensity = 0;
|
||||
}
|
||||
else if (m_nChaos >= 40 && m_nChaos < 200) {
|
||||
m_nWantedLevel = WANTEDLEVEL_1;
|
||||
m_MaximumLawEnforcerVehicles = 1;
|
||||
m_MaxCops = 1;
|
||||
m_RoadblockDensity = 0;
|
||||
}
|
||||
else if (m_nChaos >= 200 && m_nChaos < 400) {
|
||||
m_nWantedLevel = WANTEDLEVEL_2;
|
||||
m_MaximumLawEnforcerVehicles = 2;
|
||||
m_MaxCops = 3;
|
||||
m_RoadblockDensity = 0;
|
||||
}
|
||||
else if (m_nChaos >= 400 && m_nChaos < 800) {
|
||||
m_nWantedLevel = WANTEDLEVEL_3;
|
||||
m_MaximumLawEnforcerVehicles = 2;
|
||||
m_MaxCops = 4;
|
||||
m_RoadblockDensity = 4;
|
||||
}
|
||||
else if (m_nChaos >= 800 && m_nChaos < 1600) {
|
||||
m_nWantedLevel = WANTEDLEVEL_4;
|
||||
m_MaximumLawEnforcerVehicles = 2;
|
||||
m_MaxCops = 6;
|
||||
m_RoadblockDensity = 8;
|
||||
}
|
||||
else if (m_nChaos >= 1600 && m_nChaos < 3200) {
|
||||
m_nWantedLevel = WANTEDLEVEL_5;
|
||||
m_MaximumLawEnforcerVehicles = 3;
|
||||
m_MaxCops = 8;
|
||||
m_RoadblockDensity = 10;
|
||||
}
|
||||
else if (m_nChaos >= 3200) {
|
||||
m_nWantedLevel = WANTEDLEVEL_6;
|
||||
m_MaximumLawEnforcerVehicles = 3;
|
||||
m_MaxCops = 10;
|
||||
m_RoadblockDensity = 12;
|
||||
}
|
||||
|
||||
if (CurrWantedLevel != m_nWantedLevel)
|
||||
m_nLastWantedLevelChange = CTimer::GetTimeInMilliseconds();
|
||||
}
|
@ -20,11 +20,11 @@ public:
|
||||
int32 m_nLastUpdateTime;
|
||||
int32 m_nLastWantedLevelChange;
|
||||
float m_fCrimeSensitivity;
|
||||
uint8 m_bCurrentCops;
|
||||
uint8 m_bMaxCops;
|
||||
uint8 m_bMaximumLawEnforcerVehicles;
|
||||
uint8 m_CurrentCops;
|
||||
uint8 m_MaxCops;
|
||||
uint8 m_MaximumLawEnforcerVehicles;
|
||||
int8 field_19;
|
||||
int16 m_wRoadblockDensity;
|
||||
int16 m_RoadblockDensity;
|
||||
uint8 m_IsIgnoredByCops : 1;
|
||||
uint8 m_IsIgnoredByEveryOne : 1;
|
||||
uint8 m_IsSwatRequired : 1;
|
||||
@ -34,12 +34,17 @@ public:
|
||||
int32 m_nWantedLevel;
|
||||
CCrime m_sCrimes[16];
|
||||
CCopPed *m_pCops[10];
|
||||
static int32 &MaximumWantedLevel;
|
||||
|
||||
public:
|
||||
bool AreSwatRequired();
|
||||
bool AreFbiRequired();
|
||||
bool AreArmyRequired();
|
||||
int NumOfHelisRequired();
|
||||
void SetWantedLevel(int32);
|
||||
void SetWantedLevelNoDrop(int32 level);
|
||||
void ClearQdCrimes();
|
||||
void UpdateWantedLevel();
|
||||
};
|
||||
|
||||
static_assert(sizeof(CWanted) == 0x204, "CWanted: error");
|
||||
|
@ -564,6 +564,82 @@ CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bo
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CWorld::FindObjectsInRangeSectorList(CPtrList &list, CVector ¢re, float distance, bool ignoreZ, short *nextObject, short lastObject, CEntity **objects)
|
||||
{
|
||||
float distSqr = distance * distance;
|
||||
float objDistSqr;
|
||||
|
||||
for (CPtrNode *node = list.first; node; node = node->next) {
|
||||
CEntity *object = (CEntity*)node->item;
|
||||
if (object->m_scanCode != CWorld::GetCurrentScanCode()) {
|
||||
object->m_scanCode = CWorld::GetCurrentScanCode();
|
||||
|
||||
CVector diff = centre - object->GetPosition();
|
||||
if (ignoreZ)
|
||||
objDistSqr = diff.MagnitudeSqr2D();
|
||||
else
|
||||
objDistSqr = diff.MagnitudeSqr();
|
||||
|
||||
if (objDistSqr < distSqr && *nextObject < lastObject) {
|
||||
if (objects) {
|
||||
objects[*nextObject] = object;
|
||||
}
|
||||
(*nextObject)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CWorld::FindObjectsInRange(CVector ¢re, float distance, bool ignoreZ, short *nextObject, short lastObject, CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies)
|
||||
{
|
||||
int minX = GetSectorIndexX(centre.x - distance);
|
||||
if (minX <= 0)
|
||||
minX = 0;
|
||||
|
||||
int minY = GetSectorIndexY(centre.y - distance);
|
||||
if (minY <= 0)
|
||||
minY = 0;
|
||||
|
||||
int maxX = GetSectorIndexX(centre.x + distance);
|
||||
if (maxX >= 100)
|
||||
maxX = 100;
|
||||
|
||||
int maxY = GetSectorIndexY(centre.y + distance);
|
||||
if (maxY >= 100)
|
||||
maxY = 100;
|
||||
|
||||
AdvanceCurrentScanCode();
|
||||
|
||||
*nextObject = 0;
|
||||
for(int curY = minY; curY <= maxY; curY++) {
|
||||
for(int curX = minX; curX <= maxX; curX++) {
|
||||
CSector *sector = GetSector(curX, curY);
|
||||
if (checkBuildings) {
|
||||
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], centre, distance, ignoreZ, nextObject, lastObject, objects);
|
||||
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects);
|
||||
}
|
||||
if (checkVehicles) {
|
||||
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES], centre, distance, ignoreZ, nextObject, lastObject, objects);
|
||||
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects);
|
||||
}
|
||||
if (checkPeds) {
|
||||
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS], centre, distance, ignoreZ, nextObject, lastObject, objects);
|
||||
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects);
|
||||
}
|
||||
if (checkObjects) {
|
||||
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS], centre, distance, ignoreZ, nextObject, lastObject, objects);
|
||||
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects);
|
||||
}
|
||||
if (checkDummies) {
|
||||
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES], centre, distance, ignoreZ, nextObject, lastObject, objects);
|
||||
CWorld::FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float
|
||||
CWorld::FindGroundZForCoord(float x, float y)
|
||||
{
|
||||
@ -712,6 +788,8 @@ STARTPATCHES
|
||||
InjectHook(0x4B2000, CWorld::GetIsLineOfSightSectorClear, PATCH_JUMP);
|
||||
InjectHook(0x4B2160, CWorld::GetIsLineOfSightSectorListClear, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x4B2200, CWorld::FindObjectsInRange, PATCH_JUMP);
|
||||
InjectHook(0x4B2540, CWorld::FindObjectsInRangeSectorList, PATCH_JUMP);
|
||||
InjectHook(0x4B3A80, CWorld::FindGroundZForCoord, PATCH_JUMP);
|
||||
InjectHook(0x4B3AE0, CWorld::FindGroundZFor3DCoord, PATCH_JUMP);
|
||||
InjectHook(0x4B3B50, CWorld::FindRoofZFor3DCoord, PATCH_JUMP);
|
||||
|
@ -93,7 +93,9 @@ public:
|
||||
static bool GetIsLineOfSightClear(const CVector &point1, const CVector &point2, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
|
||||
static bool GetIsLineOfSightSectorClear(CSector §or, const CColLine &line, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
|
||||
static bool GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
|
||||
|
||||
|
||||
static void FindObjectsInRangeSectorList(CPtrList&, CVector&, float, bool, short*, short, CEntity**);
|
||||
static void FindObjectsInRange(CVector&, float, bool, short*, short, CEntity**, bool, bool, bool, bool, bool);
|
||||
static float FindGroundZForCoord(float x, float y);
|
||||
static float FindGroundZFor3DCoord(float x, float y, float z, bool *found);
|
||||
static float FindRoofZFor3DCoord(float x, float y, float z, bool *found);
|
||||
|
@ -97,6 +97,7 @@ extern void **rwengine;
|
||||
#define SCREEN_SCALE_AR(a) (a)
|
||||
#endif
|
||||
|
||||
#include "math/maths.h"
|
||||
#include "math/Vector.h"
|
||||
#include "math/Vector2D.h"
|
||||
#include "math/Matrix.h"
|
||||
|
@ -30,6 +30,8 @@ enum Config {
|
||||
NUMDUMMIES = 2802, // 2368 on PS2
|
||||
NUMAUDIOSCRIPTOBJECTS = 256,
|
||||
|
||||
NUMTEMPOBJECTS = 30,
|
||||
|
||||
// Link list lengths
|
||||
// TODO: alpha list
|
||||
NUMCOLCACHELINKS = 200,
|
||||
@ -114,3 +116,4 @@ enum Config {
|
||||
#define FIX_BUGS // fix bugs in the game, TODO: use this more
|
||||
#define KANGAROO_CHEAT
|
||||
#define ASPECT_RATIO_SCALE
|
||||
#define USE_DEBUG_SCRIPT_LOADER
|
@ -48,14 +48,20 @@
|
||||
#include "RpAnimBlend.h"
|
||||
#include "Frontend.h"
|
||||
|
||||
#define DEFAULT_VIEWWINDOW (tan(DEGTORAD(CDraw::GetFOV() * 0.5f)))
|
||||
#define DEFAULT_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetFOV() * 0.5f)))
|
||||
|
||||
|
||||
GlobalScene &Scene = *(GlobalScene*)0x726768;
|
||||
|
||||
uint8 work_buff[55000];
|
||||
char gString[256];
|
||||
//char gString[256];
|
||||
//char gString2[512];
|
||||
//wchar gUString[256];
|
||||
//wchar gUString2[256];
|
||||
char *gString = (char*)0x711B40;
|
||||
char *gString2 = (char*)0x878A40;
|
||||
wchar *gUString = (wchar*)0x74B018;
|
||||
wchar *gUString2 = (wchar*)0x6EDD70;
|
||||
|
||||
bool &b_FoundRecentSavedGameWantToLoad = *(bool*)0x95CDA8;
|
||||
|
||||
|
@ -8,8 +8,14 @@ struct GlobalScene
|
||||
extern GlobalScene &Scene;
|
||||
|
||||
extern uint8 work_buff[55000];
|
||||
extern char gString[256];
|
||||
//extern char gString[256];
|
||||
//extern char gString2[512];
|
||||
//extern wchar gUString[256];
|
||||
//extern wchar gUString2[256];
|
||||
extern char *gString;
|
||||
extern char *gString2;
|
||||
extern wchar *gUString;
|
||||
extern wchar *gUString2;
|
||||
extern bool &b_FoundRecentSavedGameWantToLoad;
|
||||
|
||||
class CSprite2d;
|
||||
|
@ -57,27 +57,6 @@ mysrand(unsigned int seed)
|
||||
myrand_seed = seed;
|
||||
}
|
||||
|
||||
int (*open_script_orig)(const char *path, const char *mode);
|
||||
int
|
||||
open_script(const char *path, const char *mode)
|
||||
{
|
||||
static int scriptToLoad = 1;
|
||||
|
||||
if(GetAsyncKeyState('G') & 0x8000)
|
||||
scriptToLoad = 0;
|
||||
if(GetAsyncKeyState('R') & 0x8000)
|
||||
scriptToLoad = 1;
|
||||
if(GetAsyncKeyState('D') & 0x8000)
|
||||
scriptToLoad = 2;
|
||||
|
||||
switch(scriptToLoad){
|
||||
case 0: return open_script_orig(path, mode);
|
||||
case 1: return open_script_orig("main_freeroam.scm", mode);
|
||||
case 2: return open_script_orig("main_d.scm", mode);
|
||||
}
|
||||
return open_script_orig(path, mode);
|
||||
}
|
||||
|
||||
int gDbgSurf;
|
||||
|
||||
void (*DebugMenuProcess)(void);
|
||||
@ -175,6 +154,19 @@ spawnCar(int id)
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
FixCar(void)
|
||||
{
|
||||
CVehicle *veh = FindPlayerVehicle();
|
||||
if(veh == nil)
|
||||
return;
|
||||
veh->m_fHealth = 1000.0f;
|
||||
if(!veh->IsCar())
|
||||
return;
|
||||
((CAutomobile*)veh)->Damage.SetEngineStatus(0);
|
||||
((CAutomobile*)veh)->Fix();
|
||||
}
|
||||
|
||||
void
|
||||
DebugMenuPopulate(void)
|
||||
{
|
||||
@ -219,6 +211,7 @@ DebugMenuPopulate(void)
|
||||
DebugMenuAddCmd("Cheats", "Strong grip", StrongGripCheat);
|
||||
DebugMenuAddCmd("Cheats", "Nasty limbs", NastyLimbsCheat);
|
||||
|
||||
DebugMenuAddCmd("Debug", "Fix Car", FixCar);
|
||||
DebugMenuAddVarBool8("Debug", "Show Ped Road Groups", (int8*)&gbShowPedRoadGroups, nil);
|
||||
DebugMenuAddVarBool8("Debug", "Show Car Road Groups", (int8*)&gbShowCarRoadGroups, nil);
|
||||
DebugMenuAddVarBool8("Debug", "Show Collision Polys", (int8*)&gbShowCollisionPolys, nil);
|
||||
@ -356,7 +349,7 @@ patch()
|
||||
Patch<WORD>(0x5382BF, 0x0EEB);
|
||||
InjectHook(0x5382EC, HeadlightsFix, PATCH_JUMP);
|
||||
|
||||
InterceptCall(&open_script_orig, open_script, 0x438869);
|
||||
// InterceptCall(&open_script_orig, open_script, 0x438869);
|
||||
|
||||
// InterceptCall(&RsEventHandler_orig, delayedPatches10, 0x58275E);
|
||||
}
|
||||
|
@ -21,8 +21,15 @@ CBuilding::ReplaceWithNewModel(int32 id)
|
||||
CStreaming::RequestModel(id, STREAMFLAGS_DONT_REMOVE);
|
||||
}
|
||||
|
||||
class CBuilding_ : public CBuilding
|
||||
{
|
||||
public:
|
||||
CBuilding *ctor(void) { return ::new (this) CBuilding(); }
|
||||
void dtor(void) { CBuilding::~CBuilding(); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x4057D0, &CBuilding::ctor, PATCH_JUMP);
|
||||
InjectHook(0x405800, &CBuilding::dtor, PATCH_JUMP);
|
||||
InjectHook(0x4057D0, &CBuilding_::ctor, PATCH_JUMP);
|
||||
InjectHook(0x405800, &CBuilding_::dtor, PATCH_JUMP);
|
||||
InjectHook(0x405850, &CBuilding::ReplaceWithNewModel, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -15,8 +15,5 @@ public:
|
||||
void ReplaceWithNewModel(int32 id);
|
||||
|
||||
virtual bool GetIsATreadable(void) { return false; }
|
||||
|
||||
CBuilding *ctor(void) { return ::new (this) CBuilding(); }
|
||||
void dtor(void) { this->CBuilding::~CBuilding(); }
|
||||
};
|
||||
static_assert(sizeof(CBuilding) == 0x64, "CBuilding: error");
|
||||
|
@ -51,8 +51,16 @@ CDummy::Remove(void)
|
||||
}
|
||||
}
|
||||
|
||||
class CDummy_ : public CDummy
|
||||
{
|
||||
public:
|
||||
void Add_(void) { CDummy::Add(); }
|
||||
void Remove_(void) { CDummy::Remove(); }
|
||||
void dtor(void) { CDummy::~CDummy(); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x473810, &CDummy::dtor, PATCH_JUMP);
|
||||
InjectHook(0x473860, &CDummy::Add_, PATCH_JUMP);
|
||||
InjectHook(0x473AD0, &CDummy::Remove_, PATCH_JUMP);
|
||||
InjectHook(0x473810, &CDummy_::dtor, PATCH_JUMP);
|
||||
InjectHook(0x473860, &CDummy_::Add_, PATCH_JUMP);
|
||||
InjectHook(0x473AD0, &CDummy_::Remove_, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -14,10 +14,5 @@ public:
|
||||
|
||||
static void *operator new(size_t);
|
||||
static void operator delete(void*, size_t);
|
||||
|
||||
// to make patching virtual functions possible
|
||||
void Add_(void) { CDummy::Add(); }
|
||||
void Remove_(void) { CDummy::Remove(); }
|
||||
void dtor(void) { this->CDummy::~CDummy(); }
|
||||
};
|
||||
static_assert(sizeof(CDummy) == 0x68, "CDummy: error");
|
||||
|
@ -632,7 +632,7 @@ CEntity::ProcessLightsForEntity(void)
|
||||
lightOn = true;
|
||||
else
|
||||
lightFlickering = true;
|
||||
if((CTimer::GetTimeInMilliseconds()>>1 ^ m_randomSeed) & 3)
|
||||
if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3)
|
||||
lightOn = true;
|
||||
break;
|
||||
case LIGHT_FLICKER_NIGHT:
|
||||
@ -641,7 +641,7 @@ CEntity::ProcessLightsForEntity(void)
|
||||
lightOn = true;
|
||||
else
|
||||
lightFlickering = true;
|
||||
if((CTimer::GetTimeInMilliseconds()>>1 ^ m_randomSeed) & 3)
|
||||
if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3)
|
||||
lightOn = true;
|
||||
}
|
||||
break;
|
||||
@ -680,7 +680,7 @@ CEntity::ProcessLightsForEntity(void)
|
||||
lightOn = true;
|
||||
else
|
||||
lightFlickering = true;
|
||||
if((CTimer::GetTimeInMilliseconds()>>1 ^ m_randomSeed*8) & 3)
|
||||
if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3)
|
||||
lightOn = true;
|
||||
}
|
||||
break;
|
||||
@ -693,7 +693,7 @@ CEntity::ProcessLightsForEntity(void)
|
||||
lightOn = true;
|
||||
else
|
||||
lightFlickering = true;
|
||||
if((CTimer::GetTimeInMilliseconds()>>1 ^ m_randomSeed*8) & 3)
|
||||
if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3)
|
||||
lightOn = true;
|
||||
}
|
||||
}
|
||||
@ -806,17 +806,17 @@ CEntity::ModifyMatrixForTreeInWind(void)
|
||||
}else if(CWeather::Wind >= 0.2){
|
||||
t = (uintptr)this + CTimer::GetTimeInMilliseconds();
|
||||
f = (t & 0xFFF)/(float)0x1000;
|
||||
flutter = sin(f * 6.28f);
|
||||
flutter = Sin(f * 6.28f);
|
||||
strength = 0.008f;
|
||||
}else{
|
||||
t = (uintptr)this + CTimer::GetTimeInMilliseconds();
|
||||
f = (t & 0xFFF)/(float)0x1000;
|
||||
flutter = sin(f * 6.28f);
|
||||
flutter = Sin(f * 6.28f);
|
||||
strength = 0.005f;
|
||||
}
|
||||
|
||||
mat.GetUp()->x = strength * flutter;
|
||||
mat.GetUp()->y = mat.GetUp()->x;
|
||||
mat.GetUp().x = strength * flutter;
|
||||
mat.GetUp().y = mat.GetUp().x;
|
||||
|
||||
mat.UpdateRW();
|
||||
UpdateRwFrame();
|
||||
@ -847,7 +847,7 @@ CEntity::ModifyMatrixForBannerInWind(void)
|
||||
else
|
||||
strength = 0.66f;
|
||||
|
||||
t = ((int)(GetMatrix().GetPosition()->x + GetMatrix().GetPosition()->y) << 10) + 16*CTimer::GetTimeInMilliseconds();
|
||||
t = ((int)(GetMatrix().GetPosition().x + GetMatrix().GetPosition().y) << 10) + 16*CTimer::GetTimeInMilliseconds();
|
||||
f = (t & 0x7FF)/(float)0x800;
|
||||
flutter = f * BannerWindTabel[(t>>11)+1 & 0x1F] +
|
||||
(1.0f - f) * BannerWindTabel[(t>>11) & 0x1F];
|
||||
@ -857,7 +857,7 @@ CEntity::ModifyMatrixForBannerInWind(void)
|
||||
right.z = 0.0f;
|
||||
right.Normalise();
|
||||
up = right * flutter;
|
||||
up.z = sqrt(sq(1.0f) - sq(flutter));
|
||||
up.z = Sqrt(sq(1.0f) - sq(flutter));
|
||||
GetRight() = CrossProduct(GetForward(), up);
|
||||
GetUp() = up;
|
||||
|
||||
@ -865,10 +865,35 @@ CEntity::ModifyMatrixForBannerInWind(void)
|
||||
UpdateRwFrame();
|
||||
}
|
||||
|
||||
class CEntity_ : public CEntity
|
||||
{
|
||||
public:
|
||||
CEntity *ctor(void) { return ::new (this) CEntity(); }
|
||||
void dtor(void) { this->CEntity::~CEntity(); }
|
||||
void Add_(void) { CEntity::Add(); }
|
||||
void Remove_(void) { CEntity::Remove(); }
|
||||
void SetModelIndex_(uint32 i) { CEntity::SetModelIndex(i); }
|
||||
void CreateRwObject_(void) { CEntity::CreateRwObject(); }
|
||||
void DeleteRwObject_(void) { CEntity::DeleteRwObject(); }
|
||||
CRect GetBoundRect_(void) { return CEntity::GetBoundRect(); }
|
||||
void PreRender_(void) { CEntity::PreRender(); }
|
||||
void Render_(void) { CEntity::Render(); }
|
||||
bool SetupLighting_(void) { return CEntity::SetupLighting(); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x473C30, &CEntity::ctor, PATCH_JUMP);
|
||||
InjectHook(0x473E40, &CEntity::dtor, PATCH_JUMP);
|
||||
InjectHook(0x473E70, &CEntity::SetModelIndex_, PATCH_JUMP);
|
||||
InjectHook(0x473C30, &CEntity_::ctor, PATCH_JUMP);
|
||||
InjectHook(0x473E40, &CEntity_::dtor, PATCH_JUMP);
|
||||
InjectHook(0x473E70, &CEntity_::SetModelIndex_, PATCH_JUMP);
|
||||
InjectHook(0x475080, &CEntity_::Add_, PATCH_JUMP);
|
||||
InjectHook(0x475310, &CEntity_::Remove_, PATCH_JUMP);
|
||||
InjectHook(0x473EA0, &CEntity_::CreateRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x473F90, &CEntity_::DeleteRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x474000, &CEntity_::GetBoundRect_, PATCH_JUMP);
|
||||
InjectHook(0x474350, &CEntity_::PreRender_, PATCH_JUMP);
|
||||
InjectHook(0x474BD0, &CEntity_::Render_, PATCH_JUMP);
|
||||
InjectHook(0x4A7C60, &CEntity_::SetupLighting_, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x4742C0, (void (CEntity::*)(CVector&))&CEntity::GetBoundCentre, PATCH_JUMP);
|
||||
InjectHook(0x474310, &CEntity::GetBoundRadius, PATCH_JUMP);
|
||||
InjectHook(0x474C10, &CEntity::GetIsTouching, PATCH_JUMP);
|
||||
@ -889,13 +914,4 @@ STARTPATCHES
|
||||
InjectHook(0x475670, &CEntity::ModifyMatrixForTreeInWind, PATCH_JUMP);
|
||||
InjectHook(0x475830, &CEntity::ModifyMatrixForBannerInWind, PATCH_JUMP);
|
||||
InjectHook(0x4FA530, &CEntity::ProcessLightsForEntity, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x475080, &CEntity::Add_, PATCH_JUMP);
|
||||
InjectHook(0x475310, &CEntity::Remove_, PATCH_JUMP);
|
||||
InjectHook(0x473EA0, &CEntity::CreateRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x473F90, &CEntity::DeleteRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x474000, &CEntity::GetBoundRect_, PATCH_JUMP);
|
||||
InjectHook(0x474350, &CEntity::PreRender_, PATCH_JUMP);
|
||||
InjectHook(0x474BD0, &CEntity::Render_, PATCH_JUMP);
|
||||
InjectHook(0x4A7C60, &CEntity::SetupLighting_, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -94,13 +94,15 @@ public:
|
||||
uint16 m_level; // int16
|
||||
CReference *m_pFirstReference;
|
||||
|
||||
CColModel *GetColModel(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); }
|
||||
|
||||
CEntity(void);
|
||||
virtual ~CEntity(void);
|
||||
~CEntity(void);
|
||||
|
||||
virtual void Add(void);
|
||||
virtual void Remove(void);
|
||||
virtual void SetModelIndex(uint32 i) { m_modelIndex = i; CreateRwObject(); }
|
||||
virtual void SetModelIndexNoCreate(uint32 i) { m_modelIndex = i; }
|
||||
virtual void SetModelIndex(uint32 id) { m_modelIndex = id; CreateRwObject(); }
|
||||
virtual void SetModelIndexNoCreate(uint32 id) { m_modelIndex = id; }
|
||||
virtual void CreateRwObject(void);
|
||||
virtual void DeleteRwObject(void);
|
||||
virtual CRect GetBoundRect(void);
|
||||
@ -145,19 +147,5 @@ public:
|
||||
void ModifyMatrixForTreeInWind(void);
|
||||
void ModifyMatrixForBannerInWind(void);
|
||||
void ProcessLightsForEntity(void);
|
||||
|
||||
|
||||
// to make patching virtual functions possible
|
||||
CEntity *ctor(void) { return ::new (this) CEntity(); }
|
||||
void dtor(void) { this->CEntity::~CEntity(); }
|
||||
void Add_(void) { CEntity::Add(); }
|
||||
void Remove_(void) { CEntity::Remove(); }
|
||||
void SetModelIndex_(uint32 i) { CEntity::SetModelIndex(i); }
|
||||
void CreateRwObject_(void) { CEntity::CreateRwObject(); }
|
||||
void DeleteRwObject_(void) { CEntity::DeleteRwObject(); }
|
||||
CRect GetBoundRect_(void) { return CEntity::GetBoundRect(); }
|
||||
void PreRender_(void) { CEntity::PreRender(); }
|
||||
void Render_(void) { CEntity::Render(); }
|
||||
bool SetupLighting_(void) { return CEntity::SetupLighting(); }
|
||||
};
|
||||
static_assert(sizeof(CEntity) == 0x64, "CEntity: error");
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "World.h"
|
||||
#include "Timer.h"
|
||||
#include "ModelIndices.h"
|
||||
#include "Treadable.h"
|
||||
#include "Vehicle.h"
|
||||
#include "Ped.h"
|
||||
#include "Object.h"
|
||||
@ -32,7 +33,7 @@ CPhysical::CPhysical(void)
|
||||
|
||||
m_nCollisionRecords = 0;
|
||||
for(i = 0; i < 6; i++)
|
||||
m_aCollisionRecords[0] = nil;
|
||||
m_aCollisionRecords[i] = nil;
|
||||
|
||||
field_EF = false;
|
||||
|
||||
@ -61,7 +62,7 @@ CPhysical::CPhysical(void)
|
||||
m_phy_flagA10 = false;
|
||||
m_phy_flagA20 = false;
|
||||
|
||||
m_nLastCollType = 0;
|
||||
m_nSurfaceTouched = SURFACE_DEFAULT;
|
||||
}
|
||||
|
||||
CPhysical::~CPhysical(void)
|
||||
@ -456,7 +457,7 @@ CPhysical::ApplySpringCollision(float springConst, CVector &springDir, CVector &
|
||||
float compression = 1.0f - springRatio;
|
||||
if(compression > 0.0f){
|
||||
float step = min(CTimer::GetTimeStep(), 3.0f);
|
||||
float impulse = -0.008f*m_fMass*step * springConst * compression * bias*2.0f;
|
||||
float impulse = -GRAVITY*m_fMass*step * springConst * compression * bias*2.0f;
|
||||
ApplyMoveForce(springDir*impulse);
|
||||
ApplyTurnForce(springDir*impulse, point);
|
||||
}
|
||||
@ -475,7 +476,7 @@ CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &poin
|
||||
// what is this?
|
||||
float a = m_fTurnMass / ((point.MagnitudeSqr() + 1.0f) * 2.0f * m_fMass);
|
||||
a = min(a, 1.0f);
|
||||
float b = fabs(impulse / (speedB * m_fMass));
|
||||
float b = Abs(impulse / (speedB * m_fMass));
|
||||
if(a < b)
|
||||
impulse *= a/b;
|
||||
|
||||
@ -488,7 +489,7 @@ void
|
||||
CPhysical::ApplyGravity(void)
|
||||
{
|
||||
if(bAffectedByGravity)
|
||||
m_vecMoveSpeed.z -= 0.008f * CTimer::GetTimeStep();
|
||||
m_vecMoveSpeed.z -= GRAVITY * CTimer::GetTimeStep();
|
||||
}
|
||||
|
||||
void
|
||||
@ -504,11 +505,11 @@ void
|
||||
CPhysical::ApplyAirResistance(void)
|
||||
{
|
||||
if(m_fAirResistance > 0.1f){
|
||||
float f = powf(m_fAirResistance, CTimer::GetTimeStep());
|
||||
float f = Pow(m_fAirResistance, CTimer::GetTimeStep());
|
||||
m_vecMoveSpeed *= f;
|
||||
m_vecTurnSpeed *= f;
|
||||
}else{
|
||||
float f = powf(1.0f/(m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr() + 1.0f), CTimer::GetTimeStep());
|
||||
float f = Pow(1.0f/(m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr() + 1.0f), CTimer::GetTimeStep());
|
||||
m_vecMoveSpeed *= f;
|
||||
m_vecTurnSpeed *= 0.99f;
|
||||
}
|
||||
@ -718,7 +719,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
|
||||
if(!B->bInfiniteMass){
|
||||
if(fB.z < 0.0f){
|
||||
fB.z = 0.0f;
|
||||
if(fabs(speedA) < 0.01f)
|
||||
if(Abs(speedA) < 0.01f)
|
||||
fB *= 0.5f;
|
||||
}
|
||||
if(ispedcontactA){
|
||||
@ -814,9 +815,9 @@ CPhysical::ApplyCollisionAlt(CEntity *B, CColPoint &colpoint, float &impulse, CV
|
||||
float minspeed = 0.0104f * CTimer::GetTimeStep();
|
||||
if((IsObject() || IsVehicle() && GetUp().z < -0.3f) &&
|
||||
!bHasContacted &&
|
||||
fabs(m_vecMoveSpeed.x) < minspeed &&
|
||||
fabs(m_vecMoveSpeed.y) < minspeed &&
|
||||
fabs(m_vecMoveSpeed.z) < minspeed*2.0f)
|
||||
Abs(m_vecMoveSpeed.x) < minspeed &&
|
||||
Abs(m_vecMoveSpeed.y) < minspeed &&
|
||||
Abs(m_vecMoveSpeed.z) < minspeed*2.0f)
|
||||
e = -1.0f;
|
||||
else
|
||||
e = -(m_fElasticity + 1.0f);
|
||||
@ -1149,14 +1150,14 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
|
||||
shift += dir * colpoints[mostColliding].depth * 0.5f;
|
||||
}else if(A->IsPed() && B->IsVehicle() && ((CVehicle*)B)->IsBoat()){
|
||||
CVector dir = colpoints[mostColliding].normal;
|
||||
float f = min(fabs(dir.z), 0.9f);
|
||||
float f = min(Abs(dir.z), 0.9f);
|
||||
dir.z = 0.0f;
|
||||
dir.Normalise();
|
||||
shift += dir * colpoints[mostColliding].depth / (1.0f - f);
|
||||
boat = B;
|
||||
}else if(B->IsPed() && A->IsVehicle() && ((CVehicle*)A)->IsBoat()){
|
||||
CVector dir = colpoints[mostColliding].normal * -1.0f;
|
||||
float f = min(fabs(dir.z), 0.9f);
|
||||
float f = min(Abs(dir.z), 0.9f);
|
||||
dir.z = 0.0f;
|
||||
dir.Normalise();
|
||||
B->GetPosition() += dir * colpoints[mostColliding].depth / (1.0f - f);
|
||||
@ -1497,8 +1498,8 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
|
||||
|
||||
float imp = impulseA;
|
||||
if(A->IsVehicle() && A->GetUp().z < -0.6f &&
|
||||
fabs(A->m_vecMoveSpeed.x) < 0.05f &&
|
||||
fabs(A->m_vecMoveSpeed.y) < 0.05f)
|
||||
Abs(A->m_vecMoveSpeed.x) < 0.05f &&
|
||||
Abs(A->m_vecMoveSpeed.y) < 0.05f)
|
||||
imp *= 0.1f;
|
||||
|
||||
float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr();
|
||||
@ -1518,8 +1519,8 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
|
||||
|
||||
float imp = impulseA;
|
||||
if(A->IsVehicle() && A->GetUp().z < -0.6f &&
|
||||
fabs(A->m_vecMoveSpeed.x) < 0.05f &&
|
||||
fabs(A->m_vecMoveSpeed.y) < 0.05f)
|
||||
Abs(A->m_vecMoveSpeed.x) < 0.05f &&
|
||||
Abs(A->m_vecMoveSpeed.y) < 0.05f)
|
||||
imp *= 0.1f;
|
||||
|
||||
float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr();
|
||||
@ -1556,8 +1557,8 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
|
||||
m_vecTurnSpeed += turnSpeed / numResponses;
|
||||
if(!CWorld::bNoMoreCollisionTorque &&
|
||||
A->m_status == STATUS_PLAYER && A->IsVehicle() &&
|
||||
fabs(A->m_vecMoveSpeed.x) > 0.2f &&
|
||||
fabs(A->m_vecMoveSpeed.y) > 0.2f){
|
||||
Abs(A->m_vecMoveSpeed.x) > 0.2f &&
|
||||
Abs(A->m_vecMoveSpeed.y) > 0.2f){
|
||||
A->m_vecMoveFriction.x += moveSpeed.x * -0.3f / numCollisions;
|
||||
A->m_vecMoveFriction.y += moveSpeed.y * -0.3f / numCollisions;
|
||||
A->m_vecTurnFriction += turnSpeed * -0.3f / numCollisions;
|
||||
@ -1782,13 +1783,13 @@ CPhysical::ProcessShift(void)
|
||||
}
|
||||
bIsStuck = false;
|
||||
bIsInSafePosition = true;
|
||||
m_fDistanceTravelled = (GetPosition() - *matrix.GetPosition()).Magnitude();
|
||||
m_fDistanceTravelled = (GetPosition() - matrix.GetPosition()).Magnitude();
|
||||
RemoveAndAdd();
|
||||
}
|
||||
}
|
||||
|
||||
// x is the number of units (m) we would like to step
|
||||
#define NUMSTEPS(x) ceil(sqrt(distSq) * (1.0f/(x)))
|
||||
#define NUMSTEPS(x) ceil(Sqrt(distSq) * (1.0f/(x)))
|
||||
|
||||
void
|
||||
CPhysical::ProcessCollision(void)
|
||||
@ -1882,7 +1883,7 @@ CPhysical::ProcessCollision(void)
|
||||
if(IsPed() && m_vecMoveSpeed.z == 0.0f &&
|
||||
!ped->m_ped_flagA2 &&
|
||||
ped->bIsStanding)
|
||||
savedMatrix.GetPosition()->z = GetPosition().z;
|
||||
savedMatrix.GetPosition().z = GetPosition().z;
|
||||
GetMatrix() = savedMatrix;
|
||||
CTimer::SetTimeStep(savedTimeStep);
|
||||
return;
|
||||
@ -1890,7 +1891,7 @@ CPhysical::ProcessCollision(void)
|
||||
if(IsPed() && m_vecMoveSpeed.z == 0.0f &&
|
||||
!ped->m_ped_flagA2 &&
|
||||
ped->bIsStanding)
|
||||
savedMatrix.GetPosition()->z = GetPosition().z;
|
||||
savedMatrix.GetPosition().z = GetPosition().z;
|
||||
GetMatrix() = savedMatrix;
|
||||
CTimer::SetTimeStep(savedTimeStep);
|
||||
if(IsVehicle()){
|
||||
@ -1917,14 +1918,14 @@ CPhysical::ProcessCollision(void)
|
||||
bHitByTrain ||
|
||||
m_status == STATUS_PLAYER || IsPed() && ped->IsPlayer()){
|
||||
if(IsVehicle())
|
||||
((CVehicle*)this)->m_veh_flagD4 = true;
|
||||
((CVehicle*)this)->bVehicleColProcessed = true;
|
||||
if(CheckCollision()){
|
||||
GetMatrix() = savedMatrix;
|
||||
return;
|
||||
}
|
||||
}
|
||||
bHitByTrain = false;
|
||||
m_fDistanceTravelled = (GetPosition() - *savedMatrix.GetPosition()).Magnitude();
|
||||
m_fDistanceTravelled = (GetPosition() - savedMatrix.GetPosition()).Magnitude();
|
||||
m_phy_flagA80 = false;
|
||||
|
||||
bIsStuck = false;
|
||||
@ -1932,16 +1933,28 @@ CPhysical::ProcessCollision(void)
|
||||
RemoveAndAdd();
|
||||
}
|
||||
|
||||
class CPhysical_ : public CPhysical
|
||||
{
|
||||
public:
|
||||
void dtor(void) { CPhysical::~CPhysical(); }
|
||||
void Add_(void) { CPhysical::Add(); }
|
||||
void Remove_(void) { CPhysical::Remove(); }
|
||||
CRect GetBoundRect_(void) { return CPhysical::GetBoundRect(); }
|
||||
void ProcessControl_(void) { CPhysical::ProcessControl(); }
|
||||
void ProcessShift_(void) { CPhysical::ProcessShift(); }
|
||||
void ProcessCollision_(void) { CPhysical::ProcessCollision(); }
|
||||
int32 ProcessEntityCollision_(CEntity *ent, CColPoint *point) { return CPhysical::ProcessEntityCollision(ent, point); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x495130, &CPhysical::dtor, PATCH_JUMP);
|
||||
InjectHook(0x4951F0, &CPhysical::Add_, PATCH_JUMP);
|
||||
InjectHook(0x4954B0, &CPhysical::Remove_, PATCH_JUMP);
|
||||
InjectHook(0x495540, &CPhysical::RemoveAndAdd, PATCH_JUMP);
|
||||
InjectHook(0x495F10, &CPhysical::ProcessControl_, PATCH_JUMP);
|
||||
InjectHook(0x496F10, &CPhysical::ProcessShift_, PATCH_JUMP);
|
||||
InjectHook(0x4961A0, &CPhysical::ProcessCollision_, PATCH_JUMP);
|
||||
InjectHook(0x49F790, &CPhysical::ProcessEntityCollision_, PATCH_JUMP);
|
||||
InjectHook(0x495130, &CPhysical_::dtor, PATCH_JUMP);
|
||||
InjectHook(0x4951F0, &CPhysical_::Add_, PATCH_JUMP);
|
||||
InjectHook(0x4954B0, &CPhysical_::Remove_, PATCH_JUMP);
|
||||
InjectHook(0x495540, &CPhysical_::RemoveAndAdd, PATCH_JUMP);
|
||||
InjectHook(0x495F10, &CPhysical_::ProcessControl_, PATCH_JUMP);
|
||||
InjectHook(0x496F10, &CPhysical_::ProcessShift_, PATCH_JUMP);
|
||||
InjectHook(0x4961A0, &CPhysical_::ProcessCollision_, PATCH_JUMP);
|
||||
InjectHook(0x49F790, &CPhysical_::ProcessEntityCollision_, PATCH_JUMP);
|
||||
InjectHook(0x4958F0, &CPhysical::AddToMovingList, PATCH_JUMP);
|
||||
InjectHook(0x495940, &CPhysical::RemoveFromMovingList, PATCH_JUMP);
|
||||
InjectHook(0x497180, &CPhysical::AddCollisionRecord, PATCH_JUMP);
|
||||
|
@ -3,12 +3,15 @@
|
||||
#include "Lists.h"
|
||||
#include "Timer.h"
|
||||
#include "Entity.h"
|
||||
#include "Treadable.h"
|
||||
|
||||
enum {
|
||||
PHYSICAL_MAX_COLLISIONRECORDS = 6
|
||||
};
|
||||
|
||||
#define GRAVITY (0.008f)
|
||||
|
||||
class CTreadable;
|
||||
|
||||
class CPhysical : public CEntity
|
||||
{
|
||||
public:
|
||||
@ -58,20 +61,21 @@ public:
|
||||
uint8 bHitByTrain : 1; // from nick
|
||||
uint8 m_phy_flagA80 : 1;
|
||||
|
||||
uint8 m_nLastCollType;
|
||||
uint8 m_nSurfaceTouched;
|
||||
uint8 m_nZoneLevel;
|
||||
|
||||
CPhysical(void);
|
||||
~CPhysical(void);
|
||||
|
||||
// from CEntity
|
||||
virtual void Add(void);
|
||||
virtual void Remove(void);
|
||||
virtual CRect GetBoundRect(void);
|
||||
virtual void ProcessControl(void);
|
||||
virtual int32 ProcessEntityCollision(CEntity *ent, CColPoint *point);
|
||||
virtual void ProcessShift(void);
|
||||
virtual void ProcessCollision(void);
|
||||
void Add(void);
|
||||
void Remove(void);
|
||||
CRect GetBoundRect(void);
|
||||
void ProcessControl(void);
|
||||
void ProcessShift(void);
|
||||
void ProcessCollision(void);
|
||||
|
||||
virtual int32 ProcessEntityCollision(CEntity *ent, CColPoint *colpoints);
|
||||
|
||||
void RemoveAndAdd(void);
|
||||
void AddToMovingList(void);
|
||||
@ -106,7 +110,23 @@ public:
|
||||
}
|
||||
|
||||
const CVector &GetMoveSpeed() { return m_vecMoveSpeed; }
|
||||
void SetMoveSpeed(float x, float y, float z) {
|
||||
m_vecMoveSpeed.x = x;
|
||||
m_vecMoveSpeed.y = y;
|
||||
m_vecMoveSpeed.z = z;
|
||||
}
|
||||
const CVector &GetTurnSpeed() { return m_vecTurnSpeed; }
|
||||
void SetTurnSpeed(float x, float y, float z) {
|
||||
m_vecTurnSpeed.x = x;
|
||||
m_vecTurnSpeed.y = y;
|
||||
m_vecTurnSpeed.z = z;
|
||||
}
|
||||
const CVector &GetCenterOfMass() { return m_vecCentreOfMass; }
|
||||
void SetCenterOfMass(float x, float y, float z) {
|
||||
m_vecCentreOfMass.x = x;
|
||||
m_vecCentreOfMass.y = y;
|
||||
m_vecCentreOfMass.z = z;
|
||||
}
|
||||
|
||||
void ApplyMoveSpeed(void);
|
||||
void ApplyTurnSpeed(void);
|
||||
@ -137,15 +157,5 @@ public:
|
||||
bool ProcessCollisionSectorList(CPtrList *lists);
|
||||
bool CheckCollision(void);
|
||||
bool CheckCollision_SimpleCar(void);
|
||||
|
||||
// to make patching virtual functions possible
|
||||
void dtor(void) { this->CPhysical::~CPhysical(); }
|
||||
void Add_(void) { CPhysical::Add(); }
|
||||
void Remove_(void) { CPhysical::Remove(); }
|
||||
CRect GetBoundRect_(void) { return CPhysical::GetBoundRect(); }
|
||||
void ProcessControl_(void) { CPhysical::ProcessControl(); }
|
||||
void ProcessShift_(void) { CPhysical::ProcessShift(); }
|
||||
void ProcessCollision_(void) { CPhysical::ProcessCollision(); }
|
||||
int32 ProcessEntityCollision_(CEntity *ent, CColPoint *point) { return CPhysical::ProcessEntityCollision(ent, point); }
|
||||
};
|
||||
static_assert(sizeof(CPhysical) == 0x128, "CPhysical: error");
|
||||
|
@ -7,6 +7,12 @@
|
||||
void *CTreadable::operator new(size_t sz) { return CPools::GetTreadablePool()->New(); }
|
||||
void CTreadable::operator delete(void *p, size_t sz) { CPools::GetTreadablePool()->Delete((CTreadable*)p); }
|
||||
|
||||
class CTreadable_ : public CTreadable
|
||||
{
|
||||
public:
|
||||
void dtor(void) { CTreadable::~CTreadable(); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x405A10, &CTreadable::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
InjectHook(0x405A10, &CTreadable_::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -11,7 +11,6 @@ public:
|
||||
int16 m_nodeIndicesCars[12];
|
||||
int16 m_nodeIndicesPeds[12];
|
||||
|
||||
virtual bool GetIsATreadable(void) { return true; }
|
||||
void dtor(void) { this->CTreadable::~CTreadable(); }
|
||||
bool GetIsATreadable(void) { return true; }
|
||||
};
|
||||
static_assert(sizeof(CTreadable) == 0x94, "CTreadable: error");
|
||||
|
@ -78,10 +78,36 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
CVector *GetPosition(void){ return (CVector*)&m_matrix.pos; }
|
||||
CVector *GetRight(void) { return (CVector*)&m_matrix.right; }
|
||||
CVector *GetForward(void) { return (CVector*)&m_matrix.up; }
|
||||
CVector *GetUp(void) { return (CVector*)&m_matrix.at; }
|
||||
CVector &GetPosition(void){ return *(CVector*)&m_matrix.pos; }
|
||||
CVector &GetRight(void) { return *(CVector*)&m_matrix.right; }
|
||||
CVector &GetForward(void) { return *(CVector*)&m_matrix.up; }
|
||||
CVector &GetUp(void) { return *(CVector*)&m_matrix.at; }
|
||||
|
||||
void SetTranslate(float x, float y, float z){
|
||||
m_matrix.right.x = 1.0f;
|
||||
m_matrix.right.y = 0.0f;
|
||||
m_matrix.right.z = 0.0f;
|
||||
|
||||
m_matrix.up.x = 0.0f;
|
||||
m_matrix.up.y = 1.0f;
|
||||
m_matrix.up.z = 0.0f;
|
||||
|
||||
m_matrix.at.x = 0.0f;
|
||||
m_matrix.at.y = 0.0f;
|
||||
m_matrix.at.z = 1.0f;
|
||||
|
||||
m_matrix.pos.x = x;
|
||||
m_matrix.pos.y = y;
|
||||
m_matrix.pos.z = z;
|
||||
}
|
||||
void SetTranslate(const CVector &trans){ SetTranslate(trans.x, trans.y, trans.z); }
|
||||
void Translate(float x, float y, float z){
|
||||
m_matrix.pos.x += x;
|
||||
m_matrix.pos.y += y;
|
||||
m_matrix.pos.z += z;
|
||||
}
|
||||
void Translate(const CVector &trans){ Translate(trans.x, trans.y, trans.z); }
|
||||
|
||||
void SetScale(float s){
|
||||
m_matrix.right.x = s;
|
||||
m_matrix.right.y = 0.0f;
|
||||
@ -99,9 +125,10 @@ public:
|
||||
m_matrix.pos.y = 0.0f;
|
||||
m_matrix.pos.z = 0.0f;
|
||||
}
|
||||
|
||||
void SetRotateXOnly(float angle){
|
||||
float c = cos(angle);
|
||||
float s = sin(angle);
|
||||
float c = Cos(angle);
|
||||
float s = Sin(angle);
|
||||
|
||||
m_matrix.right.x = 1.0f;
|
||||
m_matrix.right.y = 0.0f;
|
||||
@ -122,8 +149,8 @@ public:
|
||||
m_matrix.pos.z = 0.0f;
|
||||
}
|
||||
void SetRotateYOnly(float angle){
|
||||
float c = cos(angle);
|
||||
float s = sin(angle);
|
||||
float c = Cos(angle);
|
||||
float s = Sin(angle);
|
||||
|
||||
m_matrix.right.x = c;
|
||||
m_matrix.right.y = 0.0f;
|
||||
@ -144,8 +171,8 @@ public:
|
||||
m_matrix.pos.z = 0.0f;
|
||||
}
|
||||
void SetRotateZOnly(float angle){
|
||||
float c = cos(angle);
|
||||
float s = sin(angle);
|
||||
float c = Cos(angle);
|
||||
float s = Sin(angle);
|
||||
|
||||
m_matrix.right.x = c;
|
||||
m_matrix.right.y = s;
|
||||
@ -166,12 +193,12 @@ public:
|
||||
m_matrix.pos.z = 0.0f;
|
||||
}
|
||||
void SetRotate(float xAngle, float yAngle, float zAngle) {
|
||||
float cX = cos(xAngle);
|
||||
float sX = sin(xAngle);
|
||||
float cY = cos(yAngle);
|
||||
float sY = sin(yAngle);
|
||||
float cZ = cos(zAngle);
|
||||
float sZ = sin(zAngle);
|
||||
float cX = Cos(xAngle);
|
||||
float sX = Sin(xAngle);
|
||||
float cY = Cos(yAngle);
|
||||
float sY = Sin(yAngle);
|
||||
float cZ = Cos(zAngle);
|
||||
float sZ = Sin(zAngle);
|
||||
|
||||
m_matrix.right.x = cZ * cY - (sZ * sX) * sY;
|
||||
m_matrix.right.y = (cZ * sX) * sY + sZ * cY;
|
||||
@ -190,9 +217,9 @@ public:
|
||||
m_matrix.pos.z = 0.0f;
|
||||
}
|
||||
void Reorthogonalise(void){
|
||||
CVector &r = *GetRight();
|
||||
CVector &f = *GetForward();
|
||||
CVector &u = *GetUp();
|
||||
CVector &r = GetRight();
|
||||
CVector &f = GetForward();
|
||||
CVector &u = GetUp();
|
||||
u = CrossProduct(r, f);
|
||||
u.Normalise();
|
||||
r = CrossProduct(f, u);
|
||||
@ -306,6 +333,15 @@ Multiply3x3(const CMatrix &mat, const CVector &vec)
|
||||
mat.m_matrix.right.z * vec.x + mat.m_matrix.up.z * vec.y + mat.m_matrix.at.z * vec.z);
|
||||
}
|
||||
|
||||
inline CVector
|
||||
Multiply3x3(const CVector &vec, const CMatrix &mat)
|
||||
{
|
||||
return CVector(
|
||||
mat.m_matrix.right.x * vec.x + mat.m_matrix.right.y * vec.y + mat.m_matrix.right.z * vec.z,
|
||||
mat.m_matrix.up.x * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.up.z * vec.z,
|
||||
mat.m_matrix.at.x * vec.x + mat.m_matrix.at.y * vec.y + mat.m_matrix.at.z * vec.z);
|
||||
}
|
||||
|
||||
class CCompressedMatrixNotAligned
|
||||
{
|
||||
CVector m_vecPos;
|
||||
@ -318,24 +354,24 @@ class CCompressedMatrixNotAligned
|
||||
public:
|
||||
void CompressFromFullMatrix(CMatrix &other)
|
||||
{
|
||||
m_rightX = 127.0f * other.GetRight()->x;
|
||||
m_rightY = 127.0f * other.GetRight()->y;
|
||||
m_rightZ = 127.0f * other.GetRight()->z;
|
||||
m_upX = 127.0f * other.GetForward()->x;
|
||||
m_upY = 127.0f * other.GetForward()->y;
|
||||
m_upZ = 127.0f * other.GetForward()->z;
|
||||
m_vecPos = *other.GetPosition();
|
||||
m_rightX = 127.0f * other.GetRight().x;
|
||||
m_rightY = 127.0f * other.GetRight().y;
|
||||
m_rightZ = 127.0f * other.GetRight().z;
|
||||
m_upX = 127.0f * other.GetForward().x;
|
||||
m_upY = 127.0f * other.GetForward().y;
|
||||
m_upZ = 127.0f * other.GetForward().z;
|
||||
m_vecPos = other.GetPosition();
|
||||
}
|
||||
void DecompressIntoFullMatrix(CMatrix &other)
|
||||
{
|
||||
other.GetRight()->x = m_rightX / 127.0f;
|
||||
other.GetRight()->y = m_rightY / 127.0f;
|
||||
other.GetRight()->z = m_rightZ / 127.0f;
|
||||
other.GetForward()->x = m_upX / 127.0f;
|
||||
other.GetForward()->y = m_upY / 127.0f;
|
||||
other.GetForward()->z = m_upZ / 127.0f;
|
||||
*other.GetUp() = CrossProduct(*other.GetRight(), *other.GetForward());
|
||||
*other.GetPosition() = m_vecPos;
|
||||
other.GetRight().x = m_rightX / 127.0f;
|
||||
other.GetRight().y = m_rightY / 127.0f;
|
||||
other.GetRight().z = m_rightZ / 127.0f;
|
||||
other.GetForward().x = m_upX / 127.0f;
|
||||
other.GetForward().y = m_upY / 127.0f;
|
||||
other.GetForward().z = m_upZ / 127.0f;
|
||||
other.GetUp() = CrossProduct(other.GetRight(), other.GetForward());
|
||||
other.GetPosition() = m_vecPos;
|
||||
other.Reorthogonalise();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -8,7 +8,7 @@ public:
|
||||
CQuaternion(void) {}
|
||||
CQuaternion(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
|
||||
|
||||
float Magnitude(void) const { return sqrt(x*x + y*y + z*z + w*w); }
|
||||
float Magnitude(void) const { return Sqrt(x*x + y*y + z*z + w*w); }
|
||||
float MagnitudeSqr(void) const { return x*x + y*y + z*z + w*w; }
|
||||
|
||||
const CQuaternion &operator+=(CQuaternion const &right) {
|
||||
|
@ -22,15 +22,15 @@ public:
|
||||
return *((RwV3d*)this);
|
||||
}
|
||||
#endif
|
||||
float Heading(void) const { return atan2(-x, y); }
|
||||
float Magnitude(void) const { return sqrt(x*x + y*y + z*z); }
|
||||
float Heading(void) const { return Atan2(-x, y); }
|
||||
float Magnitude(void) const { return Sqrt(x*x + y*y + z*z); }
|
||||
float MagnitudeSqr(void) const { return x*x + y*y + z*z; }
|
||||
float Magnitude2D(void) const { return sqrt(x*x + y*y); }
|
||||
float Magnitude2D(void) const { return Sqrt(x*x + y*y); }
|
||||
float MagnitudeSqr2D(void) const { return x*x + y*y; }
|
||||
void Normalise(void) {
|
||||
float sq = MagnitudeSqr();
|
||||
if(sq > 0.0f){
|
||||
float invsqrt = 1.0f/sqrt(sq); // CMaths::RecipSqrt
|
||||
float invsqrt = 1.0f/Sqrt(sq); // CMaths::RecipSqrt
|
||||
x *= invsqrt;
|
||||
y *= invsqrt;
|
||||
z *= invsqrt;
|
||||
|
@ -7,13 +7,13 @@ public:
|
||||
CVector2D(void) {}
|
||||
CVector2D(float x, float y) : x(x), y(y) {}
|
||||
CVector2D(const CVector &v) : x(v.x), y(v.y) {}
|
||||
float Magnitude(void) const { return sqrt(x*x + y*y); }
|
||||
float Magnitude(void) const { return Sqrt(x*x + y*y); }
|
||||
float MagnitudeSqr(void) const { return x*x + y*y; }
|
||||
|
||||
void Normalise(void){
|
||||
float sq = MagnitudeSqr();
|
||||
if(sq > 0.0f){
|
||||
float invsqrt = 1.0f/sqrt(sq);
|
||||
float invsqrt = 1.0f/Sqrt(sq);
|
||||
x *= invsqrt;
|
||||
y *= invsqrt;
|
||||
}else
|
||||
|
@ -13,11 +13,11 @@ CQuaternion::Slerp(const CQuaternion &q1, const CQuaternion &q2, float theta, fl
|
||||
float w1, w2;
|
||||
if(theta > PI/2){
|
||||
theta = PI - theta;
|
||||
w1 = sin((1.0f - t) * theta) * invSin;
|
||||
w2 = -sin(t * theta) * invSin;
|
||||
w1 = Sin((1.0f - t) * theta) * invSin;
|
||||
w2 = -Sin(t * theta) * invSin;
|
||||
}else{
|
||||
w1 = sin((1.0f - t) * theta) * invSin;
|
||||
w2 = sin(t * theta) * invSin;
|
||||
w1 = Sin((1.0f - t) * theta) * invSin;
|
||||
w2 = Sin(t * theta) * invSin;
|
||||
}
|
||||
*this = w1*q1 + w2*q2;
|
||||
}
|
||||
|
16
src/math/maths.h
Normal file
16
src/math/maths.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
// wrapper around float versions of functions
|
||||
// in gta they are in CMaths but that makes the code rather noisy
|
||||
|
||||
inline float Sin(float x) { return sinf(x); }
|
||||
inline float Asin(float x) { return asinf(x); }
|
||||
inline float Cos(float x) { return cosf(x); }
|
||||
inline float Acos(float x) { return acosf(x); }
|
||||
inline float Tan(float x) { return tanf(x); }
|
||||
inline float Atan(float x) { return atanf(x); }
|
||||
inline float Atan2(float y, float x) { return atan2f(y, x); }
|
||||
inline float Abs(float x) { return fabs(x); }
|
||||
inline float Sqrt(float x) { return sqrtf(x); }
|
||||
inline float RecipSqrt(float x) { return 1.0f/Sqrt(x); }
|
||||
inline float Pow(float x, float y) { return powf(x, y); }
|
@ -101,9 +101,15 @@ CBaseModelInfo::Get2dEffect(int n)
|
||||
}
|
||||
|
||||
|
||||
class CBaseModelInfo_ : public CBaseModelInfo
|
||||
{
|
||||
public:
|
||||
void Shutdown_(void) { CBaseModelInfo::Shutdown(); }
|
||||
};
|
||||
STARTPATCHES
|
||||
// can't easily replace ctor at 4F6A50
|
||||
InjectHook(0x4F6A90, &CBaseModelInfo::Shutdown_, PATCH_JUMP);
|
||||
InjectHook(0x4F6A90, &CBaseModelInfo_::Shutdown_, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x4F6AC0, &CBaseModelInfo::DeleteCollisionModel, PATCH_JUMP);
|
||||
InjectHook(0x4F6B70, &CBaseModelInfo::ClearTexDictionary, PATCH_JUMP);
|
||||
InjectHook(0x4F6BA0, &CBaseModelInfo::AddRef, PATCH_JUMP);
|
||||
|
@ -62,8 +62,6 @@ public:
|
||||
void Init2dEffects(void);
|
||||
void Add2dEffect(C2dEffect *fx);
|
||||
C2dEffect *Get2dEffect(int n);
|
||||
|
||||
void Shutdown_(void) { this->CBaseModelInfo::Shutdown(); }
|
||||
};
|
||||
|
||||
static_assert(sizeof(CBaseModelInfo) == 0x30, "CBaseModelInfo: error");
|
||||
|
@ -139,12 +139,22 @@ CClumpModelInfo::GetFrameFromId(RpClump *clump, int32 id)
|
||||
}
|
||||
|
||||
|
||||
class CClumpModelInfo_ : public CClumpModelInfo
|
||||
{
|
||||
public:
|
||||
void DeleteRwObject_(void) { this->CClumpModelInfo::DeleteRwObject(); }
|
||||
RwObject *CreateInstance_1(void) { return CClumpModelInfo::CreateInstance(); }
|
||||
RwObject *CreateInstance_2(RwMatrix *m) { return CClumpModelInfo::CreateInstance(m); }
|
||||
RwObject *GetRwObject_(void) { return CClumpModelInfo::GetRwObject(); }
|
||||
void SetClump_(RpClump *clump) { CClumpModelInfo::SetClump(clump); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x4F8800, &CClumpModelInfo::DeleteRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x4F8920, &CClumpModelInfo::CreateInstance_1, PATCH_JUMP);
|
||||
InjectHook(0x4F88A0, &CClumpModelInfo::CreateInstance_2, PATCH_JUMP);
|
||||
InjectHook(0x50C1C0, &CClumpModelInfo::GetRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x4F8830, &CClumpModelInfo::SetClump_, PATCH_JUMP);
|
||||
InjectHook(0x4F8800, &CClumpModelInfo_::DeleteRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x4F8920, &CClumpModelInfo_::CreateInstance_1, PATCH_JUMP);
|
||||
InjectHook(0x4F88A0, &CClumpModelInfo_::CreateInstance_2, PATCH_JUMP);
|
||||
InjectHook(0x50C1C0, &CClumpModelInfo_::GetRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x4F8830, &CClumpModelInfo_::SetClump_, PATCH_JUMP);
|
||||
InjectHook(0x4F8940, &CClumpModelInfo::SetAtomicRendererCB, PATCH_JUMP);
|
||||
InjectHook(0x4F8960, &CClumpModelInfo::FindFrameFromNameCB, PATCH_JUMP);
|
||||
InjectHook(0x4F8A10, &CClumpModelInfo::FindFrameFromNameWithoutIdCB, PATCH_JUMP);
|
||||
|
@ -49,12 +49,5 @@ public:
|
||||
static void FillFrameArray(RpClump *clump, RwFrame **frames);
|
||||
static RwFrame *FillFrameArrayCB(RwFrame *frame, void *data);
|
||||
static RwFrame *GetFrameFromId(RpClump *clump, int32 id);
|
||||
|
||||
|
||||
void DeleteRwObject_(void) { this->CClumpModelInfo::DeleteRwObject(); }
|
||||
RwObject *CreateInstance_1(void) { return this->CClumpModelInfo::CreateInstance(); }
|
||||
RwObject *CreateInstance_2(RwMatrix *m) { return this->CClumpModelInfo::CreateInstance(m); }
|
||||
RwObject *GetRwObject_(void) { return this->CClumpModelInfo::GetRwObject(); }
|
||||
void SetClump_(RpClump *clump) { this->CClumpModelInfo::SetClump(clump); }
|
||||
};
|
||||
static_assert(sizeof(CClumpModelInfo) == 0x34, "CClumpModelInfo: error");
|
||||
|
@ -1,7 +0,0 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "MloInstance.h"
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x50BE90, &CMloInstance::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
@ -1,9 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Placeable.h"
|
||||
|
||||
class CMloInstance : CPlaceable
|
||||
{
|
||||
public:
|
||||
void dtor() { this->CMloInstance::~CMloInstance(); }
|
||||
};
|
@ -164,7 +164,8 @@
|
||||
// expand as needed
|
||||
enum
|
||||
{
|
||||
MI_COP = 1,
|
||||
MI_PLAYER = 0,
|
||||
MI_COP,
|
||||
MI_SWAT,
|
||||
MI_FBI,
|
||||
MI_ARMY,
|
||||
|
@ -189,9 +189,17 @@ CPedModelInfo::CreateHitColModel(void)
|
||||
m_hitColModel = colmodel;
|
||||
}
|
||||
|
||||
|
||||
class CPedModelInfo_ : public CPedModelInfo
|
||||
{
|
||||
public:
|
||||
void DeleteRwObject_(void) { CPedModelInfo::DeleteRwObject(); }
|
||||
void SetClump_(RpClump *clump) { CPedModelInfo::SetClump(clump); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x510210, &CPedModelInfo::SetClump_, PATCH_JUMP);
|
||||
InjectHook(0x510280, &CPedModelInfo::DeleteRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x510210, &CPedModelInfo_::SetClump_, PATCH_JUMP);
|
||||
InjectHook(0x510280, &CPedModelInfo_::DeleteRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x510390, &CPedModelInfo::SetLowDetailClump, PATCH_JUMP);
|
||||
InjectHook(0x5104D0, &CPedModelInfo::CreateHitColModel, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -39,9 +39,5 @@ public:
|
||||
void SetLowDetailClump(RpClump*);
|
||||
void CreateHitColModel(void);
|
||||
CColModel *GetHitColModel(void) { return m_hitColModel; }
|
||||
|
||||
|
||||
void DeleteRwObject_(void) { this->CPedModelInfo::DeleteRwObject(); }
|
||||
void SetClump_(RpClump *clump) { this->CPedModelInfo::SetClump(clump); }
|
||||
};
|
||||
static_assert(sizeof(CPedModelInfo) == 0x54, "CPedModelInfo: error");
|
||||
|
@ -154,12 +154,20 @@ CSimpleModelInfo::SetupBigBuilding(void)
|
||||
}
|
||||
}
|
||||
|
||||
class CSimpleModelInfo_ : public CSimpleModelInfo
|
||||
{
|
||||
public:
|
||||
void DeleteRwObject_(void) { CSimpleModelInfo::DeleteRwObject(); }
|
||||
RwObject *CreateInstance_1(void) { return CSimpleModelInfo::CreateInstance(); }
|
||||
RwObject *CreateInstance_2(RwMatrix *m) { return CSimpleModelInfo::CreateInstance(m); }
|
||||
RwObject *GetRwObject_(void) { return CSimpleModelInfo::GetRwObject(); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x5179B0, &CSimpleModelInfo::DeleteRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x517B60, &CSimpleModelInfo::CreateInstance_1, PATCH_JUMP);
|
||||
InjectHook(0x517AC0, &CSimpleModelInfo::CreateInstance_2, PATCH_JUMP);
|
||||
InjectHook(0x4A9BA0, &CSimpleModelInfo::GetRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x5179B0, &CSimpleModelInfo_::DeleteRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x517B60, &CSimpleModelInfo_::CreateInstance_1, PATCH_JUMP);
|
||||
InjectHook(0x517AC0, &CSimpleModelInfo_::CreateInstance_2, PATCH_JUMP);
|
||||
InjectHook(0x4A9BA0, &CSimpleModelInfo_::GetRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x517990, &CSimpleModelInfo::Init, PATCH_JUMP);
|
||||
InjectHook(0x517C60, &CSimpleModelInfo::IncreaseAlpha, PATCH_JUMP);
|
||||
InjectHook(0x517950, &CSimpleModelInfo::SetAtomic, PATCH_JUMP);
|
||||
|
@ -48,10 +48,5 @@ public:
|
||||
return (CSimpleModelInfo*)m_atomics[2]; }
|
||||
void SetRelatedModel(CSimpleModelInfo *m){
|
||||
m_atomics[2] = (RpAtomic*)m; }
|
||||
|
||||
void DeleteRwObject_(void) { this->CSimpleModelInfo::DeleteRwObject(); }
|
||||
RwObject *CreateInstance_1(void) { return this->CSimpleModelInfo::CreateInstance(); }
|
||||
RwObject *CreateInstance_2(RwMatrix *m) { return this->CSimpleModelInfo::CreateInstance(m); }
|
||||
RwObject *GetRwObject_(void) { return this->CSimpleModelInfo::GetRwObject(); }
|
||||
};
|
||||
static_assert(sizeof(CSimpleModelInfo) == 0x4C, "CSimpleModelInfo: error");
|
||||
|
@ -414,11 +414,13 @@ CVehicleModelInfo::SetAtomicFlagCB(RwObject *object, void *data)
|
||||
return object;
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
CVehicleModelInfo::ClearAtomicFlagCB(RpAtomic *atomic, void *data)
|
||||
RwObject*
|
||||
CVehicleModelInfo::ClearAtomicFlagCB(RwObject *object, void *data)
|
||||
{
|
||||
RpAtomic *atomic = (RpAtomic*)object;
|
||||
assert(RwObjectGetType(object) == rpATOMIC);
|
||||
CVisibilityPlugins::ClearAtomicFlag(atomic, (int)data);
|
||||
return atomic;
|
||||
return object;
|
||||
}
|
||||
|
||||
RwObject*
|
||||
@ -1098,10 +1100,18 @@ CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(int id)
|
||||
return n - 1;
|
||||
}
|
||||
|
||||
class CVehicleModelInfo_ : public CVehicleModelInfo
|
||||
{
|
||||
public:
|
||||
void DeleteRwObject_(void) { CVehicleModelInfo::DeleteRwObject(); }
|
||||
RwObject *CreateInstance_(void) { return CVehicleModelInfo::CreateInstance(); }
|
||||
void SetClump_(RpClump *clump) { CVehicleModelInfo::SetClump(clump); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x51FDC0, &CVehicleModelInfo::DeleteRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x51FCB0, &CVehicleModelInfo::CreateInstance_, PATCH_JUMP);
|
||||
InjectHook(0x51FC60, &CVehicleModelInfo::SetClump_, PATCH_JUMP);
|
||||
InjectHook(0x51FDC0, &CVehicleModelInfo_::DeleteRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x51FCB0, &CVehicleModelInfo_::CreateInstance_, PATCH_JUMP);
|
||||
InjectHook(0x51FC60, &CVehicleModelInfo_::SetClump_, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x51FE10, &CVehicleModelInfo::CollapseFramesCB, PATCH_JUMP);
|
||||
InjectHook(0x51FE50, &CVehicleModelInfo::MoveObjectsCB, PATCH_JUMP);
|
||||
|
@ -10,6 +10,7 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
ATOMIC_FLAG_NONE = 0x0,
|
||||
ATOMIC_FLAG_OK = 0x1,
|
||||
ATOMIC_FLAG_DAM = 0x2,
|
||||
ATOMIC_FLAG_LEFT = 0x4,
|
||||
@ -106,7 +107,7 @@ public:
|
||||
void SetAtomicRenderCallbacks(void);
|
||||
|
||||
static RwObject *SetAtomicFlagCB(RwObject *object, void *data);
|
||||
static RpAtomic *ClearAtomicFlagCB(RpAtomic *atomic, void *data);
|
||||
static RwObject *ClearAtomicFlagCB(RwObject *atomic, void *data);
|
||||
void SetVehicleComponentFlags(RwFrame *frame, uint32 flags);
|
||||
void PreprocessHierarchy(void);
|
||||
void GetWheelPosn(int32 n, CVector &pos);
|
||||
@ -131,9 +132,5 @@ public:
|
||||
static void ShutdownEnvironmentMaps(void);
|
||||
|
||||
static int GetMaximumNumberOfPassengersFromNumberOfDoors(int id);
|
||||
|
||||
void DeleteRwObject_(void) { this->CVehicleModelInfo::DeleteRwObject(); }
|
||||
RwObject *CreateInstance_(void) { return this->CVehicleModelInfo::CreateInstance(); }
|
||||
void SetClump_(RpClump *clump) { this->CVehicleModelInfo::SetClump(clump); }
|
||||
};
|
||||
static_assert(sizeof(CVehicleModelInfo) == 0x1F8, "CVehicleModelInfo: error");
|
||||
|
@ -109,10 +109,19 @@ CCutsceneHead::PlayAnimation(const char *animName)
|
||||
}
|
||||
}
|
||||
|
||||
class CCutsceneHead_ : public CCutsceneHead
|
||||
{
|
||||
public:
|
||||
void CreateRwObject_(void) { CCutsceneHead::CreateRwObject(); }
|
||||
void DeleteRwObject_(void) { CCutsceneHead::DeleteRwObject(); }
|
||||
void ProcessControl_(void) { CCutsceneHead::ProcessControl(); }
|
||||
void Render_(void) { CCutsceneHead::Render(); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x4BA650, &CCutsceneHead::CreateRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x4BA690, &CCutsceneHead::DeleteRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x4BA760, &CCutsceneHead::ProcessControl_, PATCH_JUMP);
|
||||
InjectHook(0x4BA800, &CCutsceneHead::Render_, PATCH_JUMP);
|
||||
InjectHook(0x4BA650, &CCutsceneHead_::CreateRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x4BA690, &CCutsceneHead_::DeleteRwObject_, PATCH_JUMP);
|
||||
InjectHook(0x4BA760, &CCutsceneHead_::ProcessControl_, PATCH_JUMP);
|
||||
InjectHook(0x4BA800, &CCutsceneHead_::Render_, PATCH_JUMP);
|
||||
InjectHook(0x4BA6A0, &CCutsceneHead::PlayAnimation, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -15,10 +15,5 @@ public:
|
||||
void Render(void);
|
||||
|
||||
void PlayAnimation(const char *animName);
|
||||
|
||||
void CreateRwObject_(void) { CCutsceneHead::CreateRwObject(); }
|
||||
void DeleteRwObject_(void) { CCutsceneHead::DeleteRwObject(); }
|
||||
void ProcessControl_(void) { CCutsceneHead::ProcessControl(); }
|
||||
void Render_(void) { CCutsceneHead::Render(); }
|
||||
};
|
||||
static_assert(sizeof(CCutsceneHead) == 0x19C, "CCutsceneHead: error");
|
||||
|
@ -89,12 +89,24 @@ CCutsceneObject::RemoveLighting(bool reset)
|
||||
CRenderer::RemoveVehiclePedLights(this, reset);
|
||||
}
|
||||
|
||||
class CCutsceneObject_ : public CCutsceneObject
|
||||
{
|
||||
public:
|
||||
void dtor(void) { this->CCutsceneObject::~CCutsceneObject(); }
|
||||
void SetModelIndex_(uint32 id) { CCutsceneObject::SetModelIndex(id); }
|
||||
void ProcessControl_(void) { CCutsceneObject::ProcessControl(); }
|
||||
void PreRender_(void) { CCutsceneObject::PreRender(); }
|
||||
void Render_(void) { CCutsceneObject::Render(); }
|
||||
bool SetupLighting_(void) { return CCutsceneObject::SetupLighting(); }
|
||||
void RemoveLighting_(bool reset) { CCutsceneObject::RemoveLighting(reset); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x4BA960, &CCutsceneObject::dtor, PATCH_JUMP);
|
||||
InjectHook(0x4BA980, &CCutsceneObject::SetModelIndex_, PATCH_JUMP);
|
||||
InjectHook(0x4BA9C0, &CCutsceneObject::ProcessControl_, PATCH_JUMP);
|
||||
InjectHook(0x4BAA40, &CCutsceneObject::PreRender_, PATCH_JUMP);
|
||||
InjectHook(0x4BAAA0, &CCutsceneObject::Render_, PATCH_JUMP);
|
||||
InjectHook(0x4A7E70, &CCutsceneObject::SetupLighting_, PATCH_JUMP);
|
||||
InjectHook(0x4A7F00, &CCutsceneObject::RemoveLighting_, PATCH_JUMP);
|
||||
InjectHook(0x4BA960, &CCutsceneObject_::dtor, PATCH_JUMP);
|
||||
InjectHook(0x4BA980, &CCutsceneObject_::SetModelIndex_, PATCH_JUMP);
|
||||
InjectHook(0x4BA9C0, &CCutsceneObject_::ProcessControl_, PATCH_JUMP);
|
||||
InjectHook(0x4BAA40, &CCutsceneObject_::PreRender_, PATCH_JUMP);
|
||||
InjectHook(0x4BAAA0, &CCutsceneObject_::Render_, PATCH_JUMP);
|
||||
InjectHook(0x4A7E70, &CCutsceneObject_::SetupLighting_, PATCH_JUMP);
|
||||
InjectHook(0x4A7F00, &CCutsceneObject_::RemoveLighting_, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -7,19 +7,11 @@ class CCutsceneObject : public CObject
|
||||
public:
|
||||
CCutsceneObject(void);
|
||||
|
||||
virtual void SetModelIndex(uint32 id);
|
||||
virtual void ProcessControl(void);
|
||||
virtual void PreRender(void);
|
||||
virtual void Render(void);
|
||||
virtual bool SetupLighting(void);
|
||||
virtual void RemoveLighting(bool reset);
|
||||
|
||||
void dtor(void) { this->CCutsceneObject::~CCutsceneObject(); }
|
||||
void SetModelIndex_(uint32 id) { CCutsceneObject::SetModelIndex(id); }
|
||||
void ProcessControl_(void) { CCutsceneObject::ProcessControl(); }
|
||||
void PreRender_(void) { CCutsceneObject::PreRender(); }
|
||||
void Render_(void) { CCutsceneObject::Render(); }
|
||||
bool SetupLighting_(void) { return CCutsceneObject::SetupLighting(); }
|
||||
void RemoveLighting_(bool reset) { CCutsceneObject::RemoveLighting(reset); }
|
||||
void SetModelIndex(uint32 id);
|
||||
void ProcessControl(void);
|
||||
void PreRender(void);
|
||||
void Render(void);
|
||||
bool SetupLighting(void);
|
||||
void RemoveLighting(bool reset);
|
||||
};
|
||||
static_assert(sizeof(CCutsceneObject) == 0x198, "CCutsceneObject: error");
|
||||
|
@ -12,6 +12,12 @@ CDummyObject::CDummyObject(CObject *obj)
|
||||
m_level = obj->m_level;
|
||||
}
|
||||
|
||||
class CDummyObject_ : public CDummyObject
|
||||
{
|
||||
public:
|
||||
void dtor(void) { CDummyObject::~CDummyObject(); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x4BAB70, &CDummyObject::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
InjectHook(0x4BAB70, &CDummyObject_::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -9,6 +9,5 @@ class CDummyObject : public CDummy
|
||||
public:
|
||||
CDummyObject(void) {}
|
||||
CDummyObject(CObject *obj);
|
||||
void dtor(void) { this->CDummyObject::~CDummyObject(); }
|
||||
};
|
||||
static_assert(sizeof(CDummyObject) == 0x68, "CDummyObject: error");
|
||||
|
@ -7,8 +7,10 @@
|
||||
#include "Object.h"
|
||||
|
||||
WRAPPER void CObject::ObjectDamage(float amount) { EAXJMP(0x4BB240); }
|
||||
WRAPPER void CObject::DeleteAllTempObjectInArea(CVector, float) { EAXJMP(0x4BBED0); }
|
||||
|
||||
int16 &CObject::nNoTempObjects = *(int16*)0x95CCA2;
|
||||
int16 &CObject::nBodyCastHealth = *(int16*)0x5F7D4C; // 1000
|
||||
|
||||
void *CObject::operator new(size_t sz) { return CPools::GetObjectPool()->New(); }
|
||||
void CObject::operator delete(void *p, size_t sz) { CPools::GetObjectPool()->Delete((CObject*)p); }
|
||||
@ -85,9 +87,22 @@ CObject::RemoveLighting(bool reset)
|
||||
WorldReplaceScorchedLightsWithNormal(Scene.world);
|
||||
}
|
||||
|
||||
WRAPPER void CObject::DeleteAllTempObjectInArea(CVector, float) { EAXJMP(0x4BBED0); }
|
||||
|
||||
void
|
||||
CObject::RefModelInfo(int32 modelId)
|
||||
{
|
||||
m_nRefModelIndex = modelId;
|
||||
CModelInfo::GetModelInfo(modelId)->AddRef();
|
||||
}
|
||||
|
||||
class CObject_ : public CObject
|
||||
{
|
||||
public:
|
||||
void dtor(void) { this->CObject::~CObject(); }
|
||||
void Render_(void) { CObject::Render(); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x4BAE00, &CObject::dtor, PATCH_JUMP);
|
||||
InjectHook(0x4BB1E0, &CObject::Render_, PATCH_JUMP);
|
||||
InjectHook(0x4BAE00, &CObject_::dtor, PATCH_JUMP);
|
||||
InjectHook(0x4BB1E0, &CObject_::Render_, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -60,6 +60,7 @@ public:
|
||||
int8 m_colour1, m_colour2;
|
||||
|
||||
static int16 &nNoTempObjects;
|
||||
static int16 &nBodyCastHealth;
|
||||
|
||||
static void *operator new(size_t);
|
||||
static void operator delete(void*, size_t);
|
||||
@ -72,10 +73,8 @@ public:
|
||||
void RemoveLighting(bool reset);
|
||||
|
||||
void ObjectDamage(float amount);
|
||||
void RefModelInfo(int32 modelId);
|
||||
|
||||
static void DeleteAllTempObjectInArea(CVector, float);
|
||||
|
||||
void dtor(void) { this->CObject::~CObject(); }
|
||||
void Render_(void) { CObject::Render(); }
|
||||
};
|
||||
static_assert(sizeof(CObject) == 0x198, "CObject: error");
|
||||
|
@ -18,6 +18,12 @@ void CParticleObject::UpdateAll()
|
||||
((void (__cdecl *)())0x4BCA30)();
|
||||
}
|
||||
|
||||
class CParticleObject_ : public CParticleObject
|
||||
{
|
||||
public:
|
||||
void dtor() { CParticleObject::~CParticleObject(); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x4BC420, &CParticleObject::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
InjectHook(0x4BC420, &CParticleObject_::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -34,6 +34,4 @@ public:
|
||||
static void AddObject(uint16 type, const CVector &pos, const CVector &dir, float size, bool remove);
|
||||
static void Initialise();
|
||||
static void UpdateAll();
|
||||
|
||||
void dtor() { this->CParticleObject::~CParticleObject(); }
|
||||
};
|
||||
|
@ -2,6 +2,12 @@
|
||||
#include "patcher.h"
|
||||
#include "Projectile.h"
|
||||
|
||||
class CProjectile_ : public CProjectile
|
||||
{
|
||||
public:
|
||||
void dtor(void) { CProjectile::~CProjectile(); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x4BFED0, &CProjectile::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
InjectHook(0x4BFED0, &CProjectile_::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -7,5 +7,4 @@
|
||||
class CProjectile : public CObject
|
||||
{
|
||||
public:
|
||||
void dtor(void) { this->CProjectile::~CProjectile(); }
|
||||
};
|
||||
|
@ -13,7 +13,14 @@ CCivilianPed::CCivilianPed(int pedtype, int mi) : CPed(pedtype)
|
||||
}
|
||||
}
|
||||
|
||||
class CCivilianPed_ : public CCivilianPed
|
||||
{
|
||||
public:
|
||||
CCivilianPed *ctor(int pedtype, int mi) { return ::new (this) CCivilianPed(pedtype, mi); };
|
||||
void dtor(void) { CCivilianPed::~CCivilianPed(); }
|
||||
};
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x4BFF30, &CCivilianPed::ctor, PATCH_JUMP);
|
||||
InjectHook(0x4BFFC0, &CCivilianPed::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
InjectHook(0x4BFF30, &CCivilianPed_::ctor, PATCH_JUMP);
|
||||
InjectHook(0x4BFFC0, &CCivilianPed_::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user