merge with upstream
This commit is contained in:
commit
5b0cf80a76
@ -46,13 +46,11 @@ CBulletInfo
|
|||||||
CBulletTraces
|
CBulletTraces
|
||||||
CCam
|
CCam
|
||||||
CCamera
|
CCamera
|
||||||
CCivilianPed
|
|
||||||
CCopPed
|
CCopPed
|
||||||
CCrane
|
CCrane
|
||||||
CCranes
|
CCranes
|
||||||
CCullZone
|
CCullZone
|
||||||
CCullZones
|
CCullZones
|
||||||
CEmergencyPed
|
|
||||||
CExplosion
|
CExplosion
|
||||||
CFallingGlassPane
|
CFallingGlassPane
|
||||||
CFire
|
CFire
|
||||||
@ -64,10 +62,8 @@ CGlass
|
|||||||
CMenuManager
|
CMenuManager
|
||||||
CMotionBlurStreaks
|
CMotionBlurStreaks
|
||||||
CPacManPickups
|
CPacManPickups
|
||||||
CPed - being worked on
|
|
||||||
CPedIK
|
CPedIK
|
||||||
CPhoneInfo - one function left
|
CPedPath
|
||||||
CPlayerInfo
|
|
||||||
CPlayerPed
|
CPlayerPed
|
||||||
CProjectile
|
CProjectile
|
||||||
CProjectileInfo
|
CProjectileInfo
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "General.h"
|
||||||
#include "ModelInfo.h"
|
#include "ModelInfo.h"
|
||||||
#include "AnimManager.h"
|
#include "AnimManager.h"
|
||||||
#include "RpAnimBlend.h"
|
#include "RpAnimBlend.h"
|
||||||
@ -38,7 +39,7 @@ CAnimBlendAssocGroup::GetAnimation(const char *name)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < numAssociations; i++)
|
for(i = 0; i < numAssociations; i++)
|
||||||
if(strcmpi(assocList[i].hierarchy->name, name) == 0)
|
if(!CGeneral::faststricmp(assocList[i].hierarchy->name, name))
|
||||||
return &assocList[i];
|
return &assocList[i];
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
@ -64,7 +65,7 @@ CAnimBlendAssocGroup::CopyAnimation(const char *name)
|
|||||||
return new CAnimBlendAssociation(*anim);
|
return new CAnimBlendAssociation(*anim);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
bool
|
||||||
strcmpIgnoringDigits(const char *s1, const char *s2)
|
strcmpIgnoringDigits(const char *s1, const char *s2)
|
||||||
{
|
{
|
||||||
char c1, c2;
|
char c1, c2;
|
||||||
@ -75,13 +76,13 @@ strcmpIgnoringDigits(const char *s1, const char *s2)
|
|||||||
if(c1) s1++;
|
if(c1) s1++;
|
||||||
if(c2) s2++;
|
if(c2) s2++;
|
||||||
if(c1 == '\0' && c2 == '\0')
|
if(c1 == '\0' && c2 == '\0')
|
||||||
return 1;
|
return true;
|
||||||
if(islower(c1)) c1 = toupper(c1);
|
if(__ascii_iswdigit(c1) && __ascii_iswdigit(c2))
|
||||||
if(islower(c2)) c2 = toupper(c2);
|
|
||||||
if(isdigit(c1) && isdigit(c2))
|
|
||||||
continue;
|
continue;
|
||||||
|
c1 = __ascii_toupper(c1);
|
||||||
|
c2 = __ascii_toupper(c2);
|
||||||
if(c1 != c2)
|
if(c1 != c2)
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ enum {
|
|||||||
ASSOC_FLAG80 = 0x80, // used for footstep sound calculation
|
ASSOC_FLAG80 = 0x80, // used for footstep sound calculation
|
||||||
ASSOC_FLAG100 = 0x100,
|
ASSOC_FLAG100 = 0x100,
|
||||||
ASSOC_FLAG200 = 0x200,
|
ASSOC_FLAG200 = 0x200,
|
||||||
ASSOC_FLAG400 = 0x400, // not seen yet
|
ASSOC_FLAG400 = 0x400, // unused, blending it with move anims makes them stop. 0x800 in VC
|
||||||
ASSOC_FLAG800 = 0x800, // anims that we fall to front. 0x1000 in VC
|
ASSOC_FLAG800 = 0x800, // anims that we fall to front. 0x1000 in VC
|
||||||
ASSOC_HAS_X_TRANSLATION = 0x1000,
|
ASSOC_HAS_X_TRANSLATION = 0x1000,
|
||||||
// 0x2000 is vehicle anims in VC
|
// 0x2000 is vehicle anims in VC
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "General.h"
|
||||||
#include "ModelInfo.h"
|
#include "ModelInfo.h"
|
||||||
#include "ModelIndices.h"
|
#include "ModelIndices.h"
|
||||||
#include "FileMgr.h"
|
#include "FileMgr.h"
|
||||||
@ -605,7 +606,7 @@ CAnimManager::GetAnimationBlock(const char *name)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < ms_numAnimBlocks; i++)
|
for(i = 0; i < ms_numAnimBlocks; i++)
|
||||||
if(strcmpi(ms_aAnimBlocks[i].name, name) == 0)
|
if(strcasecmp(ms_aAnimBlocks[i].name, name) == 0)
|
||||||
return &ms_aAnimBlocks[i];
|
return &ms_aAnimBlocks[i];
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
@ -617,7 +618,7 @@ CAnimManager::GetAnimation(const char *name, CAnimBlock *animBlock)
|
|||||||
CAnimBlendHierarchy *hier = &ms_aAnimations[animBlock->firstIndex];
|
CAnimBlendHierarchy *hier = &ms_aAnimations[animBlock->firstIndex];
|
||||||
|
|
||||||
for(i = 0; i < animBlock->numAnims; i++){
|
for(i = 0; i < animBlock->numAnims; i++){
|
||||||
if(strcmpi(hier->name, name) == 0)
|
if(!CGeneral::faststricmp(hier->name, name))
|
||||||
return hier;
|
return hier;
|
||||||
hier++;
|
hier++;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "General.h"
|
||||||
#include "NodeName.h"
|
#include "NodeName.h"
|
||||||
#include "VisibilityPlugins.h"
|
#include "VisibilityPlugins.h"
|
||||||
#include "AnimBlendClumpData.h"
|
#include "AnimBlendClumpData.h"
|
||||||
@ -320,7 +321,7 @@ void
|
|||||||
FrameFindCallBack(AnimBlendFrameData *frame, void *arg)
|
FrameFindCallBack(AnimBlendFrameData *frame, void *arg)
|
||||||
{
|
{
|
||||||
char *nodename = GetFrameNodeName(frame->frame);
|
char *nodename = GetFrameNodeName(frame->frame);
|
||||||
if(strcmpi(nodename, (char*)arg) == 0)
|
if(!CGeneral::faststricmp(nodename, (char*)arg))
|
||||||
pFrameDataFound = frame;
|
pFrameDataFound = frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "General.h"
|
||||||
#include "audio_enums.h"
|
#include "audio_enums.h"
|
||||||
|
|
||||||
#include "AudioManager.h"
|
#include "AudioManager.h"
|
||||||
@ -517,11 +518,11 @@ cAudioManager::AgeCrimes()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cAudioManager::CalculateDistance(bool *ptr, float dist)
|
cAudioManager::CalculateDistance(bool &distCalculated, float dist)
|
||||||
{
|
{
|
||||||
if(*ptr == false) {
|
if(!distCalculated) {
|
||||||
m_sQueueSample.m_fDistance = Sqrt(dist);
|
m_sQueueSample.m_fDistance = Sqrt(dist);
|
||||||
*ptr = true;
|
distCalculated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2130,16 +2131,16 @@ uint32
|
|||||||
cAudioManager::GetSpecialCharacterTalkSfx(int32 modelIndex, int32 sound)
|
cAudioManager::GetSpecialCharacterTalkSfx(int32 modelIndex, int32 sound)
|
||||||
{
|
{
|
||||||
char *modelName = CModelInfo::GetModelInfo(modelIndex)->GetName();
|
char *modelName = CModelInfo::GetModelInfo(modelIndex)->GetName();
|
||||||
if(strcmpi(modelName, "eight") == 0 || strcmpi(modelName, "eight2") == 0) { return GetEightTalkSfx(sound); }
|
if(!CGeneral::faststricmp(modelName, "eight") || !CGeneral::faststricmp(modelName, "eight2")) { return GetEightTalkSfx(sound); }
|
||||||
if(strcmpi(modelName, "frankie") == 0) { return GetFrankieTalkSfx(sound); }
|
if(!CGeneral::faststricmp(modelName, "frankie")) { return GetFrankieTalkSfx(sound); }
|
||||||
if(strcmpi(modelName, "misty") == 0) { return GetMistyTalkSfx(sound); }
|
if(!CGeneral::faststricmp(modelName, "misty")) { return GetMistyTalkSfx(sound); }
|
||||||
if(strcmpi(modelName, "ojg") == 0 || strcmpi(modelName, "ojg_p") == 0) { return GetOJGTalkSfx(sound); }
|
if(!CGeneral::faststricmp(modelName, "ojg") || !CGeneral::faststricmp(modelName, "ojg_p")) { return GetOJGTalkSfx(sound); }
|
||||||
if(strcmpi(modelName, "cat") == 0) { return GetCatatalinaTalkSfx(sound); }
|
if(!CGeneral::faststricmp(modelName, "cat")) { return GetCatatalinaTalkSfx(sound); }
|
||||||
if(strcmpi(modelName, "bomber") == 0) { return GetBomberTalkSfx(sound); }
|
if(!CGeneral::faststricmp(modelName, "bomber")) { return GetBomberTalkSfx(sound); }
|
||||||
if(strcmpi(modelName, "s_guard") == 0) { return GetSecurityGuardTalkSfx(sound); }
|
if(!CGeneral::faststricmp(modelName, "s_guard")) { return GetSecurityGuardTalkSfx(sound); }
|
||||||
if(strcmpi(modelName, "chunky") == 0) { return GetChunkyTalkSfx(sound); }
|
if(!CGeneral::faststricmp(modelName, "chunky")) { return GetChunkyTalkSfx(sound); }
|
||||||
if(strcmpi(modelName, "asuka") == 0) { return GetGenericFemaleTalkSfx(sound); }
|
if(!CGeneral::faststricmp(modelName, "asuka")) { return GetGenericFemaleTalkSfx(sound); }
|
||||||
if(strcmpi(modelName, "maria") == 0) { return GetGenericFemaleTalkSfx(sound); }
|
if(!CGeneral::faststricmp(modelName, "maria")) { return GetGenericFemaleTalkSfx(sound); }
|
||||||
|
|
||||||
return GetGenericMaleTalkSfx(sound);
|
return GetGenericMaleTalkSfx(sound);
|
||||||
}
|
}
|
||||||
@ -2601,7 +2602,7 @@ cAudioManager::InitialisePoliceRadio()
|
|||||||
|
|
||||||
SampleManager.SetChannelReverbFlag(policeChannel, 0);
|
SampleManager.SetChannelReverbFlag(policeChannel, 0);
|
||||||
gSpecialSuspectLastSeenReport = 0;
|
gSpecialSuspectLastSeenReport = 0;
|
||||||
for(int32 i = 0; i < 18; i++) { gMinTimeToNextReport[i] = m_nTimeOfRecentCrime; }
|
for(int32 i = 0; i < 17; i++) { gMinTimeToNextReport[i] = m_nTimeOfRecentCrime; }
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tPoliceRadioZone {
|
struct tPoliceRadioZone {
|
||||||
@ -3100,7 +3101,7 @@ int32
|
|||||||
FindMissionAudioSfx(const char *name)
|
FindMissionAudioSfx(const char *name)
|
||||||
{
|
{
|
||||||
for(uint32 i = 0; i < ARRAY_SIZE(MissionAudioNameSfxAssoc); ++i) {
|
for(uint32 i = 0; i < ARRAY_SIZE(MissionAudioNameSfxAssoc); ++i) {
|
||||||
if(strcmpi(MissionAudioNameSfxAssoc[i].m_pName, name) == 0) return MissionAudioNameSfxAssoc[i].m_nId;
|
if(!CGeneral::faststricmp(MissionAudioNameSfxAssoc[i].m_pName, name)) return MissionAudioNameSfxAssoc[i].m_nId;
|
||||||
}
|
}
|
||||||
debug("Can't find mission audio %s", name);
|
debug("Can't find mission audio %s", name);
|
||||||
return NO_SAMPLE;
|
return NO_SAMPLE;
|
||||||
@ -3180,7 +3181,7 @@ cAudioManager::ProcessAirBrakes(cVehicleParams *params)
|
|||||||
(automobile->m_fVelocityChangeForAudio > -0.025f || params->m_fVelocityChange <= 0.025f))
|
(automobile->m_fVelocityChangeForAudio > -0.025f || params->m_fVelocityChange <= 0.025f))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
rand = m_anRandomTable[0] % 10 + 70;
|
rand = m_anRandomTable[0] % 10 + 70;
|
||||||
m_sQueueSample.m_bVolume = ComputeVolume(rand, 30.0f, m_sQueueSample.m_fDistance);
|
m_sQueueSample.m_bVolume = ComputeVolume(rand, 30.0f, m_sQueueSample.m_fDistance);
|
||||||
if(m_sQueueSample.m_bVolume) {
|
if(m_sQueueSample.m_bVolume) {
|
||||||
@ -3272,7 +3273,7 @@ cAudioManager::ProcessBoatEngine(cVehicleParams *params)
|
|||||||
if(params->m_fDistance < 2500.f) {
|
if(params->m_fDistance < 2500.f) {
|
||||||
boat = (CBoat *)params->m_pVehicle;
|
boat = (CBoat *)params->m_pVehicle;
|
||||||
if(params->m_nIndex == REEFER) {
|
if(params->m_nIndex == REEFER) {
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
m_sQueueSample.m_bVolume = ComputeVolume(80, 50.f, m_sQueueSample.m_fDistance);
|
m_sQueueSample.m_bVolume = ComputeVolume(80, 50.f, m_sQueueSample.m_fDistance);
|
||||||
if(m_sQueueSample.m_bVolume) {
|
if(m_sQueueSample.m_bVolume) {
|
||||||
m_sQueueSample.m_counter = 39;
|
m_sQueueSample.m_counter = 39;
|
||||||
@ -3378,7 +3379,7 @@ cAudioManager::ProcessBoatEngine(cVehicleParams *params)
|
|||||||
m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_ACCEL;
|
m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_ACCEL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance);
|
m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance);
|
||||||
if(!m_sQueueSample.m_bVolume) return 1;
|
if(!m_sQueueSample.m_bVolume) return 1;
|
||||||
m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex << 16) % 1000;
|
m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex << 16) % 1000;
|
||||||
@ -3417,7 +3418,7 @@ cAudioManager::ProcessBoatMovingOverWater(cVehicleParams *params)
|
|||||||
|
|
||||||
velocityChange = min(0.75f, velocityChange);
|
velocityChange = min(0.75f, velocityChange);
|
||||||
multiplier = (velocityChange - 0.0005f) * 1.3342f;
|
multiplier = (velocityChange - 0.0005f) * 1.3342f;
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
vol = (30.f * multiplier);
|
vol = (30.f * multiplier);
|
||||||
m_sQueueSample.m_bVolume = ComputeVolume(vol, 50.f, m_sQueueSample.m_fDistance);
|
m_sQueueSample.m_bVolume = ComputeVolume(vol, 50.f, m_sQueueSample.m_fDistance);
|
||||||
if(m_sQueueSample.m_bVolume) {
|
if(m_sQueueSample.m_bVolume) {
|
||||||
@ -3447,13 +3448,13 @@ void
|
|||||||
cAudioManager::ProcessBridge()
|
cAudioManager::ProcessBridge()
|
||||||
{
|
{
|
||||||
float dist;
|
float dist;
|
||||||
bool something = false;
|
bool distCalculated = false;
|
||||||
|
|
||||||
if(CBridge::pLiftRoad) {
|
if(CBridge::pLiftRoad) {
|
||||||
m_sQueueSample.m_vecPos = CBridge::pLiftRoad->GetPosition();
|
m_sQueueSample.m_vecPos = CBridge::pLiftRoad->GetPosition();
|
||||||
dist = GetDistanceSquared(&m_sQueueSample.m_vecPos);
|
dist = GetDistanceSquared(&m_sQueueSample.m_vecPos);
|
||||||
if(dist < 202500.0f) {
|
if(dist < 202500.0f) {
|
||||||
CalculateDistance(&something, dist);
|
CalculateDistance(distCalculated, dist);
|
||||||
switch(CBridge::State) {
|
switch(CBridge::State) {
|
||||||
case STATE_BRIDGE_LOCKED:
|
case STATE_BRIDGE_LOCKED:
|
||||||
case STATE_LIFT_PART_IS_UP:
|
case STATE_LIFT_PART_IS_UP:
|
||||||
@ -3583,7 +3584,7 @@ cAudioManager::ProcessCarBombTick(cVehicleParams *params)
|
|||||||
if(params->m_fDistance >= 1600.f) return 0;
|
if(params->m_fDistance >= 1600.f) return 0;
|
||||||
automobile = (CAutomobile *)params->m_pVehicle;
|
automobile = (CAutomobile *)params->m_pVehicle;
|
||||||
if(automobile->bEngineOn && automobile->m_bombType == CARBOMB_TIMEDACTIVE) {
|
if(automobile->bEngineOn && automobile->m_bombType == CARBOMB_TIMEDACTIVE) {
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
m_sQueueSample.m_bVolume = ComputeVolume(60, 40.f, m_sQueueSample.m_fDistance);
|
m_sQueueSample.m_bVolume = ComputeVolume(60, 40.f, m_sQueueSample.m_fDistance);
|
||||||
if(m_sQueueSample.m_bVolume) {
|
if(m_sQueueSample.m_bVolume) {
|
||||||
m_sQueueSample.m_counter = 35;
|
m_sQueueSample.m_counter = 35;
|
||||||
@ -3749,7 +3750,7 @@ cAudioManager::ProcessEngineDamage(cVehicleParams *params)
|
|||||||
m_sQueueSample.field_16 = 7;
|
m_sQueueSample.field_16 = 7;
|
||||||
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE);
|
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE);
|
||||||
}
|
}
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
m_sQueueSample.m_bVolume = ComputeVolume(emittingVolume, 40.f, m_sQueueSample.m_fDistance);
|
m_sQueueSample.m_bVolume = ComputeVolume(emittingVolume, 40.f, m_sQueueSample.m_fDistance);
|
||||||
if(m_sQueueSample.m_bVolume) {
|
if(m_sQueueSample.m_bVolume) {
|
||||||
m_sQueueSample.m_counter = 28;
|
m_sQueueSample.m_counter = 28;
|
||||||
@ -3932,12 +3933,12 @@ void
|
|||||||
cAudioManager::ProcessFireHydrant()
|
cAudioManager::ProcessFireHydrant()
|
||||||
{
|
{
|
||||||
float distSquared;
|
float distSquared;
|
||||||
bool something = false;
|
bool distCalculated = false;
|
||||||
|
|
||||||
m_sQueueSample.m_vecPos = *(CVector *)((size_t)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity + 52);
|
m_sQueueSample.m_vecPos = *(CVector *)((size_t)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity + 52);
|
||||||
distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
|
distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
|
||||||
if(distSquared < 1225.f) {
|
if(distSquared < 1225.f) {
|
||||||
CalculateDistance(&something, distSquared);
|
CalculateDistance(distCalculated, distSquared);
|
||||||
m_sQueueSample.m_bVolume = ComputeVolume(40, 35.f, m_sQueueSample.m_fDistance);
|
m_sQueueSample.m_bVolume = ComputeVolume(40, 35.f, m_sQueueSample.m_fDistance);
|
||||||
if(m_sQueueSample.m_bVolume) {
|
if(m_sQueueSample.m_bVolume) {
|
||||||
m_sQueueSample.m_counter = 0;
|
m_sQueueSample.m_counter = 0;
|
||||||
@ -4154,7 +4155,7 @@ cAudioManager::ProcessHelicopter(cVehicleParams *params)
|
|||||||
|
|
||||||
if(gHeliSfxRanges[0].m_fMaxDistance * gHeliSfxRanges[0].m_fMaxDistance <= params->m_fDistance) return 0;
|
if(gHeliSfxRanges[0].m_fMaxDistance * gHeliSfxRanges[0].m_fMaxDistance <= params->m_fDistance) return 0;
|
||||||
|
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
heli = (CHeli *)params->m_pVehicle;
|
heli = (CHeli *)params->m_pVehicle;
|
||||||
for(uint32 i = 0; i < 3; i++) {
|
for(uint32 i = 0; i < 3; i++) {
|
||||||
MaxDist = gHeliSfxRanges[i].m_fMaxDistance;
|
MaxDist = gHeliSfxRanges[i].m_fMaxDistance;
|
||||||
@ -4253,7 +4254,7 @@ cAudioManager::ProcessJumbo(cVehicleParams *params)
|
|||||||
float position;
|
float position;
|
||||||
|
|
||||||
if(params->m_fDistance < 193600.0f) {
|
if(params->m_fDistance < 193600.0f) {
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
plane = (CPlane *)params->m_pVehicle;
|
plane = (CPlane *)params->m_pVehicle;
|
||||||
DoJumboVolOffset();
|
DoJumboVolOffset();
|
||||||
position = PlanePathPosition[plane->m_nPlaneId];
|
position = PlanePathPosition[plane->m_nPlaneId];
|
||||||
@ -5213,7 +5214,7 @@ cAudioManager::ProcessModelCarEngine(cVehicleParams *params)
|
|||||||
else
|
else
|
||||||
emittingVol = 90;
|
emittingVol = 90;
|
||||||
if(emittingVol) {
|
if(emittingVol) {
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
m_sQueueSample.m_bVolume =
|
m_sQueueSample.m_bVolume =
|
||||||
ComputeVolume(emittingVol, 30.f, m_sQueueSample.m_fDistance);
|
ComputeVolume(emittingVol, 30.f, m_sQueueSample.m_fDistance);
|
||||||
if(m_sQueueSample.m_bVolume) {
|
if(m_sQueueSample.m_bVolume) {
|
||||||
@ -5535,12 +5536,12 @@ cAudioManager::ProcessPedHeadphones(cPedParams *params)
|
|||||||
|
|
||||||
if(params->m_fDistance < 49.f) {
|
if(params->m_fDistance < 49.f) {
|
||||||
ped = params->m_pPed;
|
ped = params->m_pPed;
|
||||||
if(!ped->bIsAimingGun || ped->m_bodyPartBleeding != 2) {
|
if(!ped->bIsAimingGun || ped->m_bodyPartBleeding != PED_HEAD) {
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
if(ped->bInVehicle && ped->m_nPedState == PED_DRIVING) {
|
if(ped->bInVehicle && ped->m_nPedState == PED_DRIVING) {
|
||||||
emittingVol = 10;
|
emittingVol = 10;
|
||||||
veh = ped->m_pMyVehicle;
|
veh = ped->m_pMyVehicle;
|
||||||
if(veh && veh->m_type == 0) {
|
if(veh && veh->IsCar()) {
|
||||||
for(int32 i = 2; i < 6; i++) {
|
for(int32 i = 2; i < 6; i++) {
|
||||||
if(!veh->IsDoorClosed((eDoors)i) || veh->IsDoorMissing((eDoors)i)) {
|
if(!veh->IsDoorClosed((eDoors)i) || veh->IsDoorMissing((eDoors)i)) {
|
||||||
emittingVol = 42;
|
emittingVol = 42;
|
||||||
@ -6450,7 +6451,7 @@ cAudioManager::ProcessPhysical(int32 id)
|
|||||||
{
|
{
|
||||||
CPhysical *entity = (CPhysical *)m_asAudioEntities[id].m_pEntity;
|
CPhysical *entity = (CPhysical *)m_asAudioEntities[id].m_pEntity;
|
||||||
if(entity) {
|
if(entity) {
|
||||||
switch(entity->m_type & 7) {
|
switch(entity->m_type) {
|
||||||
case ENTITY_TYPE_VEHICLE: ProcessVehicle((CVehicle *)m_asAudioEntities[id].m_pEntity); break;
|
case ENTITY_TYPE_VEHICLE: ProcessVehicle((CVehicle *)m_asAudioEntities[id].m_pEntity); break;
|
||||||
case ENTITY_TYPE_PED: ProcessPed((CPhysical *)m_asAudioEntities[id].m_pEntity); break;
|
case ENTITY_TYPE_PED: ProcessPed((CPhysical *)m_asAudioEntities[id].m_pEntity); break;
|
||||||
default: return;
|
default: return;
|
||||||
@ -6491,7 +6492,6 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
|
|||||||
float relativeVelocityChange;
|
float relativeVelocityChange;
|
||||||
float accelerationMultipler;
|
float accelerationMultipler;
|
||||||
uint8 wheelInUseCounter;
|
uint8 wheelInUseCounter;
|
||||||
uint8 i;
|
|
||||||
float time;
|
float time;
|
||||||
int baseFreq;
|
int baseFreq;
|
||||||
uint8 vol;
|
uint8 vol;
|
||||||
@ -6539,19 +6539,15 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
|
|||||||
velocityChange = params->m_fVelocityChange;
|
velocityChange = params->m_fVelocityChange;
|
||||||
relativeVelocityChange = 2.0f * velocityChange / transmission->fMaxVelocity;
|
relativeVelocityChange = 2.0f * velocityChange / transmission->fMaxVelocity;
|
||||||
|
|
||||||
accelerationMultipler = 0.0f;
|
accelerationMultipler = min(min(1.f, relativeVelocityChange), 0.f);
|
||||||
|
|
||||||
if(relativeVelocityChange > 1.0f) accelerationMultipler = relativeVelocityChange;
|
|
||||||
|
|
||||||
gasPedalAudio = accelerationMultipler;
|
gasPedalAudio = accelerationMultipler;
|
||||||
currentGear = params->m_pVehicle->m_nCurrentGear;
|
currentGear = params->m_pVehicle->m_nCurrentGear;
|
||||||
|
|
||||||
if(transmission->nDriveType == '4') {
|
if(transmission->nDriveType == '4') {
|
||||||
wheelInUseCounter = 0;
|
wheelInUseCounter = 0;
|
||||||
i = 0;
|
for (uint8 i = 0; i < 4; i++){
|
||||||
do {
|
|
||||||
if(automobile->m_aWheelState[i]) ++wheelInUseCounter;
|
if(automobile->m_aWheelState[i]) ++wheelInUseCounter;
|
||||||
++i;
|
}
|
||||||
} while(i < 4);
|
|
||||||
if(wheelInUseCounter > 2) lostTraction = 1;
|
if(wheelInUseCounter > 2) lostTraction = 1;
|
||||||
} else if(transmission->nDriveType == 'F') {
|
} else if(transmission->nDriveType == 'F') {
|
||||||
if((automobile->m_aWheelState[0] || automobile->m_aWheelState[2]) &&
|
if((automobile->m_aWheelState[0] || automobile->m_aWheelState[2]) &&
|
||||||
@ -6622,7 +6618,8 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
|
|||||||
if(!nCruising) {
|
if(!nCruising) {
|
||||||
if(accelerateState < 150 || !automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn ||
|
if(accelerateState < 150 || !automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn ||
|
||||||
lostTraction ||
|
lostTraction ||
|
||||||
currentGear < 2u && velocityChange - automobile->m_fVelocityChangeForAudio >= 0.01f) {
|
currentGear < 2 &&
|
||||||
|
velocityChange - automobile->m_fVelocityChangeForAudio < 0.01f) { // here could be used abs
|
||||||
if(!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction) {
|
if(!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction) {
|
||||||
if(!automobile->m_nWheelsOnGround && automobile->m_nDriveWheelsOnGround ||
|
if(!automobile->m_nWheelsOnGround && automobile->m_nDriveWheelsOnGround ||
|
||||||
(automobile->bIsHandbrakeOn && !bHandbrakeOnLastFrame ||
|
(automobile->bIsHandbrakeOn && !bHandbrakeOnLastFrame ||
|
||||||
@ -6994,7 +6991,7 @@ cAudioManager::ProcessRainOnVehicle(cVehicleParams *params)
|
|||||||
veh = params->m_pVehicle;
|
veh = params->m_pVehicle;
|
||||||
if(veh->m_bRainAudioCounter >= 2) {
|
if(veh->m_bRainAudioCounter >= 2) {
|
||||||
veh->m_bRainAudioCounter = 0;
|
veh->m_bRainAudioCounter = 0;
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
emittingVol = 30.f * CWeather::Rain;
|
emittingVol = 30.f * CWeather::Rain;
|
||||||
m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 22.f, m_sQueueSample.m_fDistance);
|
m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 22.f, m_sQueueSample.m_fDistance);
|
||||||
if(m_sQueueSample.m_bVolume) {
|
if(m_sQueueSample.m_bVolume) {
|
||||||
@ -7043,7 +7040,7 @@ cAudioManager::ProcessReverseGear(cVehicleParams *params)
|
|||||||
if(params->m_fDistance >= 900.f) return 0;
|
if(params->m_fDistance >= 900.f) return 0;
|
||||||
veh = params->m_pVehicle;
|
veh = params->m_pVehicle;
|
||||||
if(veh->bEngineOn && (veh->m_fGasPedal < 0.0f || !veh->m_nCurrentGear)) {
|
if(veh->bEngineOn && (veh->m_fGasPedal < 0.0f || !veh->m_nCurrentGear)) {
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
automobile = (CAutomobile *)params->m_pVehicle;
|
automobile = (CAutomobile *)params->m_pVehicle;
|
||||||
if(automobile->m_nWheelsOnGround) {
|
if(automobile->m_nWheelsOnGround) {
|
||||||
modificator = params->m_fVelocityChange / params->m_pTransmission->fMaxReverseVelocity;
|
modificator = params->m_fVelocityChange / params->m_pTransmission->fMaxReverseVelocity;
|
||||||
@ -7261,7 +7258,7 @@ cAudioManager::ProcessTrainNoise(cVehicleParams *params)
|
|||||||
if(params->m_fDistance >= 90000.f) return 0;
|
if(params->m_fDistance >= 90000.f) return 0;
|
||||||
|
|
||||||
if(params->m_fVelocityChange > 0.0f) {
|
if(params->m_fVelocityChange > 0.0f) {
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
train = (CTrain *)params->m_pVehicle;
|
train = (CTrain *)params->m_pVehicle;
|
||||||
speedMultipler = min(1.0f, train->m_fSpeed * 250.f / 51.f);
|
speedMultipler = min(1.0f, train->m_fSpeed * 250.f / 51.f);
|
||||||
emittingVol = (75.f * speedMultipler);
|
emittingVol = (75.f * speedMultipler);
|
||||||
@ -7326,7 +7323,7 @@ cAudioManager::ProcessVehicle(CVehicle *veh)
|
|||||||
cVehicleParams params;
|
cVehicleParams params;
|
||||||
m_sQueueSample.m_vecPos = veh->GetPosition();
|
m_sQueueSample.m_vecPos = veh->GetPosition();
|
||||||
|
|
||||||
params.m_bDistancECalculated = 0;
|
params.m_bDistanceCalculated = false;
|
||||||
params.m_fDistance = GetDistanceSquared(&m_sQueueSample.m_vecPos);
|
params.m_fDistance = GetDistanceSquared(&m_sQueueSample.m_vecPos);
|
||||||
params.m_pVehicle = veh;
|
params.m_pVehicle = veh;
|
||||||
params.m_pTransmission = nil;
|
params.m_pTransmission = nil;
|
||||||
@ -7419,7 +7416,7 @@ cAudioManager::ProcessVehicleDoors(cVehicleParams *params)
|
|||||||
if(params->m_fDistance >= 1600.f) return 0;
|
if(params->m_fDistance >= 1600.f) return 0;
|
||||||
|
|
||||||
automobile = (CAutomobile *)params->m_pVehicle;
|
automobile = (CAutomobile *)params->m_pVehicle;
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
for(int32 i = 0; i < 6; i++) {
|
for(int32 i = 0; i < 6; i++) {
|
||||||
if(automobile->Damage.GetDoorStatus(i) == 2) {
|
if(automobile->Damage.GetDoorStatus(i) == 2) {
|
||||||
doorState = automobile->Doors[i].m_nDoorState;
|
doorState = automobile->Doors[i].m_nDoorState;
|
||||||
@ -7475,7 +7472,7 @@ cAudioManager::ProcessVehicleHorn(cVehicleParams *params)
|
|||||||
automobile->m_modelIndex != MI_MRWHOOP) {
|
automobile->m_modelIndex != MI_MRWHOOP) {
|
||||||
if(automobile->m_nCarHornTimer) {
|
if(automobile->m_nCarHornTimer) {
|
||||||
if(!params->m_pVehicle->m_status) {
|
if(!params->m_pVehicle->m_status) {
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
m_sQueueSample.m_bVolume = ComputeVolume(80, 40.f, m_sQueueSample.m_fDistance);
|
m_sQueueSample.m_bVolume = ComputeVolume(80, 40.f, m_sQueueSample.m_fDistance);
|
||||||
if(m_sQueueSample.m_bVolume) {
|
if(m_sQueueSample.m_bVolume) {
|
||||||
m_sQueueSample.m_counter = 4;
|
m_sQueueSample.m_counter = 4;
|
||||||
@ -7507,7 +7504,7 @@ cAudioManager::ProcessVehicleHorn(cVehicleParams *params)
|
|||||||
automobile->field_22D =
|
automobile->field_22D =
|
||||||
(LOBYTE(m_nTimeOfRecentCrime) + LOBYTE(m_sQueueSample.m_nEntityIndex)) & 7;
|
(LOBYTE(m_nTimeOfRecentCrime) + LOBYTE(m_sQueueSample.m_nEntityIndex)) & 7;
|
||||||
if(hornPatternsArray[automobile->field_22D][44 - automobile->m_nCarHornTimer]) {
|
if(hornPatternsArray[automobile->field_22D][44 - automobile->m_nCarHornTimer]) {
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
m_sQueueSample.m_bVolume = ComputeVolume(80, 40.f, m_sQueueSample.m_fDistance);
|
m_sQueueSample.m_bVolume = ComputeVolume(80, 40.f, m_sQueueSample.m_fDistance);
|
||||||
if(m_sQueueSample.m_bVolume) {
|
if(m_sQueueSample.m_bVolume) {
|
||||||
m_sQueueSample.m_counter = 4;
|
m_sQueueSample.m_counter = 4;
|
||||||
@ -7553,7 +7550,7 @@ cAudioManager::ProcessVehicleReverseWarning(cVehicleParams *params)
|
|||||||
if(params->m_fDistance >= 2500.f) return 0;
|
if(params->m_fDistance >= 2500.f) return 0;
|
||||||
|
|
||||||
if(veh->bEngineOn && veh->m_fGasPedal < 0.0f) {
|
if(veh->bEngineOn && veh->m_fGasPedal < 0.0f) {
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
m_sQueueSample.m_bVolume = ComputeVolume(60, 50.f, m_sQueueSample.m_fDistance);
|
m_sQueueSample.m_bVolume = ComputeVolume(60, 50.f, m_sQueueSample.m_fDistance);
|
||||||
if(m_sQueueSample.m_bVolume) {
|
if(m_sQueueSample.m_bVolume) {
|
||||||
m_sQueueSample.m_counter = 12;
|
m_sQueueSample.m_counter = 12;
|
||||||
@ -7595,7 +7592,7 @@ cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params)
|
|||||||
if(params->m_pVehicle->m_vecMoveSpeed.z) {
|
if(params->m_pVehicle->m_vecMoveSpeed.z) {
|
||||||
velocity = Abs(params->m_fVelocityChange);
|
velocity = Abs(params->m_fVelocityChange);
|
||||||
if(velocity > 0.0f) {
|
if(velocity > 0.0f) {
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
emittingVol =
|
emittingVol =
|
||||||
30.f * min(1.f, velocity / (0.5f * params->m_pTransmission->fMaxVelocity));
|
30.f * min(1.f, velocity / (0.5f * params->m_pTransmission->fMaxVelocity));
|
||||||
m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 95.f, m_sQueueSample.m_fDistance);
|
m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 95.f, m_sQueueSample.m_fDistance);
|
||||||
@ -7635,11 +7632,55 @@ cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
WRAPPER
|
|
||||||
void
|
void
|
||||||
cAudioManager::ProcessVehicleSirenOrAlarm(void *)
|
cAudioManager::ProcessVehicleSirenOrAlarm(cVehicleParams *params)
|
||||||
{
|
{
|
||||||
EAXJMP(0x56C420);
|
if(params->m_fDistance < 12100.f) {
|
||||||
|
CVehicle *veh = params->m_pVehicle;
|
||||||
|
if(veh->m_bSirenOrAlarm == 0 && veh->m_nAlarmState <= 0) return;
|
||||||
|
|
||||||
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
|
m_sQueueSample.m_bVolume = ComputeVolume(80, 110.f, m_sQueueSample.m_fDistance);
|
||||||
|
if(m_sQueueSample.m_bVolume) {
|
||||||
|
m_sQueueSample.m_counter = 5;
|
||||||
|
if(UsesSiren(params->m_nIndex)) {
|
||||||
|
if(params->m_pVehicle->m_status == STATUS_ABANDONED) return;
|
||||||
|
if(veh->m_nCarHornTimer && params->m_nIndex != FIRETRUK) {
|
||||||
|
m_sQueueSample.m_nSampleIndex = SFX_SIREN_FAST;
|
||||||
|
if(params->m_nIndex == FBICAR)
|
||||||
|
m_sQueueSample.m_nFrequency = 16113;
|
||||||
|
else
|
||||||
|
m_sQueueSample.m_nFrequency =
|
||||||
|
SampleManager.GetSampleBaseFrequency(SFX_SIREN_FAST);
|
||||||
|
m_sQueueSample.m_counter = 60;
|
||||||
|
} else {
|
||||||
|
m_sQueueSample.m_nSampleIndex =
|
||||||
|
CarSounds[params->m_nIndex].m_nSirenOrAlarmSample;
|
||||||
|
m_sQueueSample.m_nFrequency =
|
||||||
|
CarSounds[params->m_nIndex].m_nSirenOrAlarmFrequency;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_sQueueSample.m_nSampleIndex = CarSounds[params->m_nIndex].m_nSirenOrAlarmSample;
|
||||||
|
m_sQueueSample.m_nFrequency = CarSounds[params->m_nIndex].m_nSirenOrAlarmFrequency;
|
||||||
|
}
|
||||||
|
m_sQueueSample.m_bBankIndex = 0;
|
||||||
|
m_sQueueSample.m_bIsDistant = 0;
|
||||||
|
m_sQueueSample.field_16 = 1;
|
||||||
|
m_sQueueSample.m_nLoopCount = 0;
|
||||||
|
m_sQueueSample.m_bEmittingVolume = 80;
|
||||||
|
m_sQueueSample.m_nLoopStart =
|
||||||
|
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
|
||||||
|
m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
|
||||||
|
m_sQueueSample.field_48 = 7.0f;
|
||||||
|
m_sQueueSample.m_fSoundIntensity = 110.0f;
|
||||||
|
m_sQueueSample.field_56 = 0;
|
||||||
|
m_sQueueSample.field_76 = 5;
|
||||||
|
m_sQueueSample.m_bReverbFlag = 1;
|
||||||
|
m_sQueueSample.m_bRequireReflection = 0;
|
||||||
|
AddSampleToRequestedQueue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -7654,7 +7695,7 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams *params)
|
|||||||
if(params->m_fDistance >= 1600.f) return;
|
if(params->m_fDistance >= 1600.f) return;
|
||||||
automobile = (CAutomobile *)params->m_pVehicle;
|
automobile = (CAutomobile *)params->m_pVehicle;
|
||||||
if(!automobile->m_nWheelsOnGround) return;
|
if(!automobile->m_nWheelsOnGround) return;
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
for(int32 i = 0; i < 4; i++) {
|
for(int32 i = 0; i < 4; i++) {
|
||||||
if(!automobile->m_aWheelState[i] || automobile->Damage.GetWheelStatus(i) == WHEEL_STATUS_MISSING)
|
if(!automobile->m_aWheelState[i] || automobile->Damage.GetWheelStatus(i) == WHEEL_STATUS_MISSING)
|
||||||
continue;
|
continue;
|
||||||
@ -7843,7 +7884,7 @@ cAudioManager::ProcessWetRoadNoise(cVehicleParams *params)
|
|||||||
if(params->m_pVehicle->m_vecMoveSpeed.z) {
|
if(params->m_pVehicle->m_vecMoveSpeed.z) {
|
||||||
velChange = Abs(params->m_fVelocityChange);
|
velChange = Abs(params->m_fVelocityChange);
|
||||||
if(velChange > 0.f) {
|
if(velChange > 0.f) {
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
relativeVelocity =
|
relativeVelocity =
|
||||||
min(1.0f, velChange / (0.5f * params->m_pTransmission->fMaxVelocity));
|
min(1.0f, velChange / (0.5f * params->m_pTransmission->fMaxVelocity));
|
||||||
emittingVol = 23.0f * relativeVelocity * CWeather::WetRoads;
|
emittingVol = 23.0f * relativeVelocity * CWeather::WetRoads;
|
||||||
@ -8872,14 +8913,14 @@ cAudioManager::SetupPedComments(cPedParams *params, uint32 sound)
|
|||||||
soundIntensity = 50.f;
|
soundIntensity = 50.f;
|
||||||
|
|
||||||
if(params->m_fDistance < maxDist) {
|
if(params->m_fDistance < maxDist) {
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
if(sound != SOUND_PAGER) {
|
if(sound != SOUND_PAGER) {
|
||||||
switch(sound) {
|
switch(sound) {
|
||||||
case SOUND_AMMUNATION_WELCOME_1:
|
case SOUND_AMMUNATION_WELCOME_1:
|
||||||
case SOUND_AMMUNATION_WELCOME_2:
|
case SOUND_AMMUNATION_WELCOME_2:
|
||||||
case SOUND_AMMUNATION_WELCOME_3: emittingVol = maxVolume; break;
|
case SOUND_AMMUNATION_WELCOME_3: emittingVol = maxVolume; break;
|
||||||
default:
|
default:
|
||||||
if(CWorld::GetIsLineOfSightClear(TheCamera.GetGameCamPosition(),
|
if(CWorld::GetIsLineOfSightClear(TheCamera.GetPosition(),
|
||||||
m_sQueueSample.m_vecPos, 1, 0, 0, 0, 0, 0,
|
m_sQueueSample.m_vecPos, 1, 0, 0, 0, 0, 0,
|
||||||
0)) {
|
0)) {
|
||||||
emittingVol = maxVolume;
|
emittingVol = maxVolume;
|
||||||
@ -8933,14 +8974,14 @@ cAudioManager::SetupPedComments(cPedParams *params, uint32 sound)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(params->m_fDistance < maxDist) {
|
if(params->m_fDistance < maxDist) {
|
||||||
CalculateDistance((bool *)params, params->m_fDistance);
|
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
|
||||||
if(sound != SOUND_PAGER) {
|
if(sound != SOUND_PAGER) {
|
||||||
switch(sound) {
|
switch(sound) {
|
||||||
case SOUND_AMMUNATION_WELCOME_1:
|
case SOUND_AMMUNATION_WELCOME_1:
|
||||||
case SOUND_AMMUNATION_WELCOME_2:
|
case SOUND_AMMUNATION_WELCOME_2:
|
||||||
case SOUND_AMMUNATION_WELCOME_3: emittingVol = maxVolume; break;
|
case SOUND_AMMUNATION_WELCOME_3: emittingVol = maxVolume; break;
|
||||||
default:
|
default:
|
||||||
if(CWorld::GetIsLineOfSightClear(TheCamera.GetGameCamPosition(),
|
if(CWorld::GetIsLineOfSightClear(TheCamera.GetPosition(),
|
||||||
m_sQueueSample.m_vecPos, 1, 0, 0, 0, 0, 0,
|
m_sQueueSample.m_vecPos, 1, 0, 0, 0, 0, 0,
|
||||||
0)) {
|
0)) {
|
||||||
emittingVol = maxVolume;
|
emittingVol = maxVolume;
|
||||||
@ -9594,6 +9635,7 @@ InjectHook(0x56C770, &cAudioManager::ProcessVehicleDoors, PATCH_JUMP);
|
|||||||
InjectHook(0x56C200, &cAudioManager::ProcessVehicleHorn, PATCH_JUMP);
|
InjectHook(0x56C200, &cAudioManager::ProcessVehicleHorn, PATCH_JUMP);
|
||||||
InjectHook(0x56C640, &cAudioManager::ProcessVehicleReverseWarning, PATCH_JUMP);
|
InjectHook(0x56C640, &cAudioManager::ProcessVehicleReverseWarning, PATCH_JUMP);
|
||||||
InjectHook(0x56A230, &cAudioManager::ProcessVehicleRoadNoise, PATCH_JUMP);
|
InjectHook(0x56A230, &cAudioManager::ProcessVehicleRoadNoise, PATCH_JUMP);
|
||||||
|
InjectHook(0x56C420, &cAudioManager::ProcessVehicleSirenOrAlarm, PATCH_JUMP);
|
||||||
InjectHook(0x56BCB0, &cAudioManager::ProcessVehicleSkidding, PATCH_JUMP);
|
InjectHook(0x56BCB0, &cAudioManager::ProcessVehicleSkidding, PATCH_JUMP);
|
||||||
InjectHook(0x575F30, &cAudioManager::ProcessWaterCannon, PATCH_JUMP);
|
InjectHook(0x575F30, &cAudioManager::ProcessWaterCannon, PATCH_JUMP);
|
||||||
InjectHook(0x578370, &cAudioManager::ProcessWeather, PATCH_JUMP);
|
InjectHook(0x578370, &cAudioManager::ProcessWeather, PATCH_JUMP);
|
||||||
|
@ -440,11 +440,11 @@ public:
|
|||||||
void AddSampleToRequestedQueue(); /// ok
|
void AddSampleToRequestedQueue(); /// ok
|
||||||
void AgeCrimes(); /// ok
|
void AgeCrimes(); /// ok
|
||||||
|
|
||||||
void CalculateDistance(bool *ptr, float dist); /// ok
|
void CalculateDistance(bool &condition, float dist); /// ok
|
||||||
bool CheckForAnAudioFileOnCD() const; /// ok
|
bool CheckForAnAudioFileOnCD() const; /// ok
|
||||||
void ClearActiveSamples(); /// ok
|
void ClearActiveSamples(); /// ok
|
||||||
void ClearMissionAudio(); /// ok
|
void ClearMissionAudio(); /// ok
|
||||||
void ClearRequestedQueue(); /// ok
|
void ClearRequestedQueue(); /// ok
|
||||||
int32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2,
|
int32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2,
|
||||||
float speedMultiplier) const; /// ok
|
float speedMultiplier) const; /// ok
|
||||||
int32 ComputePan(float, CVector *); /// ok
|
int32 ComputePan(float, CVector *); /// ok
|
||||||
@ -640,7 +640,7 @@ public:
|
|||||||
void ProcessVehicleOneShots(void *); // todo
|
void ProcessVehicleOneShots(void *); // todo
|
||||||
bool ProcessVehicleReverseWarning(cVehicleParams *params); /// ok
|
bool ProcessVehicleReverseWarning(cVehicleParams *params); /// ok
|
||||||
bool ProcessVehicleRoadNoise(cVehicleParams *params); /// ok
|
bool ProcessVehicleRoadNoise(cVehicleParams *params); /// ok
|
||||||
void ProcessVehicleSirenOrAlarm(void *); // todo
|
void ProcessVehicleSirenOrAlarm(cVehicleParams *params); /// ok
|
||||||
void ProcessVehicleSkidding(cVehicleParams *params); /// ok
|
void ProcessVehicleSkidding(cVehicleParams *params); /// ok
|
||||||
void ProcessWaterCannon(int32); /// ok
|
void ProcessWaterCannon(int32); /// ok
|
||||||
void ProcessWeather(int32 id); /// ok
|
void ProcessWeather(int32 id); /// ok
|
||||||
|
@ -35,7 +35,7 @@ int32 _nSampleDataEndOffset;
|
|||||||
|
|
||||||
int32 nPedSlotSfx [MAX_PEDSFX];
|
int32 nPedSlotSfx [MAX_PEDSFX];
|
||||||
int32 nPedSlotSfxAddr[MAX_PEDSFX];
|
int32 nPedSlotSfxAddr[MAX_PEDSFX];
|
||||||
int32 nCurrentPedSlot;
|
uint8 nCurrentPedSlot;
|
||||||
|
|
||||||
uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
|
uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ typedef struct provider_stuff
|
|||||||
|
|
||||||
static int __cdecl comp(const provider_stuff*s1,const provider_stuff*s2)
|
static int __cdecl comp(const provider_stuff*s1,const provider_stuff*s2)
|
||||||
{
|
{
|
||||||
return( _stricmp(s1->name,s2->name) );
|
return(strcasecmp(s1->name, s2->name));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -352,7 +352,11 @@ _ResolveLink(char const *path, char *out)
|
|||||||
OutputDebugString(fd.cFileName);
|
OutputDebugString(fd.cFileName);
|
||||||
|
|
||||||
strcpy(out, filepath);
|
strcpy(out, filepath);
|
||||||
|
// FIX: Release the objects. Taken from SA.
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
ppf->Release();
|
||||||
|
psl->Release();
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1437,7 +1441,7 @@ cSampleManager::IsSampleBankLoaded(uint8 nBank)
|
|||||||
bool
|
bool
|
||||||
cSampleManager::IsPedCommentLoaded(uint32 nComment)
|
cSampleManager::IsPedCommentLoaded(uint32 nComment)
|
||||||
{
|
{
|
||||||
int32 slot;
|
uint8 slot;
|
||||||
|
|
||||||
for ( int32 i = 0; i < _TODOCONST(3); i++ )
|
for ( int32 i = 0; i < _TODOCONST(3); i++ )
|
||||||
{
|
{
|
||||||
@ -1452,7 +1456,7 @@ cSampleManager::IsPedCommentLoaded(uint32 nComment)
|
|||||||
int32
|
int32
|
||||||
cSampleManager::_GetPedCommentSlot(uint32 nComment)
|
cSampleManager::_GetPedCommentSlot(uint32 nComment)
|
||||||
{
|
{
|
||||||
int32 slot;
|
uint8 slot;
|
||||||
|
|
||||||
for ( int32 i = 0; i < _TODOCONST(3); i++ )
|
for ( int32 i = 0; i < _TODOCONST(3); i++ )
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,8 @@ CAccidentManager& gAccidentManager = *(CAccidentManager*)0x87FD10;
|
|||||||
|
|
||||||
WRAPPER void CAccidentManager::Update(void) { EAXJMP(0x456710); }
|
WRAPPER void CAccidentManager::Update(void) { EAXJMP(0x456710); }
|
||||||
|
|
||||||
uint16 CAccidentManager::CountActiveAccidents()
|
uint16
|
||||||
|
CAccidentManager::CountActiveAccidents()
|
||||||
{
|
{
|
||||||
uint16 accidents = 0;
|
uint16 accidents = 0;
|
||||||
for (int i = 0; i < NUM_ACCIDENTS; i++){
|
for (int i = 0; i < NUM_ACCIDENTS; i++){
|
||||||
@ -18,7 +19,8 @@ uint16 CAccidentManager::CountActiveAccidents()
|
|||||||
return accidents;
|
return accidents;
|
||||||
}
|
}
|
||||||
|
|
||||||
CAccident* CAccidentManager::FindNearestAccident(CVector vecPos, float* pDistance)
|
CAccident*
|
||||||
|
CAccidentManager::FindNearestAccident(CVector vecPos, float* pDistance)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAX_MEDICS_TO_ATTEND_ACCIDENT; i++){
|
for (int i = 0; i < MAX_MEDICS_TO_ATTEND_ACCIDENT; i++){
|
||||||
int accidentId = -1;
|
int accidentId = -1;
|
||||||
@ -45,3 +47,13 @@ CAccident* CAccidentManager::FindNearestAccident(CVector vecPos, float* pDistanc
|
|||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CAccidentManager::UnattendedAccidents(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_ACCIDENTS; i++) {
|
||||||
|
if (m_aAccidents[i].m_pVictim && m_aAccidents[i].m_nMedicsAttending == 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
@ -21,6 +21,7 @@ class CAccidentManager
|
|||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
uint16 CountActiveAccidents();
|
uint16 CountActiveAccidents();
|
||||||
|
bool UnattendedAccidents();
|
||||||
CAccident* FindNearestAccident(CVector, float*);
|
CAccident* FindNearestAccident(CVector, float*);
|
||||||
void Update(void);
|
void Update(void);
|
||||||
};
|
};
|
||||||
|
@ -309,7 +309,7 @@ CPathFind::CountFloodFillGroups(uint8 type)
|
|||||||
if(m_pathNodes[l].group == 0){
|
if(m_pathNodes[l].group == 0){
|
||||||
m_pathNodes[l].group = n;
|
m_pathNodes[l].group = n;
|
||||||
if(m_pathNodes[l].group == 0)
|
if(m_pathNodes[l].group == 0)
|
||||||
m_pathNodes[l].group = 0x80; // ???
|
m_pathNodes[l].group = INT8_MIN;
|
||||||
m_pathNodes[l].next = node;
|
m_pathNodes[l].next = node;
|
||||||
node = &m_pathNodes[l];
|
node = &m_pathNodes[l];
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ struct CPathNode
|
|||||||
uint8 bDisabled : 1;
|
uint8 bDisabled : 1;
|
||||||
uint8 bBetweenLevels : 1;
|
uint8 bBetweenLevels : 1;
|
||||||
|
|
||||||
uint8 group;
|
int8 group;
|
||||||
/* For reference VC:
|
/* For reference VC:
|
||||||
int16 prevIndex;
|
int16 prevIndex;
|
||||||
int16 nextIndex;
|
int16 nextIndex;
|
||||||
|
@ -6,16 +6,146 @@
|
|||||||
#include "Ped.h"
|
#include "Ped.h"
|
||||||
#include "Pad.h"
|
#include "Pad.h"
|
||||||
#include "Messages.h"
|
#include "Messages.h"
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "World.h"
|
||||||
|
#include "General.h"
|
||||||
|
#include "AudioScriptObject.h"
|
||||||
|
#include "RpAnimBlend.h"
|
||||||
|
|
||||||
CPhoneInfo &gPhoneInfo = *(CPhoneInfo*)0x732A20;
|
CPhoneInfo &gPhoneInfo = *(CPhoneInfo*)0x732A20;
|
||||||
|
|
||||||
bool &CPhoneInfo::isPhonePickedUp = *(bool*)0x6283AC;
|
bool &CPhoneInfo::bDisplayingPhoneMessage = *(bool*)0x6283AC; // is phone picked up
|
||||||
uint32 &CPhoneInfo::phoneMessagesTimer = *(uint32*)0x6283A8;
|
uint32 &CPhoneInfo::PhoneEnableControlsTimer = *(uint32*)0x6283A8;
|
||||||
CPhone *&CPhoneInfo::pickedUpPhone = *(CPhone**)0x6283B0;
|
CPhone *&CPhoneInfo::pPhoneDisplayingMessages = *(CPhone**)0x6283B0;
|
||||||
bool &CPhoneInfo::isPhoneBeingPickedUp = *(bool*)0x6283B4;
|
bool &CPhoneInfo::bPickingUpPhone = *(bool*)0x6283B4;
|
||||||
CPed *&CPhoneInfo::pedWhoPickingUpPhone = *(CPed**)0x6283B8;
|
CPed *&CPhoneInfo::pCallBackPed = *(CPed**)0x6283B8; // ped who picking up the phone (reset after pickup cb)
|
||||||
|
|
||||||
WRAPPER void CPhoneInfo::Update(void) { EAXJMP(0x42F7A0); }
|
/*
|
||||||
|
Entering phonebooth cutscene, showing messages and triggering these things
|
||||||
|
by checking coordinates happens in here - blue mission marker is cosmetic.
|
||||||
|
|
||||||
|
Repeated message means after the script set the messages for a particular phone,
|
||||||
|
player can pick the phone again with the same messages appearing,
|
||||||
|
after 60 seconds of last phone pick-up.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
|
CPed* crimeReporters[NUMPHONES] = {};
|
||||||
|
bool
|
||||||
|
isPhoneAvailable(int m_phoneId)
|
||||||
|
{
|
||||||
|
return gPhoneInfo.m_aPhones[m_phoneId].m_nState == PHONE_STATE_FREE &&
|
||||||
|
(crimeReporters[m_phoneId] == nil || !crimeReporters[m_phoneId]->IsPointerValid() || !crimeReporters[m_phoneId]->bRunningToPhone || crimeReporters[m_phoneId]->m_objective > OBJECTIVE_IDLE ||
|
||||||
|
crimeReporters[m_phoneId]->m_nLastPedState != PED_SEEK_POS &&
|
||||||
|
(crimeReporters[m_phoneId]->m_nPedState != PED_MAKE_CALL && crimeReporters[m_phoneId]->m_nPedState != PED_FACE_PHONE && crimeReporters[m_phoneId]->m_nPedState != PED_SEEK_POS));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
CPhoneInfo::Update(void)
|
||||||
|
{
|
||||||
|
CPlayerPed *player = FindPlayerPed();
|
||||||
|
CPlayerInfo *playerInfo = &CWorld::Players[CWorld::PlayerInFocus];
|
||||||
|
if (bDisplayingPhoneMessage && CTimer::GetTimeInMilliseconds() > PhoneEnableControlsTimer) {
|
||||||
|
playerInfo->MakePlayerSafe(false);
|
||||||
|
TheCamera.SetWideScreenOff();
|
||||||
|
pPhoneDisplayingMessages = nil;
|
||||||
|
bDisplayingPhoneMessage = false;
|
||||||
|
CAnimBlendAssociation *talkAssoc = RpAnimBlendClumpGetAssociation(player->GetClump(), ANIM_PHONE_TALK);
|
||||||
|
if (talkAssoc && talkAssoc->blendAmount > 0.5f) {
|
||||||
|
CAnimBlendAssociation *endAssoc = CAnimManager::BlendAnimation(player->GetClump(), ASSOCGRP_STD, ANIM_PHONE_OUT, 8.0f);
|
||||||
|
endAssoc->flags &= ~ASSOC_DELETEFADEDOUT;
|
||||||
|
endAssoc->SetFinishCallback(PhonePutDownCB, player);
|
||||||
|
} else {
|
||||||
|
CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_40;
|
||||||
|
if (player->m_nPedState == PED_MAKE_CALL)
|
||||||
|
player->m_nPedState = PED_IDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool notInCar;
|
||||||
|
CVector playerPos;
|
||||||
|
if (FindPlayerVehicle()) {
|
||||||
|
notInCar = false;
|
||||||
|
playerPos = FindPlayerVehicle()->GetPosition();
|
||||||
|
} else {
|
||||||
|
notInCar = true;
|
||||||
|
playerPos = player->GetPosition();
|
||||||
|
}
|
||||||
|
bool phoneRings = false;
|
||||||
|
bool scratchTheCabinet;
|
||||||
|
for(int phoneId = 0; phoneId < m_nScriptPhonesMax; phoneId++) {
|
||||||
|
if (m_aPhones[phoneId].m_visibleToCam) {
|
||||||
|
switch (m_aPhones[phoneId].m_nState) {
|
||||||
|
case PHONE_STATE_ONETIME_MESSAGE_SET:
|
||||||
|
case PHONE_STATE_REPEATED_MESSAGE_SET:
|
||||||
|
case PHONE_STATE_REPEATED_MESSAGE_SHOWN_ONCE:
|
||||||
|
if (bPickingUpPhone) {
|
||||||
|
scratchTheCabinet = false;
|
||||||
|
phoneRings = false;
|
||||||
|
} else {
|
||||||
|
scratchTheCabinet = (CTimer::GetTimeInMilliseconds() / 1880) % 2 == 1;
|
||||||
|
phoneRings = (CTimer::GetPreviousTimeInMilliseconds() / 1880) % 2 == 1;
|
||||||
|
}
|
||||||
|
if (scratchTheCabinet) {
|
||||||
|
m_aPhones[phoneId].m_pEntity->GetUp().z = (CGeneral::GetRandomNumber() % 1024) / 16000.0f + 1.0f;
|
||||||
|
if (!phoneRings)
|
||||||
|
PlayOneShotScriptObject(_SCRSOUND_PHONE_RING, m_aPhones[phoneId].m_pEntity->GetPosition());
|
||||||
|
} else {
|
||||||
|
m_aPhones[phoneId].m_pEntity->GetUp().z = 1.0f;
|
||||||
|
}
|
||||||
|
m_aPhones[phoneId].m_pEntity->GetMatrix().UpdateRW();
|
||||||
|
m_aPhones[phoneId].m_pEntity->UpdateRwFrame();
|
||||||
|
if (notInCar && !bPickingUpPhone && player->IsPedInControl()) {
|
||||||
|
CVector2D distToPhone = playerPos - m_aPhones[phoneId].m_vecPos;
|
||||||
|
if (Abs(distToPhone.x) < 1.0f && Abs(distToPhone.y) < 1.0f) {
|
||||||
|
if (DotProduct2D(distToPhone, m_aPhones[phoneId].m_pEntity->GetForward()) / distToPhone.Magnitude() < -0.85f) {
|
||||||
|
CVector2D distToPhoneObj = playerPos - m_aPhones[phoneId].m_pEntity->GetPosition();
|
||||||
|
float angleToFace = CGeneral::GetATanOfXY(distToPhoneObj.x, distToPhoneObj.y) + HALFPI;
|
||||||
|
if (angleToFace > TWOPI)
|
||||||
|
angleToFace = angleToFace - TWOPI;
|
||||||
|
player->m_fRotationCur = angleToFace;
|
||||||
|
player->m_fRotationDest = angleToFace;
|
||||||
|
player->SetHeading(angleToFace);
|
||||||
|
player->m_nPedState = PED_MAKE_CALL;
|
||||||
|
CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_40;
|
||||||
|
TheCamera.SetWideScreenOn();
|
||||||
|
playerInfo->MakePlayerSafe(true);
|
||||||
|
CAnimBlendAssociation *phonePickAssoc = CAnimManager::BlendAnimation(player->GetClump(), ASSOCGRP_STD, ANIM_PHONE_IN, 4.0f);
|
||||||
|
phonePickAssoc->SetFinishCallback(PhonePickUpCB, &m_aPhones[phoneId]);
|
||||||
|
bPickingUpPhone = true;
|
||||||
|
pCallBackPed = player;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PHONE_STATE_REPEATED_MESSAGE_STARTED:
|
||||||
|
if (CTimer::GetTimeInMilliseconds() - m_aPhones[phoneId].m_repeatedMessagePickupStart > 60000)
|
||||||
|
m_aPhones[phoneId].m_nState = PHONE_STATE_REPEATED_MESSAGE_SHOWN_ONCE;
|
||||||
|
break;
|
||||||
|
case PHONE_STATE_9:
|
||||||
|
scratchTheCabinet = (CTimer::GetTimeInMilliseconds() / 1880) % 2 == 1;
|
||||||
|
phoneRings = (CTimer::GetPreviousTimeInMilliseconds() / 1880) % 2 == 1;
|
||||||
|
if (scratchTheCabinet) {
|
||||||
|
m_aPhones[phoneId].m_pEntity->GetUp().z = (CGeneral::GetRandomNumber() % 1024) / 16000.0f + 1.0f;
|
||||||
|
if (!phoneRings)
|
||||||
|
PlayOneShotScriptObject(_SCRSOUND_PHONE_RING, m_aPhones[phoneId].m_pEntity->GetPosition());
|
||||||
|
} else {
|
||||||
|
m_aPhones[phoneId].m_pEntity->GetUp().z = 1.0f;
|
||||||
|
}
|
||||||
|
m_aPhones[phoneId].m_pEntity->GetMatrix().UpdateRW();
|
||||||
|
m_aPhones[phoneId].m_pEntity->UpdateRwFrame();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (CVector2D(TheCamera.GetPosition() - m_aPhones[phoneId].m_vecPos).MagnitudeSqr() > sq(100.0f))
|
||||||
|
m_aPhones[phoneId].m_visibleToCam = false;
|
||||||
|
} else if (!((CTimer::GetFrameCounter() + m_aPhones[phoneId].m_pEntity->m_randomSeed) % 16)) {
|
||||||
|
if (CVector2D(TheCamera.GetPosition() - m_aPhones[phoneId].m_vecPos).MagnitudeSqr() < sq(60.0f))
|
||||||
|
m_aPhones[phoneId].m_visibleToCam = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
CPhoneInfo::FindNearestFreePhone(CVector *pos)
|
CPhoneInfo::FindNearestFreePhone(CVector *pos)
|
||||||
@ -25,7 +155,11 @@ CPhoneInfo::FindNearestFreePhone(CVector *pos)
|
|||||||
|
|
||||||
for (int phoneId = 0; phoneId < m_nMax; phoneId++) {
|
for (int phoneId = 0; phoneId < m_nMax; phoneId++) {
|
||||||
|
|
||||||
if (gPhoneInfo.m_aPhones[phoneId].m_nState == PHONE_STATE_FREE) {
|
if (gPhoneInfo.m_aPhones[phoneId].m_nState == PHONE_STATE_FREE
|
||||||
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
|
&& isPhoneAvailable(phoneId)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
float phoneDist = (m_aPhones[phoneId].m_vecPos - *pos).Magnitude2D();
|
float phoneDist = (m_aPhones[phoneId].m_vecPos - *pos).Magnitude2D();
|
||||||
|
|
||||||
if (phoneDist < nearestPhoneDist) {
|
if (phoneDist < nearestPhoneDist) {
|
||||||
@ -50,20 +184,20 @@ CPhoneInfo::PhoneAtThisPosition(CVector pos)
|
|||||||
bool
|
bool
|
||||||
CPhoneInfo::HasMessageBeenDisplayed(int phoneId)
|
CPhoneInfo::HasMessageBeenDisplayed(int phoneId)
|
||||||
{
|
{
|
||||||
if (isPhonePickedUp)
|
if (bDisplayingPhoneMessage)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int state = m_aPhones[phoneId].m_nState;
|
int state = m_aPhones[phoneId].m_nState;
|
||||||
|
|
||||||
return state == PHONE_STATE_REPEATED_MESSAGE_SHOWN_ONCE ||
|
return state == PHONE_STATE_REPEATED_MESSAGE_SHOWN_ONCE ||
|
||||||
state == PHONE_STATE_ONETIME_MESSAGE_SHOWN ||
|
state == PHONE_STATE_ONETIME_MESSAGE_STARTED ||
|
||||||
state == PHONE_STATE_REPEATED_MESSAGE_SHOWN;
|
state == PHONE_STATE_REPEATED_MESSAGE_STARTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CPhoneInfo::IsMessageBeingDisplayed(int phoneId)
|
CPhoneInfo::IsMessageBeingDisplayed(int phoneId)
|
||||||
{
|
{
|
||||||
return pickedUpPhone == &m_aPhones[phoneId];
|
return pPhoneDisplayingMessages == &m_aPhones[phoneId];
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -71,8 +205,8 @@ CPhoneInfo::Load(uint8 *buf, uint32 size)
|
|||||||
{
|
{
|
||||||
INITSAVEBUF
|
INITSAVEBUF
|
||||||
m_nMax = ReadSaveBuf<int32>(buf);
|
m_nMax = ReadSaveBuf<int32>(buf);
|
||||||
m_nNum = ReadSaveBuf<int32>(buf);
|
m_nScriptPhonesMax = ReadSaveBuf<int32>(buf);
|
||||||
for (int i = 0; i < 50; i++) {
|
for (int i = 0; i < NUMPHONES; i++) {
|
||||||
m_aPhones[i] = ReadSaveBuf<CPhone>(buf);
|
m_aPhones[i] = ReadSaveBuf<CPhone>(buf);
|
||||||
// It's saved as building pool index in save file, convert it to true entity
|
// It's saved as building pool index in save file, convert it to true entity
|
||||||
if (m_aPhones[i].m_pEntity) {
|
if (m_aPhones[i].m_pEntity) {
|
||||||
@ -127,7 +261,7 @@ CPhoneInfo::GrabPhone(float xPos, float yPos)
|
|||||||
CVector pos(xPos, yPos, 0.0f);
|
CVector pos(xPos, yPos, 0.0f);
|
||||||
float nearestPhoneDist = 100.0f;
|
float nearestPhoneDist = 100.0f;
|
||||||
|
|
||||||
for (int phoneId = m_nNum; phoneId < m_nMax; phoneId++) {
|
for (int phoneId = m_nScriptPhonesMax; phoneId < m_nMax; phoneId++) {
|
||||||
float phoneDistance = (m_aPhones[phoneId].m_vecPos - pos).Magnitude2D();
|
float phoneDistance = (m_aPhones[phoneId].m_vecPos - pos).Magnitude2D();
|
||||||
if (phoneDistance < nearestPhoneDist) {
|
if (phoneDistance < nearestPhoneDist) {
|
||||||
nearestPhoneDist = phoneDistance;
|
nearestPhoneDist = phoneDistance;
|
||||||
@ -136,23 +270,23 @@ CPhoneInfo::GrabPhone(float xPos, float yPos)
|
|||||||
}
|
}
|
||||||
m_aPhones[nearestPhoneId].m_nState = PHONE_STATE_MESSAGE_REMOVED;
|
m_aPhones[nearestPhoneId].m_nState = PHONE_STATE_MESSAGE_REMOVED;
|
||||||
|
|
||||||
CPhone oldFirstPhone = m_aPhones[m_nNum];
|
CPhone oldFirstPhone = m_aPhones[m_nScriptPhonesMax];
|
||||||
m_aPhones[m_nNum] = m_aPhones[nearestPhoneId];
|
m_aPhones[m_nScriptPhonesMax] = m_aPhones[nearestPhoneId];
|
||||||
m_aPhones[nearestPhoneId] = oldFirstPhone;
|
m_aPhones[nearestPhoneId] = oldFirstPhone;
|
||||||
m_nNum++;
|
m_nScriptPhonesMax++;
|
||||||
return m_nNum - 1;
|
return m_nScriptPhonesMax - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CPhoneInfo::Initialise(void)
|
CPhoneInfo::Initialise(void)
|
||||||
{
|
{
|
||||||
CBuildingPool *pool = CPools::GetBuildingPool();
|
CBuildingPool *pool = CPools::GetBuildingPool();
|
||||||
pedWhoPickingUpPhone = nil;
|
pCallBackPed = nil;
|
||||||
isPhonePickedUp = false;
|
bDisplayingPhoneMessage = false;
|
||||||
isPhoneBeingPickedUp = false;
|
bPickingUpPhone = false;
|
||||||
pickedUpPhone = nil;
|
pPhoneDisplayingMessages = nil;
|
||||||
m_nMax = 0;
|
m_nMax = 0;
|
||||||
m_nNum = 0;
|
m_nScriptPhonesMax = 0;
|
||||||
for (int i = pool->GetSize() - 1; i >= 0; i--) {
|
for (int i = pool->GetSize() - 1; i >= 0; i--) {
|
||||||
CBuilding *building = pool->GetSlot(i);
|
CBuilding *building = pool->GetSlot(i);
|
||||||
if (building) {
|
if (building) {
|
||||||
@ -173,8 +307,8 @@ CPhoneInfo::Save(uint8 *buf, uint32 *size)
|
|||||||
*size = sizeof(CPhoneInfo);
|
*size = sizeof(CPhoneInfo);
|
||||||
INITSAVEBUF
|
INITSAVEBUF
|
||||||
WriteSaveBuf(buf, m_nMax);
|
WriteSaveBuf(buf, m_nMax);
|
||||||
WriteSaveBuf(buf, m_nNum);
|
WriteSaveBuf(buf, m_nScriptPhonesMax);
|
||||||
for(int phoneId = 0; phoneId < 50; phoneId++) {
|
for(int phoneId = 0; phoneId < NUMPHONES; phoneId++) {
|
||||||
CPhone* phone = WriteSaveBuf(buf, m_aPhones[phoneId]);
|
CPhone* phone = WriteSaveBuf(buf, m_aPhones[phoneId]);
|
||||||
|
|
||||||
// Convert entity pointer to building pool index while saving
|
// Convert entity pointer to building pool index while saving
|
||||||
@ -189,7 +323,7 @@ void
|
|||||||
CPhoneInfo::Shutdown(void)
|
CPhoneInfo::Shutdown(void)
|
||||||
{
|
{
|
||||||
m_nMax = 0;
|
m_nMax = 0;
|
||||||
m_nNum = 0;
|
m_nScriptPhonesMax = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -221,26 +355,26 @@ PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPhoneInfo::isPhoneBeingPickedUp = false;
|
CPhoneInfo::bPickingUpPhone = false;
|
||||||
CPhoneInfo::isPhonePickedUp = true;
|
CPhoneInfo::bDisplayingPhoneMessage = true;
|
||||||
CPhoneInfo::pickedUpPhone = phone;
|
CPhoneInfo::pPhoneDisplayingMessages = phone;
|
||||||
CPhoneInfo::phoneMessagesTimer = CTimer::GetTimeInMilliseconds() + messagesDisplayTime;
|
CPhoneInfo::PhoneEnableControlsTimer = CTimer::GetTimeInMilliseconds() + messagesDisplayTime;
|
||||||
|
|
||||||
if (phone->m_nState == PHONE_STATE_ONETIME_MESSAGE_SET) {
|
if (phone->m_nState == PHONE_STATE_ONETIME_MESSAGE_SET) {
|
||||||
phone->m_nState = PHONE_STATE_ONETIME_MESSAGE_SHOWN;
|
phone->m_nState = PHONE_STATE_ONETIME_MESSAGE_STARTED;
|
||||||
} else {
|
} else {
|
||||||
phone->m_nState = PHONE_STATE_REPEATED_MESSAGE_SHOWN;
|
phone->m_nState = PHONE_STATE_REPEATED_MESSAGE_STARTED;
|
||||||
phone->m_lastTimeRepeatedMsgShown = CTimer::GetTimeInMilliseconds();
|
phone->m_repeatedMessagePickupStart = CTimer::GetTimeInMilliseconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPed *ped = CPhoneInfo::pedWhoPickingUpPhone;
|
CPed *ped = CPhoneInfo::pCallBackPed;
|
||||||
ped->m_nMoveState = PEDMOVE_STILL;
|
ped->m_nMoveState = PEDMOVE_STILL;
|
||||||
CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_IDLE_STANCE, 8.0f);
|
CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_IDLE_STANCE, 8.0f);
|
||||||
|
|
||||||
if (assoc->blendAmount > 0.5f && ped)
|
if (assoc->blendAmount > 0.5f && ped)
|
||||||
CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_PHONE_TALK, 8.0f);
|
CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_PHONE_TALK, 8.0f);
|
||||||
|
|
||||||
CPhoneInfo::pedWhoPickingUpPhone = nil;
|
CPhoneInfo::pCallBackPed = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
STARTPATCHES
|
STARTPATCHES
|
||||||
@ -255,6 +389,7 @@ STARTPATCHES
|
|||||||
InjectHook(0x42F710, &CPhoneInfo::Shutdown, PATCH_JUMP);
|
InjectHook(0x42F710, &CPhoneInfo::Shutdown, PATCH_JUMP);
|
||||||
InjectHook(0x42F640, &CPhoneInfo::Initialise, PATCH_JUMP);
|
InjectHook(0x42F640, &CPhoneInfo::Initialise, PATCH_JUMP);
|
||||||
InjectHook(0x42FDB0, &CPhoneInfo::GrabPhone, PATCH_JUMP);
|
InjectHook(0x42FDB0, &CPhoneInfo::GrabPhone, PATCH_JUMP);
|
||||||
|
InjectHook(0x42F7A0, &CPhoneInfo::Update, PATCH_JUMP);
|
||||||
InjectHook(0x42F570, &PhonePutDownCB, PATCH_JUMP);
|
InjectHook(0x42F570, &PhonePutDownCB, PATCH_JUMP);
|
||||||
InjectHook(0x42F470, &PhonePickUpCB, PATCH_JUMP);
|
InjectHook(0x42F470, &PhonePickUpCB, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
@ -5,42 +5,46 @@
|
|||||||
class CPed;
|
class CPed;
|
||||||
class CAnimBlendAssociation;
|
class CAnimBlendAssociation;
|
||||||
|
|
||||||
enum {
|
enum PhoneState {
|
||||||
PHONE_STATE_FREE,
|
PHONE_STATE_FREE,
|
||||||
PHONE_STATE_1,
|
PHONE_STATE_REPORTING_CRIME, // CCivilianPed::ProcessControl sets it but unused
|
||||||
PHONE_STATE_2,
|
PHONE_STATE_2,
|
||||||
PHONE_STATE_MESSAGE_REMOVED,
|
PHONE_STATE_MESSAGE_REMOVED,
|
||||||
PHONE_STATE_ONETIME_MESSAGE_SET,
|
PHONE_STATE_ONETIME_MESSAGE_SET,
|
||||||
PHONE_STATE_REPEATED_MESSAGE_SET,
|
PHONE_STATE_REPEATED_MESSAGE_SET,
|
||||||
PHONE_STATE_REPEATED_MESSAGE_SHOWN_ONCE,
|
PHONE_STATE_REPEATED_MESSAGE_SHOWN_ONCE,
|
||||||
PHONE_STATE_ONETIME_MESSAGE_SHOWN,
|
PHONE_STATE_ONETIME_MESSAGE_STARTED,
|
||||||
PHONE_STATE_REPEATED_MESSAGE_SHOWN,
|
PHONE_STATE_REPEATED_MESSAGE_STARTED,
|
||||||
PHONE_STATE_9
|
PHONE_STATE_9 // just rings, picking being handled via script. most of the time game uses this
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CPhone
|
class CPhone
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
CVector m_vecPos;
|
CVector m_vecPos;
|
||||||
wchar *m_apMessages[6];
|
wchar *m_apMessages[6];
|
||||||
uint32 m_lastTimeRepeatedMsgShown;
|
uint32 m_repeatedMessagePickupStart;
|
||||||
CEntity *m_pEntity; // it's building pool index in save files
|
CEntity *m_pEntity; // stored as building pool index in save files
|
||||||
int32 m_nState;
|
PhoneState m_nState;
|
||||||
uint8 field_30;
|
bool m_visibleToCam;
|
||||||
|
|
||||||
|
CPhone() { }
|
||||||
|
~CPhone() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(CPhone) == 0x34, "CPhone: error");
|
static_assert(sizeof(CPhone) == 0x34, "CPhone: error");
|
||||||
|
|
||||||
class CPhoneInfo {
|
class CPhoneInfo {
|
||||||
public:
|
public:
|
||||||
static bool &isPhonePickedUp;
|
static bool &bDisplayingPhoneMessage;
|
||||||
static uint32 &phoneMessagesTimer;
|
static uint32 &PhoneEnableControlsTimer;
|
||||||
static CPhone *&pickedUpPhone;
|
static CPhone *&pPhoneDisplayingMessages;
|
||||||
static bool &isPhoneBeingPickedUp;
|
static bool &bPickingUpPhone;
|
||||||
static CPed *&pedWhoPickingUpPhone;
|
static CPed *&pCallBackPed;
|
||||||
|
|
||||||
int32 m_nMax;
|
int32 m_nMax;
|
||||||
int32 m_nNum;
|
int32 m_nScriptPhonesMax;
|
||||||
CPhone m_aPhones[50];
|
CPhone m_aPhones[NUMPHONES];
|
||||||
|
|
||||||
CPhoneInfo() { }
|
CPhoneInfo() { }
|
||||||
~CPhoneInfo() { }
|
~CPhoneInfo() { }
|
||||||
@ -63,3 +67,8 @@ extern CPhoneInfo &gPhoneInfo;
|
|||||||
|
|
||||||
void PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg);
|
void PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg);
|
||||||
void PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg);
|
void PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg);
|
||||||
|
|
||||||
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
|
extern CPed *crimeReporters[NUMPHONES];
|
||||||
|
bool isPhoneAvailable(int);
|
||||||
|
#endif
|
@ -346,7 +346,7 @@ void CReplay::StorePedUpdate(CPed *ped, int id)
|
|||||||
pp->matrix.CompressFromFullMatrix(ped->GetMatrix());
|
pp->matrix.CompressFromFullMatrix(ped->GetMatrix());
|
||||||
pp->assoc_group_id = ped->m_animGroup;
|
pp->assoc_group_id = ped->m_animGroup;
|
||||||
/* Would be more sane to use GetJustIndex(ped->m_pMyVehicle) in following assignment */
|
/* Would be more sane to use GetJustIndex(ped->m_pMyVehicle) in following assignment */
|
||||||
if (ped->bInVehicle && ped->m_pMyVehicle)
|
if (ped->InVehicle())
|
||||||
pp->vehicle_index = (CPools::GetVehiclePool()->GetIndex(ped->m_pMyVehicle) >> 8) + 1;
|
pp->vehicle_index = (CPools::GetVehiclePool()->GetIndex(ped->m_pMyVehicle) >> 8) + 1;
|
||||||
else
|
else
|
||||||
pp->vehicle_index = 0;
|
pp->vehicle_index = 0;
|
||||||
|
@ -204,7 +204,7 @@ void CUpsideDownCarCheck::Init()
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){
|
for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){
|
||||||
m_sCars[i].m_nVehicleIndex = -1;
|
m_sCars[i].m_nVehicleIndex = -1;
|
||||||
m_sCars[i].m_nVehicleIndex = 0;
|
m_sCars[i].m_nUpsideDownTimer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,6 +220,10 @@ void CUpsideDownCarCheck::UpdateTimers()
|
|||||||
{
|
{
|
||||||
uint32 timeStep = CTimer::GetTimeStepInMilliseconds();
|
uint32 timeStep = CTimer::GetTimeStepInMilliseconds();
|
||||||
for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){
|
for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
if (m_sCars[i].m_nVehicleIndex == -1)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
CVehicle* v = CPools::GetVehiclePool()->GetAt(m_sCars[i].m_nVehicleIndex);
|
CVehicle* v = CPools::GetVehiclePool()->GetAt(m_sCars[i].m_nVehicleIndex);
|
||||||
if (v){
|
if (v){
|
||||||
if (IsCarUpsideDown(m_sCars[i].m_nVehicleIndex))
|
if (IsCarUpsideDown(m_sCars[i].m_nVehicleIndex))
|
||||||
@ -1744,7 +1748,7 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
|
|||||||
CollectParameters(&m_nIp, 1);
|
CollectParameters(&m_nIp, 1);
|
||||||
CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]);
|
CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]);
|
||||||
if (ped) {
|
if (ped) {
|
||||||
if (ped->bInVehicle && ped->m_pMyVehicle) {
|
if (ped->InVehicle()) {
|
||||||
if (ped->m_pMyVehicle->pDriver == ped) {
|
if (ped->m_pMyVehicle->pDriver == ped) {
|
||||||
ped->m_pMyVehicle->RemoveDriver();
|
ped->m_pMyVehicle->RemoveDriver();
|
||||||
ped->m_pMyVehicle->m_status = STATUS_ABANDONED;
|
ped->m_pMyVehicle->m_status = STATUS_ABANDONED;
|
||||||
@ -2317,17 +2321,23 @@ int8 CRunningScript::ProcessCommandsFrom200To299(int32 command)
|
|||||||
assert(pCurrent); // GetIndex(0) doesn't look good
|
assert(pCurrent); // GetIndex(0) doesn't look good
|
||||||
int handle = CPools::GetVehiclePool()->GetIndex(pCurrent);
|
int handle = CPools::GetVehiclePool()->GetIndex(pCurrent);
|
||||||
if (handle != CTheScripts::StoreVehicleIndex && m_bIsMissionScript){
|
if (handle != CTheScripts::StoreVehicleIndex && m_bIsMissionScript){
|
||||||
CVehicle* pOld = CPools::GetVehiclePool()->GetAt(CTheScripts::StoreVehicleIndex);
|
#ifdef FIX_BUGS
|
||||||
if (pOld){
|
if (CTheScripts::StoreVehicleIndex != -1)
|
||||||
CCarCtrl::RemoveFromInterestingVehicleList(pOld);
|
#endif
|
||||||
if (pOld->VehicleCreatedBy == MISSION_VEHICLE && CTheScripts::StoreVehicleWasRandom){
|
{
|
||||||
pOld->VehicleCreatedBy = RANDOM_VEHICLE;
|
CVehicle* pOld = CPools::GetVehiclePool()->GetAt(CTheScripts::StoreVehicleIndex);
|
||||||
pOld->bIsLocked = false;
|
if (pOld){
|
||||||
CCarCtrl::NumRandomCars++;
|
CCarCtrl::RemoveFromInterestingVehicleList(pOld);
|
||||||
CCarCtrl::NumMissionCars--;
|
if (pOld->VehicleCreatedBy == MISSION_VEHICLE && CTheScripts::StoreVehicleWasRandom){
|
||||||
CTheScripts::MissionCleanup.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR);
|
pOld->VehicleCreatedBy = RANDOM_VEHICLE;
|
||||||
|
pOld->bIsLocked = false;
|
||||||
|
CCarCtrl::NumRandomCars++;
|
||||||
|
CCarCtrl::NumMissionCars--;
|
||||||
|
CTheScripts::MissionCleanup.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CTheScripts::StoreVehicleIndex = handle;
|
CTheScripts::StoreVehicleIndex = handle;
|
||||||
switch (pCurrent->VehicleCreatedBy){
|
switch (pCurrent->VehicleCreatedBy){
|
||||||
case RANDOM_VEHICLE:
|
case RANDOM_VEHICLE:
|
||||||
@ -2367,17 +2377,23 @@ int8 CRunningScript::ProcessCommandsFrom200To299(int32 command)
|
|||||||
assert(pCurrent); // Here pCurrent shouldn't be NULL anyway
|
assert(pCurrent); // Here pCurrent shouldn't be NULL anyway
|
||||||
int handle = CPools::GetVehiclePool()->GetIndex(pCurrent);
|
int handle = CPools::GetVehiclePool()->GetIndex(pCurrent);
|
||||||
if (handle != CTheScripts::StoreVehicleIndex && m_bIsMissionScript) {
|
if (handle != CTheScripts::StoreVehicleIndex && m_bIsMissionScript) {
|
||||||
CVehicle* pOld = CPools::GetVehiclePool()->GetAt(CTheScripts::StoreVehicleIndex);
|
#ifdef FIX_BUGS
|
||||||
if (pOld) {
|
if (CTheScripts::StoreVehicleIndex != -1)
|
||||||
CCarCtrl::RemoveFromInterestingVehicleList(pOld);
|
#endif
|
||||||
if (pOld->VehicleCreatedBy == MISSION_VEHICLE && CTheScripts::StoreVehicleWasRandom) {
|
{
|
||||||
pOld->VehicleCreatedBy = RANDOM_VEHICLE;
|
CVehicle* pOld = CPools::GetVehiclePool()->GetAt(CTheScripts::StoreVehicleIndex);
|
||||||
pOld->bIsLocked = false;
|
if (pOld){
|
||||||
CCarCtrl::NumRandomCars++;
|
CCarCtrl::RemoveFromInterestingVehicleList(pOld);
|
||||||
CCarCtrl::NumMissionCars--;
|
if (pOld->VehicleCreatedBy == MISSION_VEHICLE && CTheScripts::StoreVehicleWasRandom){
|
||||||
CTheScripts::MissionCleanup.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR);
|
pOld->VehicleCreatedBy = RANDOM_VEHICLE;
|
||||||
|
pOld->bIsLocked = false;
|
||||||
|
CCarCtrl::NumRandomCars++;
|
||||||
|
CCarCtrl::NumMissionCars--;
|
||||||
|
CTheScripts::MissionCleanup.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CTheScripts::StoreVehicleIndex = handle;
|
CTheScripts::StoreVehicleIndex = handle;
|
||||||
switch (pCurrent->VehicleCreatedBy) {
|
switch (pCurrent->VehicleCreatedBy) {
|
||||||
case RANDOM_VEHICLE:
|
case RANDOM_VEHICLE:
|
||||||
@ -3438,7 +3454,7 @@ int8 CRunningScript::ProcessCommandsFrom300To399(int32 command)
|
|||||||
assert(pPed);
|
assert(pPed);
|
||||||
// Useless call.
|
// Useless call.
|
||||||
CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
|
CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
|
||||||
int handle = CRadar::SetEntityBlip(BLIP_CHAR, ScriptParams[0], 0, BLIP_DISPLAY_BOTH);
|
int handle = CRadar::SetEntityBlip(BLIP_CHAR, ScriptParams[0], 1, BLIP_DISPLAY_BOTH);
|
||||||
CRadar::ChangeBlipScale(handle, 3);
|
CRadar::ChangeBlipScale(handle, 3);
|
||||||
ScriptParams[0] = handle;
|
ScriptParams[0] = handle;
|
||||||
StoreParameters(&m_nIp, 1);
|
StoreParameters(&m_nIp, 1);
|
||||||
@ -3451,7 +3467,7 @@ int8 CRunningScript::ProcessCommandsFrom300To399(int32 command)
|
|||||||
assert(pObject);
|
assert(pObject);
|
||||||
// Useless call.
|
// Useless call.
|
||||||
CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
|
CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
|
||||||
int handle = CRadar::SetEntityBlip(BLIP_OBJECT, ScriptParams[0], 0, BLIP_DISPLAY_BOTH);
|
int handle = CRadar::SetEntityBlip(BLIP_OBJECT, ScriptParams[0], 6, BLIP_DISPLAY_BOTH);
|
||||||
CRadar::ChangeBlipScale(handle, 3);
|
CRadar::ChangeBlipScale(handle, 3);
|
||||||
ScriptParams[0] = handle;
|
ScriptParams[0] = handle;
|
||||||
StoreParameters(&m_nIp, 1);
|
StoreParameters(&m_nIp, 1);
|
||||||
@ -4948,7 +4964,7 @@ int8 CRunningScript::ProcessCommandsFrom500To599(int32 command)
|
|||||||
assert(pPed);
|
assert(pPed);
|
||||||
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
|
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
|
||||||
bool isTouching = false;
|
bool isTouching = false;
|
||||||
if (pPed->bInVehicle && pPed->m_pMyVehicle)
|
if (pPed->InVehicle())
|
||||||
isTouching = false;
|
isTouching = false;
|
||||||
else if (pPed->GetHasCollidedWith(pObject))
|
else if (pPed->GetHasCollidedWith(pObject))
|
||||||
isTouching = true;
|
isTouching = true;
|
||||||
@ -5089,7 +5105,7 @@ int8 CRunningScript::ProcessCommandsFrom500To599(int32 command)
|
|||||||
case COMMAND_HAS_PHONE_DISPLAYED_MESSAGE:
|
case COMMAND_HAS_PHONE_DISPLAYED_MESSAGE:
|
||||||
{
|
{
|
||||||
CollectParameters(&m_nIp, 1);
|
CollectParameters(&m_nIp, 1);
|
||||||
gPhoneInfo.HasMessageBeenDisplayed(ScriptParams[0]);
|
UpdateCompareFlag(gPhoneInfo.HasMessageBeenDisplayed(ScriptParams[0]));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case COMMAND_TURN_PHONE_OFF:
|
case COMMAND_TURN_PHONE_OFF:
|
||||||
|
@ -1443,39 +1443,36 @@ bool CControllerConfigManager::GetIsMouseButtonDown(RsKeyCodes keycode)
|
|||||||
|
|
||||||
bool CControllerConfigManager::GetIsMouseButtonUp(RsKeyCodes keycode)
|
bool CControllerConfigManager::GetIsMouseButtonUp(RsKeyCodes keycode)
|
||||||
{
|
{
|
||||||
if (keycode > rsMOUSEX2BUTTON)
|
switch (keycode)
|
||||||
{
|
{
|
||||||
switch (keycode)
|
case rsMOUSELEFTBUTTON:
|
||||||
{
|
if (CPad::GetPad(PAD1)->GetLeftMouseUp())
|
||||||
case rsMOUSELEFTBUTTON:
|
return true;
|
||||||
if (CPad::GetPad(PAD1)->GetLeftMouseUp())
|
break;
|
||||||
return true;
|
case rsMOUSMIDDLEBUTTON:
|
||||||
break;
|
if (CPad::GetPad(PAD1)->GetMiddleMouseUp())
|
||||||
case rsMOUSMIDDLEBUTTON:
|
return true;
|
||||||
if (CPad::GetPad(PAD1)->GetMiddleMouseUp())
|
break;
|
||||||
return true;
|
case rsMOUSERIGHTBUTTON:
|
||||||
break;
|
if (CPad::GetPad(PAD1)->GetRightMouseUp())
|
||||||
case rsMOUSERIGHTBUTTON:
|
return true;
|
||||||
if (CPad::GetPad(PAD1)->GetRightMouseUp())
|
break;
|
||||||
return true;
|
case rsMOUSEWHEELUPBUTTON:
|
||||||
break;
|
if (CPad::GetPad(PAD1)->GetMouseWheelUpUp())
|
||||||
case rsMOUSEWHEELUPBUTTON:
|
return true;
|
||||||
if (CPad::GetPad(PAD1)->GetMouseWheelUpUp())
|
break;
|
||||||
return true;
|
case rsMOUSEWHEELDOWNBUTTON:
|
||||||
break;
|
if (CPad::GetPad(PAD1)->GetMouseWheelDownUp())
|
||||||
case rsMOUSEWHEELDOWNBUTTON:
|
return true;
|
||||||
if (CPad::GetPad(PAD1)->GetMouseWheelDownUp())
|
break;
|
||||||
return true;
|
case rsMOUSEX1BUTTON:
|
||||||
break;
|
if (CPad::GetPad(PAD1)->GetMouseX1Up())
|
||||||
case rsMOUSEX1BUTTON:
|
return true;
|
||||||
if (CPad::GetPad(PAD1)->GetMouseX1Up())
|
break;
|
||||||
return true;
|
case rsMOUSEX2BUTTON:
|
||||||
break;
|
if (CPad::GetPad(PAD1)->GetMouseX2Up())
|
||||||
case rsMOUSEX2BUTTON:
|
return true;
|
||||||
if (CPad::GetPad(PAD1)->GetMouseX2Up())
|
break;
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1662,9 +1659,6 @@ void CControllerConfigManager::DeleteMatchingActionInitiators(e_ControllerAction
|
|||||||
|
|
||||||
bool CControllerConfigManager::GetIsKeyBlank(int32 key, eControllerType type)
|
bool CControllerConfigManager::GetIsKeyBlank(int32 key, eControllerType type)
|
||||||
{
|
{
|
||||||
if (type > JOYSTICK)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case KEYBOARD:
|
case KEYBOARD:
|
||||||
@ -1755,27 +1749,24 @@ e_ControllerActionType CControllerConfigManager::GetActionType(e_ControllerActio
|
|||||||
|
|
||||||
void CControllerConfigManager::ClearSettingsAssociatedWithAction(e_ControllerAction action, eControllerType type)
|
void CControllerConfigManager::ClearSettingsAssociatedWithAction(e_ControllerAction action, eControllerType type)
|
||||||
{
|
{
|
||||||
if (type <= JOYSTICK)
|
switch (type)
|
||||||
{
|
{
|
||||||
switch (type)
|
case KEYBOARD:
|
||||||
{
|
m_aSettings[action][type].m_Key = rsNULL;
|
||||||
case KEYBOARD:
|
m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
|
||||||
m_aSettings[action][type].m_Key = rsNULL;
|
break;
|
||||||
m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
|
case OPTIONAL_EXTRA:
|
||||||
break;
|
m_aSettings[action][type].m_Key = rsNULL;
|
||||||
case OPTIONAL_EXTRA:
|
m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
|
||||||
m_aSettings[action][type].m_Key = rsNULL;
|
break;
|
||||||
m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
|
case MOUSE:
|
||||||
break;
|
m_aSettings[action][type].m_Key = 0;
|
||||||
case MOUSE:
|
m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
|
||||||
m_aSettings[action][type].m_Key = 0;
|
break;
|
||||||
m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
|
case JOYSTICK:
|
||||||
break;
|
m_aSettings[action][type].m_Key = 0;
|
||||||
case JOYSTICK:
|
m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
|
||||||
m_aSettings[action][type].m_Key = 0;
|
break;
|
||||||
m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResetSettingOrder(action);
|
ResetSettingOrder(action);
|
||||||
@ -2257,6 +2248,7 @@ void CControllerConfigManager::UpdateJoyButtonState(int32 padnumber)
|
|||||||
for (int32 i = 0; i < MAX_BUTTONS; i++)
|
for (int32 i = 0; i < MAX_BUTTONS; i++)
|
||||||
m_aButtonStates[i] = false;
|
m_aButtonStates[i] = false;
|
||||||
|
|
||||||
|
#ifdef __DINPUT_INCLUDED__
|
||||||
for (int32 i = 0; i < MAX_BUTTONS; i++)
|
for (int32 i = 0; i < MAX_BUTTONS; i++)
|
||||||
{
|
{
|
||||||
if (m_NewState.rgbButtons[i] & 0x80)
|
if (m_NewState.rgbButtons[i] & 0x80)
|
||||||
@ -2264,6 +2256,7 @@ void CControllerConfigManager::UpdateJoyButtonState(int32 padnumber)
|
|||||||
else
|
else
|
||||||
m_aButtonStates[i] = false;
|
m_aButtonStates[i] = false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CControllerConfigManager::GetIsActionAButtonCombo(e_ControllerAction action)
|
bool CControllerConfigManager::GetIsActionAButtonCombo(e_ControllerAction action)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "General.h"
|
||||||
#include "CutsceneMgr.h"
|
#include "CutsceneMgr.h"
|
||||||
#include "Directory.h"
|
#include "Directory.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
@ -107,7 +108,7 @@ int
|
|||||||
FindCutsceneAudioTrackId(const char *szCutsceneName)
|
FindCutsceneAudioTrackId(const char *szCutsceneName)
|
||||||
{
|
{
|
||||||
for (int i = 0; musicNameIdAssoc[i].szTrackName; i++) {
|
for (int i = 0; musicNameIdAssoc[i].szTrackName; i++) {
|
||||||
if (!strcmpi(musicNameIdAssoc[i].szTrackName, szCutsceneName))
|
if (!CGeneral::faststricmp(musicNameIdAssoc[i].szTrackName, szCutsceneName))
|
||||||
return musicNameIdAssoc[i].iTrackId;
|
return musicNameIdAssoc[i].iTrackId;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -171,7 +172,7 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
|
|||||||
CPlayerPed *pPlayerPed;
|
CPlayerPed *pPlayerPed;
|
||||||
|
|
||||||
ms_cutsceneProcessing = true;
|
ms_cutsceneProcessing = true;
|
||||||
if (!strcmpi(szCutsceneName, "jb"))
|
if (!strcasecmp(szCutsceneName, "jb"))
|
||||||
ms_useLodMultiplier = true;
|
ms_useLodMultiplier = true;
|
||||||
CTimer::Stop();
|
CTimer::Stop();
|
||||||
|
|
||||||
@ -207,7 +208,7 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
|
|||||||
|
|
||||||
CFileMgr::CloseFile(file);
|
CFileMgr::CloseFile(file);
|
||||||
|
|
||||||
if (strcmpi(ms_cutsceneName, "end")) {
|
if (CGeneral::faststricmp(ms_cutsceneName, "end")) {
|
||||||
DMAudio.ChangeMusicMode(MUSICMODE_CUTSCENE);
|
DMAudio.ChangeMusicMode(MUSICMODE_CUTSCENE);
|
||||||
int trackId = FindCutsceneAudioTrackId(szCutsceneName);
|
int trackId = FindCutsceneAudioTrackId(szCutsceneName);
|
||||||
if (trackId != -1) {
|
if (trackId != -1) {
|
||||||
@ -364,9 +365,9 @@ CCutsceneMgr::DeleteCutsceneData(void)
|
|||||||
CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_80;
|
CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_80;
|
||||||
CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(false);
|
CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(false);
|
||||||
|
|
||||||
if (strcmpi(ms_cutsceneName, "end")) {
|
if (CGeneral::faststricmp(ms_cutsceneName, "end")) {
|
||||||
DMAudio.StopCutSceneMusic();
|
DMAudio.StopCutSceneMusic();
|
||||||
if (strcmpi(ms_cutsceneName, "bet"))
|
if (CGeneral::faststricmp(ms_cutsceneName, "bet"))
|
||||||
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
|
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
|
||||||
}
|
}
|
||||||
CTimer::Stop();
|
CTimer::Stop();
|
||||||
@ -389,7 +390,7 @@ CCutsceneMgr::Update(void)
|
|||||||
switch (ms_cutsceneLoadStatus) {
|
switch (ms_cutsceneLoadStatus) {
|
||||||
case CUTSCENE_LOADING_AUDIO:
|
case CUTSCENE_LOADING_AUDIO:
|
||||||
SetupCutsceneToStart();
|
SetupCutsceneToStart();
|
||||||
if (strcmpi(ms_cutsceneName, "end"))
|
if (CGeneral::faststricmp(ms_cutsceneName, "end"))
|
||||||
DMAudio.PlayPreloadedCutSceneMusic();
|
DMAudio.PlayPreloadedCutSceneMusic();
|
||||||
ms_cutsceneLoadStatus++;
|
ms_cutsceneLoadStatus++;
|
||||||
break;
|
break;
|
||||||
@ -407,7 +408,7 @@ CCutsceneMgr::Update(void)
|
|||||||
if (!ms_running) return;
|
if (!ms_running) return;
|
||||||
|
|
||||||
ms_cutsceneTimer += CTimer::GetTimeStepNonClipped() * 0.02f;
|
ms_cutsceneTimer += CTimer::GetTimeStepNonClipped() * 0.02f;
|
||||||
if (strcmpi(ms_cutsceneName, "end") && TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FLYBY && ms_cutsceneLoadStatus == CUTSCENE_LOADING_0) {
|
if (CGeneral::faststricmp(ms_cutsceneName, "end") && TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FLYBY && ms_cutsceneLoadStatus == CUTSCENE_LOADING_0) {
|
||||||
if (CPad::GetPad(0)->GetCrossJustDown()
|
if (CPad::GetPad(0)->GetCrossJustDown()
|
||||||
|| (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown())
|
|| (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown())
|
||||||
|| CPad::GetPad(0)->GetLeftMouseJustDown()
|
|| CPad::GetPad(0)->GetLeftMouseJustDown()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "General.h"
|
||||||
#include "FileMgr.h"
|
#include "FileMgr.h"
|
||||||
#include "Directory.h"
|
#include "Directory.h"
|
||||||
|
|
||||||
@ -49,7 +50,7 @@ CDirectory::FindItem(const char *name, uint32 &offset, uint32 &size)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < numEntries; i++)
|
for(i = 0; i < numEntries; i++)
|
||||||
if(strcmpi(entries[i].name, name) == 0){
|
if(!CGeneral::faststricmp(entries[i].name, name)){
|
||||||
offset = entries[i].offset;
|
offset = entries[i].offset;
|
||||||
size = entries[i].size;
|
size = entries[i].size;
|
||||||
return true;
|
return true;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "Explosion.h"
|
#include "Explosion.h"
|
||||||
|
|
||||||
WRAPPER void CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32) { EAXJMP(0x5591C0); }
|
WRAPPER void CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32) { EAXJMP(0x5591C0); }
|
||||||
|
WRAPPER void CExplosion::RemoveAllExplosionsInArea(CVector, float) { EAXJMP(0x55AD40); }
|
||||||
|
|
||||||
WRAPPER
|
WRAPPER
|
||||||
int8 CExplosion::GetExplosionActiveCounter(uint8 id)
|
int8 CExplosion::GetExplosionActiveCounter(uint8 id)
|
||||||
|
@ -27,4 +27,5 @@ public:
|
|||||||
static CVector *GetExplosionPosition(uint8 id);
|
static CVector *GetExplosionPosition(uint8 id);
|
||||||
static uint8 GetExplosionType(uint8 id);
|
static uint8 GetExplosionType(uint8 id);
|
||||||
static void ResetExplosionActiveCounter(uint8 id);
|
static void ResetExplosionActiveCounter(uint8 id);
|
||||||
|
static void RemoveAllExplosionsInArea(CVector, float);
|
||||||
};
|
};
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
CFireManager &gFireManager = *(CFireManager*)0x8F31D0;
|
CFireManager &gFireManager = *(CFireManager*)0x8F31D0;
|
||||||
|
|
||||||
WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); }
|
WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); }
|
||||||
|
WRAPPER void CFireManager::StartFire(CEntity* entityOnFire, CEntity* culprit, float, uint32) { EAXJMP(0x479590); }
|
||||||
|
WRAPPER void CFireManager::Update(void) { EAXJMP(0x479310); }
|
||||||
|
WRAPPER CFire* CFireManager::FindFurthestFire_NeverMindFireMen(CVector coors, float, float) { EAXJMP(0x479430); }
|
||||||
|
|
||||||
uint32 CFireManager::GetTotalActiveFires() const
|
uint32 CFireManager::GetTotalActiveFires() const
|
||||||
{
|
{
|
||||||
@ -38,12 +41,28 @@ CFire* CFireManager::FindNearestFire(CVector vecPos, float* pDistance)
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CFireManager::ExtinguishPoint(CVector point, float range)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_FIRES; i++) {
|
||||||
|
if (m_aFires[i].m_bIsOngoing) {
|
||||||
|
if ((point - m_aFires[i].m_vecPos).MagnitudeSqr() < sq(range))
|
||||||
|
m_aFires[i].Extinguish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WRAPPER CFire *CFireManager::FindFurthestFire_NeverMindFireMen(CVector coors, float, float) { EAXJMP(0x479430); }
|
WRAPPER CFire *CFireManager::FindFurthestFire_NeverMindFireMen(CVector coors, float, float) { EAXJMP(0x479430); }
|
||||||
WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); }
|
WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); }
|
||||||
WRAPPER void CFireManager::StartFire(CVector, float, uint8) { EAXJMP(0x479500); }
|
WRAPPER void CFireManager::StartFire(CVector, float, uint8) { EAXJMP(0x479500); }
|
||||||
WRAPPER void CFireManager::ExtinguishPoint(CVector, float) { EAXJMP(0x479DB0); }
|
|
||||||
WRAPPER int32 CFireManager::StartScriptFire(const CVector& pos, CEntity* culprit, float, uint8) { EAXJMP(0x479E60); }
|
WRAPPER int32 CFireManager::StartScriptFire(const CVector& pos, CEntity* culprit, float, uint8) { EAXJMP(0x479E60); }
|
||||||
WRAPPER bool CFireManager::IsScriptFireExtinguish(int16) { EAXJMP(0x479FC0); }
|
WRAPPER bool CFireManager::IsScriptFireExtinguish(int16) { EAXJMP(0x479FC0); }
|
||||||
WRAPPER void CFireManager::RemoveScriptFire(int16) { EAXJMP(0x479FE0); }
|
WRAPPER void CFireManager::RemoveScriptFire(int16) { EAXJMP(0x479FE0); }
|
||||||
WRAPPER void CFireManager::RemoveAllScriptFires(void) { EAXJMP(0x47A000); }
|
WRAPPER void CFireManager::RemoveAllScriptFires(void) { EAXJMP(0x47A000); }
|
||||||
WRAPPER void CFireManager::SetScriptFireAudio(int16, bool) { EAXJMP(0x47A040); }
|
WRAPPER void CFireManager::SetScriptFireAudio(int16, bool) { EAXJMP(0x47A040); }
|
||||||
|
|
||||||
|
STARTPATCHES
|
||||||
|
InjectHook(0x479DB0, &CFireManager::ExtinguishPoint, PATCH_JUMP);
|
||||||
|
InjectHook(0x479340, &CFireManager::FindNearestFire, PATCH_JUMP);
|
||||||
|
ENDPATCHES
|
||||||
|
|
||||||
|
@ -35,12 +35,13 @@ public:
|
|||||||
void Update(void);
|
void Update(void);
|
||||||
CFire *FindFurthestFire_NeverMindFireMen(CVector coors, float, float);
|
CFire *FindFurthestFire_NeverMindFireMen(CVector coors, float, float);
|
||||||
CFire *FindNearestFire(CVector, float*);
|
CFire *FindNearestFire(CVector, float*);
|
||||||
uint32 GetTotalActiveFires() const;
|
uint32 GetTotalActiveFires() const { return m_nTotalFires; }
|
||||||
void ExtinguishPoint(CVector, float);
|
void ExtinguishPoint(CVector, float);
|
||||||
int32 StartScriptFire(const CVector& pos, CEntity* culprit, float, uint8);
|
int32 StartScriptFire(const CVector& pos, CEntity* culprit, float, uint8);
|
||||||
bool IsScriptFireExtinguish(int16);
|
bool IsScriptFireExtinguish(int16);
|
||||||
void RemoveScriptFire(int16);
|
void RemoveScriptFire(int16);
|
||||||
void RemoveAllScriptFires(void);
|
void RemoveAllScriptFires(void);
|
||||||
void SetScriptFireAudio(int16, bool);
|
void SetScriptFireAudio(int16, bool);
|
||||||
|
void ExtinguishPoint(CVector, float);
|
||||||
};
|
};
|
||||||
extern CFireManager &gFireManager;
|
extern CFireManager &gFireManager;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -7,10 +7,10 @@
|
|||||||
#define MENUHEADER_WIDTH 0.84f
|
#define MENUHEADER_WIDTH 0.84f
|
||||||
#define MENUHEADER_HEIGHT 1.6f
|
#define MENUHEADER_HEIGHT 1.6f
|
||||||
|
|
||||||
#define MENUACTION_POS_X 20.0f
|
#define MENUACTION_POS_X 40.0f
|
||||||
#define MENUACTION_POS_Y 37.5f
|
#define MENUACTION_POS_Y 37.5f
|
||||||
#define MENUACTION_WIDTH 0.675f
|
#define MENUACTION_WIDTH 0.405f
|
||||||
#define MENUACTION_HEIGHT 0.81f
|
#define MENUACTION_HEIGHT 0.63f
|
||||||
|
|
||||||
#define MENUCOLUMN_POS_X MENUHEADER_POS_X + 16.0f
|
#define MENUCOLUMN_POS_X MENUHEADER_POS_X + 16.0f
|
||||||
#define MENUCOLUMN_MAX_Y 149.0f
|
#define MENUCOLUMN_MAX_Y 149.0f
|
||||||
@ -467,8 +467,12 @@ public:
|
|||||||
static bool &m_bShutDownFrontEndRequested;
|
static bool &m_bShutDownFrontEndRequested;
|
||||||
static bool &m_PrefsAllowNastyGame;
|
static bool &m_PrefsAllowNastyGame;
|
||||||
|
|
||||||
|
static float &headingYStart;
|
||||||
|
static float &unkX;
|
||||||
|
static float &unkY;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void BuildStatLine(char *text, float *stat, bool aFloat, float* stat2);
|
static void BuildStatLine(char *text, void *stat, uint8 aFloat, void *stat2);
|
||||||
static void CentreMousePointer();
|
static void CentreMousePointer();
|
||||||
int CheckCodesForControls(int32);
|
int CheckCodesForControls(int32);
|
||||||
bool CheckHover(int x1, int x2, int y1, int y2);
|
bool CheckHover(int x1, int x2, int y1, int y2);
|
||||||
|
@ -104,6 +104,29 @@ public:
|
|||||||
return (int)floorf(angle / DEGTORAD(45.0f));
|
return (int)floorf(angle / DEGTORAD(45.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unlike usual string comparison functions, these don't care about greater or lesser
|
||||||
|
static bool faststrcmp(const char *str1, const char *str2)
|
||||||
|
{
|
||||||
|
for (; *str1; str1++, str2++) {
|
||||||
|
if (*str1 != *str2)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return *str2 != '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool faststricmp(const char *str1, const char *str2)
|
||||||
|
{
|
||||||
|
for (; *str1; str1++, str2++) {
|
||||||
|
#if MUCH_SLOWER
|
||||||
|
if (toupper(*str1) != toupper(*str2))
|
||||||
|
#else
|
||||||
|
if (__ascii_toupper(*str1) != __ascii_toupper(*str2))
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return *str2 != '\0';
|
||||||
|
}
|
||||||
|
|
||||||
// not too sure about all these...
|
// not too sure about all these...
|
||||||
static uint16 GetRandomNumber(void)
|
static uint16 GetRandomNumber(void)
|
||||||
{ return myrand() & MYRAND_MAX; }
|
{ return myrand() & MYRAND_MAX; }
|
||||||
|
@ -36,7 +36,7 @@ CKeyboardState &CPad::OldKeyState = *(CKeyboardState*)0x6F1E70;
|
|||||||
CKeyboardState &CPad::NewKeyState = *(CKeyboardState*)0x6E60D0;
|
CKeyboardState &CPad::NewKeyState = *(CKeyboardState*)0x6E60D0;
|
||||||
CKeyboardState &CPad::TempKeyState = *(CKeyboardState*)0x774DE8;
|
CKeyboardState &CPad::TempKeyState = *(CKeyboardState*)0x774DE8;
|
||||||
|
|
||||||
char CPad::KeyBoardCheatString[18];
|
char CPad::KeyBoardCheatString[20];
|
||||||
|
|
||||||
CMouseControllerState &CPad::OldMouseControllerState = *(CMouseControllerState*)0x8472A0;
|
CMouseControllerState &CPad::OldMouseControllerState = *(CMouseControllerState*)0x8472A0;
|
||||||
CMouseControllerState &CPad::NewMouseControllerState = *(CMouseControllerState*)0x8809F0;
|
CMouseControllerState &CPad::NewMouseControllerState = *(CMouseControllerState*)0x8809F0;
|
||||||
@ -427,7 +427,7 @@ void CPad::StartShake_Train(float fX, float fY)
|
|||||||
|
|
||||||
void CPad::AddToPCCheatString(char c)
|
void CPad::AddToPCCheatString(char c)
|
||||||
{
|
{
|
||||||
for ( int32 i = ARRAY_SIZE(KeyBoardCheatString); i >= 0; i-- )
|
for ( int32 i = ARRAY_SIZE(KeyBoardCheatString) - 2; i >= 0; i-- )
|
||||||
KeyBoardCheatString[i + 1] = KeyBoardCheatString[i];
|
KeyBoardCheatString[i + 1] = KeyBoardCheatString[i];
|
||||||
|
|
||||||
KeyBoardCheatString[0] = c;
|
KeyBoardCheatString[0] = c;
|
||||||
|
@ -7,7 +7,7 @@ enum {
|
|||||||
PLAYERCONTROL_DISABLED_4 = 4,
|
PLAYERCONTROL_DISABLED_4 = 4,
|
||||||
PLAYERCONTROL_DISABLED_8 = 8,
|
PLAYERCONTROL_DISABLED_8 = 8,
|
||||||
PLAYERCONTROL_DISABLED_10 = 16,
|
PLAYERCONTROL_DISABLED_10 = 16,
|
||||||
PLAYERCONTROL_DISABLED_20 = 32,
|
PLAYERCONTROL_DISABLED_20 = 32, // used on CPlayerInfo::MakePlayerSafe
|
||||||
PLAYERCONTROL_DISABLED_40 = 64, // used on phone calls
|
PLAYERCONTROL_DISABLED_40 = 64, // used on phone calls
|
||||||
PLAYERCONTROL_DISABLED_80 = 128,
|
PLAYERCONTROL_DISABLED_80 = 128,
|
||||||
};
|
};
|
||||||
@ -166,7 +166,7 @@ public:
|
|||||||
static CKeyboardState &OldKeyState;
|
static CKeyboardState &OldKeyState;
|
||||||
static CKeyboardState &NewKeyState;
|
static CKeyboardState &NewKeyState;
|
||||||
static CKeyboardState &TempKeyState;
|
static CKeyboardState &TempKeyState;
|
||||||
static char KeyBoardCheatString[18];
|
static char KeyBoardCheatString[20];
|
||||||
static CMouseControllerState &OldMouseControllerState;
|
static CMouseControllerState &OldMouseControllerState;
|
||||||
static CMouseControllerState &NewMouseControllerState;
|
static CMouseControllerState &NewMouseControllerState;
|
||||||
static CMouseControllerState &PCTempMouseControllerState;
|
static CMouseControllerState &PCTempMouseControllerState;
|
||||||
|
@ -1,18 +1,32 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
#include "PlayerPed.h"
|
#include "PlayerPed.h"
|
||||||
#include "PlayerInfo.h"
|
#include "PlayerInfo.h"
|
||||||
#include "Frontend.h"
|
#include "Frontend.h"
|
||||||
#include "Vehicle.h"
|
|
||||||
#include "PlayerSkin.h"
|
#include "PlayerSkin.h"
|
||||||
#include "Darkel.h"
|
#include "Darkel.h"
|
||||||
#include "Messages.h"
|
#include "Messages.h"
|
||||||
#include "Text.h"
|
#include "Text.h"
|
||||||
#include "Stats.h"
|
#include "Stats.h"
|
||||||
|
#include "Remote.h"
|
||||||
WRAPPER void CPlayerInfo::MakePlayerSafe(bool) { EAXJMP(0x4A1400); }
|
#include "World.h"
|
||||||
WRAPPER void CPlayerInfo::AwardMoneyForExplosion(CVehicle *vehicle) { EAXJMP(0x4A15F0); }
|
#include "Replay.h"
|
||||||
WRAPPER void CPlayerInfo::Process(void) { EAXJMP(0x49FD30); }
|
#include "Pad.h"
|
||||||
|
#include "ProjectileInfo.h"
|
||||||
|
#include "Explosion.h"
|
||||||
|
#include "Script.h"
|
||||||
|
#include "Automobile.h"
|
||||||
|
#include "HandlingMgr.h"
|
||||||
|
#include "General.h"
|
||||||
|
#include "SpecialFX.h"
|
||||||
|
#include "Cranes.h"
|
||||||
|
#include "Bridge.h"
|
||||||
|
#include "WaterLevel.h"
|
||||||
|
#include "PathFind.h"
|
||||||
|
#include "ZoneCull.h"
|
||||||
|
#include "Renderer.h"
|
||||||
|
#include "Streaming.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
CPlayerInfo::SetPlayerSkin(char *skin)
|
CPlayerInfo::SetPlayerSkin(char *skin)
|
||||||
@ -24,7 +38,7 @@ CPlayerInfo::SetPlayerSkin(char *skin)
|
|||||||
CVector&
|
CVector&
|
||||||
CPlayerInfo::GetPos()
|
CPlayerInfo::GetPos()
|
||||||
{
|
{
|
||||||
if (m_pPed->bInVehicle && m_pPed->m_pMyVehicle)
|
if (m_pPed->InVehicle())
|
||||||
return m_pPed->m_pMyVehicle->GetPosition();
|
return m_pPed->m_pMyVehicle->GetPosition();
|
||||||
return m_pPed->GetPosition();
|
return m_pPed->GetPosition();
|
||||||
}
|
}
|
||||||
@ -44,7 +58,7 @@ CPlayerInfo::DeletePlayerSkin()
|
|||||||
{
|
{
|
||||||
if (m_pSkinTexture) {
|
if (m_pSkinTexture) {
|
||||||
RwTextureDestroy(m_pSkinTexture);
|
RwTextureDestroy(m_pSkinTexture);
|
||||||
m_pSkinTexture = NULL;
|
m_pSkinTexture = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,9 +102,473 @@ CPlayerInfo::PlayerFailedCriticalMission()
|
|||||||
CDarkel::ResetOnPlayerDeath();
|
CDarkel::ResetOnPlayerDeath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerInfo::Clear(void)
|
||||||
|
{
|
||||||
|
m_pPed = nil;
|
||||||
|
m_pRemoteVehicle = nil;
|
||||||
|
if (m_pVehicleEx) {
|
||||||
|
m_pVehicleEx->bUsingSpecialColModel = false;
|
||||||
|
m_pVehicleEx = nil;
|
||||||
|
}
|
||||||
|
m_nVisibleMoney = 0;
|
||||||
|
m_nMoney = m_nVisibleMoney;
|
||||||
|
m_WBState = WBSTATE_PLAYING;
|
||||||
|
m_nWBTime = 0;
|
||||||
|
m_nTrafficMultiplier = 0;
|
||||||
|
m_fRoadDensity = 1.0f;
|
||||||
|
m_bInRemoteMode = false;
|
||||||
|
m_bUnusedTaxiThing = false;
|
||||||
|
m_nUnusedTaxiTimer = 0;
|
||||||
|
m_nCollectedPackages = 0;
|
||||||
|
m_nTotalPackages = 3;
|
||||||
|
m_nTimeLastHealthLoss = 0;
|
||||||
|
m_nTimeLastArmourLoss = 0;
|
||||||
|
m_nNextSexFrequencyUpdateTime = 0;
|
||||||
|
m_nNextSexMoneyUpdateTime = 0;
|
||||||
|
m_nSexFrequency = 0;
|
||||||
|
m_pHooker = nil;
|
||||||
|
m_nTimeTankShotGun = 0;
|
||||||
|
field_248 = 0;
|
||||||
|
m_nUpsideDownCounter = 0;
|
||||||
|
m_bInfiniteSprint = false;
|
||||||
|
m_bFastReload = false;
|
||||||
|
m_bGetOutOfJailFree = false;
|
||||||
|
m_bGetOutOfHospitalFree = false;
|
||||||
|
m_nPreviousTimeRewardedForExplosion = 0;
|
||||||
|
m_nExplosionsSinceLastReward = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerInfo::BlowUpRCBuggy(void)
|
||||||
|
{
|
||||||
|
if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CRemote::TakeRemoteControlledCarFromPlayer();
|
||||||
|
m_pRemoteVehicle->BlowUpCar(FindPlayerPed());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car)
|
||||||
|
{
|
||||||
|
if (!car || car == m_pPed->m_pMyVehicle) {
|
||||||
|
if (m_pPed->m_nPedState == PED_CARJACK || m_pPed->m_nPedState == PED_ENTER_CAR)
|
||||||
|
m_pPed->QuitEnteringCar();
|
||||||
|
}
|
||||||
|
if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
|
||||||
|
m_pPed->ClearObjective();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerInfo::MakePlayerSafe(bool toggle)
|
||||||
|
{
|
||||||
|
if (toggle) {
|
||||||
|
CTheScripts::CountdownToMakePlayerUnsafe = 0;
|
||||||
|
m_pPed->m_pWanted->m_bIgnoredByEveryone = true;
|
||||||
|
CWorld::StopAllLawEnforcersInTheirTracks();
|
||||||
|
CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_20;
|
||||||
|
CPad::StopPadsShaking();
|
||||||
|
m_pPed->bBulletProof = true;
|
||||||
|
m_pPed->bFireProof = true;
|
||||||
|
m_pPed->bCollisionProof = true;
|
||||||
|
m_pPed->bMeleeProof = true;
|
||||||
|
m_pPed->bOnlyDamagedByPlayer = true;
|
||||||
|
m_pPed->bExplosionProof = true;
|
||||||
|
m_pPed->m_bCanBeDamaged = false;
|
||||||
|
((CPlayerPed*)m_pPed)->ClearAdrenaline();
|
||||||
|
CancelPlayerEnteringCars(false);
|
||||||
|
gFireManager.ExtinguishPoint(GetPos(), 4000.0f);
|
||||||
|
CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f);
|
||||||
|
CProjectileInfo::RemoveAllProjectiles();
|
||||||
|
CWorld::SetAllCarsCanBeDamaged(false);
|
||||||
|
CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f);
|
||||||
|
CReplay::DisableReplays();
|
||||||
|
|
||||||
|
} else if (!CGame::playingIntro && !CTheScripts::CountdownToMakePlayerUnsafe) {
|
||||||
|
m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
|
||||||
|
CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_20;
|
||||||
|
m_pPed->bBulletProof = false;
|
||||||
|
m_pPed->bFireProof = false;
|
||||||
|
m_pPed->bCollisionProof = false;
|
||||||
|
m_pPed->bMeleeProof = false;
|
||||||
|
m_pPed->bOnlyDamagedByPlayer = false;
|
||||||
|
m_pPed->bExplosionProof = false;
|
||||||
|
m_pPed->m_bCanBeDamaged = true;
|
||||||
|
CWorld::SetAllCarsCanBeDamaged(true);
|
||||||
|
CReplay::EnableReplays();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CPlayerInfo::IsRestartingAfterDeath()
|
||||||
|
{
|
||||||
|
return m_WBState == WBSTATE_WASTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CPlayerInfo::IsRestartingAfterArrest()
|
||||||
|
{
|
||||||
|
return m_WBState == WBSTATE_BUSTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// lastClosestness is passed to other calls of this function
|
||||||
|
void
|
||||||
|
CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastClosestness, CVehicle **closestCarOutput)
|
||||||
|
{
|
||||||
|
// This dist used for determining the angle to face
|
||||||
|
CVector2D dist(carToTest->GetPosition() - player->GetPosition());
|
||||||
|
float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y);
|
||||||
|
while (neededTurn >= PI) {
|
||||||
|
neededTurn -= 2 * PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (neededTurn < -PI) {
|
||||||
|
neededTurn += 2 * PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This dist used for evaluating cars' distances, weird...
|
||||||
|
// Accounts inverted needed turn (or needed turn in long way) and car dist.
|
||||||
|
float closestness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist);
|
||||||
|
if (closestness > *lastClosestness) {
|
||||||
|
*lastClosestness = closestness;
|
||||||
|
*closestCarOutput = (CVehicle*)carToTest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// There is something unfinished in here... Sadly all IDBs we have have it unfinished.
|
||||||
|
void
|
||||||
|
CPlayerInfo::AwardMoneyForExplosion(CVehicle *wreckedCar)
|
||||||
|
{
|
||||||
|
if (CTimer::GetTimeInMilliseconds() - m_nPreviousTimeRewardedForExplosion < 6000)
|
||||||
|
++m_nExplosionsSinceLastReward;
|
||||||
|
else
|
||||||
|
m_nExplosionsSinceLastReward = 1;
|
||||||
|
|
||||||
|
m_nPreviousTimeRewardedForExplosion = CTimer::GetTimeInMilliseconds();
|
||||||
|
int award = wreckedCar->pHandling->nMonetaryValue * 0.002f;
|
||||||
|
sprintf(gString, "$%d", award);
|
||||||
|
#ifdef MONEY_MESSAGES
|
||||||
|
// This line is a leftover from PS2, I don't know what it was meant to be.
|
||||||
|
// CVector sth(TheCamera.GetPosition() * 4.0f);
|
||||||
|
|
||||||
|
CMoneyMessages::RegisterOne(wreckedCar->GetPosition() + CVector(0.0f, 0.0f, 2.0f), gString, 0, 255, 0, 2.0f, 0.5f);
|
||||||
|
#endif
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
|
||||||
|
|
||||||
|
for (int i = m_nExplosionsSinceLastReward; i > 1; --i) {
|
||||||
|
CGeneral::GetRandomNumber();
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size)
|
||||||
|
{
|
||||||
|
// Interesting
|
||||||
|
*size = sizeof(CPlayerInfo);
|
||||||
|
|
||||||
|
INITSAVEBUF
|
||||||
|
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
|
||||||
|
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
|
||||||
|
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
|
||||||
|
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
|
||||||
|
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
|
||||||
|
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
|
||||||
|
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
|
||||||
|
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
|
||||||
|
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
|
||||||
|
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
|
||||||
|
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
|
||||||
|
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
|
||||||
|
for (int i = 0; i < sizeof(CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); i++) {
|
||||||
|
WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName[i]);
|
||||||
|
}
|
||||||
|
// Save struct is different
|
||||||
|
// VALIDATESAVEBUF(*size)
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size)
|
||||||
|
{
|
||||||
|
INITSAVEBUF
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nMoney = ReadSaveBuf<uint32>(buf);
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_WBState = ReadSaveBuf<int8>(buf);
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nWBTime = ReadSaveBuf<uint32>(buf);
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier = ReadSaveBuf<int16>(buf);
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity = ReadSaveBuf<float>(buf);
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney = ReadSaveBuf<int32>(buf);
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages = ReadSaveBuf<int32>(buf);
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages = ReadSaveBuf<int32>(buf);
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint = ReadSaveBuf<bool>(buf);
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_bFastReload = ReadSaveBuf<bool>(buf);
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree = ReadSaveBuf<bool>(buf);
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree = ReadSaveBuf<bool>(buf);
|
||||||
|
for (int i = 0; i < sizeof(CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); i++) {
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName[i] = ReadSaveBuf<char>(buf);
|
||||||
|
}
|
||||||
|
// Save struct is different
|
||||||
|
// VALIDATESAVEBUF(size)
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastClosestness, CVehicle** closestCarOutput)
|
||||||
|
{
|
||||||
|
for (CPtrNode* node = carList.first; node; node = node->next) {
|
||||||
|
CVehicle *car = (CVehicle*)node->item;
|
||||||
|
if(car->m_scanCode != CWorld::GetCurrentScanCode()) {
|
||||||
|
if (!car->bUsesCollision || !car->IsVehicle())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
car->m_scanCode = CWorld::GetCurrentScanCode();
|
||||||
|
if (car->m_status != STATUS_WRECKED && car->m_status != STATUS_TRAIN_MOVING
|
||||||
|
&& (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) {
|
||||||
|
CVector carCentre = car->GetBoundCentre();
|
||||||
|
|
||||||
|
if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f) {
|
||||||
|
float dist = (ped->GetPosition() - carCentre).Magnitude2D();
|
||||||
|
if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) {
|
||||||
|
EvaluateCarPosition(car, ped, dist, lastClosestness, closestCarOutput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerInfo::Process(void)
|
||||||
|
{
|
||||||
|
// Unused taxi feature. Gives you a dollar for every second with a passenger. Can be toggled via 0x29A opcode.
|
||||||
|
bool startTaxiTimer = true;
|
||||||
|
if (m_bUnusedTaxiThing && m_pPed->bInVehicle) {
|
||||||
|
CVehicle *veh = m_pPed->m_pMyVehicle;
|
||||||
|
if ((veh->m_modelIndex == MI_TAXI || veh->m_modelIndex == MI_CABBIE || veh->m_modelIndex == MI_BORGNINE)
|
||||||
|
&& veh->pDriver == m_pPed && veh->m_nNumPassengers != 0) {
|
||||||
|
for (uint32 timePassed = CTimer::GetTimeInMilliseconds() - m_nUnusedTaxiTimer; timePassed >= 1000; m_nUnusedTaxiTimer += 1000) {
|
||||||
|
timePassed -= 1000;
|
||||||
|
++m_nMoney;
|
||||||
|
}
|
||||||
|
startTaxiTimer = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (startTaxiTimer)
|
||||||
|
m_nUnusedTaxiTimer = CTimer::GetTimeInMilliseconds();
|
||||||
|
|
||||||
|
// The effect that makes money counter does while earning/losing money
|
||||||
|
if (m_nVisibleMoney != m_nMoney) {
|
||||||
|
int diff = m_nMoney - m_nVisibleMoney;
|
||||||
|
int diffAbs = Abs(diff);
|
||||||
|
int changeBy;
|
||||||
|
|
||||||
|
if (diffAbs > 100000)
|
||||||
|
changeBy = 12345;
|
||||||
|
else if (diffAbs > 10000)
|
||||||
|
changeBy = 1234;
|
||||||
|
else if (diffAbs > 1000)
|
||||||
|
changeBy = 123;
|
||||||
|
else if (diffAbs > 50)
|
||||||
|
changeBy = 42;
|
||||||
|
else
|
||||||
|
changeBy = 1;
|
||||||
|
|
||||||
|
if (diff < 0)
|
||||||
|
m_nVisibleMoney -= changeBy;
|
||||||
|
else
|
||||||
|
m_nVisibleMoney += changeBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(CTimer::GetFrameCounter() & 15)) {
|
||||||
|
CVector2D playerPos = m_pPed->bInVehicle ? m_pPed->m_pMyVehicle->GetPosition() : m_pPed->GetPosition();
|
||||||
|
m_fRoadDensity = ThePaths.CalcRoadDensity(playerPos.x, playerPos.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fRoadDensity = clamp(m_fRoadDensity, 0.4f, 1.45f);
|
||||||
|
|
||||||
|
// Because vehicle enter/exit use same key binding.
|
||||||
|
bool enterOrExitVeh;
|
||||||
|
if (m_pPed->m_ped_flagI4 && m_pPed->bInVehicle)
|
||||||
|
enterOrExitVeh = CPad::GetPad(0)->ExitVehicleJustDown();
|
||||||
|
else
|
||||||
|
enterOrExitVeh = CPad::GetPad(0)->GetExitVehicle();
|
||||||
|
|
||||||
|
if (enterOrExitVeh && m_pPed->m_nPedState != PED_SNIPER_MODE && m_pPed->m_nPedState != PED_ROCKET_ODE) {
|
||||||
|
if (m_pPed->bInVehicle) {
|
||||||
|
if (!m_pRemoteVehicle) {
|
||||||
|
CEntity *surfaceBelowVeh = m_pPed->m_pMyVehicle->m_pCurGroundEntity;
|
||||||
|
if (!surfaceBelowVeh || !CBridge::ThisIsABridgeObjectMovingUp(surfaceBelowVeh->m_modelIndex)) {
|
||||||
|
CVehicle *veh = m_pPed->m_pMyVehicle;
|
||||||
|
if (!veh->IsBoat() || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
|
||||||
|
|
||||||
|
// This condition will always return true, else block was probably WIP Miami code.
|
||||||
|
if (veh->m_vehType != VEHICLE_TYPE_BIKE || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
|
||||||
|
if (veh->m_status != STATUS_WRECKED && veh->m_status != STATUS_TRAIN_MOVING && veh->m_nDoorLock != CARLOCK_LOCKED_PLAYER_INSIDE) {
|
||||||
|
if (veh->m_vecMoveSpeed.Magnitude() < 0.17f && CTimer::GetTimeScale() >= 0.5f && !veh->bIsInWater) {
|
||||||
|
m_pPed->SetObjective(OBJECTIVE_LEAVE_VEHICLE, veh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CVector sth = 0.7f * veh->GetRight() + veh->GetPosition();
|
||||||
|
bool found = false;
|
||||||
|
float groundZ = CWorld::FindGroundZFor3DCoord(sth.x, sth.y, 2.0f + sth.z, &found);
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
sth.z = 1.0f + groundZ;
|
||||||
|
m_pPed->m_nPedState = PED_IDLE;
|
||||||
|
m_pPed->SetMoveState(PEDMOVE_STILL);
|
||||||
|
CPed::PedSetOutCarCB(0, m_pPed);
|
||||||
|
CAnimManager::BlendAnimation(m_pPed->GetClump(), m_pPed->m_animGroup, ANIM_IDLE_STANCE, 100.0f);
|
||||||
|
CAnimManager::BlendAnimation(m_pPed->GetClump(), ASSOCGRP_STD, ANIM_FALL_LAND, 100.0f);
|
||||||
|
m_pPed->GetPosition() = sth;
|
||||||
|
m_pPed->SetMoveState(PEDMOVE_STILL);
|
||||||
|
m_pPed->m_vecMoveSpeed = veh->m_vecMoveSpeed;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The code in here was under CPed::SetExitBoat in VC, did the same for here.
|
||||||
|
m_pPed->SetExitBoat(veh);
|
||||||
|
m_pPed->bTryingToReachDryLand = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Enter vehicle
|
||||||
|
if (CPad::GetPad(0)->ExitVehicleJustDown()) {
|
||||||
|
bool weAreOnBoat = false;
|
||||||
|
float lastClosestness = 0.0f;
|
||||||
|
CVehicle *carBelow;
|
||||||
|
CEntity *surfaceBelow = m_pPed->m_pCurrentPhysSurface;
|
||||||
|
if (surfaceBelow && surfaceBelow->IsVehicle()) {
|
||||||
|
carBelow = (CVehicle*)surfaceBelow;
|
||||||
|
if (carBelow->IsBoat()) {
|
||||||
|
weAreOnBoat = true;
|
||||||
|
m_pPed->bOnBoat = true;
|
||||||
|
#ifdef VC_PED_PORTS
|
||||||
|
if (carBelow->m_status != STATUS_WRECKED && carBelow->GetUp().z > 0.3f)
|
||||||
|
#else
|
||||||
|
if (carBelow->m_status != STATUS_WRECKED)
|
||||||
|
#endif
|
||||||
|
m_pPed->SetSeekBoatPosition(carBelow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Find closest car
|
||||||
|
if (!weAreOnBoat) {
|
||||||
|
float minX = m_pPed->GetPosition().x - 10.0f;
|
||||||
|
float maxX = 10.0f + m_pPed->GetPosition().x;
|
||||||
|
float minY = m_pPed->GetPosition().y - 10.0f;
|
||||||
|
float maxY = 10.0f + m_pPed->GetPosition().y;
|
||||||
|
|
||||||
|
int minXSector = CWorld::GetSectorIndexX(minX);
|
||||||
|
if (minXSector < 0) minXSector = 0;
|
||||||
|
int minYSector = CWorld::GetSectorIndexY(minY);
|
||||||
|
if (minYSector < 0) minYSector = 0;
|
||||||
|
int maxXSector = CWorld::GetSectorIndexX(maxX);
|
||||||
|
if (maxXSector > NUMSECTORS_X - 1) maxXSector = NUMSECTORS_X - 1;
|
||||||
|
int maxYSector = CWorld::GetSectorIndexY(maxY);
|
||||||
|
if (maxYSector > NUMSECTORS_Y - 1) maxYSector = NUMSECTORS_Y - 1;
|
||||||
|
|
||||||
|
CWorld::AdvanceCurrentScanCode();
|
||||||
|
|
||||||
|
for (int curY = minYSector; curY <= maxYSector; curY++) {
|
||||||
|
for (int curX = minXSector; curX <= maxXSector; curX++) {
|
||||||
|
CSector *sector = CWorld::GetSector(curX, curY);
|
||||||
|
FindClosestCarSectorList(sector->m_lists[ENTITYLIST_VEHICLES], m_pPed,
|
||||||
|
minX, minY, maxX, maxY, &lastClosestness, &carBelow);
|
||||||
|
FindClosestCarSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], m_pPed,
|
||||||
|
minX, minY, maxX, maxY, &lastClosestness, &carBelow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// carBelow is now closest vehicle
|
||||||
|
if (carBelow && !weAreOnBoat) {
|
||||||
|
if (carBelow->m_status == STATUS_TRAIN_NOT_MOVING) {
|
||||||
|
m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, carBelow);
|
||||||
|
} else if (carBelow->IsBoat()) {
|
||||||
|
if (!carBelow->pDriver) {
|
||||||
|
m_pPed->m_vehEnterType = 0;
|
||||||
|
m_pPed->SetEnterCar(carBelow, m_pPed->m_vehEnterType);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, carBelow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_bInRemoteMode) {
|
||||||
|
uint32 timeWithoutRemoteCar = CTimer::GetTimeInMilliseconds() - m_nTimeLostRemoteCar;
|
||||||
|
if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING) {
|
||||||
|
TheCamera.SetFadeColour(0, 0, 0);
|
||||||
|
TheCamera.Fade(1.0f, 0);
|
||||||
|
}
|
||||||
|
if (timeWithoutRemoteCar > 2000) {
|
||||||
|
if (m_WBState == WBSTATE_PLAYING) {
|
||||||
|
TheCamera.RestoreWithJumpCut();
|
||||||
|
TheCamera.SetFadeColour(0, 0, 0);
|
||||||
|
TheCamera.Fade(1.0f, 1);
|
||||||
|
TheCamera.Process();
|
||||||
|
CTimer::Stop();
|
||||||
|
CCullZones::ForceCullZoneCoors(TheCamera.GetPosition());
|
||||||
|
CRenderer::RequestObjectsInFrustum();
|
||||||
|
CStreaming::LoadAllRequestedModels(false);
|
||||||
|
CTimer::Update();
|
||||||
|
}
|
||||||
|
m_bInRemoteMode = false;
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle = nil;
|
||||||
|
if (FindPlayerVehicle()) {
|
||||||
|
FindPlayerVehicle()->m_status = STATUS_PLAYER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(CTimer::GetFrameCounter() & 31)) {
|
||||||
|
CVehicle *veh = FindPlayerVehicle();
|
||||||
|
if (veh && m_pPed->bInVehicle && veh->GetUp().z < 0.0f
|
||||||
|
&& veh->m_vecMoveSpeed.Magnitude() < 0.05f && veh->IsCar() && !veh->bIsInWater) {
|
||||||
|
|
||||||
|
if (veh->GetUp().z < -0.5f) {
|
||||||
|
m_nUpsideDownCounter += 2;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
m_nUpsideDownCounter++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_nUpsideDownCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_nUpsideDownCounter > 6 && veh->bCanBeDamaged) {
|
||||||
|
veh->m_fHealth = 249.0f < veh->m_fHealth ? 249.0f : veh->m_fHealth;
|
||||||
|
if (veh->IsCar()) {
|
||||||
|
CAutomobile* car = (CAutomobile*)veh;
|
||||||
|
car->Damage.SetEngineStatus(225);
|
||||||
|
car->m_pSetOnFireEntity = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (FindPlayerVehicle()) {
|
||||||
|
CVehicle *veh = FindPlayerVehicle();
|
||||||
|
veh->m_nZoneLevel = -1;
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(veh->pPassengers); i++) {
|
||||||
|
if (veh->pPassengers[i])
|
||||||
|
veh->pPassengers[i]->m_nZoneLevel = 0;
|
||||||
|
}
|
||||||
|
CStats::DistanceTravelledInVehicle += veh->m_fDistanceTravelled;
|
||||||
|
} else {
|
||||||
|
CStats::DistanceTravelledOnFoot += FindPlayerPed()->m_fDistanceTravelled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
STARTPATCHES
|
STARTPATCHES
|
||||||
InjectHook(0x4A1700, &CPlayerInfo::LoadPlayerSkin, PATCH_JUMP);
|
InjectHook(0x4B5DC0, &CPlayerInfo::dtor, PATCH_JUMP);
|
||||||
InjectHook(0x4A1750, &CPlayerInfo::DeletePlayerSkin, PATCH_JUMP);
|
InjectHook(0x4A1700, &CPlayerInfo::LoadPlayerSkin, PATCH_JUMP);
|
||||||
InjectHook(0x4A12E0, &CPlayerInfo::KillPlayer, PATCH_JUMP);
|
InjectHook(0x4A1750, &CPlayerInfo::DeletePlayerSkin, PATCH_JUMP);
|
||||||
InjectHook(0x4A1330, &CPlayerInfo::ArrestPlayer, PATCH_JUMP);
|
InjectHook(0x4A12E0, &CPlayerInfo::KillPlayer, PATCH_JUMP);
|
||||||
|
InjectHook(0x4A1330, &CPlayerInfo::ArrestPlayer, PATCH_JUMP);
|
||||||
|
InjectHook(0x49FC10, &CPlayerInfo::Clear, PATCH_JUMP);
|
||||||
|
InjectHook(0x4A15C0, &CPlayerInfo::BlowUpRCBuggy, PATCH_JUMP);
|
||||||
|
InjectHook(0x4A13B0, &CPlayerInfo::CancelPlayerEnteringCars, PATCH_JUMP);
|
||||||
|
InjectHook(0x4A1400, &CPlayerInfo::MakePlayerSafe, PATCH_JUMP);
|
||||||
|
InjectHook(0x4A0EC0, &CPlayerInfo::EvaluateCarPosition, PATCH_JUMP);
|
||||||
|
InjectHook(0x4A15F0, &CPlayerInfo::AwardMoneyForExplosion, PATCH_JUMP);
|
||||||
|
InjectHook(0x4A0B20, &CPlayerInfo::LoadPlayerInfo, PATCH_JUMP);
|
||||||
|
InjectHook(0x4A0960, &CPlayerInfo::SavePlayerInfo, PATCH_JUMP);
|
||||||
|
InjectHook(0x49FD30, &CPlayerInfo::Process, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
||||||
|
@ -10,6 +10,8 @@ enum eWastedBustedState
|
|||||||
WBSTATE_FAILED_CRITICAL_MISSION,
|
WBSTATE_FAILED_CRITICAL_MISSION,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CEntity;
|
||||||
|
class CPed;
|
||||||
class CVehicle;
|
class CVehicle;
|
||||||
class CPlayerPed;
|
class CPlayerPed;
|
||||||
class CCivilianPed;
|
class CCivilianPed;
|
||||||
@ -27,20 +29,20 @@ public:
|
|||||||
int32 m_nCollectedPackages;
|
int32 m_nCollectedPackages;
|
||||||
int32 m_nTotalPackages;
|
int32 m_nTotalPackages;
|
||||||
uint32 m_nLastBumpPlayerCarTimer;
|
uint32 m_nLastBumpPlayerCarTimer;
|
||||||
int32 m_nSwitchTaxiTime;
|
uint32 m_nUnusedTaxiTimer;
|
||||||
bool m_bSwitchTaxi;
|
bool m_bUnusedTaxiThing;
|
||||||
int8 field_197;
|
int8 field_197;
|
||||||
int8 field_198;
|
int8 field_198;
|
||||||
int8 field_199;
|
int8 field_199;
|
||||||
int32 m_nNextSexFrequencyUpdateTime;
|
uint32 m_nNextSexFrequencyUpdateTime;
|
||||||
int32 m_nNextSexMoneyUpdateTime;
|
uint32 m_nNextSexMoneyUpdateTime;
|
||||||
int32 m_nSexFrequency;
|
int32 m_nSexFrequency;
|
||||||
CCivilianPed *m_pHooker;
|
CCivilianPed *m_pHooker;
|
||||||
int8 m_WBState; // eWastedBustedState
|
int8 m_WBState; // eWastedBustedState
|
||||||
int8 field_217;
|
int8 field_217;
|
||||||
int8 field_218;
|
int8 field_218;
|
||||||
int8 field_219;
|
int8 field_219;
|
||||||
int32 m_nWBTime;
|
uint32 m_nWBTime;
|
||||||
bool m_bInRemoteMode;
|
bool m_bInRemoteMode;
|
||||||
int8 field_225;
|
int8 field_225;
|
||||||
int8 field_226;
|
int8 field_226;
|
||||||
@ -55,7 +57,7 @@ public:
|
|||||||
int8 field_254;
|
int8 field_254;
|
||||||
int8 field_255;
|
int8 field_255;
|
||||||
float m_fRoadDensity;
|
float m_fRoadDensity;
|
||||||
int32 m_nPreviousTimeRewardedForExplosion;
|
uint32 m_nPreviousTimeRewardedForExplosion;
|
||||||
int32 m_nExplosionsSinceLastReward;
|
int32 m_nExplosionsSinceLastReward;
|
||||||
int32 field_268;
|
int32 field_268;
|
||||||
int32 field_272;
|
int32 field_272;
|
||||||
@ -77,6 +79,18 @@ public:
|
|||||||
void ArrestPlayer(void);
|
void ArrestPlayer(void);
|
||||||
bool IsPlayerInRemoteMode(void);
|
bool IsPlayerInRemoteMode(void);
|
||||||
void PlayerFailedCriticalMission(void);
|
void PlayerFailedCriticalMission(void);
|
||||||
|
void Clear(void);
|
||||||
|
void BlowUpRCBuggy(void);
|
||||||
|
void CancelPlayerEnteringCars(CVehicle*);
|
||||||
|
bool IsRestartingAfterDeath(void);
|
||||||
|
bool IsRestartingAfterArrest(void);
|
||||||
|
void EvaluateCarPosition(CEntity*, CPed*, float, float*, CVehicle**);
|
||||||
|
void LoadPlayerInfo(uint8 *buf, uint32 size);
|
||||||
|
void SavePlayerInfo(uint8 *buf, uint32* size);
|
||||||
|
void FindClosestCarSectorList(CPtrList&, CPed*, float, float, float, float, float*, CVehicle**);
|
||||||
|
|
||||||
|
~CPlayerInfo() { };
|
||||||
|
void dtor(void) { this->CPlayerInfo::~CPlayerInfo(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerInfo: error");
|
static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerInfo: error");
|
||||||
|
@ -28,7 +28,7 @@ FindPlayerDff(uint32 &offset, uint32 &size)
|
|||||||
do {
|
do {
|
||||||
if (!CFileMgr::Read(file, (char*)&info, sizeof(CDirectory::DirectoryInfo)))
|
if (!CFileMgr::Read(file, (char*)&info, sizeof(CDirectory::DirectoryInfo)))
|
||||||
return;
|
return;
|
||||||
} while (strcmpi("player.dff", info.name));
|
} while (strcasecmp("player.dff", info.name) != 0);
|
||||||
|
|
||||||
offset = info.offset;
|
offset = info.offset;
|
||||||
size = info.size;
|
size = info.size;
|
||||||
@ -94,7 +94,7 @@ CPlayerSkin::GetSkinTexture(const char *texName)
|
|||||||
CTxdStore::PopCurrentTxd();
|
CTxdStore::PopCurrentTxd();
|
||||||
if (tex) return tex;
|
if (tex) return tex;
|
||||||
|
|
||||||
if (!strcmp(DEFAULT_SKIN_NAME, texName))
|
if (strcmp(DEFAULT_SKIN_NAME, texName) == 0)
|
||||||
sprintf(gString, "models\\generic\\player.bmp");
|
sprintf(gString, "models\\generic\\player.bmp");
|
||||||
else
|
else
|
||||||
sprintf(gString, "skins\\%s.bmp", texName);
|
sprintf(gString, "skins\\%s.bmp", texName);
|
||||||
|
@ -312,7 +312,7 @@ void CRadar::DrawBlips()
|
|||||||
break;
|
break;
|
||||||
case BLIP_CHAR:
|
case BLIP_CHAR:
|
||||||
blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
|
blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
|
||||||
if (blipEntity && ((CPed*)blipEntity)->bInVehicle && ((CPed*)blipEntity)->m_pMyVehicle) {
|
if (blipEntity && ((CPed*)blipEntity)->InVehicle()) {
|
||||||
blipEntity = ((CPed*)blipEntity)->m_pMyVehicle;
|
blipEntity = ((CPed*)blipEntity)->m_pMyVehicle;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -415,7 +415,7 @@ void CRadar::DrawBlips()
|
|||||||
break;
|
break;
|
||||||
case BLIP_CHAR:
|
case BLIP_CHAR:
|
||||||
blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
|
blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
|
||||||
if (blipEntity && ((CPed*)blipEntity)->bInVehicle && ((CPed*)blipEntity)->m_pMyVehicle) {
|
if (blipEntity && ((CPed*)blipEntity)->InVehicle()) {
|
||||||
blipEntity = ((CPed*)blipEntity)->m_pMyVehicle;
|
blipEntity = ((CPed*)blipEntity)->m_pMyVehicle;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -12,6 +12,8 @@ int32 *CStats::PedsKilledOfThisType = (int32*)0x880DBC;
|
|||||||
int32 &CStats::TimesDied = *(int32*)0x8E2BDC;
|
int32 &CStats::TimesDied = *(int32*)0x8E2BDC;
|
||||||
int32 &CStats::TimesArrested = *(int32*)0x8E2BEC;
|
int32 &CStats::TimesArrested = *(int32*)0x8E2BEC;
|
||||||
int32 &CStats::KillsSinceLastCheckpoint = *(int32*)0x8F2C8C;
|
int32 &CStats::KillsSinceLastCheckpoint = *(int32*)0x8F2C8C;
|
||||||
|
int32& CStats::DistanceTravelledInVehicle = *(int32*)0x940574;
|
||||||
|
int32& CStats::DistanceTravelledOnFoot = *(int32*)0x941518;
|
||||||
int32 &CStats::ProgressMade = *(int32*)0x8F6224;
|
int32 &CStats::ProgressMade = *(int32*)0x8F6224;
|
||||||
int32 &CStats::TotalProgressInGame = *(int32*)0x885B2C;
|
int32 &CStats::TotalProgressInGame = *(int32*)0x885B2C;
|
||||||
float &CStats::MaximumJumpDistance = *(float*)0x8F2BDC;
|
float &CStats::MaximumJumpDistance = *(float*)0x8F2BDC;
|
||||||
|
@ -14,6 +14,8 @@ public:
|
|||||||
static int32 &TimesDied;
|
static int32 &TimesDied;
|
||||||
static int32 &TimesArrested;
|
static int32 &TimesArrested;
|
||||||
static int32 &KillsSinceLastCheckpoint;
|
static int32 &KillsSinceLastCheckpoint;
|
||||||
|
static int32 &DistanceTravelledInVehicle;
|
||||||
|
static int32 &DistanceTravelledOnFoot;
|
||||||
static int32 &ProgressMade;
|
static int32 &ProgressMade;
|
||||||
static int32 &TotalProgressInGame;
|
static int32 &TotalProgressInGame;
|
||||||
static float &MaximumJumpDistance;
|
static float &MaximumJumpDistance;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "General.h"
|
||||||
#include "Pad.h"
|
#include "Pad.h"
|
||||||
#include "Hud.h"
|
#include "Hud.h"
|
||||||
#include "Text.h"
|
#include "Text.h"
|
||||||
@ -347,7 +348,7 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
|
|||||||
if(direntry.size > (uint32)ms_streamingBufferSize)
|
if(direntry.size > (uint32)ms_streamingBufferSize)
|
||||||
ms_streamingBufferSize = direntry.size;
|
ms_streamingBufferSize = direntry.size;
|
||||||
|
|
||||||
if(strcmp(dot+1, "DFF") == 0 || strcmp(dot+1, "dff") == 0){
|
if(!CGeneral::faststrcmp(dot+1, "DFF") || !CGeneral::faststrcmp(dot+1, "dff")){
|
||||||
if(CModelInfo::GetModelInfo(direntry.name, &modelId)){
|
if(CModelInfo::GetModelInfo(direntry.name, &modelId)){
|
||||||
if(ms_aInfoForModel[modelId].GetCdPosnAndSize(posn, size)){
|
if(ms_aInfoForModel[modelId].GetCdPosnAndSize(posn, size)){
|
||||||
debug("%s appears more than once in %s\n", direntry.name, dirname);
|
debug("%s appears more than once in %s\n", direntry.name, dirname);
|
||||||
@ -364,20 +365,20 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
|
|||||||
ms_pExtraObjectsDir->AddItem(direntry);
|
ms_pExtraObjectsDir->AddItem(direntry);
|
||||||
lastID = -1;
|
lastID = -1;
|
||||||
}
|
}
|
||||||
}else if(strcmp(dot+1, "TXD") == 0 || strcmp(dot+1, "txd") == 0){
|
}else if(!CGeneral::faststrcmp(dot+1, "TXD") || !CGeneral::faststrcmp(dot+1, "txd")){
|
||||||
txdId = CTxdStore::FindTxdSlot(direntry.name);
|
txdId = CTxdStore::FindTxdSlot(direntry.name);
|
||||||
if(txdId == -1)
|
if(txdId == -1)
|
||||||
txdId = CTxdStore::AddTxdSlot(direntry.name);
|
txdId = CTxdStore::AddTxdSlot(direntry.name);
|
||||||
if(ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].GetCdPosnAndSize(posn, size)){
|
if(ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].GetCdPosnAndSize(posn, size)){
|
||||||
debug("%s appears more than once in %s\n", direntry.name, dirname);
|
debug("%s appears more than once in %s\n", direntry.name, dirname);
|
||||||
lastID = -1;
|
lastID = -1;
|
||||||
}else{
|
}else{
|
||||||
direntry.offset |= imgSelector;
|
direntry.offset |= imgSelector;
|
||||||
ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].SetCdPosnAndSize(direntry.offset, direntry.size);
|
ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].SetCdPosnAndSize(direntry.offset, direntry.size);
|
||||||
if(lastID != -1)
|
if(lastID != -1)
|
||||||
ms_aInfoForModel[lastID].m_nextID = txdId + STREAM_OFFSET_TXD;
|
ms_aInfoForModel[lastID].m_nextID = txdId + STREAM_OFFSET_TXD;
|
||||||
lastID = txdId + STREAM_OFFSET_TXD;
|
lastID = txdId + STREAM_OFFSET_TXD;
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
lastID = -1;
|
lastID = -1;
|
||||||
}
|
}
|
||||||
@ -720,7 +721,7 @@ CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flag
|
|||||||
uint32 pos, size;
|
uint32 pos, size;
|
||||||
|
|
||||||
mi = CModelInfo::GetModelInfo(modelId);
|
mi = CModelInfo::GetModelInfo(modelId);
|
||||||
if(strcmp(mi->GetName(), modelName) == 0){
|
if(!CGeneral::faststrcmp(mi->GetName(), modelName)){
|
||||||
// Already have the correct name, just request it
|
// Already have the correct name, just request it
|
||||||
RequestModel(modelId, flags);
|
RequestModel(modelId, flags);
|
||||||
return;
|
return;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "TempColModels.h"
|
#include "TempColModels.h"
|
||||||
|
#include "SurfaceTable.h"
|
||||||
|
|
||||||
CColModel &CTempColModels::ms_colModelPed1 = *(CColModel*)0x726CB0;
|
CColModel &CTempColModels::ms_colModelPed1 = *(CColModel*)0x726CB0;
|
||||||
CColModel &CTempColModels::ms_colModelPed2 = *(CColModel*)0x726D08;
|
CColModel &CTempColModels::ms_colModelPed2 = *(CColModel*)0x726D08;
|
||||||
@ -16,4 +17,277 @@ CColModel &CTempColModels::ms_colModelBoot1 = *(CColModel*)0x880670;
|
|||||||
CColModel &CTempColModels::ms_colModelDoor1 = *(CColModel*)0x880850;
|
CColModel &CTempColModels::ms_colModelDoor1 = *(CColModel*)0x880850;
|
||||||
CColModel &CTempColModels::ms_colModelBonnet1 = *(CColModel*)0x8808A8;
|
CColModel &CTempColModels::ms_colModelBonnet1 = *(CColModel*)0x8808A8;
|
||||||
|
|
||||||
WRAPPER void CTempColModels::Initialise(void) { EAXJMP(0x412160); }
|
|
||||||
|
CColSphere s_aPedSpheres[3];
|
||||||
|
CColSphere s_aPed2Spheres[3];
|
||||||
|
CColSphere s_aPedGSpheres[4];
|
||||||
|
CColSphere s_aDoorSpheres[4];
|
||||||
|
CColSphere s_aBumperSpheres[4];
|
||||||
|
CColSphere s_aPanelSpheres[4];
|
||||||
|
CColSphere s_aBonnetSpheres[4];
|
||||||
|
CColSphere s_aBootSpheres[4];
|
||||||
|
CColSphere s_aWheelSpheres[2];
|
||||||
|
CColSphere s_aBodyPartSpheres1[2];
|
||||||
|
CColSphere s_aBodyPartSpheres2[2];
|
||||||
|
|
||||||
|
void
|
||||||
|
CTempColModels::Initialise(void)
|
||||||
|
{
|
||||||
|
#define SET_COLMODEL_SPHERES(colmodel, sphrs)\
|
||||||
|
colmodel.numSpheres = ARRAYSIZE(sphrs);\
|
||||||
|
colmodel.spheres = sphrs;\
|
||||||
|
colmodel.level = LEVEL_NONE;\
|
||||||
|
colmodel.ownsCollisionVolumes = false;\
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
||||||
|
ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0);
|
||||||
|
ms_colModelBBox.level = LEVEL_NONE;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAYSIZE(ms_colModelCutObj); i++) {
|
||||||
|
ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
||||||
|
ms_colModelCutObj[i].boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0);
|
||||||
|
ms_colModelCutObj[i].level = LEVEL_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ped Spheres
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aPedSpheres); i++)
|
||||||
|
s_aPedSpheres[i].radius = 0.35f;
|
||||||
|
|
||||||
|
s_aPedSpheres[0].center = CVector(0.0f, 0.0f, -0.25f);
|
||||||
|
s_aPedSpheres[1].center = CVector(0.0f, 0.0f, 0.15f);
|
||||||
|
s_aPedSpheres[2].center = CVector(0.0f, 0.0f, 0.55f);
|
||||||
|
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aPedSpheres); i++) {
|
||||||
|
#else
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aPedGSpheres); i++) {
|
||||||
|
#endif
|
||||||
|
s_aPedSpheres[i].surface = SURFACE_FLESH;
|
||||||
|
s_aPedSpheres[i].piece = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
||||||
|
ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f), SURFACE_DEFAULT, 0);
|
||||||
|
SET_COLMODEL_SPHERES(ms_colModelPed1, s_aPedSpheres);
|
||||||
|
|
||||||
|
// Ped 2 Spheres
|
||||||
|
|
||||||
|
s_aPed2Spheres[0].radius = 0.3f;
|
||||||
|
s_aPed2Spheres[1].radius = 0.4f;
|
||||||
|
s_aPed2Spheres[2].radius = 0.3f;
|
||||||
|
|
||||||
|
s_aPed2Spheres[0].center = CVector(0.0f, 0.35f, -0.9f);
|
||||||
|
s_aPed2Spheres[1].center = CVector(0.0f, 0.0f, -0.9f);
|
||||||
|
s_aPed2Spheres[2].center = CVector(0.0f, -0.35f, -0.9f);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aPed2Spheres); i++) {
|
||||||
|
s_aPed2Spheres[i].surface = SURFACE_FLESH;
|
||||||
|
s_aPed2Spheres[i].piece = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ms_colModelPed2.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
||||||
|
ms_colModelPed2.boundingBox.Set(CVector(-0.7f, -0.7f, -1.2f), CVector(0.7f, 0.7f, 0.0f), SURFACE_DEFAULT, 0);
|
||||||
|
|
||||||
|
SET_COLMODEL_SPHERES(ms_colModelPed2, s_aPed2Spheres);
|
||||||
|
|
||||||
|
// Ped ground collision
|
||||||
|
|
||||||
|
s_aPedGSpheres[0].radius = 0.35f;
|
||||||
|
s_aPedGSpheres[1].radius = 0.35f;
|
||||||
|
s_aPedGSpheres[2].radius = 0.35f;
|
||||||
|
s_aPedGSpheres[3].radius = 0.3f;
|
||||||
|
|
||||||
|
s_aPedGSpheres[0].center = CVector(0.0f, -0.4f, -0.9f);
|
||||||
|
s_aPedGSpheres[1].center = CVector(0.0f, -0.1f, -0.9f);
|
||||||
|
s_aPedGSpheres[2].center = CVector(0.0f, 0.25f, -0.9f);
|
||||||
|
s_aPedGSpheres[3].center = CVector(0.0f, 0.65f, -0.9f);
|
||||||
|
|
||||||
|
s_aPedGSpheres[0].surface = SURFACE_FLESH;
|
||||||
|
s_aPedGSpheres[1].surface = SURFACE_FLESH;
|
||||||
|
s_aPedGSpheres[2].surface = SURFACE_FLESH;
|
||||||
|
s_aPedGSpheres[3].surface = SURFACE_FLESH;
|
||||||
|
s_aPedGSpheres[0].piece = 4;
|
||||||
|
s_aPedGSpheres[1].piece = 1;
|
||||||
|
s_aPedGSpheres[2].piece = 0;
|
||||||
|
s_aPedGSpheres[3].piece = 6;
|
||||||
|
|
||||||
|
ms_colModelPedGroundHit.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
||||||
|
ms_colModelPedGroundHit.boundingBox.Set(CVector(-0.4f, -1.0f, -1.25f), CVector(0.4f, 1.2f, -0.5f), SURFACE_DEFAULT, 0);
|
||||||
|
|
||||||
|
SET_COLMODEL_SPHERES(ms_colModelPedGroundHit, s_aPedGSpheres);
|
||||||
|
|
||||||
|
// Door Spheres
|
||||||
|
|
||||||
|
s_aDoorSpheres[0].radius = 0.15f;
|
||||||
|
s_aDoorSpheres[1].radius = 0.15f;
|
||||||
|
s_aDoorSpheres[2].radius = 0.25f;
|
||||||
|
|
||||||
|
s_aDoorSpheres[0].center = CVector(0.0f, -0.25f, -0.35f);
|
||||||
|
s_aDoorSpheres[1].center = CVector(0.0f, -0.95f, -0.35f);
|
||||||
|
s_aDoorSpheres[2].center = CVector(0.0f, -0.6f, 0.25f);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aDoorSpheres); i++) {
|
||||||
|
s_aDoorSpheres[i].surface = SURFACE_BILLBOARD;
|
||||||
|
s_aDoorSpheres[i].piece = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ms_colModelDoor1.boundingSphere.Set(1.5f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0);
|
||||||
|
ms_colModelDoor1.boundingBox.Set(CVector(-0.3f, 0.0f, -0.6f), CVector(0.3f, -1.2f, 0.6f), SURFACE_DEFAULT, 0);
|
||||||
|
|
||||||
|
SET_COLMODEL_SPHERES(ms_colModelDoor1, s_aDoorSpheres);
|
||||||
|
|
||||||
|
// Bumper Spheres
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aBumperSpheres); i++)
|
||||||
|
s_aBumperSpheres[i].radius = 0.15f;
|
||||||
|
|
||||||
|
s_aBumperSpheres[0].center = CVector(0.85f, -0.05f, 0.0f);
|
||||||
|
s_aBumperSpheres[1].center = CVector(0.4f, 0.05f, 0.0f);
|
||||||
|
s_aBumperSpheres[2].center = CVector(-0.4f, 0.05f, 0.0f);
|
||||||
|
s_aBumperSpheres[3].center = CVector(-0.85f, -0.05f, 0.0f);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aBumperSpheres); i++) {
|
||||||
|
s_aBumperSpheres[i].surface = SURFACE_BILLBOARD;
|
||||||
|
s_aBumperSpheres[i].piece = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ms_colModelBumper1.boundingSphere.Set(2.2f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0);
|
||||||
|
ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, -0.2f), SURFACE_DEFAULT, 0);
|
||||||
|
|
||||||
|
SET_COLMODEL_SPHERES(ms_colModelBumper1, s_aBumperSpheres);
|
||||||
|
|
||||||
|
// Panel Spheres
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aPanelSpheres); i++)
|
||||||
|
s_aPanelSpheres[i].radius = 0.15f;
|
||||||
|
|
||||||
|
s_aPanelSpheres[0].center = CVector(0.15f, 0.45f, 0.0f);
|
||||||
|
s_aPanelSpheres[1].center = CVector(0.15f, -0.45f, 0.0f);
|
||||||
|
s_aPanelSpheres[2].center = CVector(-0.15f, -0.45f, 0.0f);
|
||||||
|
s_aPanelSpheres[3].center = CVector(-0.15f, 0.45f, 0.0f);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aPanelSpheres); i++) {
|
||||||
|
s_aPanelSpheres[i].surface = SURFACE_BILLBOARD;
|
||||||
|
s_aPanelSpheres[i].piece = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ms_colModelPanel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
||||||
|
ms_colModelPanel1.boundingBox.Set(CVector(-0.3f, -0.6f, -0.15f), CVector(0.3f, 0.6f, 0.15f), SURFACE_DEFAULT, 0);
|
||||||
|
|
||||||
|
SET_COLMODEL_SPHERES(ms_colModelPanel1, s_aPanelSpheres);
|
||||||
|
|
||||||
|
// Bonnet Spheres
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aBonnetSpheres); i++)
|
||||||
|
s_aBonnetSpheres[i].radius = 0.2f;
|
||||||
|
|
||||||
|
s_aBonnetSpheres[0].center = CVector(-0.4f, 0.1f, 0.0f);
|
||||||
|
s_aBonnetSpheres[1].center = CVector(-0.4f, 0.9f, 0.0f);
|
||||||
|
s_aBonnetSpheres[2].center = CVector(0.4f, 0.1f, 0.0f);
|
||||||
|
s_aBonnetSpheres[3].center = CVector(0.4f, 0.9f, 0.0f);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aBonnetSpheres); i++) {
|
||||||
|
s_aBonnetSpheres[i].surface = SURFACE_BILLBOARD;
|
||||||
|
s_aBonnetSpheres[i].piece = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ms_colModelBonnet1.boundingSphere.Set(1.7f, CVector(0.0f, 0.5f, 0.0f), SURFACE_DEFAULT, 0);
|
||||||
|
ms_colModelBonnet1.boundingBox.Set(CVector(-0.7f, -0.2f, -0.3f), CVector(0.7f, 1.2f, 0.3f), SURFACE_DEFAULT, 0);
|
||||||
|
|
||||||
|
SET_COLMODEL_SPHERES(ms_colModelBonnet1, s_aBonnetSpheres);
|
||||||
|
|
||||||
|
// Boot Spheres
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aBootSpheres); i++)
|
||||||
|
s_aBootSpheres[i].radius = 0.2f;
|
||||||
|
|
||||||
|
s_aBootSpheres[0].center = CVector(-0.4f, -0.1f, 0.0f);
|
||||||
|
s_aBootSpheres[1].center = CVector(-0.4f, -0.6f, 0.0f);
|
||||||
|
s_aBootSpheres[2].center = CVector(0.4f, -0.1f, 0.0f);
|
||||||
|
s_aBootSpheres[3].center = CVector(0.4f, -0.6f, 0.0f);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aBootSpheres); i++) {
|
||||||
|
s_aBootSpheres[i].surface = SURFACE_BILLBOARD;
|
||||||
|
s_aBootSpheres[i].piece = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ms_colModelBoot1.boundingSphere.Set(1.4f, CVector(0.0f, -0.4f, 0.0f), SURFACE_DEFAULT, 0);
|
||||||
|
ms_colModelBoot1.boundingBox.Set(CVector(-0.7f, -0.9f, -0.3f), CVector(0.7f, 0.2f, 0.3f), SURFACE_DEFAULT, 0);
|
||||||
|
|
||||||
|
SET_COLMODEL_SPHERES(ms_colModelBoot1, s_aBootSpheres);
|
||||||
|
|
||||||
|
// Wheel Spheres
|
||||||
|
|
||||||
|
s_aWheelSpheres[0].radius = 0.35f;
|
||||||
|
s_aWheelSpheres[1].radius = 0.35f;
|
||||||
|
|
||||||
|
s_aWheelSpheres[0].center = CVector(-0.3f, 0.0f, 0.0f);
|
||||||
|
s_aWheelSpheres[1].center = CVector(0.3f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aWheelSpheres); i++) {
|
||||||
|
#else
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aBootSpheres); i++) {
|
||||||
|
#endif
|
||||||
|
s_aWheelSpheres[i].surface = SURFACE_RUBBER29;
|
||||||
|
s_aWheelSpheres[i].piece = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ms_colModelWheel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
||||||
|
ms_colModelWheel1.boundingBox.Set(CVector(-0.7f, -0.4f, -0.4f), CVector(0.7f, 0.4f, 0.4f), SURFACE_DEFAULT, 0);
|
||||||
|
|
||||||
|
SET_COLMODEL_SPHERES(ms_colModelWheel1, s_aWheelSpheres);
|
||||||
|
|
||||||
|
// Body Part Spheres 1
|
||||||
|
|
||||||
|
s_aBodyPartSpheres1[0].radius = 0.2f;
|
||||||
|
s_aBodyPartSpheres1[1].radius = 0.2f;
|
||||||
|
|
||||||
|
s_aBodyPartSpheres1[0].center = CVector(0.0f, 0.0f, 0.0f);
|
||||||
|
s_aBodyPartSpheres1[1].center = CVector(0.8f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aBodyPartSpheres1); i++) {
|
||||||
|
#else
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aBootSpheres); i++) {
|
||||||
|
#endif
|
||||||
|
s_aBodyPartSpheres1[i].surface = SURFACE_FLESH;
|
||||||
|
s_aBodyPartSpheres1[i].piece = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ms_colModelBodyPart1.boundingSphere.Set(0.7f, CVector(0.4f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
||||||
|
ms_colModelBodyPart1.boundingBox.Set(CVector(-0.3f, -0.3f, -0.3f), CVector(1.1f, 0.3f, 0.3f), SURFACE_DEFAULT, 0);
|
||||||
|
|
||||||
|
SET_COLMODEL_SPHERES(ms_colModelBodyPart1, s_aBodyPartSpheres1);
|
||||||
|
|
||||||
|
// Body Part Spheres 2
|
||||||
|
|
||||||
|
s_aBodyPartSpheres2[0].radius = 0.15f;
|
||||||
|
s_aBodyPartSpheres2[1].radius = 0.15f;
|
||||||
|
|
||||||
|
s_aBodyPartSpheres2[0].center = CVector(0.0f, 0.0f, 0.0f);
|
||||||
|
s_aBodyPartSpheres2[1].center = CVector(0.5f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aBodyPartSpheres2); i++) {
|
||||||
|
#else
|
||||||
|
for (i = 0; i < ARRAYSIZE(s_aBootSpheres); i++) {
|
||||||
|
#endif
|
||||||
|
s_aBodyPartSpheres2[i].surface = SURFACE_FLESH;
|
||||||
|
s_aBodyPartSpheres2[i].piece = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ms_colModelBodyPart2.boundingSphere.Set(0.5f, CVector(0.25f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
||||||
|
ms_colModelBodyPart2.boundingBox.Set(CVector(-0.2f, -0.2f, -0.2f), CVector(0.7f, 0.2f, 0.2f), SURFACE_DEFAULT, 0);
|
||||||
|
|
||||||
|
SET_COLMODEL_SPHERES(ms_colModelBodyPart2, s_aBodyPartSpheres2);
|
||||||
|
|
||||||
|
#undef SET_COLMODEL_SPHERES
|
||||||
|
}
|
||||||
|
|
||||||
|
STARTPATCHES
|
||||||
|
InjectHook(0x412160, CTempColModels::Initialise, PATCH_JUMP);
|
||||||
|
ENDPATCHES
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
|
#include "General.h"
|
||||||
#include "Streaming.h"
|
#include "Streaming.h"
|
||||||
#include "RwHelper.h"
|
#include "RwHelper.h"
|
||||||
#include "TxdStore.h"
|
#include "TxdStore.h"
|
||||||
@ -61,7 +62,7 @@ CTxdStore::FindTxdSlot(const char *name)
|
|||||||
int size = ms_pTxdPool->GetSize();
|
int size = ms_pTxdPool->GetSize();
|
||||||
for(int i = 0; i < size; i++){
|
for(int i = 0; i < size; i++){
|
||||||
defname = GetTxdName(i);
|
defname = GetTxdName(i);
|
||||||
if(defname && _strcmpi(defname, name) == 0)
|
if(defname && !CGeneral::faststricmp(defname, name))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -140,7 +140,7 @@ bool COnscreenTimerEntry::ProcessForDisplay() {
|
|||||||
|
|
||||||
if(m_nTimerOffset != 0) {
|
if(m_nTimerOffset != 0) {
|
||||||
m_bTimerProcessed = true;
|
m_bTimerProcessed = true;
|
||||||
ProcessForDisplayTimer();
|
ProcessForDisplayClock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_nCounterOffset != 0) {
|
if(m_nCounterOffset != 0) {
|
||||||
@ -150,21 +150,21 @@ bool COnscreenTimerEntry::ProcessForDisplay() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int COnscreenTimerEntry::ProcessForDisplayTimer() {
|
void COnscreenTimerEntry::ProcessForDisplayClock() {
|
||||||
uint32 time = *(uint32*)&CTheScripts::ScriptSpace[m_nTimerOffset];
|
uint32 time = *(uint32*)&CTheScripts::ScriptSpace[m_nTimerOffset];
|
||||||
return sprintf(m_bTimerBuffer, "%02d:%02d", time / 1000 / 60,
|
sprintf(m_bTimerBuffer, "%02d:%02d", time / 1000 / 60,
|
||||||
time / 1000 % 60);
|
time / 1000 % 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
int COnscreenTimerEntry::ProcessForDisplayCounter() {
|
void COnscreenTimerEntry::ProcessForDisplayCounter() {
|
||||||
uint32 counter = *(uint32*)&CTheScripts::ScriptSpace[m_nCounterOffset];
|
uint32 counter = *(uint32*)&CTheScripts::ScriptSpace[m_nCounterOffset];
|
||||||
return sprintf(m_bCounterBuffer, "%d", counter);
|
sprintf(m_bCounterBuffer, "%d", counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
STARTPATCHES
|
STARTPATCHES
|
||||||
InjectHook(0x429160, &COnscreenTimerEntry::Process, PATCH_JUMP);
|
InjectHook(0x429160, &COnscreenTimerEntry::Process, PATCH_JUMP);
|
||||||
InjectHook(0x429110, &COnscreenTimerEntry::ProcessForDisplay, PATCH_JUMP);
|
InjectHook(0x429110, &COnscreenTimerEntry::ProcessForDisplay, PATCH_JUMP);
|
||||||
InjectHook(0x429080, &COnscreenTimerEntry::ProcessForDisplayTimer, PATCH_JUMP);
|
InjectHook(0x429080, &COnscreenTimerEntry::ProcessForDisplayClock, PATCH_JUMP);
|
||||||
InjectHook(0x4290F0, &COnscreenTimerEntry::ProcessForDisplayCounter, PATCH_JUMP);
|
InjectHook(0x4290F0, &COnscreenTimerEntry::ProcessForDisplayCounter, PATCH_JUMP);
|
||||||
|
|
||||||
InjectHook(0x429220, &COnscreenTimer::Init, PATCH_JUMP);
|
InjectHook(0x429220, &COnscreenTimer::Init, PATCH_JUMP);
|
||||||
|
@ -18,8 +18,8 @@ public:
|
|||||||
void Process();
|
void Process();
|
||||||
bool ProcessForDisplay();
|
bool ProcessForDisplay();
|
||||||
|
|
||||||
int ProcessForDisplayTimer();
|
void ProcessForDisplayClock();
|
||||||
int ProcessForDisplayCounter();
|
void ProcessForDisplayCounter();
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(COnscreenTimerEntry) == 0x74, "COnscreenTimerEntry: error");
|
static_assert(sizeof(COnscreenTimerEntry) == 0x74, "COnscreenTimerEntry: error");
|
||||||
|
@ -859,8 +859,8 @@ FindPlayerPed(void)
|
|||||||
CVehicle*
|
CVehicle*
|
||||||
FindPlayerVehicle(void)
|
FindPlayerVehicle(void)
|
||||||
{
|
{
|
||||||
CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
|
CPlayerPed *ped = FindPlayerPed();
|
||||||
if(ped->bInVehicle && ped->m_pMyVehicle)
|
if(ped->InVehicle())
|
||||||
return ped->m_pMyVehicle;
|
return ped->m_pMyVehicle;
|
||||||
else
|
else
|
||||||
return nil;
|
return nil;
|
||||||
@ -878,8 +878,8 @@ FindPlayerTrain(void)
|
|||||||
CEntity*
|
CEntity*
|
||||||
FindPlayerEntity(void)
|
FindPlayerEntity(void)
|
||||||
{
|
{
|
||||||
CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
|
CPlayerPed *ped = FindPlayerPed();
|
||||||
if(ped->bInVehicle && ped->m_pMyVehicle)
|
if(ped->InVehicle())
|
||||||
return ped->m_pMyVehicle;
|
return ped->m_pMyVehicle;
|
||||||
else
|
else
|
||||||
return ped;
|
return ped;
|
||||||
@ -888,8 +888,8 @@ FindPlayerEntity(void)
|
|||||||
CVector
|
CVector
|
||||||
FindPlayerCoors(void)
|
FindPlayerCoors(void)
|
||||||
{
|
{
|
||||||
CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
|
CPlayerPed *ped = FindPlayerPed();
|
||||||
if(ped->bInVehicle && ped->m_pMyVehicle)
|
if(ped->InVehicle())
|
||||||
return ped->m_pMyVehicle->GetPosition();
|
return ped->m_pMyVehicle->GetPosition();
|
||||||
else
|
else
|
||||||
return ped->GetPosition();
|
return ped->GetPosition();
|
||||||
@ -898,8 +898,8 @@ FindPlayerCoors(void)
|
|||||||
CVector&
|
CVector&
|
||||||
FindPlayerSpeed(void)
|
FindPlayerSpeed(void)
|
||||||
{
|
{
|
||||||
CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
|
CPlayerPed *ped = FindPlayerPed();
|
||||||
if(ped->bInVehicle && ped->m_pMyVehicle)
|
if(ped->InVehicle())
|
||||||
return ped->m_pMyVehicle->m_vecMoveSpeed;
|
return ped->m_pMyVehicle->m_vecMoveSpeed;
|
||||||
else
|
else
|
||||||
return ped->m_vecMoveSpeed;
|
return ped->m_vecMoveSpeed;
|
||||||
@ -926,7 +926,7 @@ FindPlayerCentreOfWorld_NoSniperShift(void)
|
|||||||
return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition();
|
return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition();
|
||||||
if(FindPlayerVehicle())
|
if(FindPlayerVehicle())
|
||||||
return FindPlayerVehicle()->GetPosition();
|
return FindPlayerVehicle()->GetPosition();
|
||||||
return CWorld::Players[CWorld::PlayerInFocus].m_pPed->GetPosition();
|
return FindPlayerPed()->GetPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
@ -936,7 +936,7 @@ FindPlayerHeading(void)
|
|||||||
return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading();
|
return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading();
|
||||||
if(FindPlayerVehicle())
|
if(FindPlayerVehicle())
|
||||||
return FindPlayerVehicle()->GetForward().Heading();
|
return FindPlayerVehicle()->GetForward().Heading();
|
||||||
return CWorld::Players[CWorld::PlayerInFocus].m_pPed->GetForward().Heading();
|
return FindPlayerPed()->GetForward().Heading();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1011,6 +1011,30 @@ CWorld::StopAllLawEnforcersInTheirTracks(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CWorld::SetAllCarsCanBeDamaged(bool toggle)
|
||||||
|
{
|
||||||
|
int poolSize = CPools::GetVehiclePool()->GetSize();
|
||||||
|
for (int poolIndex = 0; poolIndex < poolSize; poolIndex++) {
|
||||||
|
CVehicle *veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
|
||||||
|
if (veh)
|
||||||
|
veh->bCanBeDamaged = toggle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CWorld::ExtinguishAllCarFiresInArea(CVector point, float range)
|
||||||
|
{
|
||||||
|
int poolSize = CPools::GetVehiclePool()->GetSize();
|
||||||
|
for (int poolIndex = 0; poolIndex < poolSize; poolIndex++) {
|
||||||
|
CVehicle* veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
|
||||||
|
if (veh) {
|
||||||
|
if ((point - veh->GetPosition()).MagnitudeSqr() < sq(range))
|
||||||
|
veh->ExtinguishCarFire();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CWorld::Process(void)
|
CWorld::Process(void)
|
||||||
{
|
{
|
||||||
@ -1212,5 +1236,9 @@ STARTPATCHES
|
|||||||
InjectHook(0x4B3AE0, CWorld::FindGroundZFor3DCoord, PATCH_JUMP);
|
InjectHook(0x4B3AE0, CWorld::FindGroundZFor3DCoord, PATCH_JUMP);
|
||||||
InjectHook(0x4B3B50, CWorld::FindRoofZFor3DCoord, PATCH_JUMP);
|
InjectHook(0x4B3B50, CWorld::FindRoofZFor3DCoord, PATCH_JUMP);
|
||||||
|
|
||||||
|
InjectHook(0x4B5BC0, CWorld::StopAllLawEnforcersInTheirTracks, PATCH_JUMP);
|
||||||
|
InjectHook(0x4B53F0, CWorld::SetAllCarsCanBeDamaged, PATCH_JUMP);
|
||||||
|
InjectHook(0x4B5460, CWorld::ExtinguishAllCarFiresInArea, PATCH_JUMP);
|
||||||
|
|
||||||
InjectHook(0x4B1A60, CWorld::Process, PATCH_JUMP);
|
InjectHook(0x4B1A60, CWorld::Process, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
||||||
|
@ -121,6 +121,8 @@ public:
|
|||||||
static void RemoveFallenCars();
|
static void RemoveFallenCars();
|
||||||
|
|
||||||
static void StopAllLawEnforcersInTheirTracks();
|
static void StopAllLawEnforcersInTheirTracks();
|
||||||
|
static void SetAllCarsCanBeDamaged(bool);
|
||||||
|
static void ExtinguishAllCarFiresInArea(CVector, float);
|
||||||
|
|
||||||
static void Initialise();
|
static void Initialise();
|
||||||
static void ShutDown();
|
static void ShutDown();
|
||||||
|
@ -153,6 +153,10 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if (defined(_MSC_VER))
|
||||||
|
extern int strcasecmp(const char *str1, const char *str2);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define clamp(v, low, high) ((v)<(low) ? (low) : (v)>(high) ? (high) : (v))
|
#define clamp(v, low, high) ((v)<(low) ? (low) : (v)>(high) ? (high) : (v))
|
||||||
|
|
||||||
inline float sq(float x) { return x*x; }
|
inline float sq(float x) { return x*x; }
|
||||||
|
@ -87,6 +87,7 @@ enum Config {
|
|||||||
NUM_FIRES = 40,
|
NUM_FIRES = 40,
|
||||||
|
|
||||||
NUMPEDROUTES = 200,
|
NUMPEDROUTES = 200,
|
||||||
|
NUMPHONES = 50,
|
||||||
|
|
||||||
NUMVISIBLEENTITIES = 2000,
|
NUMVISIBLEENTITIES = 2000,
|
||||||
NUMINVISIBLEENTITIES = 150,
|
NUMINVISIBLEENTITIES = 150,
|
||||||
@ -145,6 +146,7 @@ enum Config {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more
|
#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more
|
||||||
|
#define TOGGLEABLE_BETA_FEATURES // toggleable from debug menu. doesn't have too many things
|
||||||
|
|
||||||
// Pad
|
// Pad
|
||||||
#define KANGAROO_CHEAT
|
#define KANGAROO_CHEAT
|
||||||
|
@ -29,12 +29,10 @@ void **rwengine = *(void***)0x5A10E1;
|
|||||||
|
|
||||||
DebugMenuAPI gDebugMenuAPI;
|
DebugMenuAPI gDebugMenuAPI;
|
||||||
|
|
||||||
WRAPPER void *gtanew(uint32 sz) { EAXJMP(0x5A0690); }
|
STARTPATCHES
|
||||||
WRAPPER void gtadelete(void *p) { EAXJMP(0x5A07E0); }
|
InjectHook(0x5A07E0, (void (*)(void*)) &operator delete, PATCH_JUMP);
|
||||||
|
InjectHook(0x5A0690, (void* (*)(size_t)) &operator new, PATCH_JUMP);
|
||||||
// overload our own new/delete with GTA's functions
|
ENDPATCHES
|
||||||
void *operator new(size_t sz) { return gtanew(sz); }
|
|
||||||
void operator delete(void *ptr) noexcept { gtadelete(ptr); }
|
|
||||||
|
|
||||||
#ifdef USE_PS2_RAND
|
#ifdef USE_PS2_RAND
|
||||||
unsigned __int64 myrand_seed = 1;
|
unsigned __int64 myrand_seed = 1;
|
||||||
@ -351,10 +349,11 @@ DebugMenuPopulate(void)
|
|||||||
DebugMenuAddVarBool8("Debug", "Don't render Objects", (int8*)&gbDontRenderObjects, nil);
|
DebugMenuAddVarBool8("Debug", "Don't render Objects", (int8*)&gbDontRenderObjects, nil);
|
||||||
|
|
||||||
DebugMenuAddCmd("Debug", "Make peds follow you in formation", LetThemFollowYou);
|
DebugMenuAddCmd("Debug", "Make peds follow you in formation", LetThemFollowYou);
|
||||||
#ifndef MASTER
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
DebugMenuAddVarBool8("Debug", "Toggle unused fight feature", (int8*)&CPed::bUnusedFightThingOnPlayer, nil);
|
DebugMenuAddVarBool8("Debug", "Toggle unused fight feature", (int8*)&CPed::bUnusedFightThingOnPlayer, nil);
|
||||||
DebugMenuAddVarBool8("Debug", "Toggle banned particles", (int8*)&CParticle::bEnableBannedParticles, nil);
|
DebugMenuAddVarBool8("Debug", "Toggle banned particles", (int8*)&CParticle::bEnableBannedParticles, nil);
|
||||||
DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", (int8*)&CPed::bPopHeadsOnHeadshot, nil);
|
DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", (int8*)&CPed::bPopHeadsOnHeadshot, nil);
|
||||||
|
DebugMenuAddVarBool8("Debug", "Toggle peds running to phones to report crimes", (int8*)&CPed::bMakePedsRunToPhonesToReportCrimes, nil);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);
|
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);
|
||||||
|
@ -84,7 +84,7 @@ public:
|
|||||||
uint32 m_flagE2 : 1;
|
uint32 m_flagE2 : 1;
|
||||||
|
|
||||||
uint16 m_scanCode;
|
uint16 m_scanCode;
|
||||||
int16 m_randomSeed;
|
uint16 m_randomSeed;
|
||||||
int16 m_modelIndex;
|
int16 m_modelIndex;
|
||||||
uint16 m_level; // int16
|
uint16 m_level; // int16
|
||||||
CReference *m_pFirstReference;
|
CReference *m_pFirstReference;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "General.h"
|
||||||
#include "NodeName.h"
|
#include "NodeName.h"
|
||||||
#include "VisibilityPlugins.h"
|
#include "VisibilityPlugins.h"
|
||||||
#include "ModelInfo.h"
|
#include "ModelInfo.h"
|
||||||
@ -86,7 +87,7 @@ CClumpModelInfo::FindFrameFromNameCB(RwFrame *frame, void *data)
|
|||||||
{
|
{
|
||||||
RwObjectNameAssociation *assoc = (RwObjectNameAssociation*)data;
|
RwObjectNameAssociation *assoc = (RwObjectNameAssociation*)data;
|
||||||
|
|
||||||
if(_strcmpi(GetFrameNodeName(frame), assoc->name) != 0){
|
if(CGeneral::faststricmp(GetFrameNodeName(frame), assoc->name)){
|
||||||
RwFrameForAllChildren(frame, FindFrameFromNameCB, assoc);
|
RwFrameForAllChildren(frame, FindFrameFromNameCB, assoc);
|
||||||
return assoc->frame ? nil : frame;
|
return assoc->frame ? nil : frame;
|
||||||
}else{
|
}else{
|
||||||
@ -101,7 +102,7 @@ CClumpModelInfo::FindFrameFromNameWithoutIdCB(RwFrame *frame, void *data)
|
|||||||
RwObjectNameAssociation *assoc = (RwObjectNameAssociation*)data;
|
RwObjectNameAssociation *assoc = (RwObjectNameAssociation*)data;
|
||||||
|
|
||||||
if(CVisibilityPlugins::GetFrameHierarchyId(frame) ||
|
if(CVisibilityPlugins::GetFrameHierarchyId(frame) ||
|
||||||
_strcmpi(GetFrameNodeName(frame), assoc->name) != 0){
|
CGeneral::faststricmp(GetFrameNodeName(frame), assoc->name)){
|
||||||
RwFrameForAllChildren(frame, FindFrameFromNameWithoutIdCB, assoc);
|
RwFrameForAllChildren(frame, FindFrameFromNameWithoutIdCB, assoc);
|
||||||
return assoc->frame ? nil : frame;
|
return assoc->frame ? nil : frame;
|
||||||
}else{
|
}else{
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "General.h"
|
||||||
#include "ModelIndices.h"
|
#include "ModelIndices.h"
|
||||||
|
|
||||||
#define X(name, var, addr) int16 &var = *(int16*)addr;
|
#define X(name, var, addr) int16 &var = *(int16*)addr;
|
||||||
@ -18,7 +19,7 @@ void
|
|||||||
MatchModelString(const char *modelname, int16 id)
|
MatchModelString(const char *modelname, int16 id)
|
||||||
{
|
{
|
||||||
#define X(name, var, addr) \
|
#define X(name, var, addr) \
|
||||||
if(strcmp(name, modelname) == 0){ \
|
if(!CGeneral::faststrcmp(name, modelname)){ \
|
||||||
var = id; \
|
var = id; \
|
||||||
return; \
|
return; \
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "General.h"
|
||||||
#include "TempColModels.h"
|
#include "TempColModels.h"
|
||||||
#include "ModelIndices.h"
|
#include "ModelIndices.h"
|
||||||
#include "ModelInfo.h"
|
#include "ModelInfo.h"
|
||||||
@ -159,7 +160,7 @@ CModelInfo::GetModelInfo(const char *name, int *id)
|
|||||||
CBaseModelInfo *modelinfo;
|
CBaseModelInfo *modelinfo;
|
||||||
for(int i = 0; i < MODELINFOSIZE; i++){
|
for(int i = 0; i < MODELINFOSIZE; i++){
|
||||||
modelinfo = CModelInfo::ms_modelInfoPtrs[i];
|
modelinfo = CModelInfo::ms_modelInfoPtrs[i];
|
||||||
if(modelinfo && _strcmpi(modelinfo->GetName(), name) == 0){
|
if(modelinfo && !CGeneral::faststricmp(modelinfo->GetName(), name)){
|
||||||
if(id)
|
if(id)
|
||||||
*id = i;
|
*id = i;
|
||||||
return modelinfo;
|
return modelinfo;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "General.h"
|
||||||
#include "Ped.h"
|
#include "Ped.h"
|
||||||
#include "NodeName.h"
|
#include "NodeName.h"
|
||||||
#include "VisibilityPlugins.h"
|
#include "VisibilityPlugins.h"
|
||||||
@ -60,7 +61,7 @@ FindPedFrameFromNameCB(RwFrame *frame, void *data)
|
|||||||
{
|
{
|
||||||
RwObjectNameAssociation *assoc = (RwObjectNameAssociation*)data;
|
RwObjectNameAssociation *assoc = (RwObjectNameAssociation*)data;
|
||||||
|
|
||||||
if(_strcmpi(GetFrameNodeName(frame)+1, assoc->name+1) != 0){
|
if(CGeneral::faststricmp(GetFrameNodeName(frame)+1, assoc->name+1)){
|
||||||
RwFrameForAllChildren(frame, FindPedFrameFromNameCB, assoc);
|
RwFrameForAllChildren(frame, FindPedFrameFromNameCB, assoc);
|
||||||
return assoc->frame ? nil : frame;
|
return assoc->frame ? nil : frame;
|
||||||
}else{
|
}else{
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "General.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "ModelInfo.h"
|
#include "ModelInfo.h"
|
||||||
|
|
||||||
@ -131,7 +132,7 @@ CSimpleModelInfo::FindRelatedModel(void)
|
|||||||
for(i = 0; i < MODELINFOSIZE; i++){
|
for(i = 0; i < MODELINFOSIZE; i++){
|
||||||
mi = CModelInfo::GetModelInfo(i);
|
mi = CModelInfo::GetModelInfo(i);
|
||||||
if(mi && mi != this &&
|
if(mi && mi != this &&
|
||||||
strcmp(GetName()+3, mi->GetName()+3) == 0){
|
!CGeneral::faststrcmp(GetName()+3, mi->GetName()+3)){
|
||||||
assert(mi->IsSimple());
|
assert(mi->IsSimple());
|
||||||
this->SetRelatedModel((CSimpleModelInfo*)mi);
|
this->SetRelatedModel((CSimpleModelInfo*)mi);
|
||||||
return;
|
return;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "CutsceneMgr.h"
|
#include "CutsceneMgr.h"
|
||||||
#include "Streaming.h"
|
#include "Streaming.h"
|
||||||
#include "CutsceneHead.h"
|
#include "CutsceneHead.h"
|
||||||
|
#include "CdStream.h"
|
||||||
|
|
||||||
|
|
||||||
CCutsceneHead::CCutsceneHead(CObject *obj)
|
CCutsceneHead::CCutsceneHead(CObject *obj)
|
||||||
@ -94,7 +95,7 @@ CCutsceneHead::PlayAnimation(const char *animName)
|
|||||||
stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, "ANIM\\CUTS.IMG");
|
stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, "ANIM\\CUTS.IMG");
|
||||||
assert(stream);
|
assert(stream);
|
||||||
|
|
||||||
CStreaming::MakeSpaceFor(size*2048);
|
CStreaming::MakeSpaceFor(size * CDSTREAM_SECTOR_SIZE);
|
||||||
CStreaming::ImGonnaUseStreamingMemory();
|
CStreaming::ImGonnaUseStreamingMemory();
|
||||||
|
|
||||||
RwStreamSkip(stream, offset*2048);
|
RwStreamSkip(stream, offset*2048);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
|
|
||||||
|
|
||||||
CParticleObject (&gPObjectArray)[MAX_PARTICLEOBJECTS] = *(CParticleObject(*)[MAX_PARTICLEOBJECTS])int(0x62A58C);
|
CParticleObject (&gPObjectArray)[MAX_PARTICLEOBJECTS] = *(CParticleObject(*)[MAX_PARTICLEOBJECTS])*(uintptr*)0x62A58C;
|
||||||
|
|
||||||
CParticleObject *&CParticleObject::pCloseListHead = *(CParticleObject **)int(0x8F4340);
|
CParticleObject *&CParticleObject::pCloseListHead = *(CParticleObject **)int(0x8F4340);
|
||||||
CParticleObject *&CParticleObject::pFarListHead = *(CParticleObject **)int(0x942F78);
|
CParticleObject *&CParticleObject::pFarListHead = *(CParticleObject **)int(0x942F78);
|
||||||
|
@ -2,25 +2,415 @@
|
|||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "CivilianPed.h"
|
#include "CivilianPed.h"
|
||||||
#include "Phones.h"
|
#include "Phones.h"
|
||||||
|
#include "General.h"
|
||||||
WRAPPER void CCivilianPed::ProcessControl(void) { EAXJMP(0x4BFFE0); }
|
#include "PlayerPed.h"
|
||||||
|
#include "World.h"
|
||||||
|
#include "Vehicle.h"
|
||||||
|
#include "SurfaceTable.h"
|
||||||
|
|
||||||
CCivilianPed::CCivilianPed(int pedtype, int mi) : CPed(pedtype)
|
CCivilianPed::CCivilianPed(int pedtype, int mi) : CPed(pedtype)
|
||||||
{
|
{
|
||||||
SetModelIndex(mi);
|
SetModelIndex(mi);
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < ARRAY_SIZE(m_nearPeds); i++) {
|
||||||
m_nearPeds[i] = nil;
|
m_nearPeds[i] = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CCivilianPed::CivilianAI(void)
|
||||||
|
{
|
||||||
|
if (CTimer::GetTimeInMilliseconds() <= m_fleeTimer || m_objective != OBJECTIVE_NONE && !bRespondsToThreats
|
||||||
|
|| !IsPedInControl()) {
|
||||||
|
|
||||||
|
if (m_objective == OBJECTIVE_GUARD_SPOT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS) {
|
||||||
|
if (m_pedInObjective) {
|
||||||
|
if (m_pedInObjective->IsPlayer())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (CTimer::GetTimeInMilliseconds() <= m_lookTimer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32 closestThreatFlag = ScanForThreats();
|
||||||
|
if (closestThreatFlag == PED_FLAG_EXPLOSION) {
|
||||||
|
float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
|
||||||
|
m_eventOrThreat.x, m_eventOrThreat.y,
|
||||||
|
GetPosition().x, GetPosition().y);
|
||||||
|
SetLookFlag(angleToFace, true);
|
||||||
|
SetLookTimer(500);
|
||||||
|
|
||||||
|
} else if (closestThreatFlag == PED_FLAG_GUN) {
|
||||||
|
SetLookFlag(m_threatEntity, true);
|
||||||
|
SetLookTimer(500);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint32 closestThreatFlag = ScanForThreats();
|
||||||
|
if (closestThreatFlag == PED_FLAG_GUN) {
|
||||||
|
if (!m_threatEntity || !m_threatEntity->IsPed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CPed *threatPed = (CPed*)m_threatEntity;
|
||||||
|
float threatDistSqr = (m_threatEntity->GetPosition() - GetPosition()).MagnitudeSqr2D();
|
||||||
|
if (m_pedStats->m_fear <= m_pedStats->m_lawfulness) {
|
||||||
|
if (m_pedStats->m_temper <= m_pedStats->m_fear) {
|
||||||
|
if (!threatPed->IsPlayer() || !RunToReportCrime(CRIME_POSSESSION_GUN)) {
|
||||||
|
if (threatDistSqr < sq(10.0f)) {
|
||||||
|
Say(SOUND_PED_FLEE_SPRINT);
|
||||||
|
SetFlee(m_threatEntity, 10000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
} else {
|
||||||
|
SetFlee(m_threatEntity->GetPosition(), 5000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
SetMoveState(PEDMOVE_WALK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (m_objective != OBJECTIVE_NONE || GetWeapon()->IsTypeMelee()) {
|
||||||
|
SetFlee(m_threatEntity, 5000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
if (threatDistSqr < sq(20.0f)) {
|
||||||
|
SetMoveState(PEDMOVE_RUN);
|
||||||
|
Say(SOUND_PED_FLEE_SPRINT);
|
||||||
|
} else {
|
||||||
|
SetMoveState(PEDMOVE_WALK);
|
||||||
|
}
|
||||||
|
} else if (threatPed->IsPlayer() && FindPlayerPed()->m_pWanted->m_CurrentCops) {
|
||||||
|
SetFlee(m_threatEntity, 5000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
if (threatDistSqr < sq(10.0f)) {
|
||||||
|
SetMoveState(PEDMOVE_RUN);
|
||||||
|
} else {
|
||||||
|
SetMoveState(PEDMOVE_WALK);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (threatDistSqr < sq(10.0f)) {
|
||||||
|
Say(SOUND_PED_FLEE_SPRINT);
|
||||||
|
SetFlee(m_threatEntity, 10000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
SetMoveState(PEDMOVE_SPRINT);
|
||||||
|
} else {
|
||||||
|
Say(SOUND_PED_FLEE_SPRINT);
|
||||||
|
SetFlee(m_threatEntity, 5000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
SetMoveState(PEDMOVE_RUN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetLookFlag(m_threatEntity, false);
|
||||||
|
SetLookTimer(500);
|
||||||
|
} else if (closestThreatFlag == PED_FLAG_DEADPEDS) {
|
||||||
|
float eventDistSqr = (m_pEventEntity->GetPosition() - GetPosition()).MagnitudeSqr2D();
|
||||||
|
if (IsGangMember() && m_nPedType == ((CPed*)m_pEventEntity)->m_nPedType) {
|
||||||
|
if (eventDistSqr < sq(5.0f)) {
|
||||||
|
SetFlee(m_pEventEntity, 2000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
SetMoveState(PEDMOVE_RUN);
|
||||||
|
}
|
||||||
|
} else if (IsGangMember() || eventDistSqr > sq(5.0f)) {
|
||||||
|
bool investigateDeadPed = true;
|
||||||
|
CEntity *killerOfDeadPed = ((CPed*)m_pEventEntity)->m_threatEntity;
|
||||||
|
if (killerOfDeadPed && killerOfDeadPed->IsPed()) {
|
||||||
|
CVector killerPos = killerOfDeadPed->GetPosition();
|
||||||
|
CVector deadPedPos = m_pEventEntity->GetPosition();
|
||||||
|
if (CVector2D(killerPos - deadPedPos).MagnitudeSqr() < sq(10.0f))
|
||||||
|
investigateDeadPed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
|
eCrimeType crime = (((CPed*)m_pEventEntity)->m_ped_flagI40 ?
|
||||||
|
(((CPed*)m_pEventEntity)->m_nPedType == PEDTYPE_COP ? CRIME_RUNOVER_COP : CRIME_RUNOVER_PED) :
|
||||||
|
(((CPed*)m_pEventEntity)->m_nPedType == PEDTYPE_COP ? CRIME_SHOOT_COP : CRIME_SHOOT_PED));
|
||||||
|
bool eligibleToReport = bMakePedsRunToPhonesToReportCrimes && killerOfDeadPed && killerOfDeadPed->IsPed() && ((CPed*)killerOfDeadPed)->IsPlayer() &&
|
||||||
|
m_pedStats->m_fear <= m_pedStats->m_lawfulness && m_pedStats->m_temper <= m_pedStats->m_fear;
|
||||||
|
if (IsGangMember() || !eligibleToReport || !RunToReportCrime(crime))
|
||||||
|
#endif
|
||||||
|
if (investigateDeadPed)
|
||||||
|
SetInvestigateEvent(EVENT_DEAD_PED, CVector2D(m_pEventEntity->GetPosition()), 1.0f, 20000, 0.0f);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
|
CEntity* killerOfDeadPed = ((CPed*)m_pEventEntity)->m_threatEntity;
|
||||||
|
eCrimeType crime = (((CPed*)m_pEventEntity)->m_ped_flagI40 ?
|
||||||
|
(((CPed*)m_pEventEntity)->m_nPedType == PEDTYPE_COP ? CRIME_RUNOVER_COP : CRIME_RUNOVER_PED) :
|
||||||
|
(((CPed*)m_pEventEntity)->m_nPedType == PEDTYPE_COP ? CRIME_SHOOT_COP : CRIME_SHOOT_PED));
|
||||||
|
bool eligibleToReport = bMakePedsRunToPhonesToReportCrimes && killerOfDeadPed && killerOfDeadPed->IsPed() && ((CPed*)killerOfDeadPed)->IsPlayer() &&
|
||||||
|
m_pedStats->m_fear <= m_pedStats->m_lawfulness && m_pedStats->m_temper <= m_pedStats->m_fear;
|
||||||
|
if(!eligibleToReport || !RunToReportCrime(crime))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
SetFlee(m_pEventEntity, 5000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
SetMoveState(PEDMOVE_RUN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (closestThreatFlag == PED_FLAG_EXPLOSION) {
|
||||||
|
CVector2D eventDistVec = m_eventOrThreat - GetPosition();
|
||||||
|
float eventDistSqr = eventDistVec.MagnitudeSqr();
|
||||||
|
if (eventDistSqr < sq(20.0f)) {
|
||||||
|
Say(SOUND_PED_FLEE_SPRINT);
|
||||||
|
SetFlee(m_eventOrThreat, 2000);
|
||||||
|
float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
|
||||||
|
m_eventOrThreat.x, m_eventOrThreat.y,
|
||||||
|
GetPosition().x, GetPosition().y);
|
||||||
|
SetLookFlag(angleToFace, true);
|
||||||
|
SetLookTimer(500);
|
||||||
|
} else if (eventDistSqr < sq(40.0f)) {
|
||||||
|
if (m_ped_flagD2) {
|
||||||
|
if (CharCreatedBy != MISSION_CHAR && !IsGangMember())
|
||||||
|
SetInvestigateEvent(EVENT_EXPLOSION, m_eventOrThreat, 6.0f, 30000, 0.0f);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
float eventHeading = CGeneral::GetRadianAngleBetweenPoints(eventDistVec.x, eventDistVec.y, 0.0f, 0.0f);
|
||||||
|
eventHeading = CGeneral::LimitRadianAngle(eventHeading);
|
||||||
|
if (eventHeading < 0.0f)
|
||||||
|
eventHeading = eventHeading + TWOPI;
|
||||||
|
|
||||||
|
SetWanderPath(eventHeading / 8.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (m_threatEntity && m_threatEntity->IsPed()) {
|
||||||
|
CPed *threatPed = (CPed*)m_threatEntity;
|
||||||
|
if (m_pedStats->m_fear <= 100 - threatPed->m_pedStats->m_temper && threatPed->m_nPedType != PEDTYPE_COP) {
|
||||||
|
if (threatPed->GetWeapon()->IsTypeMelee() || !GetWeapon()->IsTypeMelee()) {
|
||||||
|
if (threatPed->IsPlayer() && FindPlayerPed()->m_pWanted->m_CurrentCops) {
|
||||||
|
if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS) {
|
||||||
|
SetFlee(m_threatEntity, 10000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SetFlee(m_threatEntity, 10000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
SetMoveState(PEDMOVE_WALK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CCivilianPed::ProcessControl(void)
|
||||||
|
{
|
||||||
|
if (m_nZoneLevel > LEVEL_NONE && m_nZoneLevel != CCollision::ms_collisionInMemory)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CPed::ProcessControl();
|
||||||
|
|
||||||
|
if (bWasPostponed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (DyingOrDead())
|
||||||
|
return;
|
||||||
|
|
||||||
|
GetWeapon()->Update(m_audioEntityId);
|
||||||
|
switch (m_nPedState) {
|
||||||
|
case PED_WANDER_RANGE:
|
||||||
|
case PED_WANDER_PATH:
|
||||||
|
if (IsVisible())
|
||||||
|
ScanForInterestingStuff();
|
||||||
|
break;
|
||||||
|
case PED_SEEK_ENTITY:
|
||||||
|
if (!m_pSeekTarget) {
|
||||||
|
RestorePreviousState();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_vecSeekPos = m_pSeekTarget->GetPosition();
|
||||||
|
|
||||||
|
// fall through
|
||||||
|
case PED_SEEK_POS:
|
||||||
|
if (Seek()) {
|
||||||
|
if ((m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA) && m_pNextPathNode) {
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
|
} else if (bRunningToPhone && m_objective < OBJECTIVE_FLEE_TILL_SAFE) {
|
||||||
|
if (!isPhoneAvailable(m_phoneId)) {
|
||||||
|
RestorePreviousState();
|
||||||
|
crimeReporters[m_phoneId] = nil;
|
||||||
|
m_phoneId = -1;
|
||||||
|
bRunningToPhone = false;
|
||||||
|
} else {
|
||||||
|
crimeReporters[m_phoneId] = this;
|
||||||
|
m_nPedState = PED_FACE_PHONE;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
} else if (bRunningToPhone) {
|
||||||
|
if (gPhoneInfo.m_aPhones[m_phoneId].m_nState != PHONE_STATE_FREE) {
|
||||||
|
RestorePreviousState();
|
||||||
|
m_phoneId = -1;
|
||||||
|
} else {
|
||||||
|
gPhoneInfo.m_aPhones[m_phoneId].m_nState = PHONE_STATE_REPORTING_CRIME;
|
||||||
|
m_nPedState = PED_FACE_PHONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else if (m_objective != OBJECTIVE_KILL_CHAR_ANY_MEANS && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) {
|
||||||
|
if (m_objective == OBJECTIVE_FOLLOW_PED_IN_FORMATION) {
|
||||||
|
if (m_moved.Magnitude() == 0.0f) {
|
||||||
|
if (m_pedInObjective->m_nMoveState == PEDMOVE_STILL)
|
||||||
|
m_fRotationDest = m_pedInObjective->m_fRotationCur;
|
||||||
|
}
|
||||||
|
} else if (m_objective == OBJECTIVE_GOTO_CHAR_ON_FOOT
|
||||||
|
&& m_pedInObjective && m_pedInObjective->m_nMoveState != PEDMOVE_STILL) {
|
||||||
|
SetMoveState(m_pedInObjective->m_nMoveState);
|
||||||
|
} else if (m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA) {
|
||||||
|
SetIdle();
|
||||||
|
} else {
|
||||||
|
RestorePreviousState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PED_FACE_PHONE:
|
||||||
|
if (FacePhone())
|
||||||
|
m_nPedState = PED_MAKE_CALL;
|
||||||
|
break;
|
||||||
|
case PED_MAKE_CALL:
|
||||||
|
if (MakePhonecall())
|
||||||
|
SetWanderPath(CGeneral::GetRandomNumber() & 7);
|
||||||
|
break;
|
||||||
|
case PED_MUG:
|
||||||
|
Mug();
|
||||||
|
break;
|
||||||
|
case PED_SOLICIT:
|
||||||
|
Solicit();
|
||||||
|
break;
|
||||||
|
case PED_UNKNOWN:
|
||||||
|
{
|
||||||
|
int pedsInSameState = 0;
|
||||||
|
Idle();
|
||||||
|
for (int i = 0; i < m_numNearPeds; ++i) {
|
||||||
|
CPed *nearPed = m_nearPeds[i];
|
||||||
|
if (nearPed->m_nPedType == m_nPedType && nearPed->m_nPedState == PED_UNKNOWN) {
|
||||||
|
++pedsInSameState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pedsInSameState < 5) {
|
||||||
|
for (int j = 0; j < m_numNearPeds; ++j) {
|
||||||
|
CPed *nearPed = m_nearPeds[j];
|
||||||
|
if (nearPed->m_nPedType == m_nPedType && nearPed->m_nPedState == PED_WANDER_PATH) {
|
||||||
|
nearPed->m_nPedState = PED_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PED_DRIVING:
|
||||||
|
if (m_nPedType != PEDTYPE_PROSTITUTE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (CWorld::Players[CWorld::PlayerInFocus].m_pHooker != this)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime) {
|
||||||
|
if (m_nPedState == PED_DRIVING
|
||||||
|
&& m_pMyVehicle->pDriver && m_pMyVehicle->pDriver->IsPlayer() && m_pMyVehicle->pDriver->m_nPedState == PED_DRIVING) {
|
||||||
|
CColPoint foundCol;
|
||||||
|
CEntity* foundEnt;
|
||||||
|
|
||||||
|
CWorld::ProcessVerticalLine(m_pMyVehicle->GetPosition(), -100.0f,
|
||||||
|
foundCol, foundEnt, true, false, false, false, false, false, nil);
|
||||||
|
|
||||||
|
if (m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr() < sq(0.01f)
|
||||||
|
&& foundCol.surfaceB != SURFACE_DEFAULT && foundCol.surfaceB != SURFACE_TARMAC && foundCol.surfaceB != SURFACE_PAVEMENT) {
|
||||||
|
|
||||||
|
if (m_pMyVehicle->CarHasRoof()) {
|
||||||
|
m_pMyVehicle->ApplyTurnForce(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(-0.8f, -1.2f) * m_fMass,
|
||||||
|
GetPosition().x - m_pMyVehicle->GetPosition().x, GetPosition().y - m_pMyVehicle->GetPosition().y, 0.0f);
|
||||||
|
|
||||||
|
DMAudio.PlayOneShot(m_pMyVehicle->m_audioEntityId, SOUND_CAR_JERK, 0.0f);
|
||||||
|
|
||||||
|
int playerSexFrequency = CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency;
|
||||||
|
if (CWorld::Players[CWorld::PlayerInFocus].m_nMoney >= 10 && playerSexFrequency > 250) {
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + playerSexFrequency;
|
||||||
|
if (playerSexFrequency >= 350) {
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = max(250, playerSexFrequency - 30);
|
||||||
|
} else {
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = max(250, playerSexFrequency - 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pMyVehicle->pDriver->m_fHealth = min(125.0f, 1.0f + m_pMyVehicle->pDriver->m_fHealth);
|
||||||
|
if (CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency == 250)
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000;
|
||||||
|
} else {
|
||||||
|
bWanderPathAfterExitingCar = true;
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
|
||||||
|
SetObjective(OBJECTIVE_LEAVE_VEHICLE, m_pMyVehicle);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bWanderPathAfterExitingCar = true;
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
|
||||||
|
m_pMyVehicle->pDriver->m_fHealth = 125.0f;
|
||||||
|
SetObjective(OBJECTIVE_LEAVE_VEHICLE, m_pMyVehicle);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000;
|
||||||
|
int playerSexFrequency = CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency;
|
||||||
|
if (playerSexFrequency >= 1000 || playerSexFrequency <= 250)
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = 1200;
|
||||||
|
else
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = 250;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bWanderPathAfterExitingCar = true;
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
|
||||||
|
SetObjective(OBJECTIVE_LEAVE_VEHICLE, m_pMyVehicle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nNextSexMoneyUpdateTime) {
|
||||||
|
int playerMoney = CWorld::Players[CWorld::PlayerInFocus].m_nMoney;
|
||||||
|
if (playerMoney <= 1) {
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = 250;
|
||||||
|
} else {
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nMoney = max(0, playerMoney - 1);
|
||||||
|
}
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexMoneyUpdateTime = CTimer::GetTimeInMilliseconds() + 1000;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (IsPedInControl())
|
||||||
|
CivilianAI();
|
||||||
|
|
||||||
|
if (CTimer::GetTimeInMilliseconds() > m_timerUnused) {
|
||||||
|
m_stateUnused = 0;
|
||||||
|
m_timerUnused = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_moved.Magnitude() > 0.0f)
|
||||||
|
Avoid();
|
||||||
|
}
|
||||||
|
|
||||||
class CCivilianPed_ : public CCivilianPed
|
class CCivilianPed_ : public CCivilianPed
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CCivilianPed *ctor(int pedtype, int mi) { return ::new (this) CCivilianPed(pedtype, mi); };
|
CCivilianPed *ctor(int pedtype, int mi) { return ::new (this) CCivilianPed(pedtype, mi); };
|
||||||
void dtor(void) { CCivilianPed::~CCivilianPed(); }
|
void dtor(void) { CCivilianPed::~CCivilianPed(); }
|
||||||
|
void ProcessControl_(void) { CCivilianPed::ProcessControl(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
STARTPATCHES
|
STARTPATCHES
|
||||||
InjectHook(0x4BFF30, &CCivilianPed_::ctor, PATCH_JUMP);
|
InjectHook(0x4BFF30, &CCivilianPed_::ctor, PATCH_JUMP);
|
||||||
InjectHook(0x4BFFC0, &CCivilianPed_::dtor, PATCH_JUMP);
|
InjectHook(0x4BFFC0, &CCivilianPed_::dtor, PATCH_JUMP);
|
||||||
|
InjectHook(0x4BFFE0, &CCivilianPed_::ProcessControl_, PATCH_JUMP);
|
||||||
|
|
||||||
|
InjectHook(0x4C07A0, &CCivilianPed::CivilianAI, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
||||||
|
@ -8,6 +8,7 @@ public:
|
|||||||
CCivilianPed(int, int);
|
CCivilianPed(int, int);
|
||||||
~CCivilianPed(void) { }
|
~CCivilianPed(void) { }
|
||||||
|
|
||||||
|
void CivilianAI(void);
|
||||||
void ProcessControl(void);
|
void ProcessControl(void);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CCivilianPed) == 0x53C, "CCivilianPed: error");
|
static_assert(sizeof(CCivilianPed) == 0x53C, "CCivilianPed: error");
|
||||||
|
@ -2,37 +2,428 @@
|
|||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "EmergencyPed.h"
|
#include "EmergencyPed.h"
|
||||||
#include "ModelIndices.h"
|
#include "ModelIndices.h"
|
||||||
|
#include "Vehicle.h"
|
||||||
class CEmergencyPed_ : public CEmergencyPed
|
#include "Fire.h"
|
||||||
{
|
#include "General.h"
|
||||||
public:
|
#include "CarCtrl.h"
|
||||||
CEmergencyPed *ctor(int pedtype) { return ::new (this) CEmergencyPed(pedtype); };
|
#include "AccidentManager.h"
|
||||||
void dtor(void) { CEmergencyPed::~CEmergencyPed(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
WRAPPER void CEmergencyPed::ProcessControl(void) { EAXJMP(0x4C2F10); }
|
|
||||||
|
|
||||||
CEmergencyPed::CEmergencyPed(uint32 type) : CPed(type)
|
CEmergencyPed::CEmergencyPed(uint32 type) : CPed(type)
|
||||||
{
|
{
|
||||||
switch (type){
|
switch (type){
|
||||||
case PEDTYPE_EMERGENCY:
|
case PEDTYPE_EMERGENCY:
|
||||||
SetModelIndex(MI_MEDIC);
|
SetModelIndex(MI_MEDIC);
|
||||||
m_pRevivedPed = nil;
|
m_pRevivedPed = nil;
|
||||||
field_1360 = 0;
|
field_1360 = 0;
|
||||||
break;
|
break;
|
||||||
case PEDTYPE_FIREMAN:
|
case PEDTYPE_FIREMAN:
|
||||||
SetModelIndex(MI_FIREMAN);
|
SetModelIndex(MI_FIREMAN);
|
||||||
m_pRevivedPed = nil;
|
m_pRevivedPed = nil;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_nEmergencyPedState = 0;
|
m_nEmergencyPedState = EMERGENCY_PED_READY;
|
||||||
m_pAttendedAccident = nil;
|
m_pAttendedAccident = nil;
|
||||||
field_1356 = 0;
|
m_bStartedToCPR = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CEmergencyPed::InRange(CPed *victim)
|
||||||
|
{
|
||||||
|
if (!m_pMyVehicle)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ((m_pMyVehicle->GetPosition() - victim->GetPosition()).Magnitude() > 30.0f)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CEmergencyPed::ProcessControl(void)
|
||||||
|
{
|
||||||
|
if (m_nZoneLevel > LEVEL_NONE && m_nZoneLevel != CCollision::ms_collisionInMemory)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CPed::ProcessControl();
|
||||||
|
if (bWasPostponed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!DyingOrDead()) {
|
||||||
|
GetWeapon()->Update(m_audioEntityId);
|
||||||
|
|
||||||
|
if (IsPedInControl() && m_moved.Magnitude() > 0.0f)
|
||||||
|
Avoid();
|
||||||
|
|
||||||
|
switch (m_nPedState) {
|
||||||
|
case PED_SEEK_POS:
|
||||||
|
Seek();
|
||||||
|
break;
|
||||||
|
case PED_SEEK_ENTITY:
|
||||||
|
if (m_pSeekTarget) {
|
||||||
|
m_vecSeekPos = m_pSeekTarget->GetPosition();
|
||||||
|
Seek();
|
||||||
|
} else {
|
||||||
|
ClearSeek();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (m_nPedType) {
|
||||||
|
case PEDTYPE_EMERGENCY:
|
||||||
|
if (IsPedInControl() || m_nPedState == PED_DRIVING)
|
||||||
|
MedicAI();
|
||||||
|
break;
|
||||||
|
case PEDTYPE_FIREMAN:
|
||||||
|
if (IsPedInControl())
|
||||||
|
FiremanAI();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function was buggy and incomplete in both III and VC, firemen had to be in 5.0m range of fire etc. etc.
|
||||||
|
// Copied some code from MedicAI to make it work.
|
||||||
|
void
|
||||||
|
CEmergencyPed::FiremanAI(void)
|
||||||
|
{
|
||||||
|
float fireDist;
|
||||||
|
CFire *nearestFire;
|
||||||
|
|
||||||
|
switch (m_nEmergencyPedState) {
|
||||||
|
case EMERGENCY_PED_READY:
|
||||||
|
nearestFire = gFireManager.FindNearestFire(GetPosition(), &fireDist);
|
||||||
|
if (nearestFire) {
|
||||||
|
m_nPedState = PED_NONE;
|
||||||
|
SetSeek(nearestFire->m_vecPos, 1.0f);
|
||||||
|
SetMoveState(PEDMOVE_RUN);
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE;
|
||||||
|
m_pAttendedFire = nearestFire;
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
bIsRunning = true;
|
||||||
|
++nearestFire->m_nFiremenPuttingOut;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EMERGENCY_PED_DETERMINE_NEXT_STATE:
|
||||||
|
nearestFire = gFireManager.FindNearestFire(GetPosition(), &fireDist);
|
||||||
|
if (nearestFire && nearestFire != m_pAttendedFire) {
|
||||||
|
m_nPedState = PED_NONE;
|
||||||
|
SetSeek(nearestFire->m_vecPos, 1.0f);
|
||||||
|
SetMoveState(PEDMOVE_RUN);
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
bIsRunning = true;
|
||||||
|
if (m_pAttendedFire) {
|
||||||
|
--m_pAttendedFire->m_nFiremenPuttingOut;
|
||||||
|
}
|
||||||
|
++nearestFire->m_nFiremenPuttingOut;
|
||||||
|
m_pAttendedFire = nearestFire;
|
||||||
|
} else if (!nearestFire) {
|
||||||
|
#else
|
||||||
|
m_pAttendedFire = nearestFire;
|
||||||
|
} else {
|
||||||
|
#endif
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Extinguish" the fire (Will overwrite the stop decision above if the attended and nearest fires are same)
|
||||||
|
if (fireDist < 5.0f) {
|
||||||
|
SetIdle();
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_STAND_STILL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EMERGENCY_PED_STAND_STILL:
|
||||||
|
if (!m_pAttendedFire->m_bIsOngoing)
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_STOP;
|
||||||
|
|
||||||
|
// Leftover
|
||||||
|
// fireDist = 30.0f;
|
||||||
|
nearestFire = gFireManager.FindNearestFire(GetPosition(), &fireDist);
|
||||||
|
if (nearestFire) {
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
if(nearestFire != m_pAttendedFire && (nearestFire->m_vecPos - GetPosition()).Magnitude() < 30.0f)
|
||||||
|
#endif
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE;
|
||||||
|
}
|
||||||
|
Say(SOUND_PED_EXTINGUISHING_FIRE);
|
||||||
|
break;
|
||||||
|
case EMERGENCY_PED_STOP:
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
bIsRunning = false;
|
||||||
|
if (m_pAttendedFire)
|
||||||
|
#endif
|
||||||
|
--m_pAttendedFire->m_nFiremenPuttingOut;
|
||||||
|
|
||||||
|
m_nPedState = PED_NONE;
|
||||||
|
SetWanderPath(CGeneral::GetRandomNumber() & 7);
|
||||||
|
m_pAttendedFire = nil;
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_READY;
|
||||||
|
SetMoveState(PEDMOVE_WALK);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CEmergencyPed::MedicAI(void)
|
||||||
|
{
|
||||||
|
float distToEmergency;
|
||||||
|
if (!bInVehicle && IsPedInControl()) {
|
||||||
|
ScanForThreats();
|
||||||
|
if (m_threatEntity && m_threatEntity->IsPed() && ((CPed*)m_threatEntity)->IsPlayer()) {
|
||||||
|
if (((CPed*)m_threatEntity)->GetWeapon()->IsTypeMelee()) {
|
||||||
|
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
|
||||||
|
} else {
|
||||||
|
SetFlee(m_threatEntity, 6000);
|
||||||
|
Say(SOUND_PED_FLEE_SPRINT);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InVehicle()) {
|
||||||
|
if (m_pMyVehicle->IsCar() && m_objective != OBJECTIVE_LEAVE_VEHICLE) {
|
||||||
|
if (gAccidentManager.FindNearestAccident(m_pMyVehicle->GetPosition(), &distToEmergency)
|
||||||
|
&& distToEmergency < 25.0f && m_pMyVehicle->m_vecMoveSpeed.Magnitude() < 0.01f) {
|
||||||
|
|
||||||
|
m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
SetObjective(OBJECTIVE_LEAVE_VEHICLE, m_pMyVehicle);
|
||||||
|
Say(SOUND_PED_LEAVE_VEHICLE);
|
||||||
|
} else if (m_pMyVehicle->pDriver == this && m_nPedState == PED_DRIVING
|
||||||
|
&& m_pMyVehicle->AutoPilot.m_nCarMission == MISSION_NONE && !(CGeneral::GetRandomNumber() & 31)) {
|
||||||
|
|
||||||
|
bool waitUntilMedicEntersCar = false;
|
||||||
|
for (int i = 0; i < m_numNearPeds; ++i) {
|
||||||
|
CPed *nearPed = m_nearPeds[i];
|
||||||
|
if (nearPed->m_nPedType == PEDTYPE_EMERGENCY) {
|
||||||
|
if ((nearPed->m_nPedState == PED_SEEK_CAR || nearPed->m_nPedState == PED_ENTER_CAR)
|
||||||
|
&& nearPed->m_pMyVehicle == m_pMyVehicle) {
|
||||||
|
waitUntilMedicEntersCar = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!waitUntilMedicEntersCar) {
|
||||||
|
CCarCtrl::JoinCarWithRoadSystem(m_pMyVehicle);
|
||||||
|
m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
|
||||||
|
m_pMyVehicle->m_bSirenOrAlarm = 0;
|
||||||
|
m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 12;
|
||||||
|
m_pMyVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_SLOW_DOWN_FOR_CARS;
|
||||||
|
if (m_pMyVehicle->bIsAmbulanceOnDuty) {
|
||||||
|
m_pMyVehicle->bIsAmbulanceOnDuty = false;
|
||||||
|
--CCarCtrl::NumAmbulancesOnDuty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CVector headPos, midPos;
|
||||||
|
CAccident *nearestAccident;
|
||||||
|
if (IsPedInControl()) {
|
||||||
|
switch (m_nEmergencyPedState) {
|
||||||
|
case EMERGENCY_PED_READY:
|
||||||
|
nearestAccident = gAccidentManager.FindNearestAccident(GetPosition(), &distToEmergency);
|
||||||
|
field_1360 = 0;
|
||||||
|
if (nearestAccident) {
|
||||||
|
m_pRevivedPed = nearestAccident->m_pVictim;
|
||||||
|
m_pRevivedPed->RegisterReference((CEntity**)&m_pRevivedPed);
|
||||||
|
m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&midPos, PED_MID);
|
||||||
|
m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&headPos, PED_HEAD);
|
||||||
|
SetSeek((headPos + midPos) * 0.5f, 1.0f);
|
||||||
|
SetObjective(OBJECTIVE_NONE);
|
||||||
|
bIsRunning = true;
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE;
|
||||||
|
m_pAttendedAccident = nearestAccident;
|
||||||
|
++m_pAttendedAccident->m_nMedicsAttending;
|
||||||
|
} else {
|
||||||
|
if (m_pMyVehicle) {
|
||||||
|
if (!bInVehicle) {
|
||||||
|
if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || m_pMyVehicle->pDriver || m_pMyVehicle->m_nGettingInFlags) {
|
||||||
|
|
||||||
|
CPed* driver = m_pMyVehicle->pDriver;
|
||||||
|
if (driver && driver->m_nPedType != PEDTYPE_EMERGENCY && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) {
|
||||||
|
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, driver);
|
||||||
|
} else if (m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER
|
||||||
|
&& m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER
|
||||||
|
&& m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) {
|
||||||
|
SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_pMyVehicle);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (m_nPedState != PED_WANDER_PATH) {
|
||||||
|
SetWanderPath(CGeneral::GetRandomNumber() & 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EMERGENCY_PED_DETERMINE_NEXT_STATE:
|
||||||
|
nearestAccident = gAccidentManager.FindNearestAccident(GetPosition(), &distToEmergency);
|
||||||
|
if (nearestAccident) {
|
||||||
|
if (nearestAccident != m_pAttendedAccident || m_nPedState != PED_SEEK_POS) {
|
||||||
|
m_pRevivedPed = nearestAccident->m_pVictim;
|
||||||
|
m_pRevivedPed->RegisterReference((CEntity**)&m_pRevivedPed);
|
||||||
|
if (!InRange(m_pRevivedPed)) {
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_STOP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&midPos, PED_MID);
|
||||||
|
m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&headPos, PED_HEAD);
|
||||||
|
SetSeek((headPos + midPos) * 0.5f, nearestAccident->m_nMedicsPerformingCPR * 0.5f + 1.0f);
|
||||||
|
SetObjective(OBJECTIVE_NONE);
|
||||||
|
bIsRunning = true;
|
||||||
|
--m_pAttendedAccident->m_nMedicsAttending;
|
||||||
|
++nearestAccident->m_nMedicsAttending;
|
||||||
|
m_pAttendedAccident = nearestAccident;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_STOP;
|
||||||
|
bIsRunning = false;
|
||||||
|
}
|
||||||
|
if (distToEmergency < 5.0f) {
|
||||||
|
if (m_pRevivedPed->m_pFire) {
|
||||||
|
bIsRunning = false;
|
||||||
|
SetMoveState(PEDMOVE_STILL);
|
||||||
|
} else if (distToEmergency < 4.5f) {
|
||||||
|
bIsRunning = false;
|
||||||
|
SetMoveState(PEDMOVE_WALK);
|
||||||
|
if (distToEmergency < 1.0f
|
||||||
|
|| distToEmergency < 4.5f && m_pAttendedAccident->m_nMedicsPerformingCPR) {
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_START_CPR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EMERGENCY_PED_START_CPR:
|
||||||
|
if (!m_pRevivedPed || m_pRevivedPed->m_fHealth > 0.0f || m_pRevivedPed->bFadeOut) {
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE;
|
||||||
|
} else {
|
||||||
|
m_pRevivedPed->m_bloodyFootprintCount = CTimer::GetTimeInMilliseconds();
|
||||||
|
SetMoveState(PEDMOVE_STILL);
|
||||||
|
m_nPedState = PED_CPR;
|
||||||
|
m_nLastPedState = PED_CPR;
|
||||||
|
SetLookFlag(m_pRevivedPed, 0);
|
||||||
|
SetLookTimer(500);
|
||||||
|
Say(SOUND_PED_HEALING);
|
||||||
|
if (m_pAttendedAccident->m_nMedicsPerformingCPR) {
|
||||||
|
SetIdle();
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_STAND_STILL;
|
||||||
|
} else {
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_FACE_TO_PATIENT;
|
||||||
|
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CPR, 4.0f);
|
||||||
|
bIsDucking = true;
|
||||||
|
}
|
||||||
|
SetLookTimer(2000);
|
||||||
|
++m_pAttendedAccident->m_nMedicsPerformingCPR;
|
||||||
|
m_bStartedToCPR = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EMERGENCY_PED_FACE_TO_PATIENT:
|
||||||
|
if (!m_pRevivedPed || m_pRevivedPed->m_fHealth > 0.0f)
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE;
|
||||||
|
else {
|
||||||
|
m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&midPos, PED_MID);
|
||||||
|
m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&headPos, PED_HEAD);
|
||||||
|
midPos = (headPos + midPos) * 0.5f;
|
||||||
|
m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
|
||||||
|
midPos.x, midPos.y,
|
||||||
|
GetPosition().x, GetPosition().y);
|
||||||
|
m_fRotationDest = CGeneral::LimitAngle(m_fRotationDest);
|
||||||
|
m_pLookTarget = m_pRevivedPed;
|
||||||
|
m_pLookTarget->RegisterReference((CEntity**)&m_pLookTarget);
|
||||||
|
TurnBody();
|
||||||
|
|
||||||
|
if (Abs(m_fRotationCur - m_fRotationDest) < DEGTORAD(45.0f))
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_PERFORM_CPR;
|
||||||
|
else
|
||||||
|
m_fRotationCur = (m_fRotationCur + m_fRotationDest) * 0.5f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EMERGENCY_PED_PERFORM_CPR:
|
||||||
|
if (!m_pRevivedPed || m_pRevivedPed->m_fHealth > 0.0f) {
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&midPos, PED_MID);
|
||||||
|
m_pRevivedPed->m_pedIK.GetComponentPosition((RwV3d*)&headPos, PED_HEAD);
|
||||||
|
midPos = (headPos + midPos) * 0.5f;
|
||||||
|
m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
|
||||||
|
midPos.x, midPos.y,
|
||||||
|
GetPosition().x, GetPosition().y);
|
||||||
|
m_fRotationDest = CGeneral::LimitAngle(m_fRotationDest);
|
||||||
|
m_pLookTarget = m_pRevivedPed;
|
||||||
|
m_pLookTarget->RegisterReference((CEntity**)&m_pLookTarget);
|
||||||
|
TurnBody();
|
||||||
|
if (CTimer::GetTimeInMilliseconds() <= m_lookTimer) {
|
||||||
|
SetMoveState(PEDMOVE_STILL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_STOP_CPR;
|
||||||
|
m_nPedState = PED_NONE;
|
||||||
|
SetMoveState(PEDMOVE_WALK);
|
||||||
|
m_pVehicleAnim = nil;
|
||||||
|
if (!m_pRevivedPed->bBodyPartJustCameOff) {
|
||||||
|
m_pRevivedPed->m_fHealth = 100.0f;
|
||||||
|
m_pRevivedPed->m_nPedState = PED_NONE;
|
||||||
|
m_pRevivedPed->m_nLastPedState = PED_WANDER_PATH;
|
||||||
|
m_pRevivedPed->SetGetUp();
|
||||||
|
m_pRevivedPed->bUsesCollision = true;
|
||||||
|
m_pRevivedPed->SetMoveState(PEDMOVE_WALK);
|
||||||
|
m_pRevivedPed->RestartNonPartialAnims();
|
||||||
|
m_pRevivedPed->bIsPedDieAnimPlaying = false;
|
||||||
|
m_pRevivedPed->m_ped_flagH1 = false;
|
||||||
|
m_pRevivedPed->m_pCollidingEntity = nil;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EMERGENCY_PED_STOP_CPR:
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_STOP;
|
||||||
|
bIsDucking = true;
|
||||||
|
break;
|
||||||
|
case EMERGENCY_PED_STAND_STILL:
|
||||||
|
if (!m_pRevivedPed || m_pRevivedPed->m_fHealth > 0.0f)
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE;
|
||||||
|
else {
|
||||||
|
if (!m_pAttendedAccident->m_pVictim)
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE;
|
||||||
|
if (!m_pAttendedAccident->m_nMedicsPerformingCPR)
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE;
|
||||||
|
if (gAccidentManager.UnattendedAccidents())
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EMERGENCY_PED_STOP:
|
||||||
|
m_bStartedToCPR = false;
|
||||||
|
m_nPedState = PED_NONE;
|
||||||
|
if (m_pAttendedAccident) {
|
||||||
|
m_pAttendedAccident->m_pVictim = nil;
|
||||||
|
--m_pAttendedAccident->m_nMedicsAttending;
|
||||||
|
m_pAttendedAccident = nil;
|
||||||
|
}
|
||||||
|
SetWanderPath(CGeneral::GetRandomNumber() & 7);
|
||||||
|
m_pRevivedPed = nil;
|
||||||
|
m_nEmergencyPedState = EMERGENCY_PED_READY;
|
||||||
|
SetMoveState(PEDMOVE_WALK);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CEmergencyPed_ : public CEmergencyPed
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CEmergencyPed* ctor(int pedtype) { return ::new (this) CEmergencyPed(pedtype); };
|
||||||
|
void dtor(void) { CEmergencyPed::~CEmergencyPed(); }
|
||||||
|
void ProcessControl_(void) { CEmergencyPed::ProcessControl(); }
|
||||||
|
};
|
||||||
|
|
||||||
STARTPATCHES
|
STARTPATCHES
|
||||||
InjectHook(0x4C2E40, &CEmergencyPed_::ctor, PATCH_JUMP);
|
InjectHook(0x4C2E40, &CEmergencyPed_::ctor, PATCH_JUMP);
|
||||||
InjectHook(0x4C2EF0, &CEmergencyPed_::dtor, PATCH_JUMP);
|
InjectHook(0x4C2EF0, &CEmergencyPed_::dtor, PATCH_JUMP);
|
||||||
|
InjectHook(0x4C2F10, &CEmergencyPed_::ProcessControl_, PATCH_JUMP);
|
||||||
|
InjectHook(0x4C3EC0, &CEmergencyPed::InRange, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
||||||
|
@ -1,20 +1,40 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Fire.h"
|
|
||||||
#include "Ped.h"
|
#include "Ped.h"
|
||||||
|
|
||||||
|
class CAccident;
|
||||||
|
class CFire;
|
||||||
|
|
||||||
|
enum EmergencyPedState
|
||||||
|
{
|
||||||
|
EMERGENCY_PED_READY = 0x0,
|
||||||
|
EMERGENCY_PED_DETERMINE_NEXT_STATE = 0x1, // you can set that anytime you want
|
||||||
|
EMERGENCY_PED_START_CPR = 0x2,
|
||||||
|
EMERGENCY_PED_FLAG_4 = 0x4, // unused
|
||||||
|
EMERGENCY_PED_FLAG_8 = 0x8, // unused
|
||||||
|
EMERGENCY_PED_FACE_TO_PATIENT = 0x10, // for CPR
|
||||||
|
EMERGENCY_PED_PERFORM_CPR = 0x20,
|
||||||
|
EMERGENCY_PED_STOP_CPR = 0x40,
|
||||||
|
EMERGENCY_PED_STAND_STILL = 0x80, // waiting colleagues for medics, "extinguishing" fire for firemen
|
||||||
|
EMERGENCY_PED_STOP = 0x100,
|
||||||
|
};
|
||||||
|
|
||||||
class CEmergencyPed : public CPed
|
class CEmergencyPed : public CPed
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// 0x53C
|
// 0x53C
|
||||||
CPed* m_pRevivedPed;
|
CPed *m_pRevivedPed;
|
||||||
int32 m_nEmergencyPedState; // looks like flags
|
EmergencyPedState m_nEmergencyPedState;
|
||||||
void* m_pAttendedAccident; //TODO: CAccident*
|
CAccident *m_pAttendedAccident;
|
||||||
CFire* m_pAttendedFire;
|
CFire *m_pAttendedFire;
|
||||||
int8 field_1356;
|
bool m_bStartedToCPR; // set but unused(?)
|
||||||
int32 field_1360;
|
int32 field_1360; // also something for medics, unused(?)
|
||||||
|
|
||||||
CEmergencyPed(uint32);
|
CEmergencyPed(uint32);
|
||||||
|
~CEmergencyPed() { }
|
||||||
|
bool InRange(CPed*);
|
||||||
void ProcessControl(void);
|
void ProcessControl(void);
|
||||||
|
void FiremanAI(void);
|
||||||
|
void MedicAI(void);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CEmergencyPed) == 0x554, "CEmergencyPed: error");
|
static_assert(sizeof(CEmergencyPed) == 0x554, "CEmergencyPed: error");
|
||||||
|
1072
src/peds/Ped.cpp
1072
src/peds/Ped.cpp
File diff suppressed because it is too large
Load Diff
@ -243,9 +243,11 @@ enum PedState
|
|||||||
PED_STEP_AWAY,
|
PED_STEP_AWAY,
|
||||||
PED_ON_FIRE,
|
PED_ON_FIRE,
|
||||||
|
|
||||||
PED_UNKNOWN, // HANG_OUT in Fire_Head's idb
|
PED_UNKNOWN, // Same with IDLE, but also infects up to 5 peds with same pedType and WANDER_PATH, so they become stone too. HANG_OUT in Fire_Head's idb
|
||||||
|
|
||||||
PED_STATES_NO_AI,
|
PED_STATES_NO_AI,
|
||||||
|
|
||||||
|
// One of these states isn't on PS2 - start
|
||||||
PED_JUMP,
|
PED_JUMP,
|
||||||
PED_FALL,
|
PED_FALL,
|
||||||
PED_GETUP,
|
PED_GETUP,
|
||||||
@ -256,6 +258,8 @@ enum PedState
|
|||||||
PED_ENTER_TRAIN,
|
PED_ENTER_TRAIN,
|
||||||
PED_EXIT_TRAIN,
|
PED_EXIT_TRAIN,
|
||||||
PED_ARREST_PLAYER,
|
PED_ARREST_PLAYER,
|
||||||
|
// One of these states isn't on PS2 - end
|
||||||
|
|
||||||
PED_DRIVING,
|
PED_DRIVING,
|
||||||
PED_PASSENGER,
|
PED_PASSENGER,
|
||||||
PED_TAXI_PASSENGER,
|
PED_TAXI_PASSENGER,
|
||||||
@ -363,7 +367,7 @@ public:
|
|||||||
|
|
||||||
uint8 bShakeFist : 1; // test shake hand at look entity
|
uint8 bShakeFist : 1; // test shake hand at look entity
|
||||||
uint8 bNoCriticalHits : 1; // if set, limbs won't came off
|
uint8 bNoCriticalHits : 1; // if set, limbs won't came off
|
||||||
uint8 m_ped_flagI4 : 1; // we've been put to car by script? - related with cars
|
uint8 m_ped_flagI4 : 1; // we've been put to car by script or without align phase? - related with cars
|
||||||
uint8 bHasAlreadyBeenRecorded : 1;
|
uint8 bHasAlreadyBeenRecorded : 1;
|
||||||
uint8 bFallenDown : 1;
|
uint8 bFallenDown : 1;
|
||||||
#ifdef VC_PED_PORTS
|
#ifdef VC_PED_PORTS
|
||||||
@ -371,8 +375,8 @@ public:
|
|||||||
#else
|
#else
|
||||||
uint8 m_ped_flagI20 : 1;
|
uint8 m_ped_flagI20 : 1;
|
||||||
#endif
|
#endif
|
||||||
uint8 m_ped_flagI40 : 1;
|
uint8 m_ped_flagI40 : 1; // bMakePedsRunToPhonesToReportCrimes makes use of this as runover by car indicator
|
||||||
uint8 m_ped_flagI80 : 1;
|
uint8 m_ped_flagI80 : 1; // KANGAROO_CHEAT define makes use of this as cheat toggle
|
||||||
|
|
||||||
uint8 stuff10[3];
|
uint8 stuff10[3];
|
||||||
uint8 CharCreatedBy;
|
uint8 CharCreatedBy;
|
||||||
@ -407,11 +411,11 @@ public:
|
|||||||
int32 m_nPrevMoveState;
|
int32 m_nPrevMoveState;
|
||||||
eWaitState m_nWaitState;
|
eWaitState m_nWaitState;
|
||||||
uint32 m_nWaitTimer;
|
uint32 m_nWaitTimer;
|
||||||
void *m_pPathNodesStates[8]; // seems unused, probably leftover from VC
|
void *m_pPathNodesStates[8]; // unused, probably leftover from VC
|
||||||
CVector2D m_stPathNodeStates[10];
|
CVector2D m_stPathNodeStates[10];
|
||||||
uint16 m_nPathNodes;
|
uint16 m_nPathNodes;
|
||||||
int16 m_nCurPathNode;
|
int16 m_nCurPathNode;
|
||||||
int8 m_nPathState;
|
int8 m_nPathDir;
|
||||||
private:
|
private:
|
||||||
int8 _pad2B5[3];
|
int8 _pad2B5[3];
|
||||||
public:
|
public:
|
||||||
@ -499,8 +503,8 @@ public:
|
|||||||
uint32 m_soundStart;
|
uint32 m_soundStart;
|
||||||
uint16 m_lastQueuedSound;
|
uint16 m_lastQueuedSound;
|
||||||
uint16 m_queuedSound;
|
uint16 m_queuedSound;
|
||||||
CVector m_vecSeekPosEx; // used in objectives
|
CVector m_vecSeekPosEx; // used for OBJECTIVE_GUARD_SPOT
|
||||||
float m_distanceToCountSeekDoneEx; // used in objectives
|
float m_distanceToCountSeekDoneEx; // used for OBJECTIVE_GUARD_SPOT
|
||||||
|
|
||||||
static void *operator new(size_t);
|
static void *operator new(size_t);
|
||||||
static void *operator new(size_t, int);
|
static void *operator new(size_t, int);
|
||||||
@ -690,7 +694,9 @@ public:
|
|||||||
void ScanForInterestingStuff(void);
|
void ScanForInterestingStuff(void);
|
||||||
void WarpPedIntoCar(CVehicle*);
|
void WarpPedIntoCar(CVehicle*);
|
||||||
void SetCarJack(CVehicle*);
|
void SetCarJack(CVehicle*);
|
||||||
void WarpPedToNearLeaderOffScreen(void);
|
bool WarpPedToNearLeaderOffScreen(void);
|
||||||
|
void Solicit(void);
|
||||||
|
void SetExitBoat(CVehicle*);
|
||||||
|
|
||||||
// Static methods
|
// Static methods
|
||||||
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset);
|
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset);
|
||||||
@ -768,6 +774,7 @@ public:
|
|||||||
void SeekBoatPosition(void);
|
void SeekBoatPosition(void);
|
||||||
void UpdatePosition(void);
|
void UpdatePosition(void);
|
||||||
CObject *SpawnFlyingComponent(int, int8);
|
CObject *SpawnFlyingComponent(int, int8);
|
||||||
|
void SetCarJack_AllClear(CVehicle*, uint32, uint32);
|
||||||
#ifdef VC_PED_PORTS
|
#ifdef VC_PED_PORTS
|
||||||
bool CanPedJumpThis(CEntity*, CVector*);
|
bool CanPedJumpThis(CEntity*, CVector*);
|
||||||
#else
|
#else
|
||||||
@ -781,7 +788,9 @@ public:
|
|||||||
PedState GetPedState(void) { return m_nPedState; }
|
PedState GetPedState(void) { return m_nPedState; }
|
||||||
void SetPedState(PedState state) { m_nPedState = state; }
|
void SetPedState(PedState state) { m_nPedState = state; }
|
||||||
bool DyingOrDead(void) { return m_nPedState == PED_DIE || m_nPedState == PED_DEAD; }
|
bool DyingOrDead(void) { return m_nPedState == PED_DIE || m_nPedState == PED_DEAD; }
|
||||||
|
bool InVehicle(void) { return bInVehicle && m_pMyVehicle; } // True when ped is sitting/standing in vehicle, not in enter/exit state.
|
||||||
void ReplaceWeaponWhenExitingVehicle(void);
|
void ReplaceWeaponWhenExitingVehicle(void);
|
||||||
|
void RemoveWeaponWhenEnteringVehicle(void);
|
||||||
bool IsNotInWreckedVehicle();
|
bool IsNotInWreckedVehicle();
|
||||||
|
|
||||||
// set by 0482:set_threat_reaction_range_multiplier opcode
|
// set by 0482:set_threat_reaction_range_multiplier opcode
|
||||||
@ -796,10 +805,13 @@ public:
|
|||||||
static CVector2D ms_vec2DFleePosition;
|
static CVector2D ms_vec2DFleePosition;
|
||||||
static CPedAudioData (&CommentWaitTime)[38];
|
static CPedAudioData (&CommentWaitTime)[38];
|
||||||
|
|
||||||
#ifndef MASTER
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
static bool bUnusedFightThingOnPlayer;
|
static bool bUnusedFightThingOnPlayer;
|
||||||
static bool bPopHeadsOnHeadshot;
|
static bool bPopHeadsOnHeadshot;
|
||||||
|
static bool bMakePedsRunToPhonesToReportCrimes;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MASTER
|
||||||
// Mobile things
|
// Mobile things
|
||||||
static void SwitchDebugDisplay(void);
|
static void SwitchDebugDisplay(void);
|
||||||
void DebugRenderOnePedText(void);
|
void DebugRenderOnePedText(void);
|
||||||
@ -809,7 +821,7 @@ public:
|
|||||||
class cPedParams
|
class cPedParams
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
char m_bDistanceCalculated;
|
bool m_bDistanceCalculated;
|
||||||
char gap_1[3];
|
char gap_1[3];
|
||||||
float m_fDistance;
|
float m_fDistance;
|
||||||
CPed *m_pPed;
|
CPed *m_pPed;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "General.h"
|
||||||
#include "FileMgr.h"
|
#include "FileMgr.h"
|
||||||
#include "PedStats.h"
|
#include "PedStats.h"
|
||||||
|
|
||||||
@ -112,7 +113,7 @@ CPedStats::GetPedStatType(char *name)
|
|||||||
int type;
|
int type;
|
||||||
|
|
||||||
for(type = 0; type < NUM_PEDSTATS; type++)
|
for(type = 0; type < NUM_PEDSTATS; type++)
|
||||||
if(strcmp(ms_apPedStats[type]->m_name, name) == 0)
|
if(!CGeneral::faststrcmp(ms_apPedStats[type]->m_name, name))
|
||||||
return type;
|
return type;
|
||||||
return NUM_PEDSTATS;
|
return NUM_PEDSTATS;
|
||||||
}
|
}
|
||||||
|
@ -5,20 +5,15 @@
|
|||||||
#include "WeaponEffects.h"
|
#include "WeaponEffects.h"
|
||||||
#include "ModelIndices.h"
|
#include "ModelIndices.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
|
#include "RpAnimBlend.h"
|
||||||
|
#include "General.h"
|
||||||
|
|
||||||
CPlayerPed::~CPlayerPed()
|
CPlayerPed::~CPlayerPed()
|
||||||
{
|
{
|
||||||
delete m_pWanted;
|
delete m_pWanted;
|
||||||
}
|
}
|
||||||
|
|
||||||
WRAPPER void CPlayerPed::ReApplyMoveAnims(void) { EAXJMP(0x4F07C0); }
|
|
||||||
WRAPPER void CPlayerPed::SetupPlayerPed(int32) { EAXJMP(0x4EFB60); }
|
|
||||||
WRAPPER void CPlayerPed::DeactivatePlayerPed(int32) { EAXJMP(0x4EFC00); }
|
|
||||||
WRAPPER void CPlayerPed::ReactivatePlayerPed(int32) { EAXJMP(0x4EFC20); }
|
|
||||||
WRAPPER void CPlayerPed::KeepAreaAroundPlayerClear(void) { EAXJMP(0x4F3460); }
|
WRAPPER void CPlayerPed::KeepAreaAroundPlayerClear(void) { EAXJMP(0x4F3460); }
|
||||||
WRAPPER void CPlayerPed::MakeChangesForNewWeapon(int8) { EAXJMP(0x4F2560); }
|
|
||||||
WRAPPER void CPlayerPed::SetInitialState(void) { EAXJMP(0x4EFC40); }
|
|
||||||
WRAPPER void CPlayerPed::SetMoveAnim(void) { EAXJMP(0x4F3760); }
|
|
||||||
WRAPPER void CPlayerPed::ProcessControl(void) { EAXJMP(0x4EFD90); }
|
WRAPPER void CPlayerPed::ProcessControl(void) { EAXJMP(0x4EFD90); }
|
||||||
|
|
||||||
CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
|
CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
|
||||||
@ -31,7 +26,7 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
|
|||||||
m_pWanted->Initialise();
|
m_pWanted->Initialise();
|
||||||
m_pArrestingCop = nil;
|
m_pArrestingCop = nil;
|
||||||
m_currentWeapon = WEAPONTYPE_UNARMED;
|
m_currentWeapon = WEAPONTYPE_UNARMED;
|
||||||
m_nSelectedWepSlot = 0;
|
m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
|
||||||
m_nSpeedTimer = 0;
|
m_nSpeedTimer = 0;
|
||||||
m_bSpeedTimerFlag = 0;
|
m_bSpeedTimerFlag = 0;
|
||||||
m_pPointGunAt = nil;
|
m_pPointGunAt = nil;
|
||||||
@ -113,17 +108,364 @@ CPlayerPed::GetPlayerInfoForThisPlayerPed()
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerPed::SetupPlayerPed(int32 index)
|
||||||
|
{
|
||||||
|
CPlayerPed *player = new CPlayerPed();
|
||||||
|
CWorld::Players[index].m_pPed = player;
|
||||||
|
|
||||||
|
player->SetOrientation(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
CWorld::Add(player);
|
||||||
|
player->m_wepAccuracy = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerPed::DeactivatePlayerPed(int32 index)
|
||||||
|
{
|
||||||
|
CWorld::Remove(CWorld::Players[index].m_pPed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerPed::ReactivatePlayerPed(int32 index)
|
||||||
|
{
|
||||||
|
CWorld::Add(CWorld::Players[index].m_pPed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerPed::UseSprintEnergy(void)
|
||||||
|
{
|
||||||
|
if (m_fCurrentStamina > -150.0f && !CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint
|
||||||
|
&& !m_bAdrenalineActive) {
|
||||||
|
m_fCurrentStamina = m_fCurrentStamina - CTimer::GetTimeStep();
|
||||||
|
m_fStaminaProgress = m_fStaminaProgress + CTimer::GetTimeStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_fStaminaProgress >= 500.0f) {
|
||||||
|
m_fStaminaProgress = 0;
|
||||||
|
if (m_fMaxStamina < 1000.0f)
|
||||||
|
m_fMaxStamina += 10.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerPed::MakeChangesForNewWeapon(int8 weapon)
|
||||||
|
{
|
||||||
|
if (m_nPedState == PED_SNIPER_MODE) {
|
||||||
|
RestorePreviousState();
|
||||||
|
TheCamera.ClearPlayerWeaponMode();
|
||||||
|
}
|
||||||
|
SetCurrentWeapon(weapon);
|
||||||
|
|
||||||
|
GetWeapon()->m_nAmmoInClip = min(GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition);
|
||||||
|
|
||||||
|
if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAim))
|
||||||
|
ClearWeaponTarget();
|
||||||
|
|
||||||
|
CAnimBlendAssociation *weaponAnim = RpAnimBlendClumpGetAssociation(GetClump(), CWeaponInfo::GetWeaponInfo(WEAPONTYPE_SNIPERRIFLE)->m_AnimToPlay);
|
||||||
|
if (weaponAnim) {
|
||||||
|
weaponAnim->SetRun();
|
||||||
|
weaponAnim->flags |= ASSOC_FADEOUTWHENDONE;
|
||||||
|
}
|
||||||
|
TheCamera.ClearPlayerWeaponMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerPed::ReApplyMoveAnims(void)
|
||||||
|
{
|
||||||
|
static AnimationId moveAnims[] = { ANIM_WALK, ANIM_RUN, ANIM_SPRINT, ANIM_IDLE_STANCE, ANIM_WALK_START };
|
||||||
|
|
||||||
|
for(int i = 0; i < ARRAY_SIZE(moveAnims); i++) {
|
||||||
|
CAnimBlendAssociation *curMoveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), moveAnims[i]);
|
||||||
|
if (curMoveAssoc) {
|
||||||
|
if (strcmp(CAnimManager::GetAnimAssociation(m_animGroup, moveAnims[i])->hierarchy->name, curMoveAssoc->hierarchy->name) != 0) {
|
||||||
|
CAnimBlendAssociation *newMoveAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, moveAnims[i]);
|
||||||
|
newMoveAssoc->blendDelta = curMoveAssoc->blendDelta;
|
||||||
|
newMoveAssoc->blendAmount = curMoveAssoc->blendAmount;
|
||||||
|
curMoveAssoc->blendDelta = -1000.0f;
|
||||||
|
curMoveAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerPed::SetInitialState(void)
|
||||||
|
{
|
||||||
|
m_bAdrenalineActive = false;
|
||||||
|
m_nAdrenalineTime = 0;
|
||||||
|
CTimer::SetTimeStep(1.0f);
|
||||||
|
m_pSeekTarget = nil;
|
||||||
|
m_vecSeekPos = { 0.0f, 0.0f, 0.0f };
|
||||||
|
m_fleeFromPosX = 0.0f;
|
||||||
|
m_fleeFromPosY = 0.0f;
|
||||||
|
m_fleeFrom = nil;
|
||||||
|
m_fleeTimer = 0;
|
||||||
|
m_objective = OBJECTIVE_NONE;
|
||||||
|
m_prevObjective = OBJECTIVE_NONE;
|
||||||
|
bUsesCollision = true;
|
||||||
|
ClearAimFlag();
|
||||||
|
ClearLookFlag();
|
||||||
|
bIsPointingGunAt = false;
|
||||||
|
bRenderPedInCar = true;
|
||||||
|
if (m_pFire)
|
||||||
|
m_pFire->Extinguish();
|
||||||
|
RpAnimBlendClumpRemoveAllAssociations(GetClump());
|
||||||
|
m_nPedState = PED_IDLE;
|
||||||
|
SetMoveState(PEDMOVE_STILL);
|
||||||
|
m_nLastPedState = PED_NONE;
|
||||||
|
m_animGroup = ASSOCGRP_PLAYER;
|
||||||
|
m_fMoveSpeed = 0.0f;
|
||||||
|
m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
|
||||||
|
m_bShouldEvade = false;
|
||||||
|
m_pEvadingFrom = nil;
|
||||||
|
bIsPedDieAnimPlaying = false;
|
||||||
|
SetRealMoveAnim();
|
||||||
|
m_bCanBeDamaged = true;
|
||||||
|
m_pedStats->m_temper = 50;
|
||||||
|
m_fWalkAngle = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPlayerPed::SetRealMoveAnim(void)
|
||||||
|
{
|
||||||
|
CAnimBlendAssociation *curWalkAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WALK);
|
||||||
|
CAnimBlendAssociation *curRunAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN);
|
||||||
|
CAnimBlendAssociation *curSprintAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SPRINT);
|
||||||
|
CAnimBlendAssociation *curWalkStartAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WALK_START);
|
||||||
|
CAnimBlendAssociation *curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
|
||||||
|
CAnimBlendAssociation *curRunStopAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP);
|
||||||
|
CAnimBlendAssociation *curRunStopRAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP_R);
|
||||||
|
if (bResetWalkAnims) {
|
||||||
|
if (curWalkAssoc)
|
||||||
|
curWalkAssoc->SetCurrentTime(0.0f);
|
||||||
|
if (curRunAssoc)
|
||||||
|
curRunAssoc->SetCurrentTime(0.0f);
|
||||||
|
if (curSprintAssoc)
|
||||||
|
curSprintAssoc->SetCurrentTime(0.0f);
|
||||||
|
bResetWalkAnims = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!curIdleAssoc)
|
||||||
|
curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
|
||||||
|
if (!curIdleAssoc)
|
||||||
|
curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
|
||||||
|
|
||||||
|
if ((!curRunStopAssoc || !(curRunStopAssoc->IsRunning())) && (!curRunStopRAssoc || !(curRunStopRAssoc->IsRunning()))) {
|
||||||
|
|
||||||
|
if (curRunStopAssoc && curRunStopAssoc->blendDelta >= 0.0f || curRunStopRAssoc && curRunStopRAssoc->blendDelta >= 0.0f) {
|
||||||
|
if (curRunStopAssoc) {
|
||||||
|
curRunStopAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||||
|
curRunStopAssoc->blendAmount = 1.0f;
|
||||||
|
curRunStopAssoc->blendDelta = -8.0f;
|
||||||
|
} else if (curRunStopRAssoc) {
|
||||||
|
curRunStopRAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||||
|
curRunStopRAssoc->blendAmount = 1.0f;
|
||||||
|
curRunStopRAssoc->blendDelta = -8.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
RestoreHeadingRate();
|
||||||
|
if (!curIdleAssoc) {
|
||||||
|
if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
|
||||||
|
nil, true, false, false, false, false, false)) {
|
||||||
|
curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 8.0f);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 8.0f);
|
||||||
|
}
|
||||||
|
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2500, 4000);
|
||||||
|
}
|
||||||
|
curIdleAssoc->blendAmount = 0.0f;
|
||||||
|
curIdleAssoc->blendDelta = 8.0f;
|
||||||
|
|
||||||
|
} else if (m_fMoveSpeed == 0.0f && !curSprintAssoc) {
|
||||||
|
if (!curIdleAssoc) {
|
||||||
|
if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
|
||||||
|
nil, true, false, false, false, false, false)) {
|
||||||
|
curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2500, 4000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_fCurrentStamina > 0.0f && curIdleAssoc->animId == ANIM_IDLE_TIRED) {
|
||||||
|
CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
|
||||||
|
|
||||||
|
} else if (m_nPedState != PED_FIGHT) {
|
||||||
|
if (m_fCurrentStamina < 0.0f && curIdleAssoc->animId != ANIM_IDLE_TIRED
|
||||||
|
&& !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f, nil, true, false, false, false, false, false)) {
|
||||||
|
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
|
||||||
|
|
||||||
|
} else if (curIdleAssoc->animId != ANIM_IDLE_STANCE) {
|
||||||
|
CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nMoveState = PEDMOVE_STILL;
|
||||||
|
} else {
|
||||||
|
if (curIdleAssoc) {
|
||||||
|
if (curWalkStartAssoc) {
|
||||||
|
curWalkStartAssoc->blendAmount = 1.0f;
|
||||||
|
curWalkStartAssoc->blendDelta = 0.0f;
|
||||||
|
} else {
|
||||||
|
curWalkStartAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_WALK_START);
|
||||||
|
}
|
||||||
|
if (curWalkAssoc)
|
||||||
|
curWalkAssoc->SetCurrentTime(0.0f);
|
||||||
|
if (curRunAssoc)
|
||||||
|
curRunAssoc->SetCurrentTime(0.0f);
|
||||||
|
|
||||||
|
delete curIdleAssoc;
|
||||||
|
delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
|
||||||
|
delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
|
||||||
|
delete curSprintAssoc;
|
||||||
|
|
||||||
|
curSprintAssoc = nil;
|
||||||
|
m_nMoveState = PEDMOVE_WALK;
|
||||||
|
}
|
||||||
|
if (curRunStopAssoc) {
|
||||||
|
delete curRunStopAssoc;
|
||||||
|
RestoreHeadingRate();
|
||||||
|
}
|
||||||
|
if (curRunStopRAssoc) {
|
||||||
|
delete curRunStopRAssoc;
|
||||||
|
RestoreHeadingRate();
|
||||||
|
}
|
||||||
|
if (!curWalkAssoc) {
|
||||||
|
curWalkAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_WALK);
|
||||||
|
curWalkAssoc->blendAmount = 0.0f;
|
||||||
|
}
|
||||||
|
if (!curRunAssoc) {
|
||||||
|
curRunAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_RUN);
|
||||||
|
curRunAssoc->blendAmount = 0.0f;
|
||||||
|
}
|
||||||
|
if (curWalkStartAssoc && !(curWalkStartAssoc->IsRunning())) {
|
||||||
|
delete curWalkStartAssoc;
|
||||||
|
curWalkStartAssoc = nil;
|
||||||
|
curWalkAssoc->SetRun();
|
||||||
|
curRunAssoc->SetRun();
|
||||||
|
}
|
||||||
|
if (m_nMoveState == PEDMOVE_SPRINT) {
|
||||||
|
if (m_fCurrentStamina < 0.0f && (m_fCurrentStamina <= -150.0f || !curSprintAssoc || curSprintAssoc->blendDelta < 0.0f))
|
||||||
|
m_nMoveState = PEDMOVE_STILL;
|
||||||
|
|
||||||
|
if (curWalkStartAssoc)
|
||||||
|
m_nMoveState = PEDMOVE_STILL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curSprintAssoc && (m_nMoveState != PEDMOVE_SPRINT || m_fMoveSpeed < 0.4f)) {
|
||||||
|
if (curSprintAssoc->blendAmount == 0.0f) {
|
||||||
|
curSprintAssoc->blendDelta = -1000.0f;
|
||||||
|
curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||||
|
|
||||||
|
} else if (curSprintAssoc->blendDelta >= 0.0f || curSprintAssoc->blendAmount >= 0.8f) {
|
||||||
|
if (m_fMoveSpeed < 0.4f) {
|
||||||
|
AnimationId runStopAnim;
|
||||||
|
if (curSprintAssoc->currentTime / curSprintAssoc->hierarchy->totalLength < 0.5) // double
|
||||||
|
runStopAnim = ANIM_RUN_STOP;
|
||||||
|
else
|
||||||
|
runStopAnim = ANIM_RUN_STOP_R;
|
||||||
|
CAnimBlendAssociation* newRunStopAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, runStopAnim);
|
||||||
|
newRunStopAssoc->blendAmount = 1.0f;
|
||||||
|
newRunStopAssoc->SetDeleteCallback(RestoreHeadingRateCB, this);
|
||||||
|
m_headingRate = 0.0f;
|
||||||
|
curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||||
|
curSprintAssoc->blendDelta = -1000.0f;
|
||||||
|
curWalkAssoc->flags &= ~ASSOC_RUNNING;
|
||||||
|
curWalkAssoc->blendAmount = 0.0f;
|
||||||
|
curWalkAssoc->blendDelta = 0.0f;
|
||||||
|
curRunAssoc->flags &= ~ASSOC_RUNNING;
|
||||||
|
curRunAssoc->blendAmount = 0.0f;
|
||||||
|
curRunAssoc->blendDelta = 0.0f;
|
||||||
|
} else if (curSprintAssoc->blendDelta < 0.0f) {
|
||||||
|
curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||||
|
curSprintAssoc->blendDelta = -1.0f;
|
||||||
|
curRunAssoc->blendDelta = 1.0f;
|
||||||
|
}
|
||||||
|
} else if (m_fMoveSpeed < 1.0f) {
|
||||||
|
curSprintAssoc->blendDelta = -8.0f;
|
||||||
|
curRunAssoc->blendDelta = 8.0f;
|
||||||
|
}
|
||||||
|
} else if (curWalkStartAssoc) {
|
||||||
|
curWalkAssoc->flags &= ~ASSOC_RUNNING;
|
||||||
|
curRunAssoc->flags &= ~ASSOC_RUNNING;
|
||||||
|
curWalkAssoc->blendAmount = 0.0f;
|
||||||
|
curRunAssoc->blendAmount = 0.0f;
|
||||||
|
|
||||||
|
} else if (m_nMoveState == PEDMOVE_SPRINT) {
|
||||||
|
if (curSprintAssoc) {
|
||||||
|
if (curSprintAssoc->blendDelta < 0.0f) {
|
||||||
|
curSprintAssoc->blendDelta = 2.0f;
|
||||||
|
curRunAssoc->blendDelta = -2.0f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
curWalkAssoc->blendAmount = 0.0f;
|
||||||
|
curRunAssoc->blendAmount = 1.0f;
|
||||||
|
curSprintAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_SPRINT, 2.0f);
|
||||||
|
}
|
||||||
|
UseSprintEnergy();
|
||||||
|
} else {
|
||||||
|
if (m_fMoveSpeed < 1.0f) {
|
||||||
|
curWalkAssoc->blendAmount = 1.0f;
|
||||||
|
curRunAssoc->blendAmount = 0.0f;
|
||||||
|
m_nMoveState = PEDMOVE_WALK;
|
||||||
|
} else if (m_fMoveSpeed < 2.0f) {
|
||||||
|
curWalkAssoc->blendAmount = 2.0f - m_fMoveSpeed;
|
||||||
|
curRunAssoc->blendAmount = m_fMoveSpeed - 1.0f;
|
||||||
|
m_nMoveState = PEDMOVE_RUN;
|
||||||
|
} else {
|
||||||
|
curWalkAssoc->blendAmount = 0.0f;
|
||||||
|
curRunAssoc->blendAmount = 1.0f;
|
||||||
|
m_nMoveState = PEDMOVE_RUN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_bAdrenalineActive) {
|
||||||
|
if (CTimer::GetTimeInMilliseconds() > m_nAdrenalineTime) {
|
||||||
|
m_bAdrenalineActive = false;
|
||||||
|
CTimer::SetTimeScale(1.0f);
|
||||||
|
if (curWalkStartAssoc)
|
||||||
|
curWalkStartAssoc->speed = 1.0f;
|
||||||
|
if (curWalkAssoc)
|
||||||
|
curWalkAssoc->speed = 1.0f;
|
||||||
|
if (curRunAssoc)
|
||||||
|
curRunAssoc->speed = 1.0f;
|
||||||
|
if (curSprintAssoc)
|
||||||
|
curSprintAssoc->speed = 1.0f;
|
||||||
|
} else {
|
||||||
|
CTimer::SetTimeScale(1.0f / 3);
|
||||||
|
if (curWalkStartAssoc)
|
||||||
|
curWalkStartAssoc->speed = 2.0f;
|
||||||
|
if (curWalkAssoc)
|
||||||
|
curWalkAssoc->speed = 2.0f;
|
||||||
|
if (curRunAssoc)
|
||||||
|
curRunAssoc->speed = 2.0f;
|
||||||
|
if (curSprintAssoc)
|
||||||
|
curSprintAssoc->speed = 2.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class CPlayerPed_ : public CPlayerPed
|
class CPlayerPed_ : public CPlayerPed
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CPlayerPed* ctor(void) { return ::new (this) CPlayerPed(); }
|
CPlayerPed* ctor(void) { return ::new (this) CPlayerPed(); }
|
||||||
void dtor(void) { CPlayerPed::~CPlayerPed(); }
|
void dtor(void) { CPlayerPed::~CPlayerPed(); }
|
||||||
|
void SetMoveAnim_(void) { CPlayerPed::SetMoveAnim(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
STARTPATCHES
|
STARTPATCHES
|
||||||
InjectHook(0x4EF7E0, &CPlayerPed_::ctor, PATCH_JUMP);
|
InjectHook(0x4EF7E0, &CPlayerPed_::ctor, PATCH_JUMP);
|
||||||
InjectHook(0x4EFB30, &CPlayerPed_::dtor, PATCH_JUMP);
|
InjectHook(0x4EFB30, &CPlayerPed_::dtor, PATCH_JUMP);
|
||||||
|
InjectHook(0x4F3760, &CPlayerPed_::SetMoveAnim_, PATCH_JUMP);
|
||||||
InjectHook(0x4F28A0, &CPlayerPed::ClearWeaponTarget, PATCH_JUMP);
|
InjectHook(0x4F28A0, &CPlayerPed::ClearWeaponTarget, PATCH_JUMP);
|
||||||
InjectHook(0x4F3700, &CPlayerPed::AnnoyPlayerPed, PATCH_JUMP);
|
InjectHook(0x4F3700, &CPlayerPed::AnnoyPlayerPed, PATCH_JUMP);
|
||||||
InjectHook(0x4F36C0, &CPlayerPed::GetPlayerInfoForThisPlayerPed, PATCH_JUMP);
|
InjectHook(0x4F36C0, &CPlayerPed::GetPlayerInfoForThisPlayerPed, PATCH_JUMP);
|
||||||
|
InjectHook(0x4F2560, &CPlayerPed::MakeChangesForNewWeapon, PATCH_JUMP);
|
||||||
|
InjectHook(0x4F07C0, &CPlayerPed::ReApplyMoveAnims, PATCH_JUMP);
|
||||||
|
InjectHook(0x4F0880, &CPlayerPed::SetRealMoveAnim, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
||||||
|
@ -41,6 +41,7 @@ public:
|
|||||||
|
|
||||||
CPlayerPed();
|
CPlayerPed();
|
||||||
~CPlayerPed();
|
~CPlayerPed();
|
||||||
|
void SetMoveAnim() { };
|
||||||
|
|
||||||
void ReApplyMoveAnims(void);
|
void ReApplyMoveAnims(void);
|
||||||
void ClearWeaponTarget(void);
|
void ClearWeaponTarget(void);
|
||||||
@ -50,10 +51,11 @@ public:
|
|||||||
void AnnoyPlayerPed(bool);
|
void AnnoyPlayerPed(bool);
|
||||||
void MakeChangesForNewWeapon(int8);
|
void MakeChangesForNewWeapon(int8);
|
||||||
void SetInitialState(void);
|
void SetInitialState(void);
|
||||||
void SetMoveAnim(void);
|
|
||||||
void ProcessControl(void);
|
void ProcessControl(void);
|
||||||
void ClearAdrenaline(void);
|
void ClearAdrenaline(void);
|
||||||
|
void UseSprintEnergy(void);
|
||||||
class CPlayerInfo *GetPlayerInfoForThisPlayerPed();
|
class CPlayerInfo *GetPlayerInfoForThisPlayerPed();
|
||||||
|
void SetRealMoveAnim(void);
|
||||||
|
|
||||||
static void SetupPlayerPed(int32);
|
static void SetupPlayerPed(int32);
|
||||||
static void DeactivatePlayerPed(int32);
|
static void DeactivatePlayerPed(int32);
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include "ParticleObject.h"
|
#include "ParticleObject.h"
|
||||||
#include "Particle.h"
|
#include "Particle.h"
|
||||||
|
|
||||||
#ifndef MASTER
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
bool CParticle::bEnableBannedParticles = false;
|
bool CParticle::bEnableBannedParticles = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -772,7 +772,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
|
|||||||
{
|
{
|
||||||
if ( CTimer::GetIsPaused() )
|
if ( CTimer::GetIsPaused() )
|
||||||
return NULL;
|
return NULL;
|
||||||
#ifndef MASTER
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
if(!bEnableBannedParticles)
|
if(!bEnableBannedParticles)
|
||||||
#endif
|
#endif
|
||||||
if ( ( type == PARTICLE_ENGINE_SMOKE
|
if ( ( type == PARTICLE_ENGINE_SMOKE
|
||||||
@ -1462,7 +1462,7 @@ void CParticle::Render()
|
|||||||
|
|
||||||
tParticleType type = psystem->m_Type;
|
tParticleType type = psystem->m_Type;
|
||||||
|
|
||||||
#ifndef MASTER
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
if (!bEnableBannedParticles)
|
if (!bEnableBannedParticles)
|
||||||
#endif
|
#endif
|
||||||
if ( type == PARTICLE_ENGINE_SMOKE
|
if ( type == PARTICLE_ENGINE_SMOKE
|
||||||
|
@ -24,6 +24,8 @@ bool gbShowPedRoadGroups;
|
|||||||
bool gbShowCarRoadGroups;
|
bool gbShowCarRoadGroups;
|
||||||
bool gbShowCollisionPolys;
|
bool gbShowCollisionPolys;
|
||||||
bool gbShowCollisionLines;
|
bool gbShowCollisionLines;
|
||||||
|
bool gbShowCullZoneDebugStuff;
|
||||||
|
bool gbBigWhiteDebugLightSwitchedOn;
|
||||||
|
|
||||||
bool gbDontRenderBuildings;
|
bool gbDontRenderBuildings;
|
||||||
bool gbDontRenderBigBuildings;
|
bool gbDontRenderBigBuildings;
|
||||||
|
@ -6,6 +6,8 @@ extern bool gbShowPedRoadGroups;
|
|||||||
extern bool gbShowCarRoadGroups;
|
extern bool gbShowCarRoadGroups;
|
||||||
extern bool gbShowCollisionPolys;
|
extern bool gbShowCollisionPolys;
|
||||||
extern bool gbShowCollisionLines;
|
extern bool gbShowCollisionLines;
|
||||||
|
extern bool gbShowCullZoneDebugStuff;
|
||||||
|
extern bool gbBigWhiteDebugLightSwitchedOn;
|
||||||
|
|
||||||
extern bool gbDontRenderBuildings;
|
extern bool gbDontRenderBuildings;
|
||||||
extern bool gbDontRenderBigBuildings;
|
extern bool gbDontRenderBigBuildings;
|
||||||
|
@ -1516,11 +1516,11 @@ CShadows::UpdatePermanentShadows(void)
|
|||||||
aPermanentShadows[i].m_nType = SHADOWTYPE_NONE;
|
aPermanentShadows[i].m_nType = SHADOWTYPE_NONE;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( timePassed >= (aPermanentShadows[i].m_nLifeTime*(1-(1/4))) )
|
if ( timePassed >= (aPermanentShadows[i].m_nLifeTime * 3 / 4) )
|
||||||
{
|
{
|
||||||
// timePassed == 0 -> 4
|
// timePassed == 0 -> 4
|
||||||
// timePassed == aPermanentShadows[i].m_nLifeTime -> 0
|
// timePassed == aPermanentShadows[i].m_nLifeTime -> 0
|
||||||
float fMult = 1.0f - (timePassed - (aPermanentShadows[i].m_nLifeTime*(1-(1/4)))) / (aPermanentShadows[i].m_nLifeTime / 4);
|
float fMult = 1.0f - float(timePassed - (aPermanentShadows[i].m_nLifeTime * 3 / 4)) / (aPermanentShadows[i].m_nLifeTime / 4);
|
||||||
|
|
||||||
StoreStaticShadow((uint32)&aPermanentShadows[i],
|
StoreStaticShadow((uint32)&aPermanentShadows[i],
|
||||||
aPermanentShadows[i].m_nType,
|
aPermanentShadows[i].m_nType,
|
||||||
|
@ -3004,6 +3004,13 @@ BOOL _InputIsExtended(INT flag)
|
|||||||
return (flag & 0x1000000) != 0;
|
return (flag & 0x1000000) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (defined(_MSC_VER))
|
||||||
|
int strcasecmp(const char *str1, const char *str2)
|
||||||
|
{
|
||||||
|
return _strcmpi(str1, str2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
STARTPATCHES
|
STARTPATCHES
|
||||||
//InjectHook(0x580B30, &CJoySticks::CJoySticks, PATCH_JUMP);
|
//InjectHook(0x580B30, &CJoySticks::CJoySticks, PATCH_JUMP);
|
||||||
|
@ -1014,7 +1014,7 @@ CAutomobile::ProcessControl(void)
|
|||||||
m_vecMoveSpeed.Magnitude() > 0.0f && CTimer::GetTimeStep() > 0.0f){
|
m_vecMoveSpeed.Magnitude() > 0.0f && CTimer::GetTimeStep() > 0.0f){
|
||||||
FlyingControl(FLIGHT_MODEL_DODO);
|
FlyingControl(FLIGHT_MODEL_DODO);
|
||||||
}else if(GetModelIndex() == MI_MIAMI_RCBARON){
|
}else if(GetModelIndex() == MI_MIAMI_RCBARON){
|
||||||
FlyingControl(FLIGHT_MODEL_HELI);
|
FlyingControl(FLIGHT_MODEL_RCPLANE);
|
||||||
}else if(GetModelIndex() == MI_MIAMI_RCRAIDER || GetModelIndex() == MI_MIAMI_SPARROW || bAllCarCheat){
|
}else if(GetModelIndex() == MI_MIAMI_RCRAIDER || GetModelIndex() == MI_MIAMI_SPARROW || bAllCarCheat){
|
||||||
if(CPad::GetPad(0)->GetCircleJustDown())
|
if(CPad::GetPad(0)->GetCircleJustDown())
|
||||||
m_aWheelSpeed[0] = max(m_aWheelSpeed[0]-0.03f, 0.0f);
|
m_aWheelSpeed[0] = max(m_aWheelSpeed[0]-0.03f, 0.0f);
|
||||||
@ -1918,7 +1918,7 @@ CAutomobile::Render(void)
|
|||||||
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
|
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
|
||||||
|
|
||||||
if(GetModelIndex() == MI_RHINO && m_aCarNodes[CAR_BONNET]){
|
if(GetModelIndex() == MI_RHINO && m_aCarNodes[CAR_BONNET]){
|
||||||
// Rhino has no bonnet...what are we doing here?
|
// Rotate Rhino turret
|
||||||
CMatrix m;
|
CMatrix m;
|
||||||
CVector p;
|
CVector p;
|
||||||
m.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BONNET]));
|
m.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BONNET]));
|
||||||
|
@ -288,7 +288,7 @@ class cTransmission;
|
|||||||
class cVehicleParams
|
class cVehicleParams
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
uint8 m_bDistancECalculated;
|
bool m_bDistanceCalculated;
|
||||||
char gap_1[3];
|
char gap_1[3];
|
||||||
float m_fDistance;
|
float m_fDistance;
|
||||||
CVehicle *m_pVehicle;
|
CVehicle *m_pVehicle;
|
||||||
@ -297,4 +297,4 @@ public:
|
|||||||
float m_fVelocityChange;
|
float m_fVelocityChange;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(cVehicleParams) == 0x18, "CVehicle: error");
|
static_assert(sizeof(cVehicleParams) == 0x18, "cVehicleParams: error");
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
#include "ProjectileInfo.h"
|
#include "ProjectileInfo.h"
|
||||||
#include "Projectile.h"
|
#include "Projectile.h"
|
||||||
|
|
||||||
|
WRAPPER void CProjectileInfo::RemoveAllProjectiles(void) { EAXJMP(0x55BB80); }
|
||||||
WRAPPER bool CProjectileInfo::RemoveIfThisIsAProjectile(CObject *pObject) { EAXJMP(0x55BBD0); }
|
WRAPPER bool CProjectileInfo::RemoveIfThisIsAProjectile(CObject *pObject) { EAXJMP(0x55BBD0); }
|
||||||
WRAPPER bool CProjectileInfo::IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove) { EAXJMP(0x55BA50); }
|
WRAPPER bool CProjectileInfo::IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove) { EAXJMP(0x55BA50); }
|
||||||
|
@ -6,5 +6,6 @@ class CProjectileInfo
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static bool RemoveIfThisIsAProjectile(CObject *pObject);
|
static bool RemoveIfThisIsAProjectile(CObject *pObject);
|
||||||
|
static void RemoveAllProjectiles(void);
|
||||||
static bool IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove);
|
static bool IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove);
|
||||||
};
|
};
|
Loading…
Reference in New Issue
Block a user