commit
29ef6e29f3
@ -11,19 +11,10 @@ CPathFind &ThePaths = *(CPathFind*)0x8F6754;
|
||||
|
||||
WRAPPER bool CPedPath::CalcPedRoute(uint8, CVector, CVector, CVector*, int16*, int16) { EAXJMP(0x42E680); }
|
||||
|
||||
enum
|
||||
{
|
||||
NodeTypeExtern = 1,
|
||||
NodeTypeIntern = 2,
|
||||
|
||||
ObjectFlag1 = 1,
|
||||
ObjectEastWest = 2,
|
||||
|
||||
MAX_DIST = INT16_MAX-1
|
||||
};
|
||||
#define MAX_DIST INT16_MAX-1
|
||||
|
||||
// object flags:
|
||||
// 1
|
||||
// 1 UseInRoadBlock
|
||||
// 2 east/west road(?)
|
||||
|
||||
CPathInfoForObject *&InfoForTileCars = *(CPathInfoForObject**)0x8F1A8C;
|
||||
@ -218,14 +209,14 @@ CPathFind::PreparePathData(void)
|
||||
if(numIntern == 1 && numExtern == 2){
|
||||
if(numLanes < 4){
|
||||
if((i & 7) == 4){ // WHAT?
|
||||
m_objectFlags[i] |= ObjectFlag1;
|
||||
m_objectFlags[i] |= UseInRoadBlock;
|
||||
if(maxX > maxY)
|
||||
m_objectFlags[i] |= ObjectEastWest;
|
||||
else
|
||||
m_objectFlags[i] &= ~ObjectEastWest;
|
||||
}
|
||||
}else{
|
||||
m_objectFlags[i] |= ObjectFlag1;
|
||||
m_objectFlags[i] |= UseInRoadBlock;
|
||||
if(maxX > maxY)
|
||||
m_objectFlags[i] |= ObjectEastWest;
|
||||
else
|
||||
|
@ -9,6 +9,15 @@ public:
|
||||
static bool CalcPedRoute(uint8, CVector, CVector, CVector*, int16*, int16);
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
NodeTypeExtern = 1,
|
||||
NodeTypeIntern = 2,
|
||||
|
||||
UseInRoadBlock = 1,
|
||||
ObjectEastWest = 2,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PATH_CAR = 0,
|
||||
|
@ -1,7 +1,37 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "RoadBlocks.h"
|
||||
#include "PathFind.h"
|
||||
|
||||
int16 &CRoadBlocks::NumRoadBlocks = *(int16*)0x95CC34;
|
||||
int16 (&CRoadBlocks::RoadBlockObjects)[NUMROADBLOCKS] = *(int16(*)[NUMROADBLOCKS]) * (uintptr*)0x72B3A8;
|
||||
bool (&CRoadBlocks::InOrOut)[NUMROADBLOCKS] = *(bool(*)[NUMROADBLOCKS]) * (uintptr*)0x733810;
|
||||
|
||||
WRAPPER void CRoadBlocks::Init(void) { EAXJMP(0x436F50); }
|
||||
WRAPPER void CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle*, int32, int16) { EAXJMP(0x4376A0); }
|
||||
WRAPPER void CRoadBlocks::GenerateRoadBlocks(void) { EAXJMP(0x436FA0); }
|
||||
WRAPPER void CRoadBlocks::GenerateRoadBlocks(void) { EAXJMP(0x436FA0); }
|
||||
|
||||
void
|
||||
CRoadBlocks::Init(void)
|
||||
{
|
||||
NumRoadBlocks = 0;
|
||||
for (int objId = 0; objId < ThePaths.m_numMapObjects; objId++) {
|
||||
if (ThePaths.m_objectFlags[objId] & UseInRoadBlock) {
|
||||
if (NumRoadBlocks < 600) {
|
||||
InOrOut[NumRoadBlocks] = true;
|
||||
RoadBlockObjects[NumRoadBlocks] = objId;
|
||||
NumRoadBlocks++;
|
||||
} else {
|
||||
#ifndef MASTER
|
||||
printf("Not enough room for the potential roadblocks\n");
|
||||
#endif
|
||||
// FIX: Don't iterate loop after NUMROADBLOCKS
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x436F50, &CRoadBlocks::Init, PATCH_JUMP);
|
||||
ENDPATCHES
|
@ -6,6 +6,10 @@ class CVehicle;
|
||||
class CRoadBlocks
|
||||
{
|
||||
public:
|
||||
static int16 (&NumRoadBlocks);
|
||||
static int16 (&RoadBlockObjects)[NUMROADBLOCKS];
|
||||
static bool (&InOrOut)[NUMROADBLOCKS];
|
||||
|
||||
static void Init(void);
|
||||
static void GenerateRoadBlockCopsForCar(CVehicle*, int32, int16);
|
||||
static void GenerateRoadBlocks(void);
|
||||
|
@ -417,6 +417,11 @@ void CControllerConfigManager::UpdateJoyInConfigMenus_ButtonDown(int32 button, i
|
||||
case 13:
|
||||
pad->PCTempJoyState.DPadUp = 255;
|
||||
break;
|
||||
#ifdef REGISTER_START_BUTTON
|
||||
case 12:
|
||||
pad->PCTempJoyState.Start = 255;
|
||||
break;
|
||||
#endif
|
||||
case 11:
|
||||
pad->PCTempJoyState.RightShock = 255;
|
||||
break;
|
||||
@ -839,6 +844,11 @@ void CControllerConfigManager::UpdateJoyInConfigMenus_ButtonUp(int32 button, int
|
||||
case 13:
|
||||
pad->PCTempJoyState.DPadUp = 0;
|
||||
break;
|
||||
#ifdef REGISTER_START_BUTTON
|
||||
case 12:
|
||||
pad->PCTempJoyState.Start = 0;
|
||||
break;
|
||||
#endif
|
||||
case 11:
|
||||
pad->PCTempJoyState.RightShock = 0;
|
||||
break;
|
||||
|
@ -5,10 +5,13 @@
|
||||
#include "World.h"
|
||||
#include "Wanted.h"
|
||||
#include "EventList.h"
|
||||
#include "Messages.h"
|
||||
#include "Text.h"
|
||||
#include "main.h"
|
||||
|
||||
int32 CEventList::ms_nFirstFreeSlotIndex;
|
||||
//CEvent gaEvent[NUMEVENTS];
|
||||
CEvent *gaEvent = (CEvent*)0x6EF830;
|
||||
CEvent gaEvent[NUMEVENTS];
|
||||
//CEvent *gaEvent = (CEvent*)0x6EF830;
|
||||
|
||||
enum
|
||||
{
|
||||
@ -207,8 +210,20 @@ CEventList::ReportCrimeForEvent(eEventType type, int32 crimeId, bool copsDontCar
|
||||
default: crime = CRIME_NONE; break;
|
||||
}
|
||||
|
||||
if(crime == CRIME_NONE)
|
||||
return;
|
||||
#ifdef VC_PED_PORTS
|
||||
if (crime == CRIME_HIT_PED && ((CPed*)crimeId)->IsPointerValid() &&
|
||||
FindPlayerPed()->m_pWanted->m_nWantedLevel == 0 && ((CPed*)crimeId)->m_ped_flagE2) {
|
||||
|
||||
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)
|
||||
return;
|
||||
|
||||
CVector playerPedCoors = FindPlayerPed()->GetPosition();
|
||||
CVector playerCoors = FindPlayerCoors();
|
||||
|
@ -63,4 +63,4 @@ public:
|
||||
static void ReportCrimeForEvent(eEventType type, int32, bool);
|
||||
};
|
||||
|
||||
extern CEvent *gaEvent;
|
||||
extern CEvent gaEvent[NUMEVENTS];
|
@ -181,6 +181,7 @@ ScaleAndCenterX(float x)
|
||||
#endif
|
||||
|
||||
#define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS || screen == MENUPAGE_STATS)
|
||||
|
||||
#ifdef PS2_LIKE_MENU
|
||||
#define ChangeScreen(screen, option, updateDelay, withReverseAlpha) \
|
||||
do { \
|
||||
@ -235,67 +236,100 @@ ScaleAndCenterX(float x)
|
||||
m_nHoverOption = HOVEROPTION_NOT_HOVERING; \
|
||||
} while(0)
|
||||
|
||||
#define ScrollUpListByOne() \
|
||||
do { \
|
||||
if (m_nSelectedListRow == m_nFirstVisibleRowOnList) { \
|
||||
if (m_nFirstVisibleRowOnList > 0) { \
|
||||
m_nSelectedListRow--; \
|
||||
m_nFirstVisibleRowOnList--; \
|
||||
m_nCurListItemY -= LIST_HEIGHT / m_nTotalListRow; \
|
||||
} \
|
||||
} else { \
|
||||
m_nSelectedListRow--; \
|
||||
} \
|
||||
} while(0)
|
||||
// --- Functions not in the game/inlined starts
|
||||
|
||||
#define ScrollDownListByOne() \
|
||||
do { \
|
||||
if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1) { \
|
||||
if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) { \
|
||||
m_nSelectedListRow++; \
|
||||
m_nFirstVisibleRowOnList++; \
|
||||
m_nCurListItemY += LIST_HEIGHT / m_nTotalListRow; \
|
||||
} \
|
||||
} else { \
|
||||
if (m_nSelectedListRow < m_nTotalListRow - 1) { \
|
||||
m_nSelectedListRow++; \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
inline void
|
||||
CMenuManager::ScrollUpListByOne()
|
||||
{
|
||||
if (m_nSelectedListRow == m_nFirstVisibleRowOnList) {
|
||||
if (m_nFirstVisibleRowOnList > 0) {
|
||||
m_nSelectedListRow--;
|
||||
m_nFirstVisibleRowOnList--;
|
||||
m_nCurListItemY -= LIST_HEIGHT / m_nTotalListRow;
|
||||
}
|
||||
} else {
|
||||
m_nSelectedListRow--;
|
||||
}
|
||||
}
|
||||
|
||||
#define PageUpList(playSoundOnSuccess) \
|
||||
do { \
|
||||
if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { \
|
||||
if (m_nFirstVisibleRowOnList > 0) { \
|
||||
if(playSoundOnSuccess) \
|
||||
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0); \
|
||||
\
|
||||
m_nFirstVisibleRowOnList = max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_LIST_ROW); \
|
||||
m_nSelectedListRow = min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1); \
|
||||
} else { \
|
||||
m_nFirstVisibleRowOnList = 0; \
|
||||
m_nSelectedListRow = 0; \
|
||||
} \
|
||||
m_nCurListItemY = (LIST_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; \
|
||||
} \
|
||||
} while(0)
|
||||
inline void
|
||||
CMenuManager::ScrollDownListByOne()
|
||||
{
|
||||
if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1) {
|
||||
if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) {
|
||||
m_nSelectedListRow++;
|
||||
m_nFirstVisibleRowOnList++;
|
||||
m_nCurListItemY += LIST_HEIGHT / m_nTotalListRow;
|
||||
}
|
||||
} else {
|
||||
if (m_nSelectedListRow < m_nTotalListRow - 1) {
|
||||
m_nSelectedListRow++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define PageDownList(playSoundOnSuccess) \
|
||||
do { \
|
||||
if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { \
|
||||
if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) { \
|
||||
if(playSoundOnSuccess) \
|
||||
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0); \
|
||||
\
|
||||
m_nFirstVisibleRowOnList = min(m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW, m_nTotalListRow - MAX_VISIBLE_LIST_ROW); \
|
||||
m_nSelectedListRow = max(m_nSelectedListRow, m_nFirstVisibleRowOnList); \
|
||||
} else { \
|
||||
m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW; \
|
||||
m_nSelectedListRow = m_nTotalListRow - 1; \
|
||||
} \
|
||||
m_nCurListItemY = (LIST_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; \
|
||||
} \
|
||||
} while(0)
|
||||
inline void
|
||||
CMenuManager::PageUpList(bool playSoundOnSuccess)
|
||||
{
|
||||
if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) {
|
||||
if (m_nFirstVisibleRowOnList > 0) {
|
||||
if(playSoundOnSuccess)
|
||||
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
|
||||
|
||||
m_nFirstVisibleRowOnList = max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_LIST_ROW);
|
||||
m_nSelectedListRow = min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1);
|
||||
} else {
|
||||
m_nFirstVisibleRowOnList = 0;
|
||||
m_nSelectedListRow = 0;
|
||||
}
|
||||
m_nCurListItemY = (LIST_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
CMenuManager::PageDownList(bool playSoundOnSuccess)
|
||||
{
|
||||
if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) {
|
||||
if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) {
|
||||
if(playSoundOnSuccess)
|
||||
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
|
||||
|
||||
m_nFirstVisibleRowOnList = min(m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW, m_nTotalListRow - MAX_VISIBLE_LIST_ROW);
|
||||
m_nSelectedListRow = max(m_nSelectedListRow, m_nFirstVisibleRowOnList);
|
||||
} else {
|
||||
m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW;
|
||||
m_nSelectedListRow = m_nTotalListRow - 1;
|
||||
}
|
||||
m_nCurListItemY = (LIST_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
CMenuManager::ThingsToDoBeforeLeavingPage()
|
||||
{
|
||||
if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && strcmp(m_aSkinName, m_PrefsSkinFile) != 0) {
|
||||
CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
|
||||
} else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) {
|
||||
if (m_nPrefsAudio3DProviderIndex != -1)
|
||||
m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex();
|
||||
#ifdef TIDY_UP_PBP
|
||||
DMAudio.StopFrontEndTrack();
|
||||
OutputDebugString("FRONTEND AUDIO TRACK STOPPED");
|
||||
#endif
|
||||
} else if (m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) {
|
||||
m_nDisplayVideoMode = m_nPrefsVideoMode;
|
||||
}
|
||||
|
||||
if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
|
||||
CPlayerSkin::EndFrontendSkinEdit();
|
||||
}
|
||||
|
||||
if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) || (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS)) {
|
||||
m_nTotalListRow = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ------ Functions not in the game/inlined ends
|
||||
|
||||
void
|
||||
CMenuManager::BuildStatLine(char *text, void *stat, uint8 aFloat, void *stat2)
|
||||
@ -1173,7 +1207,6 @@ void CMenuManager::DrawFrontEnd()
|
||||
bbNames[5] = { "FESZ_QU",MENUPAGE_EXIT };
|
||||
bbTabCount = 6;
|
||||
}
|
||||
m_nCurrScreen = MENUPAGE_NEW_GAME;
|
||||
} else {
|
||||
if (bbTabCount != 8) {
|
||||
bbNames[0] = { "FEB_STA",MENUPAGE_STATS };
|
||||
@ -1186,8 +1219,8 @@ void CMenuManager::DrawFrontEnd()
|
||||
bbNames[7] = { "FESZ_QU",MENUPAGE_EXIT };
|
||||
bbTabCount = 8;
|
||||
}
|
||||
m_nCurrScreen = MENUPAGE_STATS;
|
||||
}
|
||||
m_nCurrScreen = bbNames[0].screenId;
|
||||
bottomBarActive = true;
|
||||
curBottomBarOption = 0;
|
||||
}
|
||||
@ -1285,7 +1318,6 @@ void CMenuManager::DrawFrontEndNormal()
|
||||
eFrontendSprites currentSprite;
|
||||
switch (m_nCurrScreen) {
|
||||
case MENUPAGE_STATS:
|
||||
case MENUPAGE_NEW_GAME:
|
||||
case MENUPAGE_START_MENU:
|
||||
case MENUPAGE_PAUSE_MENU:
|
||||
case MENUPAGE_EXIT:
|
||||
@ -1315,7 +1347,7 @@ void CMenuManager::DrawFrontEndNormal()
|
||||
currentSprite = FE_ICONCONTROLS;
|
||||
break;
|
||||
default:
|
||||
/* actually MENUPAGE_NEW_GAME too*/
|
||||
/*case MENUPAGE_NEW_GAME: */
|
||||
/*case MENUPAGE_BRIEFS: */
|
||||
currentSprite = FE_ICONBRIEF;
|
||||
break;
|
||||
@ -1324,16 +1356,16 @@ 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));
|
||||
|
||||
if (m_nMenuFadeAlpha < 255) {
|
||||
static int LastFade = 0;
|
||||
static uint32 LastFade = 0;
|
||||
|
||||
if (m_nMenuFadeAlpha <= 0 && reverseAlpha) {
|
||||
reverseAlpha = false;
|
||||
ChangeScreen(pendingScreen, pendingOption, true, false);
|
||||
} else if(CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 10){
|
||||
} else {
|
||||
if (!reverseAlpha)
|
||||
m_nMenuFadeAlpha += 20;
|
||||
m_nMenuFadeAlpha += min((CTimer::GetTimeInMillisecondsPauseMode() - LastFade) / 33.0f, 1.0f) * 20.0f;
|
||||
else
|
||||
m_nMenuFadeAlpha = max(m_nMenuFadeAlpha - 30, 0);
|
||||
m_nMenuFadeAlpha = max(0, m_nMenuFadeAlpha - min((CTimer::GetTimeInMillisecondsPauseMode() - LastFade) / 33.0f, 1.0f) * 30.0f);
|
||||
|
||||
LastFade = CTimer::GetTimeInMillisecondsPauseMode();
|
||||
}
|
||||
@ -1537,12 +1569,18 @@ void CMenuManager::DrawFrontEndNormal()
|
||||
}
|
||||
|
||||
if (m_nMenuFadeAlpha < 255) {
|
||||
static int 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){
|
||||
m_nMenuFadeAlpha += 20;
|
||||
LastFade = CTimer::GetTimeInMillisecondsPauseMode();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_nMenuFadeAlpha > 255){
|
||||
m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
|
||||
@ -1950,7 +1988,7 @@ WRAPPER void CMenuManager::Process(void) { EAXJMP(0x485100); }
|
||||
#else
|
||||
void CMenuManager::Process(void)
|
||||
{
|
||||
m_bMenuNotProcessed = false;
|
||||
m_bMenuStateChanged = false;
|
||||
|
||||
if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus() != FADE_0)
|
||||
return;
|
||||
@ -2701,6 +2739,8 @@ CMenuManager::ProcessButtonPresses(void)
|
||||
if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
|
||||
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
|
||||
bottomBarActive = false;
|
||||
|
||||
// If there's a menu change with fade ongoing, finish it now
|
||||
if (reverseAlpha)
|
||||
m_nMenuFadeAlpha = 0;
|
||||
return;
|
||||
@ -3116,51 +3156,43 @@ CMenuManager::ProcessButtonPresses(void)
|
||||
if (goBack) {
|
||||
CMenuManager::ResetHelperText();
|
||||
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_EXIT, 0);
|
||||
if (m_nCurrScreen == MENUPAGE_PAUSE_MENU && !m_bGameNotLoaded && !m_bMenuNotProcessed){
|
||||
if (CMenuManager::m_PrefsVsyncDisp != CMenuManager::m_PrefsVsync) {
|
||||
CMenuManager::m_PrefsVsync = CMenuManager::m_PrefsVsyncDisp;
|
||||
}
|
||||
CMenuManager::RequestFrontEndShutDown();
|
||||
} else if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT
|
||||
#ifdef PS2_SAVE_DIALOG
|
||||
|| m_nCurrScreen == MENUPAGE_SAVE
|
||||
#endif
|
||||
) {
|
||||
CMenuManager::RequestFrontEndShutDown();
|
||||
} else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) {
|
||||
DMAudio.StopFrontEndTrack();
|
||||
OutputDebugString("FRONTEND AUDIO TRACK STOPPED");
|
||||
}
|
||||
|
||||
int oldScreen = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0];
|
||||
int oldOption = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0];
|
||||
|
||||
#ifdef PS2_LIKE_MENU
|
||||
if (bottomBarActive){
|
||||
bottomBarActive = false;
|
||||
if (!m_bGameNotLoaded) {
|
||||
if (m_nCurrScreen == MENUPAGE_PAUSE_MENU || bottomBarActive) {
|
||||
#else
|
||||
if (m_nCurrScreen == MENUPAGE_PAUSE_MENU) {
|
||||
#endif
|
||||
if (!m_bGameNotLoaded && !m_bMenuStateChanged) {
|
||||
if (CMenuManager::m_PrefsVsyncDisp != CMenuManager::m_PrefsVsync) {
|
||||
CMenuManager::m_PrefsVsync = CMenuManager::m_PrefsVsyncDisp;
|
||||
}
|
||||
CMenuManager::RequestFrontEndShutDown();
|
||||
}
|
||||
|
||||
// We're already resuming, we don't need further processing.
|
||||
#if defined(FIX_BUGS) || defined(PS2_LIKE_MENU)
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
#ifdef PS2_LIKE_MENU
|
||||
else if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT || m_nCurrScreen == MENUPAGE_SAVE) {
|
||||
#else
|
||||
else if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT) {
|
||||
#endif
|
||||
CMenuManager::RequestFrontEndShutDown();
|
||||
}
|
||||
// It's now in ThingsToDoBeforeLeavingPage()
|
||||
#ifndef TIDY_UP_PBP
|
||||
else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) {
|
||||
DMAudio.StopFrontEndTrack();
|
||||
OutputDebugString("FRONTEND AUDIO TRACK STOPPED");
|
||||
}
|
||||
#endif
|
||||
|
||||
int oldScreen = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0];
|
||||
int oldOption = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0];
|
||||
|
||||
if (oldScreen != -1) {
|
||||
if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && strcmp(m_aSkinName, m_PrefsSkinFile) != 0) {
|
||||
CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
|
||||
}
|
||||
if ((m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) && (m_nPrefsAudio3DProviderIndex != -1)) {
|
||||
m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex();
|
||||
}
|
||||
if (m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) {
|
||||
m_nDisplayVideoMode = m_nPrefsVideoMode;
|
||||
}
|
||||
if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
|
||||
CPlayerSkin::EndFrontendSkinEdit();
|
||||
}
|
||||
ThingsToDoBeforeLeavingPage();
|
||||
|
||||
#ifdef PS2_LIKE_MENU
|
||||
if (!bottomBarActive &&
|
||||
@ -3168,10 +3200,8 @@ CMenuManager::ProcessButtonPresses(void)
|
||||
bottomBarActive = true;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ChangeScreen(oldScreen, oldOption, true, true);
|
||||
|
||||
if ((m_nPrevScreen == MENUPAGE_SKIN_SELECT) || (m_nPrevScreen == MENUPAGE_KEYBOARD_CONTROLS)) {
|
||||
m_nTotalListRow = 0;
|
||||
}
|
||||
|
||||
// We will go back for sure at this point, why process other things?!
|
||||
@ -3512,11 +3542,16 @@ WRAPPER void CMenuManager::SwitchMenuOnAndOff() { EAXJMP(0x488790); }
|
||||
#else
|
||||
void CMenuManager::SwitchMenuOnAndOff()
|
||||
{
|
||||
if (!!(CPad::GetPad(0)->NewState.Start && !CPad::GetPad(0)->OldState.Start)
|
||||
|| m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested) {
|
||||
bool menuWasActive = !!m_bMenuActive;
|
||||
|
||||
if (!m_bMenuActive)
|
||||
m_bMenuActive = true;
|
||||
// Reminder: You need REGISTER_START_BUTTON defined to make it work.
|
||||
if (CPad::GetPad(0)->GetStartJustDown()
|
||||
#ifdef FIX_BUGS
|
||||
&& !m_bGameNotLoaded
|
||||
#endif
|
||||
|| m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested) {
|
||||
|
||||
m_bMenuActive = !m_bMenuActive;
|
||||
|
||||
if (m_bShutDownFrontEndRequested)
|
||||
m_bMenuActive = false;
|
||||
@ -3525,8 +3560,13 @@ void CMenuManager::SwitchMenuOnAndOff()
|
||||
|
||||
if (m_bMenuActive) {
|
||||
CTimer::StartUserPause();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
#ifdef PS2_LIKE_MENU
|
||||
bottomBarActive = false;
|
||||
#endif
|
||||
#ifdef FIX_BUGS
|
||||
ThingsToDoBeforeLeavingPage();
|
||||
#endif
|
||||
ShutdownJustMenu();
|
||||
SaveSettings();
|
||||
m_bStartUpFrontEndRequested = false;
|
||||
@ -3553,7 +3593,7 @@ void CMenuManager::SwitchMenuOnAndOff()
|
||||
PcSaveHelper.PopulateSlotInfo();
|
||||
m_nCurrOption = 0;
|
||||
}
|
||||
/* // Unused?
|
||||
/* // PS2 leftover?
|
||||
if (m_nCurrScreen != MENUPAGE_SOUND_SETTINGS && gMusicPlaying)
|
||||
{
|
||||
DMAudio.StopFrontEndTrack();
|
||||
@ -3561,8 +3601,8 @@ void CMenuManager::SwitchMenuOnAndOff()
|
||||
gMusicPlaying = 0;
|
||||
}
|
||||
*/
|
||||
if (!m_bMenuActive)
|
||||
m_bMenuNotProcessed = true;
|
||||
if (m_bMenuActive != menuWasActive)
|
||||
m_bMenuStateChanged = true;
|
||||
|
||||
m_bStartUpFrontEndRequested = false;
|
||||
m_bShutDownFrontEndRequested = false;
|
||||
|
@ -403,7 +403,7 @@ public:
|
||||
int32 m_nHelperTextMsgId;
|
||||
bool m_bLanguageLoaded;
|
||||
bool m_bMenuActive;
|
||||
bool m_bMenuNotProcessed;
|
||||
bool m_bMenuStateChanged;
|
||||
bool m_bWaitingForNewKeyBind;
|
||||
bool m_bStartGameLoading;
|
||||
bool m_bFirstTime;
|
||||
@ -540,8 +540,14 @@ public:
|
||||
void WaitForUserCD();
|
||||
void PrintController();
|
||||
|
||||
// New content:
|
||||
uint8 GetNumberOfMenuOptions();
|
||||
// New (not in function or inlined in the game)
|
||||
void ThingsToDoBeforeLeavingPage();
|
||||
void ScrollUpListByOne();
|
||||
void ScrollDownListByOne();
|
||||
void PageUpList(bool);
|
||||
void PageDownList(bool);
|
||||
|
||||
// uint8 GetNumberOfMenuOptions();
|
||||
};
|
||||
|
||||
static_assert(sizeof(CMenuManager) == 0x564, "CMenuManager: error");
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
class CTimer
|
||||
{
|
||||
public:
|
||||
|
||||
static uint32 &m_snTimeInMilliseconds;
|
||||
static uint32 &m_snTimeInMillisecondsPauseMode;
|
||||
static uint32 &m_snTimeInMillisecondsNonClipped;
|
||||
@ -11,19 +11,20 @@ public:
|
||||
static float &ms_fTimeScale;
|
||||
static float &ms_fTimeStep;
|
||||
static float &ms_fTimeStepNonClipped;
|
||||
public:
|
||||
static bool &m_UserPause;
|
||||
static bool &m_CodePause;
|
||||
|
||||
static float GetTimeStep(void) { return ms_fTimeStep; }
|
||||
static const float &GetTimeStep(void) { return ms_fTimeStep; }
|
||||
static void SetTimeStep(float ts) { ms_fTimeStep = ts; }
|
||||
static float GetTimeStepInSeconds() { return ms_fTimeStep / 50.0f; }
|
||||
static float GetTimeStepInMilliseconds() { return ms_fTimeStep / 50.0f * 1000.0f; }
|
||||
static float GetTimeStepNonClipped(void) { return ms_fTimeStepNonClipped; }
|
||||
static const float &GetTimeStepNonClipped(void) { return ms_fTimeStepNonClipped; }
|
||||
static float GetTimeStepNonClippedInSeconds(void) { return ms_fTimeStepNonClipped / 50.0f; }
|
||||
static void SetTimeStepNonClipped(float ts) { ms_fTimeStepNonClipped = ts; }
|
||||
static uint32 GetFrameCounter(void) { return m_FrameCounter; }
|
||||
static const uint32 &GetFrameCounter(void) { return m_FrameCounter; }
|
||||
static void SetFrameCounter(uint32 fc) { m_FrameCounter = fc; }
|
||||
static uint32 GetTimeInMilliseconds(void) { return m_snTimeInMilliseconds; }
|
||||
static const uint32 &GetTimeInMilliseconds(void) { return m_snTimeInMilliseconds; }
|
||||
static void SetTimeInMilliseconds(uint32 t) { m_snTimeInMilliseconds = t; }
|
||||
static uint32 GetTimeInMillisecondsNonClipped(void) { return m_snTimeInMillisecondsNonClipped; }
|
||||
static void SetTimeInMillisecondsNonClipped(uint32 t) { m_snTimeInMillisecondsNonClipped = t; }
|
||||
@ -31,7 +32,7 @@ public:
|
||||
static void SetTimeInMillisecondsPauseMode(uint32 t) { m_snTimeInMillisecondsPauseMode = t; }
|
||||
static uint32 GetPreviousTimeInMilliseconds(void) { return m_snPreviousTimeInMilliseconds; }
|
||||
static void SetPreviousTimeInMilliseconds(uint32 t) { m_snPreviousTimeInMilliseconds = t; }
|
||||
static float GetTimeScale(void) { return ms_fTimeScale; }
|
||||
static const float &GetTimeScale(void) { return ms_fTimeScale; }
|
||||
static void SetTimeScale(float ts) { ms_fTimeScale = ts; }
|
||||
|
||||
static bool GetIsPaused() { return m_UserPause || m_CodePause; }
|
||||
|
@ -101,6 +101,8 @@ enum Config {
|
||||
NUMPEDGROUPS = 31,
|
||||
NUMMODELSPERPEDGROUP = 8,
|
||||
|
||||
NUMROADBLOCKS = 600,
|
||||
|
||||
NUMVISIBLEENTITIES = 2000,
|
||||
NUMINVISIBLEENTITIES = 150,
|
||||
|
||||
@ -169,10 +171,11 @@ enum Config {
|
||||
#endif
|
||||
|
||||
#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
|
||||
#define TOGGLEABLE_BETA_FEATURES // toggleable from debug menu. not too many things
|
||||
|
||||
// Pad
|
||||
#define KANGAROO_CHEAT
|
||||
#define REGISTER_START_BUTTON // currently only in menu sadly. resumes the game
|
||||
|
||||
// Hud, frontend and radar
|
||||
#define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios
|
||||
@ -199,5 +202,5 @@ enum Config {
|
||||
// Peds
|
||||
#define ANIMATE_PED_COL_MODEL
|
||||
#define VC_PED_PORTS // various ports from VC's CPed, mostly subtle
|
||||
#define NEW_WALK_AROUND_ALGORITHM // to make walking around vehicles/objects less awkward
|
||||
// #define NEW_WALK_AROUND_ALGORITHM // to make walking around vehicles/objects less awkward
|
||||
#define CANCELLABLE_CAR_ENTER
|
||||
|
@ -7,8 +7,11 @@
|
||||
#include "Vehicle.h"
|
||||
#include "RpAnimBlend.h"
|
||||
#include "General.h"
|
||||
#include "ZoneCull.h"
|
||||
#include "PathFind.h"
|
||||
#include "RoadBlocks.h"
|
||||
|
||||
WRAPPER void CCopPed::ProcessControl() { EAXJMP(0x4C1400); }
|
||||
WRAPPER void CCopPed::ProcessControl() { EAXJMP(0x4C1400); }
|
||||
|
||||
CCopPed::CCopPed(eCopType copType) : CPed(PEDTYPE_COP)
|
||||
{
|
||||
@ -58,11 +61,16 @@ CCopPed::CCopPed(eCopType copType) : CPed(PEDTYPE_COP)
|
||||
m_bIsDisabledCop = false;
|
||||
field_1356 = 0;
|
||||
m_attackTimer = 0;
|
||||
field_1351 = 0;
|
||||
m_bBeatingSuspect = false;
|
||||
m_bZoneDisabledButClose = false;
|
||||
m_bZoneDisabled = false;
|
||||
field_1364 = -1;
|
||||
m_pPointGunAt = nil;
|
||||
|
||||
// VC also initializes in here, but it keeps object
|
||||
#ifdef FIX_BUGS
|
||||
m_wRoadblockNode = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
CCopPed::~CCopPed()
|
||||
@ -181,15 +189,15 @@ CCopPed::ClearPursuit(void)
|
||||
}
|
||||
}
|
||||
|
||||
// TO-DO: m_MaxCops in for loop may be a bug, check it out after CopAI
|
||||
// TODO: I don't know why they needed that parameter.
|
||||
void
|
||||
CCopPed::SetPursuit(bool iMayAlreadyBeInPursuit)
|
||||
CCopPed::SetPursuit(bool ignoreCopLimit)
|
||||
{
|
||||
CWanted *wanted = FindPlayerPed()->m_pWanted;
|
||||
if (m_bIsInPursuit || !IsPedInControl())
|
||||
return;
|
||||
|
||||
if (wanted->m_CurrentCops < wanted->m_MaxCops || iMayAlreadyBeInPursuit) {
|
||||
if (wanted->m_CurrentCops < wanted->m_MaxCops || ignoreCopLimit) {
|
||||
for (int i = 0; i < wanted->m_MaxCops; ++i) {
|
||||
if (!wanted->m_pCops[i]) {
|
||||
m_bIsInPursuit = true;
|
||||
@ -275,6 +283,274 @@ CCopPed::ScanForCrimes(void)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CCopPed::CopAI(void)
|
||||
{
|
||||
CWanted *wanted = FindPlayerPed()->m_pWanted;
|
||||
int wantedLevel = wanted->m_nWantedLevel;
|
||||
CPhysical *playerOrHisVeh = FindPlayerVehicle() ? (CPhysical*)FindPlayerVehicle() : (CPhysical*)FindPlayerPed();
|
||||
|
||||
if (wanted->m_bIgnoredByEveryone || wanted->m_bIgnoredByCops) {
|
||||
if (m_nPedState != PED_ARREST_PLAYER)
|
||||
ClearPursuit();
|
||||
|
||||
return;
|
||||
}
|
||||
if (CCullZones::NoPolice() && m_bIsInPursuit && !m_bIsDisabledCop) {
|
||||
if (bHitSomethingLastFrame) {
|
||||
m_bZoneDisabled = true;
|
||||
m_bIsDisabledCop = true;
|
||||
#ifdef FIX_BUGS
|
||||
m_wRoadblockNode = -1;
|
||||
#else
|
||||
m_wRoadblockNode = 0;
|
||||
#endif
|
||||
bKindaStayInSamePlace = true;
|
||||
bIsRunning = false;
|
||||
bNotAllowedToDuck = false;
|
||||
bCrouchWhenShooting = false;
|
||||
SetIdle();
|
||||
ClearObjective();
|
||||
ClearPursuit();
|
||||
m_prevObjective = OBJECTIVE_NONE;
|
||||
m_nLastPedState = PED_NONE;
|
||||
SetAttackTimer(0);
|
||||
if (m_fDistanceToTarget > 15.0f)
|
||||
m_bZoneDisabledButClose = true;
|
||||
}
|
||||
} else if (m_bZoneDisabled && !CCullZones::NoPolice()) {
|
||||
m_bZoneDisabled = false;
|
||||
m_bIsDisabledCop = false;
|
||||
m_bZoneDisabledButClose = false;
|
||||
bKindaStayInSamePlace = false;
|
||||
bCrouchWhenShooting = false;
|
||||
bDuckAndCover = false;
|
||||
ClearPursuit();
|
||||
}
|
||||
if (wantedLevel > 0) {
|
||||
if (!m_bIsDisabledCop) {
|
||||
if (!m_bIsInPursuit || wanted->m_CurrentCops > wanted->m_MaxCops) {
|
||||
CCopPed *copFarthestToTarget = nil;
|
||||
float copFarthestToTargetDist = m_fDistanceToTarget;
|
||||
|
||||
int oldCopNum = wanted->m_CurrentCops;
|
||||
int maxCops = wanted->m_MaxCops;
|
||||
|
||||
for (int i = 0; i < max(maxCops, oldCopNum); i++) {
|
||||
CCopPed *cop = wanted->m_pCops[i];
|
||||
if (cop && cop->m_fDistanceToTarget > copFarthestToTargetDist) {
|
||||
copFarthestToTargetDist = cop->m_fDistanceToTarget;
|
||||
copFarthestToTarget = wanted->m_pCops[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bIsInPursuit) {
|
||||
if (copFarthestToTarget && oldCopNum > maxCops) {
|
||||
if (copFarthestToTarget == this && m_fDistanceToTarget > 10.0f) {
|
||||
ClearPursuit();
|
||||
} else if(copFarthestToTargetDist > 10.0f)
|
||||
copFarthestToTarget->ClearPursuit();
|
||||
}
|
||||
} else {
|
||||
if (oldCopNum < maxCops) {
|
||||
SetPursuit(true);
|
||||
} else {
|
||||
if (m_fDistanceToTarget <= 10.0f || copFarthestToTarget && m_fDistanceToTarget < copFarthestToTargetDist) {
|
||||
if (copFarthestToTarget && copFarthestToTargetDist > 10.0f)
|
||||
copFarthestToTarget->ClearPursuit();
|
||||
|
||||
SetPursuit(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
SetPursuit(false);
|
||||
|
||||
if (!m_bIsInPursuit)
|
||||
return;
|
||||
|
||||
if (wantedLevel > 1 && GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED)
|
||||
SetCurrentWeapon(WEAPONTYPE_COLT45);
|
||||
else if (wantedLevel == 1 && GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && !FindPlayerPed()->m_pCurrentPhysSurface) {
|
||||
// i.e. if player is on top of car, cop will still use colt45.
|
||||
SetCurrentWeapon(WEAPONTYPE_UNARMED);
|
||||
}
|
||||
|
||||
if (FindPlayerVehicle()) {
|
||||
if (m_bBeatingSuspect) {
|
||||
--wanted->m_CopsBeatingSuspect;
|
||||
m_bBeatingSuspect = false;
|
||||
}
|
||||
if (m_fDistanceToTarget * FindPlayerSpeed().Magnitude() > 4.0f)
|
||||
ClearPursuit();
|
||||
}
|
||||
return;
|
||||
}
|
||||
float weaponRange = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange;
|
||||
SetLookFlag(playerOrHisVeh, true);
|
||||
TurnBody();
|
||||
SetCurrentWeapon(WEAPONTYPE_COLT45);
|
||||
if (!bIsDucking) {
|
||||
if (m_attackTimer >= CTimer::GetTimeInMilliseconds()) {
|
||||
if (m_nPedState != PED_ATTACK && m_nPedState != PED_FIGHT && !m_bZoneDisabled) {
|
||||
CVector targetDist = playerOrHisVeh->GetPosition() - GetPosition();
|
||||
if (m_fDistanceToTarget > 30.0f) {
|
||||
CAnimBlendAssociation* crouchShootAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RBLOCK_CSHOOT);
|
||||
if (crouchShootAssoc)
|
||||
crouchShootAssoc->blendDelta = -1000.0f;
|
||||
|
||||
// Target is coming onto us
|
||||
if (DotProduct(playerOrHisVeh->m_vecMoveSpeed, targetDist) > 0.0f) {
|
||||
m_bIsDisabledCop = false;
|
||||
bKindaStayInSamePlace = false;
|
||||
bNotAllowedToDuck = false;
|
||||
bDuckAndCover = false;
|
||||
SetPursuit(false);
|
||||
SetObjective(OBJECTIVE_KILL_CHAR_ANY_MEANS, FindPlayerPed());
|
||||
}
|
||||
} else if (m_fDistanceToTarget < 5.0f
|
||||
&& (!FindPlayerVehicle() || FindPlayerVehicle()->m_vecMoveSpeed.MagnitudeSqr() < sq(1.f/200.f))) {
|
||||
m_bIsDisabledCop = false;
|
||||
bKindaStayInSamePlace = false;
|
||||
bNotAllowedToDuck = false;
|
||||
bDuckAndCover = false;
|
||||
} else {
|
||||
// VC checks for != nil compared to buggy behaviour of III. I check for != -1 here.
|
||||
#ifdef VC_PED_PORTS
|
||||
float dotProd;
|
||||
if (m_wRoadblockNode != -1) {
|
||||
CTreadable *roadBlockRoad = ThePaths.m_mapObjects[CRoadBlocks::RoadBlockObjects[m_wRoadblockNode]];
|
||||
dotProd = DotProduct2D(playerOrHisVeh->GetPosition() - roadBlockRoad->GetPosition(), GetPosition() - roadBlockRoad->GetPosition());
|
||||
} else
|
||||
dotProd = -1.0f;
|
||||
|
||||
if(dotProd >= 0.0f) {
|
||||
#else
|
||||
|
||||
#ifndef FIX_BUGS
|
||||
float copRoadDotProd, targetRoadDotProd;
|
||||
#else
|
||||
float copRoadDotProd = 1.0f, targetRoadDotProd = 1.0f;
|
||||
if (m_wRoadblockNode != -1)
|
||||
#endif
|
||||
{
|
||||
CTreadable* roadBlockRoad = ThePaths.m_mapObjects[CRoadBlocks::RoadBlockObjects[m_wRoadblockNode]];
|
||||
CVector2D roadFwd = roadBlockRoad->GetForward();
|
||||
copRoadDotProd = DotProduct2D(GetPosition() - roadBlockRoad->GetPosition(), roadFwd);
|
||||
targetRoadDotProd = DotProduct2D(playerOrHisVeh->GetPosition() - roadBlockRoad->GetPosition(), roadFwd);
|
||||
}
|
||||
// Roadblock may be towards road's fwd or opposite, so check both
|
||||
if ((copRoadDotProd >= 0.0f || targetRoadDotProd >= 0.0f)
|
||||
&& (copRoadDotProd <= 0.0f || targetRoadDotProd <= 0.0f)) {
|
||||
#endif
|
||||
bIsPointingGunAt = true;
|
||||
} else {
|
||||
m_bIsDisabledCop = false;
|
||||
bKindaStayInSamePlace = false;
|
||||
bNotAllowedToDuck = false;
|
||||
bCrouchWhenShooting = false;
|
||||
bIsDucking = false;
|
||||
bDuckAndCover = false;
|
||||
SetPursuit(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (m_fDistanceToTarget < weaponRange) {
|
||||
CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
|
||||
CVector gunPos = weaponInfo->m_vecFireOffset;
|
||||
for (RwFrame *i = GetNodeFrame(PED_HANDR); i; i = RwFrameGetParent(i))
|
||||
RwV3dTransformPoints((RwV3d*)&gunPos, (RwV3d*)&gunPos, 1, RwFrameGetMatrix(i));
|
||||
|
||||
CColPoint foundCol;
|
||||
CEntity *foundEnt;
|
||||
if (!CWorld::ProcessLineOfSight(gunPos, playerOrHisVeh->GetPosition(), foundCol, foundEnt,
|
||||
false, true, false, false, true, false, false)
|
||||
|| foundEnt && foundEnt == playerOrHisVeh) {
|
||||
m_pPointGunAt = playerOrHisVeh;
|
||||
if (playerOrHisVeh)
|
||||
playerOrHisVeh->RegisterReference((CEntity**) &m_pPointGunAt);
|
||||
|
||||
SetAttack(playerOrHisVeh);
|
||||
SetShootTimer(CGeneral::GetRandomNumberInRange(500, 1000));
|
||||
}
|
||||
SetAttackTimer(CGeneral::GetRandomNumberInRange(100, 300));
|
||||
}
|
||||
SetMoveState(PEDMOVE_STILL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!m_bIsDisabledCop || m_bZoneDisabled) {
|
||||
if (m_nPedState != PED_AIM_GUN) {
|
||||
if (m_bIsInPursuit)
|
||||
ClearPursuit();
|
||||
|
||||
if (IsPedInControl()) {
|
||||
// Entering the vehicle
|
||||
if (m_pMyVehicle && !bInVehicle) {
|
||||
if (m_pMyVehicle->IsLawEnforcementVehicle()) {
|
||||
if (m_pMyVehicle->pDriver) {
|
||||
if (m_pMyVehicle->pDriver->m_nPedType == PEDTYPE_COP) {
|
||||
if (m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER)
|
||||
SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_pMyVehicle);
|
||||
} else if (m_pMyVehicle->pDriver->IsPlayer()) {
|
||||
FindPlayerPed()->SetWantedLevelNoDrop(1);
|
||||
}
|
||||
} else if (m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) {
|
||||
SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
|
||||
}
|
||||
} else {
|
||||
m_pMyVehicle = nil;
|
||||
ClearObjective();
|
||||
SetWanderPath(CGeneral::GetRandomNumber() & 7);
|
||||
}
|
||||
}
|
||||
#ifdef VC_PED_PORTS
|
||||
else {
|
||||
if (m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT && CharCreatedBy == RANDOM_CHAR) {
|
||||
for (int i = 0; i < m_numNearPeds; i++) {
|
||||
CPed *nearPed = m_nearPeds[i];
|
||||
if (nearPed->CharCreatedBy == RANDOM_CHAR) {
|
||||
if ((nearPed->m_nPedType == PEDTYPE_CRIMINAL || nearPed->IsGangMember())
|
||||
&& nearPed->IsPedInControl()) {
|
||||
|
||||
bool anotherCopChasesHim = false;
|
||||
if (nearPed->m_nPedState == PED_FLEE_ENTITY) {
|
||||
if (nearPed->m_fleeFrom && nearPed->m_fleeFrom->IsPed() &&
|
||||
((CPed*)nearPed->m_fleeFrom)->m_nPedType == PEDTYPE_COP) {
|
||||
anotherCopChasesHim = true;
|
||||
}
|
||||
}
|
||||
if (!anotherCopChasesHim) {
|
||||
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, nearPed);
|
||||
nearPed->SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, this);
|
||||
nearPed->m_ped_flagE2 = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (m_bIsInPursuit && m_nPedState != PED_AIM_GUN)
|
||||
ClearPursuit();
|
||||
|
||||
m_bIsDisabledCop = false;
|
||||
bKindaStayInSamePlace = false;
|
||||
bNotAllowedToDuck = false;
|
||||
bCrouchWhenShooting = false;
|
||||
bIsDucking = false;
|
||||
bDuckAndCover = false;
|
||||
if (m_pMyVehicle)
|
||||
SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CCopPed_ : public CCopPed
|
||||
{
|
||||
public:
|
||||
@ -290,4 +566,5 @@ STARTPATCHES
|
||||
InjectHook(0x4C27D0, &CCopPed::SetPursuit, PATCH_JUMP);
|
||||
InjectHook(0x4C2C90, &CCopPed::ArrestPlayer, PATCH_JUMP);
|
||||
InjectHook(0x4C26A0, &CCopPed::ScanForCrimes, PATCH_JUMP);
|
||||
InjectHook(0x4C1B50, &CCopPed::CopAI, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
@ -17,9 +17,9 @@ public:
|
||||
int8 field_1343;
|
||||
float m_fDistanceToTarget;
|
||||
int8 m_bIsInPursuit;
|
||||
int8 m_bIsDisabledCop;
|
||||
int8 m_bIsDisabledCop; // What disabled cop actually is?
|
||||
int8 field_1350;
|
||||
int8 field_1351;
|
||||
bool m_bBeatingSuspect;
|
||||
int8 m_bZoneDisabledButClose;
|
||||
int8 m_bZoneDisabled;
|
||||
int8 field_1354;
|
||||
@ -40,6 +40,7 @@ public:
|
||||
void SetPursuit(bool);
|
||||
void ArrestPlayer(void);
|
||||
void ScanForCrimes(void);
|
||||
void CopAI(void);
|
||||
};
|
||||
|
||||
static_assert(sizeof(CCopPed) == 0x558, "CCopPed: error");
|
||||
|
@ -2720,6 +2720,10 @@ CPed::SetObjective(eObjective newObj, void *entity)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef VC_PED_PORTS
|
||||
SetObjectiveTimer(0);
|
||||
ClearPointGunAt();
|
||||
#endif
|
||||
bObjectiveCompleted = false;
|
||||
if (!IsTemporaryObjective(m_objective) || IsTemporaryObjective(newObj)) {
|
||||
if (m_objective != newObj) {
|
||||
@ -3444,8 +3448,12 @@ CPed::ClearAll(void)
|
||||
m_fleeFrom = nil;
|
||||
m_fleeTimer = 0;
|
||||
bUsesCollision = true;
|
||||
#ifdef VC_PED_PORTS
|
||||
ClearPointGunAt();
|
||||
#else
|
||||
ClearAimFlag();
|
||||
ClearLookFlag();
|
||||
#endif
|
||||
bIsPointingGunAt = false;
|
||||
bRenderPedInCar = true;
|
||||
bKnockedUpIntoAir = false;
|
||||
|
@ -576,7 +576,7 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
|
||||
}
|
||||
// Yeah, float
|
||||
float maxPossiblePedsForArea = (zoneInfo.pedDensity + zoneInfo.carDensity) * playerInfo->m_fRoadDensity * PedDensityMultiplier * CIniFile::PedNumberMultiplier;
|
||||
// maxPossiblePedsForArea = min(maxPossiblePedsForArea, MaxNumberOfPedsInUse);
|
||||
maxPossiblePedsForArea = min(maxPossiblePedsForArea, MaxNumberOfPedsInUse);
|
||||
|
||||
if (ms_nTotalPeds < maxPossiblePedsForArea || addCop) {
|
||||
int decisionThreshold = CGeneral::GetRandomNumberInRange(0, 1000);
|
||||
|
@ -61,9 +61,9 @@ do {\
|
||||
MakeSpaceForSizeInBufferPointer(presize, buf, postsize);\
|
||||
save_func(buf, &size);\
|
||||
CopySizeAndPreparePointer(presize, buf, postsize, reserved, size);\
|
||||
if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, size + 4))\
|
||||
if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff))\
|
||||
return false;\
|
||||
totalSize += size;\
|
||||
totalSize += buf - work_buff;\
|
||||
} while (0)
|
||||
|
||||
bool
|
||||
@ -74,7 +74,6 @@ GenericSave(int file)
|
||||
uint32 reserved;
|
||||
|
||||
uint32 totalSize;
|
||||
uint32 i;
|
||||
|
||||
wchar *lastMissionPassed;
|
||||
wchar suffix[6];
|
||||
@ -85,13 +84,11 @@ GenericSave(int file)
|
||||
CheckSum = 0;
|
||||
buf = work_buff;
|
||||
reserved = 0;
|
||||
totalSize = 0;
|
||||
|
||||
// Save simple vars
|
||||
INITSAVEBUF
|
||||
lastMissionPassed = TheText.Get(CStats::LastMissionPassedName);
|
||||
if (*lastMissionPassed) {
|
||||
AsciiToUnicode("'...", suffix);
|
||||
AsciiToUnicode("...'", suffix);
|
||||
TextCopy(saveName, lastMissionPassed);
|
||||
int len = UnicodeStrlen(saveName);
|
||||
saveName[len] = '\0';
|
||||
@ -104,20 +101,20 @@ INITSAVEBUF
|
||||
WriteDataToBufferPointer(buf, saveTime);
|
||||
WriteDataToBufferPointer(buf, SIZE_OF_ONE_GAME_IN_BYTES);
|
||||
WriteDataToBufferPointer(buf, CGame::currLevel);
|
||||
WriteDataToBufferPointer(buf, TheCamera.m_matrix.m_matrix.pos.x);
|
||||
WriteDataToBufferPointer(buf, TheCamera.m_matrix.m_matrix.pos.y);
|
||||
WriteDataToBufferPointer(buf, TheCamera.m_matrix.m_matrix.pos.z);
|
||||
WriteDataToBufferPointer(buf, TheCamera.GetPosition().x);
|
||||
WriteDataToBufferPointer(buf, TheCamera.GetPosition().y);
|
||||
WriteDataToBufferPointer(buf, TheCamera.GetPosition().z);
|
||||
WriteDataToBufferPointer(buf, CClock::ms_nMillisecondsPerGameMinute);
|
||||
WriteDataToBufferPointer(buf, CClock::ms_nLastClockTick);
|
||||
WriteDataToBufferPointer(buf, CClock::ms_nGameClockHours);
|
||||
WriteDataToBufferPointer(buf, CClock::ms_nGameClockMinutes);
|
||||
currPad = CPad::GetPad(0);
|
||||
WriteDataToBufferPointer(buf, currPad->Mode);
|
||||
WriteDataToBufferPointer(buf, CTimer::m_snTimeInMilliseconds);
|
||||
WriteDataToBufferPointer(buf, CTimer::ms_fTimeScale);
|
||||
WriteDataToBufferPointer(buf, CTimer::ms_fTimeStep);
|
||||
WriteDataToBufferPointer(buf, CTimer::ms_fTimeStepNonClipped);
|
||||
WriteDataToBufferPointer(buf, CTimer::m_FrameCounter);
|
||||
WriteDataToBufferPointer(buf, CTimer::GetTimeInMilliseconds());
|
||||
WriteDataToBufferPointer(buf, CTimer::GetTimeScale());
|
||||
WriteDataToBufferPointer(buf, CTimer::GetTimeStep());
|
||||
WriteDataToBufferPointer(buf, CTimer::GetTimeStepNonClipped());
|
||||
WriteDataToBufferPointer(buf, CTimer::GetFrameCounter());
|
||||
WriteDataToBufferPointer(buf, CTimeStep::ms_fTimeStep);
|
||||
WriteDataToBufferPointer(buf, CTimeStep::ms_fFramesPerUpdate);
|
||||
WriteDataToBufferPointer(buf, CTimeStep::ms_fTimeScale);
|
||||
@ -134,10 +131,8 @@ INITSAVEBUF
|
||||
WriteDataToBufferPointer(buf, CWeather::WeatherTypeInList);
|
||||
WriteDataToBufferPointer(buf, TheCamera.CarZoomIndicator);
|
||||
WriteDataToBufferPointer(buf, TheCamera.PedZoomIndicator);
|
||||
#ifdef VALIDATE_SAVE_SIZE
|
||||
_saveBufCount = buf - work_buff;
|
||||
#endif
|
||||
VALIDATESAVEBUF(SIZE_OF_SIMPLEVARS);
|
||||
|
||||
assert(buf - work_buff == SIZE_OF_SIMPLEVARS);
|
||||
|
||||
// Save scripts, block is nested within the same block as simple vars for some reason
|
||||
presize = buf;
|
||||
@ -145,9 +140,10 @@ VALIDATESAVEBUF(SIZE_OF_SIMPLEVARS);
|
||||
postsize = buf;
|
||||
CTheScripts::SaveAllScripts(buf, &size);
|
||||
CopySizeAndPreparePointer(presize, buf, postsize, reserved, size);
|
||||
if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, size + SIZE_OF_SIMPLEVARS + 4))
|
||||
if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff))
|
||||
return false;
|
||||
totalSize += size + SIZE_OF_SIMPLEVARS;
|
||||
|
||||
totalSize = buf - work_buff;
|
||||
|
||||
// Save the rest
|
||||
WRITE_BLOCK(CPools::SavePedPool);
|
||||
@ -171,8 +167,7 @@ VALIDATESAVEBUF(SIZE_OF_SIMPLEVARS);
|
||||
WRITE_BLOCK(CPedType::Save);
|
||||
|
||||
// Write padding
|
||||
i = 0;
|
||||
do {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
size = align4bytes(SIZE_OF_ONE_GAME_IN_BYTES - totalSize - 4);
|
||||
if (size > sizeof(work_buff))
|
||||
size = sizeof(work_buff);
|
||||
@ -181,15 +176,15 @@ VALIDATESAVEBUF(SIZE_OF_SIMPLEVARS);
|
||||
return false;
|
||||
totalSize += size;
|
||||
}
|
||||
i++;
|
||||
} while (i < 4);
|
||||
}
|
||||
|
||||
// Write checksum and close
|
||||
CFileMgr::Write(file, (const char *) &CheckSum, sizeof(CheckSum));
|
||||
if (CFileMgr::GetErrorReadWrite(file)) {
|
||||
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
|
||||
if (CloseFile(file))
|
||||
if (!CloseFile(file))
|
||||
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ C_PcSave::SaveSlot(int32 slot)
|
||||
if (file != 0) {
|
||||
DoGameSpecificStuffBeforeSave();
|
||||
if (GenericSave(file)) {
|
||||
if (CFileMgr::CloseFile(file) != 0)
|
||||
if (!!CFileMgr::CloseFile(file))
|
||||
nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
|
||||
return true;
|
||||
}
|
||||
@ -55,21 +55,21 @@ C_PcSave::PcClassSaveRoutine(int32 file, uint8 *data, uint32 size)
|
||||
CFileMgr::Write(file, (const char*)&size, sizeof(size));
|
||||
if (CFileMgr::GetErrorReadWrite(file)) {
|
||||
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
|
||||
strncpy(SaveFileNameJustSaved, ValidSaveName, 259);
|
||||
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
CFileMgr::Write(file, (const char*)data, align4bytes(size));
|
||||
CheckSum += ((uint8*)&size)[0];
|
||||
CheckSum += ((uint8*)&size)[1];
|
||||
CheckSum += ((uint8*)&size)[2];
|
||||
CheckSum += ((uint8*)&size)[3];
|
||||
CheckSum += (uint8) size;
|
||||
CheckSum += (uint8) (size >> 8);
|
||||
CheckSum += (uint8) (size >> 16);
|
||||
CheckSum += (uint8) (size >> 24);
|
||||
for (int i = 0; i < align4bytes(size); i++) {
|
||||
CheckSum += *data++;
|
||||
}
|
||||
if (CFileMgr::GetErrorReadWrite(file)) {
|
||||
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
|
||||
strncpy(SaveFileNameJustSaved, ValidSaveName, 259);
|
||||
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user