CShotInfo, CWanted done, Frontend fix
This commit is contained in:
parent
39c9a05827
commit
a3b519ea64
@ -42,7 +42,6 @@ cAudioManager - WIP
|
|||||||
CBoat
|
CBoat
|
||||||
CBrightLights
|
CBrightLights
|
||||||
CBulletInfo
|
CBulletInfo
|
||||||
CBulletTraces
|
|
||||||
CCamera
|
CCamera
|
||||||
CCrane
|
CCrane
|
||||||
CCranes
|
CCranes
|
||||||
@ -52,7 +51,6 @@ CExplosion
|
|||||||
CFallingGlassPane
|
CFallingGlassPane
|
||||||
CFire
|
CFire
|
||||||
CFireManager
|
CFireManager
|
||||||
CGame
|
|
||||||
CGarage
|
CGarage
|
||||||
CGarages
|
CGarages
|
||||||
CGlass
|
CGlass
|
||||||
@ -66,15 +64,10 @@ CRoadBlocks
|
|||||||
CRubbish
|
CRubbish
|
||||||
CSceneEdit
|
CSceneEdit
|
||||||
CSkidmarks
|
CSkidmarks
|
||||||
CShotInfo
|
|
||||||
CSpecialFX
|
CSpecialFX
|
||||||
CStats
|
CStats
|
||||||
CTrafficLights
|
CTrafficLights
|
||||||
CWanted
|
|
||||||
CWaterCannon
|
|
||||||
CWaterCannons
|
|
||||||
CWeapon
|
CWeapon
|
||||||
CWeaponEffects
|
|
||||||
CWeather
|
CWeather
|
||||||
CWorld
|
CWorld
|
||||||
```
|
```
|
||||||
|
@ -210,18 +210,6 @@ CEventList::ReportCrimeForEvent(eEventType type, int32 crimeId, bool copsDontCar
|
|||||||
default: crime = CRIME_NONE; break;
|
default: crime = CRIME_NONE; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VC_PED_PORTS
|
|
||||||
if (crime == CRIME_HIT_PED && ((CPed*)crimeId)->IsPointerValid() &&
|
|
||||||
FindPlayerPed()->m_pWanted->m_nWantedLevel == 0 && ((CPed*)crimeId)->bBeingChasedByPolice) {
|
|
||||||
|
|
||||||
if(!((CPed*)crimeId)->DyingOrDead()) {
|
|
||||||
sprintf(gString, "$50 Good Citizen Bonus!");
|
|
||||||
AsciiToUnicode(gString, gUString);
|
|
||||||
CMessages::AddBigMessage(gUString, 5000, 0);
|
|
||||||
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 50;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
if(crime == CRIME_NONE)
|
if(crime == CRIME_NONE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1354,23 +1354,39 @@ void CMenuManager::DrawFrontEndNormal()
|
|||||||
|
|
||||||
m_aFrontEndSprites[currentSprite].Draw(CRect(MENU_X_LEFT_ALIGNED(50.0f), MENU_Y(50.0f), MENU_X_RIGHT_ALIGNED(50.0f), SCREEN_SCALE_FROM_BOTTOM(95.0f)), CRGBA(255, 255, 255, m_nMenuFadeAlpha > 255 ? 255 : m_nMenuFadeAlpha));
|
m_aFrontEndSprites[currentSprite].Draw(CRect(MENU_X_LEFT_ALIGNED(50.0f), MENU_Y(50.0f), MENU_X_RIGHT_ALIGNED(50.0f), SCREEN_SCALE_FROM_BOTTOM(95.0f)), CRGBA(255, 255, 255, m_nMenuFadeAlpha > 255 ? 255 : m_nMenuFadeAlpha));
|
||||||
|
|
||||||
|
static float fadeAlpha = 0.0f;
|
||||||
|
static int lastState = 0;
|
||||||
|
|
||||||
|
// reverseAlpha = PS2 fading (wait for 255->0, then change screen)
|
||||||
if (m_nMenuFadeAlpha < 255) {
|
if (m_nMenuFadeAlpha < 255) {
|
||||||
static uint32 LastFade = 0;
|
if (lastState == 1 && !reverseAlpha)
|
||||||
|
fadeAlpha = 0.f;
|
||||||
|
|
||||||
if (m_nMenuFadeAlpha <= 0 && reverseAlpha) {
|
if (m_nMenuFadeAlpha <= 0 && reverseAlpha) {
|
||||||
reverseAlpha = false;
|
reverseAlpha = false;
|
||||||
ChangeScreen(pendingScreen, pendingOption, true, false);
|
ChangeScreen(pendingScreen, pendingOption, true, false);
|
||||||
} else {
|
} else {
|
||||||
if (!reverseAlpha)
|
float timestep = CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
|
||||||
m_nMenuFadeAlpha += min((CTimer::GetTimeInMillisecondsPauseMode() - LastFade) / 33.0f, 1.0f) * 20.0f;
|
|
||||||
else
|
|
||||||
m_nMenuFadeAlpha = max(0, m_nMenuFadeAlpha - min((CTimer::GetTimeInMillisecondsPauseMode() - LastFade) / 33.0f, 1.0f) * 30.0f);
|
|
||||||
|
|
||||||
LastFade = CTimer::GetTimeInMillisecondsPauseMode();
|
// +20 per every 33 ms (1000.f/30.f - original frame limiter fps)
|
||||||
|
if (!reverseAlpha)
|
||||||
|
fadeAlpha += (timestep * 100.f) * 20.f / 33.f;
|
||||||
|
else
|
||||||
|
fadeAlpha = max(0.0f, fadeAlpha - (timestep * 100.f) * 30.f / 33.f);
|
||||||
|
|
||||||
|
m_nMenuFadeAlpha = fadeAlpha;
|
||||||
}
|
}
|
||||||
|
lastState = 0;
|
||||||
} else {
|
} else {
|
||||||
if (reverseAlpha)
|
if (lastState == 0) fadeAlpha = 255.f;
|
||||||
m_nMenuFadeAlpha -= 20;
|
|
||||||
|
if (reverseAlpha) {
|
||||||
|
float timestep = CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
|
||||||
|
fadeAlpha -= (timestep * 100.f) * 30.f / 33.f;
|
||||||
|
|
||||||
|
m_nMenuFadeAlpha = fadeAlpha;
|
||||||
|
}
|
||||||
|
lastState = 1;
|
||||||
|
|
||||||
// TODO: what is this? waiting mouse?
|
// TODO: what is this? waiting mouse?
|
||||||
if(field_518 == 4){
|
if(field_518 == 4){
|
||||||
@ -1568,13 +1584,20 @@ void CMenuManager::DrawFrontEndNormal()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_nMenuFadeAlpha < 255) {
|
if (m_nMenuFadeAlpha < 255) {
|
||||||
|
|
||||||
|
// Famous transparent menu bug
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
static float fadeAlpha = 0.0f;
|
||||||
|
if (m_nMenuFadeAlpha == 0 && fadeAlpha > 1.0f) fadeAlpha = 0.0f;
|
||||||
|
|
||||||
|
float timestep = CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
|
||||||
|
|
||||||
|
// +20 per every 33 ms (1000.f/30.f - original frame limiter fps)
|
||||||
|
fadeAlpha += (timestep * 100.f) * 20.f / 33.f;
|
||||||
|
m_nMenuFadeAlpha = fadeAlpha;
|
||||||
|
#else
|
||||||
static uint32 LastFade = 0;
|
static uint32 LastFade = 0;
|
||||||
|
|
||||||
// Famous transparent menu bug. 33.0f = 1000.f/30.f (original frame limiter fps)
|
|
||||||
#ifdef FIX_BUGS
|
|
||||||
m_nMenuFadeAlpha += min((CTimer::GetTimeInMillisecondsPauseMode() - LastFade) / 33.0f, 1.0f) * 20.0f;
|
|
||||||
LastFade = CTimer::GetTimeInMillisecondsPauseMode();
|
|
||||||
#else
|
|
||||||
if(CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 10){
|
if(CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 10){
|
||||||
m_nMenuFadeAlpha += 20;
|
m_nMenuFadeAlpha += 20;
|
||||||
LastFade = CTimer::GetTimeInMillisecondsPauseMode();
|
LastFade = CTimer::GetTimeInMillisecondsPauseMode();
|
||||||
|
@ -7,19 +7,16 @@
|
|||||||
#include "ZoneCull.h"
|
#include "ZoneCull.h"
|
||||||
#include "Darkel.h"
|
#include "Darkel.h"
|
||||||
#include "DMAudio.h"
|
#include "DMAudio.h"
|
||||||
|
#include "CopPed.h"
|
||||||
#include "Wanted.h"
|
#include "Wanted.h"
|
||||||
|
#include "General.h"
|
||||||
|
|
||||||
int32 &CWanted::MaximumWantedLevel = *(int32*)0x5F7714; // 6
|
int32 &CWanted::MaximumWantedLevel = *(int32*)0x5F7714; // 6
|
||||||
int32 &CWanted::nMaximumWantedLevel = *(int32*)0x5F7718; // 6400
|
int32 &CWanted::nMaximumWantedLevel = *(int32*)0x5F7718; // 6400
|
||||||
|
|
||||||
WRAPPER void CWanted::Reset() { EAXJMP(0x4AD790) };
|
|
||||||
WRAPPER void CWanted::Update() { EAXJMP(0x4AD7B0) };
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CWanted::Initialise()
|
CWanted::Initialise()
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
m_nChaos = 0;
|
m_nChaos = 0;
|
||||||
m_nLastUpdateTime = 0;
|
m_nLastUpdateTime = 0;
|
||||||
m_nLastWantedLevelChange = 0;
|
m_nLastWantedLevelChange = 0;
|
||||||
@ -35,8 +32,10 @@ CWanted::Initialise()
|
|||||||
m_fCrimeSensitivity = 1.0f;
|
m_fCrimeSensitivity = 1.0f;
|
||||||
m_nWantedLevel = 0;
|
m_nWantedLevel = 0;
|
||||||
m_CopsBeatingSuspect = 0;
|
m_CopsBeatingSuspect = 0;
|
||||||
for(i = 0; i < 10; i++)
|
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(m_pCops); i++)
|
||||||
m_pCops[i] = nil;
|
m_pCops[i] = nil;
|
||||||
|
|
||||||
ClearQdCrimes();
|
ClearQdCrimes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +60,7 @@ CWanted::AreArmyRequired()
|
|||||||
int32
|
int32
|
||||||
CWanted::NumOfHelisRequired()
|
CWanted::NumOfHelisRequired()
|
||||||
{
|
{
|
||||||
if (m_bIgnoredByCops)
|
if (m_bIgnoredByCops || m_bIgnoredByEveryone)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (m_nWantedLevel) {
|
switch (m_nWantedLevel) {
|
||||||
@ -79,9 +78,10 @@ CWanted::NumOfHelisRequired()
|
|||||||
void
|
void
|
||||||
CWanted::SetWantedLevel(int32 level)
|
CWanted::SetWantedLevel(int32 level)
|
||||||
{
|
{
|
||||||
ClearQdCrimes();
|
|
||||||
if (level > MaximumWantedLevel)
|
if (level > MaximumWantedLevel)
|
||||||
level = MaximumWantedLevel;
|
level = MaximumWantedLevel;
|
||||||
|
|
||||||
|
ClearQdCrimes();
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case 0:
|
case 0:
|
||||||
m_nChaos = 0;
|
m_nChaos = 0;
|
||||||
@ -360,10 +360,107 @@ CWanted::WorkOutPolicePresence(CVector posn, float radius)
|
|||||||
return numPolice;
|
return numPolice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CWanted::Update(void)
|
||||||
|
{
|
||||||
|
if (CTimer::GetTimeInMilliseconds() - m_nLastUpdateTime > 1000) {
|
||||||
|
if (m_nWantedLevel > 1) {
|
||||||
|
m_nLastUpdateTime = CTimer::GetTimeInMilliseconds();
|
||||||
|
} else {
|
||||||
|
float radius = 18.0f;
|
||||||
|
CVector playerPos = FindPlayerCoors();
|
||||||
|
if (WorkOutPolicePresence(playerPos, radius) == 0) {
|
||||||
|
m_nLastUpdateTime = CTimer::GetTimeInMilliseconds();
|
||||||
|
m_nChaos = max(0, m_nChaos - 1);
|
||||||
|
UpdateWantedLevel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UpdateCrimesQ();
|
||||||
|
bool orderMessedUp = false;
|
||||||
|
int currCopNum = 0;
|
||||||
|
bool foundEmptySlot = false;
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(m_pCops); i++) {
|
||||||
|
if (m_pCops[i]) {
|
||||||
|
++currCopNum;
|
||||||
|
if (foundEmptySlot)
|
||||||
|
orderMessedUp = true;
|
||||||
|
} else {
|
||||||
|
foundEmptySlot = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currCopNum != m_CurrentCops) {
|
||||||
|
printf("CopPursuit total messed up: re-setting\n");
|
||||||
|
m_CurrentCops = currCopNum;
|
||||||
|
}
|
||||||
|
if (orderMessedUp) {
|
||||||
|
printf("CopPursuit pointer list messed up: re-sorting\n");
|
||||||
|
bool fixed = true;
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(m_pCops); i++) {
|
||||||
|
if (!m_pCops[i]) {
|
||||||
|
for (int j = i; j < ARRAY_SIZE(m_pCops); j++) {
|
||||||
|
if (m_pCops[j]) {
|
||||||
|
m_pCops[i] = m_pCops[j];
|
||||||
|
m_pCops[j] = nil;
|
||||||
|
fixed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fixed)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CWanted::ResetPolicePursuit(void)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < ARRAY_SIZE(m_pCops); i++) {
|
||||||
|
CCopPed *cop = m_pCops[i];
|
||||||
|
if (!cop)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cop->m_bIsInPursuit = false;
|
||||||
|
cop->m_objective = OBJECTIVE_NONE;
|
||||||
|
cop->m_prevObjective = OBJECTIVE_NONE;
|
||||||
|
cop->m_nLastPedState = PED_NONE;
|
||||||
|
if (!cop->DyingOrDead()) {
|
||||||
|
cop->SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
|
||||||
|
}
|
||||||
|
m_pCops[i] = nil;
|
||||||
|
}
|
||||||
|
m_CurrentCops = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CWanted::Reset(void)
|
||||||
|
{
|
||||||
|
ResetPolicePursuit();
|
||||||
|
Initialise();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CWanted::UpdateCrimesQ(void)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < ARRAY_SIZE(m_aCrimes); i++) {
|
||||||
|
|
||||||
|
CCrimeBeingQd &crime = m_aCrimes[i];
|
||||||
|
if (crime.m_nType != CRIME_NONE) {
|
||||||
|
if (CTimer::GetTimeInMilliseconds() > crime.m_nTime + 500 && !crime.m_bReported) {
|
||||||
|
ReportCrimeNow(crime.m_nType, crime.m_vecPosn, crime.m_bPoliceDoesntCare);
|
||||||
|
crime.m_bReported = true;
|
||||||
|
}
|
||||||
|
if (CTimer::GetTimeInMilliseconds() > crime.m_nTime + 10000)
|
||||||
|
crime.m_nType = CRIME_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
STARTPATCHES
|
STARTPATCHES
|
||||||
InjectHook(0x4AD6E0, &CWanted::Initialise, PATCH_JUMP);
|
InjectHook(0x4AD6E0, &CWanted::Initialise, PATCH_JUMP);
|
||||||
// InjectHook(0x4AD790, &CWanted::Reset, PATCH_JUMP);
|
InjectHook(0x4AD790, &CWanted::Reset, PATCH_JUMP);
|
||||||
// InjectHook(0x4AD7B0, &CWanted::Update, PATCH_JUMP);
|
InjectHook(0x4AD7B0, &CWanted::Update, PATCH_JUMP);
|
||||||
InjectHook(0x4AD900, &CWanted::UpdateWantedLevel, PATCH_JUMP);
|
InjectHook(0x4AD900, &CWanted::UpdateWantedLevel, PATCH_JUMP);
|
||||||
InjectHook(0x4AD9F0, &CWanted::RegisterCrime, PATCH_JUMP);
|
InjectHook(0x4AD9F0, &CWanted::RegisterCrime, PATCH_JUMP);
|
||||||
InjectHook(0x4ADA10, &CWanted::RegisterCrime_Immediately, PATCH_JUMP);
|
InjectHook(0x4ADA10, &CWanted::RegisterCrime_Immediately, PATCH_JUMP);
|
||||||
@ -374,10 +471,10 @@ STARTPATCHES
|
|||||||
InjectHook(0x4ADBC0, &CWanted::AreFbiRequired, PATCH_JUMP);
|
InjectHook(0x4ADBC0, &CWanted::AreFbiRequired, PATCH_JUMP);
|
||||||
InjectHook(0x4ADBE0, &CWanted::AreArmyRequired, PATCH_JUMP);
|
InjectHook(0x4ADBE0, &CWanted::AreArmyRequired, PATCH_JUMP);
|
||||||
InjectHook(0x4ADC00, &CWanted::NumOfHelisRequired, PATCH_JUMP);
|
InjectHook(0x4ADC00, &CWanted::NumOfHelisRequired, PATCH_JUMP);
|
||||||
// InjectHook(0x4ADC40, &CWanted::ResetPolicePursuit, PATCH_JUMP);
|
InjectHook(0x4ADC40, &CWanted::ResetPolicePursuit, PATCH_JUMP);
|
||||||
InjectHook(0x4ADD00, &CWanted::WorkOutPolicePresence, PATCH_JUMP);
|
InjectHook(0x4ADD00, &CWanted::WorkOutPolicePresence, PATCH_JUMP);
|
||||||
InjectHook(0x4ADF20, &CWanted::ClearQdCrimes, PATCH_JUMP);
|
InjectHook(0x4ADF20, &CWanted::ClearQdCrimes, PATCH_JUMP);
|
||||||
InjectHook(0x4ADFD0, &CWanted::AddCrimeToQ, PATCH_JUMP);
|
InjectHook(0x4ADFD0, &CWanted::AddCrimeToQ, PATCH_JUMP);
|
||||||
// InjectHook(0x4AE090, &CWanted::UpdateCrimesQ, PATCH_JUMP);
|
InjectHook(0x4AE090, &CWanted::UpdateCrimesQ, PATCH_JUMP);
|
||||||
InjectHook(0x4AE110, &CWanted::ReportCrimeNow, PATCH_JUMP);
|
InjectHook(0x4AE110, &CWanted::ReportCrimeNow, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
||||||
|
@ -30,7 +30,7 @@ class CCrimeBeingQd
|
|||||||
public:
|
public:
|
||||||
eCrimeType m_nType;
|
eCrimeType m_nType;
|
||||||
uint32 m_nId;
|
uint32 m_nId;
|
||||||
int32 m_nTime;
|
uint32 m_nTime;
|
||||||
CVector m_vecPosn;
|
CVector m_vecPosn;
|
||||||
bool m_bReported;
|
bool m_bReported;
|
||||||
bool m_bPoliceDoesntCare;
|
bool m_bPoliceDoesntCare;
|
||||||
@ -78,6 +78,8 @@ public:
|
|||||||
void ReportCrimeNow(eCrimeType type, const CVector &coors, bool policeDoesntCare);
|
void ReportCrimeNow(eCrimeType type, const CVector &coors, bool policeDoesntCare);
|
||||||
void UpdateWantedLevel();
|
void UpdateWantedLevel();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
void ResetPolicePursuit();
|
||||||
|
void UpdateCrimesQ();
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
bool IsIgnored(void) { return m_bIgnoredByCops || m_bIgnoredByEveryone; }
|
bool IsIgnored(void) { return m_bIgnoredByCops || m_bIgnoredByEveryone; }
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "Messages.h"
|
#include "Messages.h"
|
||||||
#include "Replay.h"
|
#include "Replay.h"
|
||||||
#include "Population.h"
|
#include "Population.h"
|
||||||
|
#include "Fire.h"
|
||||||
|
|
||||||
CColPoint *gaTempSphereColPoints = (CColPoint*)0x6E64C0; // [32]
|
CColPoint *gaTempSphereColPoints = (CColPoint*)0x6E64C0; // [32]
|
||||||
|
|
||||||
@ -1051,6 +1052,19 @@ CWorld::ExtinguishAllCarFiresInArea(CVector point, float range)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CWorld::SetCarsOnFire(float x, float y, float z, float radius, CEntity *reason)
|
||||||
|
{
|
||||||
|
int poolSize = CPools::GetVehiclePool()->GetSize();
|
||||||
|
for (int poolIndex = poolSize - 1; poolIndex >= 0; poolIndex--) {
|
||||||
|
CVehicle *veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
|
||||||
|
if (veh && veh->m_status != STATUS_WRECKED && !veh->m_pCarFire && !veh->bFireProof) {
|
||||||
|
if (Abs(veh->GetPosition().z - z) < 5.0f && Abs(veh->GetPosition().x - x) < radius && Abs(veh->GetPosition().y - y) < radius)
|
||||||
|
gFireManager.StartFire(veh, reason, 0.8f, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CWorld::Process(void)
|
CWorld::Process(void)
|
||||||
{
|
{
|
||||||
|
@ -130,6 +130,7 @@ public:
|
|||||||
static void StopAllLawEnforcersInTheirTracks();
|
static void StopAllLawEnforcersInTheirTracks();
|
||||||
static void SetAllCarsCanBeDamaged(bool);
|
static void SetAllCarsCanBeDamaged(bool);
|
||||||
static void ExtinguishAllCarFiresInArea(CVector, float);
|
static void ExtinguishAllCarFiresInArea(CVector, float);
|
||||||
|
static void SetCarsOnFire(float, float, float, float, CEntity*);
|
||||||
|
|
||||||
static void Initialise();
|
static void Initialise();
|
||||||
static void AddParticles();
|
static void AddParticles();
|
||||||
|
@ -100,6 +100,7 @@ enum Config {
|
|||||||
NUMPHONES = 50,
|
NUMPHONES = 50,
|
||||||
NUMPEDGROUPS = 31,
|
NUMPEDGROUPS = 31,
|
||||||
NUMMODELSPERPEDGROUP = 8,
|
NUMMODELSPERPEDGROUP = 8,
|
||||||
|
NUMSHOTINFOS = 100,
|
||||||
|
|
||||||
NUMROADBLOCKS = 600,
|
NUMROADBLOCKS = 600,
|
||||||
|
|
||||||
|
@ -2056,13 +2056,7 @@ _WinMain(HINSTANCE instance,
|
|||||||
{
|
{
|
||||||
GetWindowPlacement(PSGLOBAL(window), &wp);
|
GetWindowPlacement(PSGLOBAL(window), &wp);
|
||||||
|
|
||||||
// Famous transparent menu bug. Also see the fix in Frontend.cpp
|
|
||||||
#ifdef FIX_BUGS
|
|
||||||
float ms = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
|
|
||||||
if ((1000.0f / 100.0f) < ms && wp.showCmd != SW_SHOWMINIMIZED)
|
|
||||||
#else
|
|
||||||
if (wp.showCmd != SW_SHOWMINIMIZED)
|
if (wp.showCmd != SW_SHOWMINIMIZED)
|
||||||
#endif
|
|
||||||
RsEventHandler(rsFRONTENDIDLE, nil);
|
RsEventHandler(rsFRONTENDIDLE, nil);
|
||||||
|
|
||||||
if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bLoadingSavedGame )
|
if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bLoadingSavedGame )
|
||||||
|
140
src/weapons/ShotInfo.cpp
Normal file
140
src/weapons/ShotInfo.cpp
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "ShotInfo.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "Weapon.h"
|
||||||
|
#include "World.h"
|
||||||
|
#include "WeaponInfo.h"
|
||||||
|
#include "General.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
#include "Ped.h"
|
||||||
|
#include "Fire.h"
|
||||||
|
|
||||||
|
CShotInfo gaShotInfo[NUMSHOTINFOS];
|
||||||
|
float CShotInfo::ms_afRandTable[20];
|
||||||
|
|
||||||
|
// CShotInfo (&gaShotInfo)[100] = *(CShotInfo(*)[100])*(uintptr*)0x64F0D0;
|
||||||
|
// float (&CShotInfo::ms_afRandTable)[20] = *(float(*)[20])*(uintptr*)0x6E9878;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Used for flamethrower. I don't know why it's name is CShotInfo.
|
||||||
|
Has no relation with any visual, just calculates the area fire affects
|
||||||
|
(including spreading and slowing of fire) and make entities burn/flee.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
CShotInfo::Initialise()
|
||||||
|
{
|
||||||
|
debug("Initialising CShotInfo...\n");
|
||||||
|
for(int i=0; i<ARRAY_SIZE(gaShotInfo); i++) {
|
||||||
|
gaShotInfo[i].m_inUse = false;
|
||||||
|
gaShotInfo[i].m_weapon = WEAPONTYPE_COLT45;
|
||||||
|
gaShotInfo[i].m_startPos = CVector(0.0f, 0.0f, 0.0f);
|
||||||
|
gaShotInfo[i].m_areaAffected = CVector(0.0f, 0.0f, 0.0f);
|
||||||
|
gaShotInfo[i].m_radius = 1.0f;
|
||||||
|
gaShotInfo[i].m_sourceEntity = nil;
|
||||||
|
gaShotInfo[i].m_timeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not random for sure
|
||||||
|
float nextVal = -0.05f;
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(ms_afRandTable); i++) {
|
||||||
|
ms_afRandTable[i] = nextVal;
|
||||||
|
nextVal += 0.005f;
|
||||||
|
}
|
||||||
|
debug("CShotInfo ready\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CShotInfo::AddShot(CEntity *sourceEntity, eWeaponType weapon, CVector startPos, CVector endPos)
|
||||||
|
{
|
||||||
|
CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(weapon);
|
||||||
|
|
||||||
|
int slot;
|
||||||
|
for (slot = 0; slot < ARRAY_SIZE(gaShotInfo) && gaShotInfo[slot].m_inUse; slot++);
|
||||||
|
|
||||||
|
if (slot == ARRAY_SIZE(gaShotInfo))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
gaShotInfo[slot].m_inUse = true;
|
||||||
|
gaShotInfo[slot].m_weapon = weapon;
|
||||||
|
gaShotInfo[slot].m_startPos = startPos;
|
||||||
|
gaShotInfo[slot].m_areaAffected = endPos - startPos;
|
||||||
|
gaShotInfo[slot].m_radius = weaponInfo->m_fRadius;
|
||||||
|
|
||||||
|
if (weaponInfo->m_fSpread != 0.0f) {
|
||||||
|
gaShotInfo[slot].m_areaAffected.x += CShotInfo::ms_afRandTable[CGeneral::GetRandomNumber() % ARRAY_SIZE(ms_afRandTable)] * weaponInfo->m_fSpread;
|
||||||
|
gaShotInfo[slot].m_areaAffected.y += CShotInfo::ms_afRandTable[CGeneral::GetRandomNumber() % ARRAY_SIZE(ms_afRandTable)] * weaponInfo->m_fSpread;
|
||||||
|
gaShotInfo[slot].m_areaAffected.z += CShotInfo::ms_afRandTable[CGeneral::GetRandomNumber() % ARRAY_SIZE(ms_afRandTable)];
|
||||||
|
}
|
||||||
|
gaShotInfo[slot].m_areaAffected.Normalise();
|
||||||
|
if (weaponInfo->m_bRandSpeed)
|
||||||
|
gaShotInfo[slot].m_areaAffected *= CShotInfo::ms_afRandTable[CGeneral::GetRandomNumber() % ARRAY_SIZE(ms_afRandTable)] + weaponInfo->m_fSpeed;
|
||||||
|
else
|
||||||
|
gaShotInfo[slot].m_areaAffected *= weaponInfo->m_fSpeed;
|
||||||
|
|
||||||
|
gaShotInfo[slot].m_sourceEntity = sourceEntity;
|
||||||
|
gaShotInfo[slot].m_timeout = CTimer::GetTimeInMilliseconds() + weaponInfo->m_fLifespan;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CShotInfo::Shutdown()
|
||||||
|
{
|
||||||
|
debug("Shutting down CShotInfo...\n");
|
||||||
|
debug("CShotInfo shut down\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CShotInfo::Update()
|
||||||
|
{
|
||||||
|
for (int slot = 0; slot < ARRAY_SIZE(gaShotInfo); slot++) {
|
||||||
|
CShotInfo &shot = gaShotInfo[slot];
|
||||||
|
if (shot.m_sourceEntity && shot.m_sourceEntity->IsPed() && !((CPed*)shot.m_sourceEntity)->IsPointerValid())
|
||||||
|
shot.m_sourceEntity = nil;
|
||||||
|
|
||||||
|
if (!shot.m_inUse)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(shot.m_weapon);
|
||||||
|
if (CTimer::GetTimeInMilliseconds() > shot.m_timeout)
|
||||||
|
shot.m_inUse = false;
|
||||||
|
|
||||||
|
if (weaponInfo->m_bSlowsDown)
|
||||||
|
shot.m_areaAffected *= pow(0.96, CTimer::GetTimeStep()); // FRAMERATE
|
||||||
|
|
||||||
|
if (weaponInfo->m_bExpands)
|
||||||
|
shot.m_radius += 0.075f * CTimer::GetTimeStep();
|
||||||
|
|
||||||
|
shot.m_startPos += CTimer::GetTimeStep() * shot.m_areaAffected;
|
||||||
|
if (shot.m_sourceEntity) {
|
||||||
|
assert(shot.m_sourceEntity->IsPed());
|
||||||
|
CPed *ped = (CPed*) shot.m_sourceEntity;
|
||||||
|
float radius = max(1.0f, shot.m_radius);
|
||||||
|
|
||||||
|
for (int i = 0; i < ped->m_numNearPeds; ++i) {
|
||||||
|
CPed *nearPed = ped->m_nearPeds[i];
|
||||||
|
if (nearPed->IsPointerValid()) {
|
||||||
|
if (nearPed->IsPedInControl() && (nearPed->GetPosition() - shot.m_startPos).MagnitudeSqr() < radius && !nearPed->bFireProof) {
|
||||||
|
|
||||||
|
if (!nearPed->IsPlayer()) {
|
||||||
|
nearPed->SetFindPathAndFlee(shot.m_sourceEntity, 10000);
|
||||||
|
nearPed->SetMoveState(PEDMOVE_SPRINT);
|
||||||
|
}
|
||||||
|
gFireManager.StartFire(nearPed, shot.m_sourceEntity, 0.8f, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!((CTimer::GetFrameCounter() + slot) & 3))
|
||||||
|
CWorld::SetCarsOnFire(shot.m_startPos.x, shot.m_startPos.y, shot.m_startPos.z, 4.0f, shot.m_sourceEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STARTPATCHES
|
||||||
|
InjectHook(0x55BFF0, &CShotInfo::Update, PATCH_JUMP);
|
||||||
|
InjectHook(0x55BD70, &CShotInfo::AddShot, PATCH_JUMP);
|
||||||
|
InjectHook(0x55BC60, &CShotInfo::Initialise, PATCH_JUMP);
|
||||||
|
InjectHook(0x55BD50, &CShotInfo::Shutdown, PATCH_JUMP);
|
||||||
|
ENDPATCHES
|
23
src/weapons/ShotInfo.h
Normal file
23
src/weapons/ShotInfo.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class CEntity;
|
||||||
|
enum eWeaponType;
|
||||||
|
|
||||||
|
class CShotInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
eWeaponType m_weapon;
|
||||||
|
CVector m_startPos;
|
||||||
|
CVector m_areaAffected;
|
||||||
|
float m_radius;
|
||||||
|
CEntity *m_sourceEntity;
|
||||||
|
float m_timeout;
|
||||||
|
bool m_inUse;
|
||||||
|
|
||||||
|
static float ms_afRandTable[20];
|
||||||
|
|
||||||
|
static void Initialise(void);
|
||||||
|
static bool AddShot(CEntity*, eWeaponType, CVector, CVector);
|
||||||
|
static void Shutdown(void);
|
||||||
|
static void Update(void);
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user