CCopPed 2 and fixes
This commit is contained in:
parent
8703758a7b
commit
0fe55eb543
@ -11,19 +11,10 @@ CPathFind &ThePaths = *(CPathFind*)0x8F6754;
|
|||||||
|
|
||||||
WRAPPER bool CPedPath::CalcPedRoute(uint8, CVector, CVector, CVector*, int16*, int16) { EAXJMP(0x42E680); }
|
WRAPPER bool CPedPath::CalcPedRoute(uint8, CVector, CVector, CVector*, int16*, int16) { EAXJMP(0x42E680); }
|
||||||
|
|
||||||
enum
|
#define MAX_DIST INT16_MAX-1
|
||||||
{
|
|
||||||
NodeTypeExtern = 1,
|
|
||||||
NodeTypeIntern = 2,
|
|
||||||
|
|
||||||
ObjectFlag1 = 1,
|
|
||||||
ObjectEastWest = 2,
|
|
||||||
|
|
||||||
MAX_DIST = INT16_MAX-1
|
|
||||||
};
|
|
||||||
|
|
||||||
// object flags:
|
// object flags:
|
||||||
// 1
|
// 1 UseInRoadBlock
|
||||||
// 2 east/west road(?)
|
// 2 east/west road(?)
|
||||||
|
|
||||||
CPathInfoForObject *&InfoForTileCars = *(CPathInfoForObject**)0x8F1A8C;
|
CPathInfoForObject *&InfoForTileCars = *(CPathInfoForObject**)0x8F1A8C;
|
||||||
@ -218,14 +209,14 @@ CPathFind::PreparePathData(void)
|
|||||||
if(numIntern == 1 && numExtern == 2){
|
if(numIntern == 1 && numExtern == 2){
|
||||||
if(numLanes < 4){
|
if(numLanes < 4){
|
||||||
if((i & 7) == 4){ // WHAT?
|
if((i & 7) == 4){ // WHAT?
|
||||||
m_objectFlags[i] |= ObjectFlag1;
|
m_objectFlags[i] |= UseInRoadBlock;
|
||||||
if(maxX > maxY)
|
if(maxX > maxY)
|
||||||
m_objectFlags[i] |= ObjectEastWest;
|
m_objectFlags[i] |= ObjectEastWest;
|
||||||
else
|
else
|
||||||
m_objectFlags[i] &= ~ObjectEastWest;
|
m_objectFlags[i] &= ~ObjectEastWest;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
m_objectFlags[i] |= ObjectFlag1;
|
m_objectFlags[i] |= UseInRoadBlock;
|
||||||
if(maxX > maxY)
|
if(maxX > maxY)
|
||||||
m_objectFlags[i] |= ObjectEastWest;
|
m_objectFlags[i] |= ObjectEastWest;
|
||||||
else
|
else
|
||||||
|
@ -9,6 +9,15 @@ public:
|
|||||||
static bool CalcPedRoute(uint8, CVector, CVector, CVector*, int16*, int16);
|
static bool CalcPedRoute(uint8, CVector, CVector, CVector*, int16*, int16);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
NodeTypeExtern = 1,
|
||||||
|
NodeTypeIntern = 2,
|
||||||
|
|
||||||
|
UseInRoadBlock = 1,
|
||||||
|
ObjectEastWest = 2,
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PATH_CAR = 0,
|
PATH_CAR = 0,
|
||||||
|
@ -1,7 +1,37 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "RoadBlocks.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::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
|
class CRoadBlocks
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static int16 (&NumRoadBlocks);
|
||||||
|
static int16 (&RoadBlockObjects)[NUMROADBLOCKS];
|
||||||
|
static bool (&InOrOut)[NUMROADBLOCKS];
|
||||||
|
|
||||||
static void Init(void);
|
static void Init(void);
|
||||||
static void GenerateRoadBlockCopsForCar(CVehicle*, int32, int16);
|
static void GenerateRoadBlockCopsForCar(CVehicle*, int32, int16);
|
||||||
static void GenerateRoadBlocks(void);
|
static void GenerateRoadBlocks(void);
|
||||||
|
@ -417,6 +417,11 @@ void CControllerConfigManager::UpdateJoyInConfigMenus_ButtonDown(int32 button, i
|
|||||||
case 13:
|
case 13:
|
||||||
pad->PCTempJoyState.DPadUp = 255;
|
pad->PCTempJoyState.DPadUp = 255;
|
||||||
break;
|
break;
|
||||||
|
#ifdef REGISTER_START_BUTTON
|
||||||
|
case 12:
|
||||||
|
pad->PCTempJoyState.Start = 255;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case 11:
|
case 11:
|
||||||
pad->PCTempJoyState.RightShock = 255;
|
pad->PCTempJoyState.RightShock = 255;
|
||||||
break;
|
break;
|
||||||
@ -839,6 +844,11 @@ void CControllerConfigManager::UpdateJoyInConfigMenus_ButtonUp(int32 button, int
|
|||||||
case 13:
|
case 13:
|
||||||
pad->PCTempJoyState.DPadUp = 0;
|
pad->PCTempJoyState.DPadUp = 0;
|
||||||
break;
|
break;
|
||||||
|
#ifdef REGISTER_START_BUTTON
|
||||||
|
case 12:
|
||||||
|
pad->PCTempJoyState.Start = 0;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case 11:
|
case 11:
|
||||||
pad->PCTempJoyState.RightShock = 0;
|
pad->PCTempJoyState.RightShock = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -5,10 +5,13 @@
|
|||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "Wanted.h"
|
#include "Wanted.h"
|
||||||
#include "EventList.h"
|
#include "EventList.h"
|
||||||
|
#include "Messages.h"
|
||||||
|
#include "Text.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
int32 CEventList::ms_nFirstFreeSlotIndex;
|
int32 CEventList::ms_nFirstFreeSlotIndex;
|
||||||
//CEvent gaEvent[NUMEVENTS];
|
CEvent gaEvent[NUMEVENTS];
|
||||||
CEvent *gaEvent = (CEvent*)0x6EF830;
|
//CEvent *gaEvent = (CEvent*)0x6EF830;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -207,8 +210,20 @@ CEventList::ReportCrimeForEvent(eEventType type, int32 crimeId, bool copsDontCar
|
|||||||
default: crime = CRIME_NONE; break;
|
default: crime = CRIME_NONE; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(crime == CRIME_NONE)
|
#ifdef VC_PED_PORTS
|
||||||
return;
|
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 playerPedCoors = FindPlayerPed()->GetPosition();
|
||||||
CVector playerCoors = FindPlayerCoors();
|
CVector playerCoors = FindPlayerCoors();
|
||||||
|
@ -63,4 +63,4 @@ public:
|
|||||||
static void ReportCrimeForEvent(eEventType type, int32, bool);
|
static void ReportCrimeForEvent(eEventType type, int32, bool);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CEvent *gaEvent;
|
extern CEvent gaEvent[NUMEVENTS];
|
@ -181,6 +181,7 @@ ScaleAndCenterX(float x)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS || screen == MENUPAGE_STATS)
|
#define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS || screen == MENUPAGE_STATS)
|
||||||
|
|
||||||
#ifdef PS2_LIKE_MENU
|
#ifdef PS2_LIKE_MENU
|
||||||
#define ChangeScreen(screen, option, updateDelay, withReverseAlpha) \
|
#define ChangeScreen(screen, option, updateDelay, withReverseAlpha) \
|
||||||
do { \
|
do { \
|
||||||
@ -235,67 +236,100 @@ ScaleAndCenterX(float x)
|
|||||||
m_nHoverOption = HOVEROPTION_NOT_HOVERING; \
|
m_nHoverOption = HOVEROPTION_NOT_HOVERING; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define ScrollUpListByOne() \
|
// --- Functions not in the game/inlined starts
|
||||||
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)
|
|
||||||
|
|
||||||
#define ScrollDownListByOne() \
|
inline void
|
||||||
do { \
|
CMenuManager::ScrollUpListByOne()
|
||||||
if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1) { \
|
{
|
||||||
if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) { \
|
if (m_nSelectedListRow == m_nFirstVisibleRowOnList) {
|
||||||
m_nSelectedListRow++; \
|
if (m_nFirstVisibleRowOnList > 0) {
|
||||||
m_nFirstVisibleRowOnList++; \
|
m_nSelectedListRow--;
|
||||||
m_nCurListItemY += LIST_HEIGHT / m_nTotalListRow; \
|
m_nFirstVisibleRowOnList--;
|
||||||
} \
|
m_nCurListItemY -= LIST_HEIGHT / m_nTotalListRow;
|
||||||
} else { \
|
}
|
||||||
if (m_nSelectedListRow < m_nTotalListRow - 1) { \
|
} else {
|
||||||
m_nSelectedListRow++; \
|
m_nSelectedListRow--;
|
||||||
} \
|
}
|
||||||
} \
|
}
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define PageUpList(playSoundOnSuccess) \
|
inline void
|
||||||
do { \
|
CMenuManager::ScrollDownListByOne()
|
||||||
if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { \
|
{
|
||||||
if (m_nFirstVisibleRowOnList > 0) { \
|
if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1) {
|
||||||
if(playSoundOnSuccess) \
|
if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) {
|
||||||
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0); \
|
m_nSelectedListRow++;
|
||||||
\
|
m_nFirstVisibleRowOnList++;
|
||||||
m_nFirstVisibleRowOnList = max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_LIST_ROW); \
|
m_nCurListItemY += LIST_HEIGHT / m_nTotalListRow;
|
||||||
m_nSelectedListRow = min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1); \
|
}
|
||||||
} else { \
|
} else {
|
||||||
m_nFirstVisibleRowOnList = 0; \
|
if (m_nSelectedListRow < m_nTotalListRow - 1) {
|
||||||
m_nSelectedListRow = 0; \
|
m_nSelectedListRow++;
|
||||||
} \
|
}
|
||||||
m_nCurListItemY = (LIST_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; \
|
}
|
||||||
} \
|
}
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define PageDownList(playSoundOnSuccess) \
|
inline void
|
||||||
do { \
|
CMenuManager::PageUpList(bool playSoundOnSuccess)
|
||||||
if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { \
|
{
|
||||||
if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) { \
|
if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) {
|
||||||
if(playSoundOnSuccess) \
|
if (m_nFirstVisibleRowOnList > 0) {
|
||||||
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0); \
|
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); \
|
m_nFirstVisibleRowOnList = max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_LIST_ROW);
|
||||||
} else { \
|
m_nSelectedListRow = min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1);
|
||||||
m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW; \
|
} else {
|
||||||
m_nSelectedListRow = m_nTotalListRow - 1; \
|
m_nFirstVisibleRowOnList = 0;
|
||||||
} \
|
m_nSelectedListRow = 0;
|
||||||
m_nCurListItemY = (LIST_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; \
|
}
|
||||||
} \
|
m_nCurListItemY = (LIST_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
|
||||||
} while(0)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
void
|
||||||
CMenuManager::BuildStatLine(char *text, void *stat, uint8 aFloat, void *stat2)
|
CMenuManager::BuildStatLine(char *text, void *stat, uint8 aFloat, void *stat2)
|
||||||
@ -1173,7 +1207,6 @@ void CMenuManager::DrawFrontEnd()
|
|||||||
bbNames[5] = { "FESZ_QU",MENUPAGE_EXIT };
|
bbNames[5] = { "FESZ_QU",MENUPAGE_EXIT };
|
||||||
bbTabCount = 6;
|
bbTabCount = 6;
|
||||||
}
|
}
|
||||||
m_nCurrScreen = MENUPAGE_NEW_GAME;
|
|
||||||
} else {
|
} else {
|
||||||
if (bbTabCount != 8) {
|
if (bbTabCount != 8) {
|
||||||
bbNames[0] = { "FEB_STA",MENUPAGE_STATS };
|
bbNames[0] = { "FEB_STA",MENUPAGE_STATS };
|
||||||
@ -1186,8 +1219,8 @@ void CMenuManager::DrawFrontEnd()
|
|||||||
bbNames[7] = { "FESZ_QU",MENUPAGE_EXIT };
|
bbNames[7] = { "FESZ_QU",MENUPAGE_EXIT };
|
||||||
bbTabCount = 8;
|
bbTabCount = 8;
|
||||||
}
|
}
|
||||||
m_nCurrScreen = MENUPAGE_STATS;
|
|
||||||
}
|
}
|
||||||
|
m_nCurrScreen = bbNames[0].screenId;
|
||||||
bottomBarActive = true;
|
bottomBarActive = true;
|
||||||
curBottomBarOption = 0;
|
curBottomBarOption = 0;
|
||||||
}
|
}
|
||||||
@ -1285,7 +1318,6 @@ void CMenuManager::DrawFrontEndNormal()
|
|||||||
eFrontendSprites currentSprite;
|
eFrontendSprites currentSprite;
|
||||||
switch (m_nCurrScreen) {
|
switch (m_nCurrScreen) {
|
||||||
case MENUPAGE_STATS:
|
case MENUPAGE_STATS:
|
||||||
case MENUPAGE_NEW_GAME:
|
|
||||||
case MENUPAGE_START_MENU:
|
case MENUPAGE_START_MENU:
|
||||||
case MENUPAGE_PAUSE_MENU:
|
case MENUPAGE_PAUSE_MENU:
|
||||||
case MENUPAGE_EXIT:
|
case MENUPAGE_EXIT:
|
||||||
@ -1315,7 +1347,7 @@ void CMenuManager::DrawFrontEndNormal()
|
|||||||
currentSprite = FE_ICONCONTROLS;
|
currentSprite = FE_ICONCONTROLS;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* actually MENUPAGE_NEW_GAME too*/
|
/*case MENUPAGE_NEW_GAME: */
|
||||||
/*case MENUPAGE_BRIEFS: */
|
/*case MENUPAGE_BRIEFS: */
|
||||||
currentSprite = FE_ICONBRIEF;
|
currentSprite = FE_ICONBRIEF;
|
||||||
break;
|
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));
|
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) {
|
if (m_nMenuFadeAlpha < 255) {
|
||||||
static int LastFade = 0;
|
static uint32 LastFade = 0;
|
||||||
|
|
||||||
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 if(CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 10){
|
} else {
|
||||||
if (!reverseAlpha)
|
if (!reverseAlpha)
|
||||||
m_nMenuFadeAlpha += 20;
|
m_nMenuFadeAlpha += min((CTimer::GetTimeInMillisecondsPauseMode() - LastFade) / 33.0f, 1.0f) * 20.0f;
|
||||||
else
|
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();
|
LastFade = CTimer::GetTimeInMillisecondsPauseMode();
|
||||||
}
|
}
|
||||||
@ -1537,12 +1569,18 @@ void CMenuManager::DrawFrontEndNormal()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_nMenuFadeAlpha < 255) {
|
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){
|
if(CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 10){
|
||||||
m_nMenuFadeAlpha += 20;
|
m_nMenuFadeAlpha += 20;
|
||||||
LastFade = CTimer::GetTimeInMillisecondsPauseMode();
|
LastFade = CTimer::GetTimeInMillisecondsPauseMode();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (m_nMenuFadeAlpha > 255){
|
if (m_nMenuFadeAlpha > 255){
|
||||||
m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 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
|
#else
|
||||||
void CMenuManager::Process(void)
|
void CMenuManager::Process(void)
|
||||||
{
|
{
|
||||||
m_bMenuNotProcessed = false;
|
m_bMenuStateChanged = false;
|
||||||
|
|
||||||
if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus() != FADE_0)
|
if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus() != FADE_0)
|
||||||
return;
|
return;
|
||||||
@ -2701,6 +2739,8 @@ CMenuManager::ProcessButtonPresses(void)
|
|||||||
if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
|
if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
|
||||||
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
|
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
|
||||||
bottomBarActive = false;
|
bottomBarActive = false;
|
||||||
|
|
||||||
|
// If there's a menu change with fade ongoing, finish it now
|
||||||
if (reverseAlpha)
|
if (reverseAlpha)
|
||||||
m_nMenuFadeAlpha = 0;
|
m_nMenuFadeAlpha = 0;
|
||||||
return;
|
return;
|
||||||
@ -3116,51 +3156,43 @@ CMenuManager::ProcessButtonPresses(void)
|
|||||||
if (goBack) {
|
if (goBack) {
|
||||||
CMenuManager::ResetHelperText();
|
CMenuManager::ResetHelperText();
|
||||||
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_EXIT, 0);
|
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
|
#ifdef PS2_LIKE_MENU
|
||||||
if (bottomBarActive){
|
if (m_nCurrScreen == MENUPAGE_PAUSE_MENU || bottomBarActive) {
|
||||||
bottomBarActive = false;
|
#else
|
||||||
if (!m_bGameNotLoaded) {
|
if (m_nCurrScreen == MENUPAGE_PAUSE_MENU) {
|
||||||
|
#endif
|
||||||
|
if (!m_bGameNotLoaded && !m_bMenuStateChanged) {
|
||||||
if (CMenuManager::m_PrefsVsyncDisp != CMenuManager::m_PrefsVsync) {
|
if (CMenuManager::m_PrefsVsyncDisp != CMenuManager::m_PrefsVsync) {
|
||||||
CMenuManager::m_PrefsVsync = CMenuManager::m_PrefsVsyncDisp;
|
CMenuManager::m_PrefsVsync = CMenuManager::m_PrefsVsyncDisp;
|
||||||
}
|
}
|
||||||
CMenuManager::RequestFrontEndShutDown();
|
CMenuManager::RequestFrontEndShutDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We're already resuming, we don't need further processing.
|
||||||
|
#if defined(FIX_BUGS) || defined(PS2_LIKE_MENU)
|
||||||
return;
|
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
|
#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 (oldScreen != -1) {
|
||||||
if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && strcmp(m_aSkinName, m_PrefsSkinFile) != 0) {
|
ThingsToDoBeforeLeavingPage();
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PS2_LIKE_MENU
|
#ifdef PS2_LIKE_MENU
|
||||||
if (!bottomBarActive &&
|
if (!bottomBarActive &&
|
||||||
@ -3168,10 +3200,8 @@ CMenuManager::ProcessButtonPresses(void)
|
|||||||
bottomBarActive = true;
|
bottomBarActive = true;
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
ChangeScreen(oldScreen, oldOption, true, true);
|
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?!
|
// We will go back for sure at this point, why process other things?!
|
||||||
@ -3512,11 +3542,16 @@ WRAPPER void CMenuManager::SwitchMenuOnAndOff() { EAXJMP(0x488790); }
|
|||||||
#else
|
#else
|
||||||
void CMenuManager::SwitchMenuOnAndOff()
|
void CMenuManager::SwitchMenuOnAndOff()
|
||||||
{
|
{
|
||||||
if (!!(CPad::GetPad(0)->NewState.Start && !CPad::GetPad(0)->OldState.Start)
|
bool menuWasActive = !!m_bMenuActive;
|
||||||
|| m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested) {
|
|
||||||
|
|
||||||
if (!m_bMenuActive)
|
// Reminder: You need REGISTER_START_BUTTON defined to make it work.
|
||||||
m_bMenuActive = true;
|
if (CPad::GetPad(0)->GetStartJustDown()
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
&& !m_bGameNotLoaded
|
||||||
|
#endif
|
||||||
|
|| m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested) {
|
||||||
|
|
||||||
|
m_bMenuActive = !m_bMenuActive;
|
||||||
|
|
||||||
if (m_bShutDownFrontEndRequested)
|
if (m_bShutDownFrontEndRequested)
|
||||||
m_bMenuActive = false;
|
m_bMenuActive = false;
|
||||||
@ -3525,8 +3560,13 @@ void CMenuManager::SwitchMenuOnAndOff()
|
|||||||
|
|
||||||
if (m_bMenuActive) {
|
if (m_bMenuActive) {
|
||||||
CTimer::StartUserPause();
|
CTimer::StartUserPause();
|
||||||
}
|
} else {
|
||||||
else {
|
#ifdef PS2_LIKE_MENU
|
||||||
|
bottomBarActive = false;
|
||||||
|
#endif
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
ThingsToDoBeforeLeavingPage();
|
||||||
|
#endif
|
||||||
ShutdownJustMenu();
|
ShutdownJustMenu();
|
||||||
SaveSettings();
|
SaveSettings();
|
||||||
m_bStartUpFrontEndRequested = false;
|
m_bStartUpFrontEndRequested = false;
|
||||||
@ -3553,7 +3593,7 @@ void CMenuManager::SwitchMenuOnAndOff()
|
|||||||
PcSaveHelper.PopulateSlotInfo();
|
PcSaveHelper.PopulateSlotInfo();
|
||||||
m_nCurrOption = 0;
|
m_nCurrOption = 0;
|
||||||
}
|
}
|
||||||
/* // Unused?
|
/* // PS2 leftover?
|
||||||
if (m_nCurrScreen != MENUPAGE_SOUND_SETTINGS && gMusicPlaying)
|
if (m_nCurrScreen != MENUPAGE_SOUND_SETTINGS && gMusicPlaying)
|
||||||
{
|
{
|
||||||
DMAudio.StopFrontEndTrack();
|
DMAudio.StopFrontEndTrack();
|
||||||
@ -3561,8 +3601,8 @@ void CMenuManager::SwitchMenuOnAndOff()
|
|||||||
gMusicPlaying = 0;
|
gMusicPlaying = 0;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if (!m_bMenuActive)
|
if (m_bMenuActive != menuWasActive)
|
||||||
m_bMenuNotProcessed = true;
|
m_bMenuStateChanged = true;
|
||||||
|
|
||||||
m_bStartUpFrontEndRequested = false;
|
m_bStartUpFrontEndRequested = false;
|
||||||
m_bShutDownFrontEndRequested = false;
|
m_bShutDownFrontEndRequested = false;
|
||||||
|
@ -403,7 +403,7 @@ public:
|
|||||||
int32 m_nHelperTextMsgId;
|
int32 m_nHelperTextMsgId;
|
||||||
bool m_bLanguageLoaded;
|
bool m_bLanguageLoaded;
|
||||||
bool m_bMenuActive;
|
bool m_bMenuActive;
|
||||||
bool m_bMenuNotProcessed;
|
bool m_bMenuStateChanged;
|
||||||
bool m_bWaitingForNewKeyBind;
|
bool m_bWaitingForNewKeyBind;
|
||||||
bool m_bStartGameLoading;
|
bool m_bStartGameLoading;
|
||||||
bool m_bFirstTime;
|
bool m_bFirstTime;
|
||||||
@ -540,8 +540,14 @@ public:
|
|||||||
void WaitForUserCD();
|
void WaitForUserCD();
|
||||||
void PrintController();
|
void PrintController();
|
||||||
|
|
||||||
// New content:
|
// New (not in function or inlined in the game)
|
||||||
uint8 GetNumberOfMenuOptions();
|
void ThingsToDoBeforeLeavingPage();
|
||||||
|
void ScrollUpListByOne();
|
||||||
|
void ScrollDownListByOne();
|
||||||
|
void PageUpList(bool);
|
||||||
|
void PageDownList(bool);
|
||||||
|
|
||||||
|
// uint8 GetNumberOfMenuOptions();
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(CMenuManager) == 0x564, "CMenuManager: error");
|
static_assert(sizeof(CMenuManager) == 0x564, "CMenuManager: error");
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
class CTimer
|
class CTimer
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
static uint32 &m_snTimeInMilliseconds;
|
static uint32 &m_snTimeInMilliseconds;
|
||||||
static uint32 &m_snTimeInMillisecondsPauseMode;
|
static uint32 &m_snTimeInMillisecondsPauseMode;
|
||||||
static uint32 &m_snTimeInMillisecondsNonClipped;
|
static uint32 &m_snTimeInMillisecondsNonClipped;
|
||||||
@ -11,19 +11,20 @@ public:
|
|||||||
static float &ms_fTimeScale;
|
static float &ms_fTimeScale;
|
||||||
static float &ms_fTimeStep;
|
static float &ms_fTimeStep;
|
||||||
static float &ms_fTimeStepNonClipped;
|
static float &ms_fTimeStepNonClipped;
|
||||||
|
public:
|
||||||
static bool &m_UserPause;
|
static bool &m_UserPause;
|
||||||
static bool &m_CodePause;
|
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 void SetTimeStep(float ts) { ms_fTimeStep = ts; }
|
||||||
static float GetTimeStepInSeconds() { return ms_fTimeStep / 50.0f; }
|
static float GetTimeStepInSeconds() { return ms_fTimeStep / 50.0f; }
|
||||||
static float GetTimeStepInMilliseconds() { return ms_fTimeStep / 50.0f * 1000.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 float GetTimeStepNonClippedInSeconds(void) { return ms_fTimeStepNonClipped / 50.0f; }
|
||||||
static void SetTimeStepNonClipped(float ts) { ms_fTimeStepNonClipped = ts; }
|
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 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 void SetTimeInMilliseconds(uint32 t) { m_snTimeInMilliseconds = t; }
|
||||||
static uint32 GetTimeInMillisecondsNonClipped(void) { return m_snTimeInMillisecondsNonClipped; }
|
static uint32 GetTimeInMillisecondsNonClipped(void) { return m_snTimeInMillisecondsNonClipped; }
|
||||||
static void SetTimeInMillisecondsNonClipped(uint32 t) { m_snTimeInMillisecondsNonClipped = t; }
|
static void SetTimeInMillisecondsNonClipped(uint32 t) { m_snTimeInMillisecondsNonClipped = t; }
|
||||||
@ -31,7 +32,7 @@ public:
|
|||||||
static void SetTimeInMillisecondsPauseMode(uint32 t) { m_snTimeInMillisecondsPauseMode = t; }
|
static void SetTimeInMillisecondsPauseMode(uint32 t) { m_snTimeInMillisecondsPauseMode = t; }
|
||||||
static uint32 GetPreviousTimeInMilliseconds(void) { return m_snPreviousTimeInMilliseconds; }
|
static uint32 GetPreviousTimeInMilliseconds(void) { return m_snPreviousTimeInMilliseconds; }
|
||||||
static void SetPreviousTimeInMilliseconds(uint32 t) { m_snPreviousTimeInMilliseconds = t; }
|
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 void SetTimeScale(float ts) { ms_fTimeScale = ts; }
|
||||||
|
|
||||||
static bool GetIsPaused() { return m_UserPause || m_CodePause; }
|
static bool GetIsPaused() { return m_UserPause || m_CodePause; }
|
||||||
|
@ -101,6 +101,8 @@ enum Config {
|
|||||||
NUMPEDGROUPS = 31,
|
NUMPEDGROUPS = 31,
|
||||||
NUMMODELSPERPEDGROUP = 8,
|
NUMMODELSPERPEDGROUP = 8,
|
||||||
|
|
||||||
|
NUMROADBLOCKS = 600,
|
||||||
|
|
||||||
NUMVISIBLEENTITIES = 2000,
|
NUMVISIBLEENTITIES = 2000,
|
||||||
NUMINVISIBLEENTITIES = 150,
|
NUMINVISIBLEENTITIES = 150,
|
||||||
|
|
||||||
@ -169,10 +171,11 @@ 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
|
#define TOGGLEABLE_BETA_FEATURES // toggleable from debug menu. not too many things
|
||||||
|
|
||||||
// Pad
|
// Pad
|
||||||
#define KANGAROO_CHEAT
|
#define KANGAROO_CHEAT
|
||||||
|
#define REGISTER_START_BUTTON // currently only in menu sadly. resumes the game
|
||||||
|
|
||||||
// Hud, frontend and radar
|
// Hud, frontend and radar
|
||||||
#define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios
|
#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
|
// Peds
|
||||||
#define ANIMATE_PED_COL_MODEL
|
#define ANIMATE_PED_COL_MODEL
|
||||||
#define VC_PED_PORTS // various ports from VC's CPed, mostly subtle
|
#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
|
#define CANCELLABLE_CAR_ENTER
|
||||||
|
@ -7,8 +7,11 @@
|
|||||||
#include "Vehicle.h"
|
#include "Vehicle.h"
|
||||||
#include "RpAnimBlend.h"
|
#include "RpAnimBlend.h"
|
||||||
#include "General.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)
|
CCopPed::CCopPed(eCopType copType) : CPed(PEDTYPE_COP)
|
||||||
{
|
{
|
||||||
@ -58,11 +61,16 @@ CCopPed::CCopPed(eCopType copType) : CPed(PEDTYPE_COP)
|
|||||||
m_bIsDisabledCop = false;
|
m_bIsDisabledCop = false;
|
||||||
field_1356 = 0;
|
field_1356 = 0;
|
||||||
m_attackTimer = 0;
|
m_attackTimer = 0;
|
||||||
field_1351 = 0;
|
m_bBeatingSuspect = false;
|
||||||
m_bZoneDisabledButClose = false;
|
m_bZoneDisabledButClose = false;
|
||||||
m_bZoneDisabled = false;
|
m_bZoneDisabled = false;
|
||||||
field_1364 = -1;
|
field_1364 = -1;
|
||||||
m_pPointGunAt = nil;
|
m_pPointGunAt = nil;
|
||||||
|
|
||||||
|
// VC also initializes in here, but it keeps object
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
m_wRoadblockNode = -1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CCopPed::~CCopPed()
|
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
|
void
|
||||||
CCopPed::SetPursuit(bool iMayAlreadyBeInPursuit)
|
CCopPed::SetPursuit(bool ignoreCopLimit)
|
||||||
{
|
{
|
||||||
CWanted *wanted = FindPlayerPed()->m_pWanted;
|
CWanted *wanted = FindPlayerPed()->m_pWanted;
|
||||||
if (m_bIsInPursuit || !IsPedInControl())
|
if (m_bIsInPursuit || !IsPedInControl())
|
||||||
return;
|
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) {
|
for (int i = 0; i < wanted->m_MaxCops; ++i) {
|
||||||
if (!wanted->m_pCops[i]) {
|
if (!wanted->m_pCops[i]) {
|
||||||
m_bIsInPursuit = true;
|
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
|
class CCopPed_ : public CCopPed
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -290,4 +566,5 @@ STARTPATCHES
|
|||||||
InjectHook(0x4C27D0, &CCopPed::SetPursuit, PATCH_JUMP);
|
InjectHook(0x4C27D0, &CCopPed::SetPursuit, PATCH_JUMP);
|
||||||
InjectHook(0x4C2C90, &CCopPed::ArrestPlayer, PATCH_JUMP);
|
InjectHook(0x4C2C90, &CCopPed::ArrestPlayer, PATCH_JUMP);
|
||||||
InjectHook(0x4C26A0, &CCopPed::ScanForCrimes, PATCH_JUMP);
|
InjectHook(0x4C26A0, &CCopPed::ScanForCrimes, PATCH_JUMP);
|
||||||
|
InjectHook(0x4C1B50, &CCopPed::CopAI, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
||||||
|
@ -17,9 +17,9 @@ public:
|
|||||||
int8 field_1343;
|
int8 field_1343;
|
||||||
float m_fDistanceToTarget;
|
float m_fDistanceToTarget;
|
||||||
int8 m_bIsInPursuit;
|
int8 m_bIsInPursuit;
|
||||||
int8 m_bIsDisabledCop;
|
int8 m_bIsDisabledCop; // What disabled cop actually is?
|
||||||
int8 field_1350;
|
int8 field_1350;
|
||||||
int8 field_1351;
|
bool m_bBeatingSuspect;
|
||||||
int8 m_bZoneDisabledButClose;
|
int8 m_bZoneDisabledButClose;
|
||||||
int8 m_bZoneDisabled;
|
int8 m_bZoneDisabled;
|
||||||
int8 field_1354;
|
int8 field_1354;
|
||||||
@ -40,6 +40,7 @@ public:
|
|||||||
void SetPursuit(bool);
|
void SetPursuit(bool);
|
||||||
void ArrestPlayer(void);
|
void ArrestPlayer(void);
|
||||||
void ScanForCrimes(void);
|
void ScanForCrimes(void);
|
||||||
|
void CopAI(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(CCopPed) == 0x558, "CCopPed: error");
|
static_assert(sizeof(CCopPed) == 0x558, "CCopPed: error");
|
||||||
|
@ -2720,6 +2720,10 @@ CPed::SetObjective(eObjective newObj, void *entity)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef VC_PED_PORTS
|
||||||
|
SetObjectiveTimer(0);
|
||||||
|
ClearPointGunAt();
|
||||||
|
#endif
|
||||||
bObjectiveCompleted = false;
|
bObjectiveCompleted = false;
|
||||||
if (!IsTemporaryObjective(m_objective) || IsTemporaryObjective(newObj)) {
|
if (!IsTemporaryObjective(m_objective) || IsTemporaryObjective(newObj)) {
|
||||||
if (m_objective != newObj) {
|
if (m_objective != newObj) {
|
||||||
@ -3444,8 +3448,12 @@ CPed::ClearAll(void)
|
|||||||
m_fleeFrom = nil;
|
m_fleeFrom = nil;
|
||||||
m_fleeTimer = 0;
|
m_fleeTimer = 0;
|
||||||
bUsesCollision = true;
|
bUsesCollision = true;
|
||||||
|
#ifdef VC_PED_PORTS
|
||||||
|
ClearPointGunAt();
|
||||||
|
#else
|
||||||
ClearAimFlag();
|
ClearAimFlag();
|
||||||
ClearLookFlag();
|
ClearLookFlag();
|
||||||
|
#endif
|
||||||
bIsPointingGunAt = false;
|
bIsPointingGunAt = false;
|
||||||
bRenderPedInCar = true;
|
bRenderPedInCar = true;
|
||||||
bKnockedUpIntoAir = false;
|
bKnockedUpIntoAir = false;
|
||||||
|
@ -576,7 +576,7 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
|
|||||||
}
|
}
|
||||||
// Yeah, float
|
// Yeah, float
|
||||||
float maxPossiblePedsForArea = (zoneInfo.pedDensity + zoneInfo.carDensity) * playerInfo->m_fRoadDensity * PedDensityMultiplier * CIniFile::PedNumberMultiplier;
|
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) {
|
if (ms_nTotalPeds < maxPossiblePedsForArea || addCop) {
|
||||||
int decisionThreshold = CGeneral::GetRandomNumberInRange(0, 1000);
|
int decisionThreshold = CGeneral::GetRandomNumberInRange(0, 1000);
|
||||||
|
@ -61,9 +61,9 @@ do {\
|
|||||||
MakeSpaceForSizeInBufferPointer(presize, buf, postsize);\
|
MakeSpaceForSizeInBufferPointer(presize, buf, postsize);\
|
||||||
save_func(buf, &size);\
|
save_func(buf, &size);\
|
||||||
CopySizeAndPreparePointer(presize, buf, postsize, reserved, 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;\
|
return false;\
|
||||||
totalSize += size;\
|
totalSize += buf - work_buff;\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -74,7 +74,6 @@ GenericSave(int file)
|
|||||||
uint32 reserved;
|
uint32 reserved;
|
||||||
|
|
||||||
uint32 totalSize;
|
uint32 totalSize;
|
||||||
uint32 i;
|
|
||||||
|
|
||||||
wchar *lastMissionPassed;
|
wchar *lastMissionPassed;
|
||||||
wchar suffix[6];
|
wchar suffix[6];
|
||||||
@ -85,13 +84,11 @@ GenericSave(int file)
|
|||||||
CheckSum = 0;
|
CheckSum = 0;
|
||||||
buf = work_buff;
|
buf = work_buff;
|
||||||
reserved = 0;
|
reserved = 0;
|
||||||
totalSize = 0;
|
|
||||||
|
|
||||||
// Save simple vars
|
// Save simple vars
|
||||||
INITSAVEBUF
|
|
||||||
lastMissionPassed = TheText.Get(CStats::LastMissionPassedName);
|
lastMissionPassed = TheText.Get(CStats::LastMissionPassedName);
|
||||||
if (*lastMissionPassed) {
|
if (*lastMissionPassed) {
|
||||||
AsciiToUnicode("'...", suffix);
|
AsciiToUnicode("...'", suffix);
|
||||||
TextCopy(saveName, lastMissionPassed);
|
TextCopy(saveName, lastMissionPassed);
|
||||||
int len = UnicodeStrlen(saveName);
|
int len = UnicodeStrlen(saveName);
|
||||||
saveName[len] = '\0';
|
saveName[len] = '\0';
|
||||||
@ -104,20 +101,20 @@ INITSAVEBUF
|
|||||||
WriteDataToBufferPointer(buf, saveTime);
|
WriteDataToBufferPointer(buf, saveTime);
|
||||||
WriteDataToBufferPointer(buf, SIZE_OF_ONE_GAME_IN_BYTES);
|
WriteDataToBufferPointer(buf, SIZE_OF_ONE_GAME_IN_BYTES);
|
||||||
WriteDataToBufferPointer(buf, CGame::currLevel);
|
WriteDataToBufferPointer(buf, CGame::currLevel);
|
||||||
WriteDataToBufferPointer(buf, TheCamera.m_matrix.m_matrix.pos.x);
|
WriteDataToBufferPointer(buf, TheCamera.GetPosition().x);
|
||||||
WriteDataToBufferPointer(buf, TheCamera.m_matrix.m_matrix.pos.y);
|
WriteDataToBufferPointer(buf, TheCamera.GetPosition().y);
|
||||||
WriteDataToBufferPointer(buf, TheCamera.m_matrix.m_matrix.pos.z);
|
WriteDataToBufferPointer(buf, TheCamera.GetPosition().z);
|
||||||
WriteDataToBufferPointer(buf, CClock::ms_nMillisecondsPerGameMinute);
|
WriteDataToBufferPointer(buf, CClock::ms_nMillisecondsPerGameMinute);
|
||||||
WriteDataToBufferPointer(buf, CClock::ms_nLastClockTick);
|
WriteDataToBufferPointer(buf, CClock::ms_nLastClockTick);
|
||||||
WriteDataToBufferPointer(buf, CClock::ms_nGameClockHours);
|
WriteDataToBufferPointer(buf, CClock::ms_nGameClockHours);
|
||||||
WriteDataToBufferPointer(buf, CClock::ms_nGameClockMinutes);
|
WriteDataToBufferPointer(buf, CClock::ms_nGameClockMinutes);
|
||||||
currPad = CPad::GetPad(0);
|
currPad = CPad::GetPad(0);
|
||||||
WriteDataToBufferPointer(buf, currPad->Mode);
|
WriteDataToBufferPointer(buf, currPad->Mode);
|
||||||
WriteDataToBufferPointer(buf, CTimer::m_snTimeInMilliseconds);
|
WriteDataToBufferPointer(buf, CTimer::GetTimeInMilliseconds());
|
||||||
WriteDataToBufferPointer(buf, CTimer::ms_fTimeScale);
|
WriteDataToBufferPointer(buf, CTimer::GetTimeScale());
|
||||||
WriteDataToBufferPointer(buf, CTimer::ms_fTimeStep);
|
WriteDataToBufferPointer(buf, CTimer::GetTimeStep());
|
||||||
WriteDataToBufferPointer(buf, CTimer::ms_fTimeStepNonClipped);
|
WriteDataToBufferPointer(buf, CTimer::GetTimeStepNonClipped());
|
||||||
WriteDataToBufferPointer(buf, CTimer::m_FrameCounter);
|
WriteDataToBufferPointer(buf, CTimer::GetFrameCounter());
|
||||||
WriteDataToBufferPointer(buf, CTimeStep::ms_fTimeStep);
|
WriteDataToBufferPointer(buf, CTimeStep::ms_fTimeStep);
|
||||||
WriteDataToBufferPointer(buf, CTimeStep::ms_fFramesPerUpdate);
|
WriteDataToBufferPointer(buf, CTimeStep::ms_fFramesPerUpdate);
|
||||||
WriteDataToBufferPointer(buf, CTimeStep::ms_fTimeScale);
|
WriteDataToBufferPointer(buf, CTimeStep::ms_fTimeScale);
|
||||||
@ -134,10 +131,8 @@ INITSAVEBUF
|
|||||||
WriteDataToBufferPointer(buf, CWeather::WeatherTypeInList);
|
WriteDataToBufferPointer(buf, CWeather::WeatherTypeInList);
|
||||||
WriteDataToBufferPointer(buf, TheCamera.CarZoomIndicator);
|
WriteDataToBufferPointer(buf, TheCamera.CarZoomIndicator);
|
||||||
WriteDataToBufferPointer(buf, TheCamera.PedZoomIndicator);
|
WriteDataToBufferPointer(buf, TheCamera.PedZoomIndicator);
|
||||||
#ifdef VALIDATE_SAVE_SIZE
|
|
||||||
_saveBufCount = buf - work_buff;
|
assert(buf - work_buff == SIZE_OF_SIMPLEVARS);
|
||||||
#endif
|
|
||||||
VALIDATESAVEBUF(SIZE_OF_SIMPLEVARS);
|
|
||||||
|
|
||||||
// Save scripts, block is nested within the same block as simple vars for some reason
|
// Save scripts, block is nested within the same block as simple vars for some reason
|
||||||
presize = buf;
|
presize = buf;
|
||||||
@ -145,9 +140,10 @@ VALIDATESAVEBUF(SIZE_OF_SIMPLEVARS);
|
|||||||
postsize = buf;
|
postsize = buf;
|
||||||
CTheScripts::SaveAllScripts(buf, &size);
|
CTheScripts::SaveAllScripts(buf, &size);
|
||||||
CopySizeAndPreparePointer(presize, buf, postsize, reserved, 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;
|
return false;
|
||||||
totalSize += size + SIZE_OF_SIMPLEVARS;
|
|
||||||
|
totalSize = buf - work_buff;
|
||||||
|
|
||||||
// Save the rest
|
// Save the rest
|
||||||
WRITE_BLOCK(CPools::SavePedPool);
|
WRITE_BLOCK(CPools::SavePedPool);
|
||||||
@ -171,8 +167,7 @@ VALIDATESAVEBUF(SIZE_OF_SIMPLEVARS);
|
|||||||
WRITE_BLOCK(CPedType::Save);
|
WRITE_BLOCK(CPedType::Save);
|
||||||
|
|
||||||
// Write padding
|
// Write padding
|
||||||
i = 0;
|
for (int i = 0; i < 4; i++) {
|
||||||
do {
|
|
||||||
size = align4bytes(SIZE_OF_ONE_GAME_IN_BYTES - totalSize - 4);
|
size = align4bytes(SIZE_OF_ONE_GAME_IN_BYTES - totalSize - 4);
|
||||||
if (size > sizeof(work_buff))
|
if (size > sizeof(work_buff))
|
||||||
size = sizeof(work_buff);
|
size = sizeof(work_buff);
|
||||||
@ -181,15 +176,15 @@ VALIDATESAVEBUF(SIZE_OF_SIMPLEVARS);
|
|||||||
return false;
|
return false;
|
||||||
totalSize += size;
|
totalSize += size;
|
||||||
}
|
}
|
||||||
i++;
|
}
|
||||||
} while (i < 4);
|
|
||||||
|
|
||||||
// Write checksum and close
|
// Write checksum and close
|
||||||
CFileMgr::Write(file, (const char *) &CheckSum, sizeof(CheckSum));
|
CFileMgr::Write(file, (const char *) &CheckSum, sizeof(CheckSum));
|
||||||
if (CFileMgr::GetErrorReadWrite(file)) {
|
if (CFileMgr::GetErrorReadWrite(file)) {
|
||||||
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
|
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
|
||||||
if (CloseFile(file))
|
if (!CloseFile(file))
|
||||||
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
|
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ C_PcSave::SaveSlot(int32 slot)
|
|||||||
if (file != 0) {
|
if (file != 0) {
|
||||||
DoGameSpecificStuffBeforeSave();
|
DoGameSpecificStuffBeforeSave();
|
||||||
if (GenericSave(file)) {
|
if (GenericSave(file)) {
|
||||||
if (CFileMgr::CloseFile(file) != 0)
|
if (!!CFileMgr::CloseFile(file))
|
||||||
nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
|
nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -55,21 +55,21 @@ C_PcSave::PcClassSaveRoutine(int32 file, uint8 *data, uint32 size)
|
|||||||
CFileMgr::Write(file, (const char*)&size, sizeof(size));
|
CFileMgr::Write(file, (const char*)&size, sizeof(size));
|
||||||
if (CFileMgr::GetErrorReadWrite(file)) {
|
if (CFileMgr::GetErrorReadWrite(file)) {
|
||||||
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
|
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
|
||||||
strncpy(SaveFileNameJustSaved, ValidSaveName, 259);
|
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CFileMgr::Write(file, (const char*)data, align4bytes(size));
|
CFileMgr::Write(file, (const char*)data, align4bytes(size));
|
||||||
CheckSum += ((uint8*)&size)[0];
|
CheckSum += (uint8) size;
|
||||||
CheckSum += ((uint8*)&size)[1];
|
CheckSum += (uint8) (size >> 8);
|
||||||
CheckSum += ((uint8*)&size)[2];
|
CheckSum += (uint8) (size >> 16);
|
||||||
CheckSum += ((uint8*)&size)[3];
|
CheckSum += (uint8) (size >> 24);
|
||||||
for (int i = 0; i < align4bytes(size); i++) {
|
for (int i = 0; i < align4bytes(size); i++) {
|
||||||
CheckSum += *data++;
|
CheckSum += *data++;
|
||||||
}
|
}
|
||||||
if (CFileMgr::GetErrorReadWrite(file)) {
|
if (CFileMgr::GetErrorReadWrite(file)) {
|
||||||
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
|
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
|
||||||
strncpy(SaveFileNameJustSaved, ValidSaveName, 259);
|
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user