mirror of
https://git.rip/DMCA_FUCKER/re3.git
synced 2025-01-11 03:44:08 +00:00
Merge branch 'miami' of https://github.com/GTAmodding/re3 into miami
This commit is contained in:
commit
99574ebfc6
|
@ -104,7 +104,7 @@ strcmpIgnoringDigits(const char *s1, const char *s2)
|
|||
c2 = toupper(c2);
|
||||
#endif
|
||||
|
||||
if(c1 != c2)
|
||||
if(c1 && c2 && c1 != c2)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -926,7 +926,7 @@ const AnimAssocDefinition CAnimManager::ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_
|
|||
{ "grenade", "grenade", MI_COP, awc(aThrowAnimations), aWeaponAnimDescs },
|
||||
{ "flame", "flame", MI_COP, awc(aFlamethrowerAnimations), aWeaponAnimDescs },
|
||||
{ "medic", "medic", MI_COP, awc(aMedicAnimations), aMedicAnimDescs },
|
||||
{ "sunbathe", "sunbathe", MI_COP, awc(aSunbatheAnimations), aSunbatheAnimDescs },
|
||||
{ "sunbathe", "sunbathe", MI_COP, 1, aSunbatheAnimations, aSunbatheAnimDescs }, // NB: not using awc here!
|
||||
{ "playidles", "playidles", MI_COP, awc(aPlayerIdleAnimations), aPlayerIdleAnimDescs },
|
||||
{ "riot", "riot", MI_COP, awc(aRiotAnimations), aRiotAnimDescs },
|
||||
{ "strip", "strip", MI_COP, awc(aStripAnimations), aStripAnimDescs },
|
||||
|
|
|
@ -358,7 +358,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
|
|||
pVehicle->AutoPilot.m_nCruiseSpeed = FindPoliceCarSpeedForWantedLevel(pVehicle);
|
||||
pVehicle->SetStatus(STATUS_PHYSICS);
|
||||
pVehicle->AutoPilot.m_nCarMission =
|
||||
pVehicle->GetVehicleAppearance() == VEHICLE_BOAT ? FindPoliceBoatMissionForWantedLevel() : FindPoliceCarMissionForWantedLevel();
|
||||
pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT ? FindPoliceBoatMissionForWantedLevel() : FindPoliceCarMissionForWantedLevel();
|
||||
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||
pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
|
||||
}else if (pVehicle->AutoPilot.m_nCarMission == MISSION_CRUISE){
|
||||
|
@ -432,7 +432,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
|
|||
if (pVehicle->bIsLawEnforcer) {
|
||||
if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_FARAWAY ||
|
||||
pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_CLOSE) {
|
||||
if (FindPlayerVehicle() && FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_BIKE)
|
||||
if (FindPlayerVehicle() && FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE)
|
||||
pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKPLAYER_FARAWAY;
|
||||
}
|
||||
}
|
||||
|
@ -489,16 +489,16 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
|
|||
|
||||
if (pVehicle->bIsLawEnforcer && FindPlayerPed()->m_pWanted->m_nWantedLevel > 0) {
|
||||
if (!FindPlayerVehicle() ||
|
||||
FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_CAR ||
|
||||
FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_BIKE) {
|
||||
if (pVehicle->GetVehicleAppearance() == VEHICLE_BOAT) {
|
||||
FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_CAR ||
|
||||
FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE) {
|
||||
if (pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT) {
|
||||
pVehicle->AutoPilot.m_nTempAction = TEMPACT_WAIT;
|
||||
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 1000;
|
||||
}
|
||||
}
|
||||
else if (FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_BOAT) {
|
||||
if (pVehicle->GetVehicleAppearance() == VEHICLE_CAR ||
|
||||
pVehicle->GetVehicleAppearance() == VEHICLE_BIKE) {
|
||||
else if (FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT) {
|
||||
if (pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_CAR ||
|
||||
pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE) {
|
||||
pVehicle->AutoPilot.m_nTempAction = TEMPACT_WAIT;
|
||||
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 1000;
|
||||
}
|
||||
|
|
|
@ -655,10 +655,10 @@ CCarCtrl::GenerateOneRandomCar()
|
|||
}
|
||||
int nMadDrivers;
|
||||
switch (pVehicle->GetVehicleAppearance()) {
|
||||
case VEHICLE_BIKE:
|
||||
case VEHICLE_APPEARANCE_BIKE:
|
||||
nMadDrivers = 30;
|
||||
break;
|
||||
case VEHICLE_BOAT:
|
||||
case VEHICLE_APPEARANCE_BOAT:
|
||||
nMadDrivers = 40;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -960,7 +960,7 @@ void CGarage::Update()
|
|||
if (m_pDoor1) {
|
||||
if (((CVector2D)FindPlayerVehicle()->GetPosition() - (CVector2D)m_pDoor1->GetPosition()).MagnitudeSqr() < SQR(DISTANCE_TO_SHOW_HIDEOUT_MESSAGE) &&
|
||||
CTimer::GetTimeInMilliseconds() - CGarages::LastTimeHelpMessage > TIME_BETWEEN_HIDEOUT_MESSAGES) {
|
||||
if (FindPlayerVehicle()->GetVehicleAppearance() != VEHICLE_HELI && FindPlayerVehicle()->GetVehicleAppearance() != VEHICLE_PLANE) {
|
||||
if (FindPlayerVehicle()->GetVehicleAppearance() != VEHICLE_APPEARANCE_HELI && FindPlayerVehicle()->GetVehicleAppearance() != VEHICLE_APPEARANCE_PLANE) {
|
||||
CHud::SetHelpMessage(TheText.Get("GA_21"), false); // You cannot store any more cars in this garage.
|
||||
CGarages::LastTimeHelpMessage = CTimer::GetTimeInMilliseconds();
|
||||
}
|
||||
|
|
|
@ -172,12 +172,12 @@ CPickup::GiveUsAPickUpObject(int32 handle)
|
|||
}
|
||||
|
||||
bool
|
||||
CPickup::CanBePickedUp(CPlayerPed *player)
|
||||
CPickup::CanBePickedUp(CPlayerPed *player, int playerId)
|
||||
{
|
||||
assert(m_pObject != nil);
|
||||
bool cannotBePickedUp =
|
||||
(m_pObject->GetModelIndex() == MI_PICKUP_BODYARMOUR && player->m_fArmour > 99.5f)
|
||||
|| (m_pObject->GetModelIndex() == MI_PICKUP_HEALTH && player->m_fHealth > 99.5f)
|
||||
(m_pObject->GetModelIndex() == MI_PICKUP_BODYARMOUR && player->m_fArmour > CWorld::Players[playerId].m_nMaxArmour - 0.5f)
|
||||
|| (m_pObject->GetModelIndex() == MI_PICKUP_HEALTH && player->m_fHealth > CWorld::Players[playerId].m_nMaxHealth - 0.5f)
|
||||
|| (m_pObject->GetModelIndex() == MI_PICKUP_BRIBE && player->m_pWanted->m_nWantedLevel == 0)
|
||||
|| (m_pObject->GetModelIndex() == MI_PICKUP_KILLFRENZY && (CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame));
|
||||
return !cannotBePickedUp;
|
||||
|
@ -233,7 +233,7 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
|
|||
}
|
||||
|
||||
// if we didn't then we've got nothing to do
|
||||
if (isPickupTouched && CanBePickedUp(player)) {
|
||||
if (isPickupTouched && CanBePickedUp(player, playerId)) {
|
||||
CPad::GetPad(0)->StartShake(120, 100);
|
||||
switch (m_eType)
|
||||
{
|
||||
|
@ -497,14 +497,14 @@ CPickups::GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex)
|
|||
DMAudio.PlayFrontEndSound(SOUND_PICKUP_ADRENALINE, 0);
|
||||
return true;
|
||||
} else if (modelIndex == MI_PICKUP_BODYARMOUR) {
|
||||
player->m_fArmour = 100.0f;
|
||||
player->m_fArmour = CWorld::Players[playerIndex].m_nMaxArmour;
|
||||
DMAudio.PlayFrontEndSound(SOUND_PICKUP_ARMOUR, 0);
|
||||
return true;
|
||||
} else if (modelIndex == MI_PICKUP_INFO) {
|
||||
DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0);
|
||||
return true;
|
||||
} else if (modelIndex == MI_PICKUP_HEALTH) {
|
||||
player->m_fHealth = 100.0f;
|
||||
player->m_fHealth = CWorld::Players[playerIndex].m_nMaxHealth;
|
||||
DMAudio.PlayFrontEndSound(SOUND_PICKUP_HEALTH, 0);
|
||||
return true;
|
||||
} else if (modelIndex == MI_PICKUP_BONUS) {
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
bool Update(CPlayerPed *player, CVehicle *vehicle, int playerId);
|
||||
private:
|
||||
bool IsMine() { return m_eType >= PICKUP_MINE_INACTIVE && m_eType <= PICKUP_FLOATINGPACKAGE_FLOATING; }
|
||||
inline bool CanBePickedUp(CPlayerPed *player);
|
||||
inline bool CanBePickedUp(CPlayerPed *player, int playerId);
|
||||
void RemoveKeepType();
|
||||
void Remove();
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -221,19 +221,17 @@ enum {
|
|||
};
|
||||
|
||||
enum {
|
||||
SIZE_MAIN_SCRIPT = 128 * 1024,
|
||||
SIZE_MISSION_SCRIPT = 32 * 1024,
|
||||
SIZE_MAIN_SCRIPT = 225512,
|
||||
SIZE_MISSION_SCRIPT = 35000,
|
||||
SIZE_SCRIPT_SPACE = SIZE_MAIN_SCRIPT + SIZE_MISSION_SCRIPT
|
||||
};
|
||||
|
||||
enum {
|
||||
MAX_NUM_SCRIPTS = 128,
|
||||
MAX_NUM_CONTACTS = 16,
|
||||
MAX_NUM_INTRO_TEXT_LINES = 2,
|
||||
MAX_NUM_INTRO_RECTANGLES = 16,
|
||||
MAX_NUM_SCRIPT_SRPITES = 16,
|
||||
MAX_NUM_SCRIPT_SPHERES = 16,
|
||||
MAX_NUM_COLLECTIVES = 32,
|
||||
MAX_NUM_USED_OBJECTS = 200,
|
||||
MAX_NUM_MISSION_SCRIPTS = 120,
|
||||
MAX_NUM_BUILDING_SWAPS = 25,
|
||||
|
@ -245,13 +243,10 @@ class CTheScripts
|
|||
{
|
||||
static uint8 ScriptSpace[SIZE_SCRIPT_SPACE];
|
||||
static CRunningScript ScriptsArray[MAX_NUM_SCRIPTS];
|
||||
static int32 BaseBriefIdForContact[MAX_NUM_CONTACTS];
|
||||
static int32 OnAMissionForContactFlag[MAX_NUM_CONTACTS];
|
||||
static intro_text_line IntroTextLines[MAX_NUM_INTRO_TEXT_LINES];
|
||||
static intro_script_rectangle IntroRectangles[MAX_NUM_INTRO_RECTANGLES];
|
||||
static CSprite2d ScriptSprites[MAX_NUM_SCRIPT_SRPITES];
|
||||
static script_sphere_struct ScriptSphereArray[MAX_NUM_SCRIPT_SPHERES];
|
||||
static tCollectiveData CollectiveArray[MAX_NUM_COLLECTIVES];
|
||||
static tUsedObject UsedObjectArray[MAX_NUM_USED_OBJECTS];
|
||||
static int32 MultiScriptArray[MAX_NUM_MISSION_SCRIPTS];
|
||||
static tBuildingSwap BuildingSwapArray[MAX_NUM_BUILDING_SWAPS];
|
||||
|
@ -275,14 +270,17 @@ class CTheScripts
|
|||
static uint32 LargestMissionScriptSize;
|
||||
static uint32 MainScriptSize;
|
||||
static uint8 FailCurrentMission;
|
||||
static uint8 CountdownToMakePlayerUnsafe;
|
||||
static uint8 DelayMakingPlayerUnsafeThisTime;
|
||||
static uint16 NumScriptDebugLines;
|
||||
static uint16 NumberOfIntroRectanglesThisFrame;
|
||||
static uint16 NumberOfIntroTextLinesThisFrame;
|
||||
static uint8 UseTextCommands;
|
||||
static uint16 CommandsExecuted;
|
||||
static uint16 ScriptsUpdated;
|
||||
static uint8 RiotIntensity;
|
||||
static uint32 LastMissionPassedTime;
|
||||
static uint16 NumberOfExclusiveMissionScripts;
|
||||
static bool bPlayerIsInTheStatium;
|
||||
static bool bPlayerHasMetDebbieHarry;
|
||||
|
||||
public:
|
||||
static void Init();
|
||||
|
@ -306,9 +304,6 @@ public:
|
|||
|
||||
static int32* GetPointerToScriptVariable(int32 offset) { assert(offset >= 8 && offset < CTheScripts::GetSizeOfVariableSpace()); return (int32*)&ScriptSpace[offset]; }
|
||||
|
||||
static void ResetCountdownToMakePlayerUnsafe() { CountdownToMakePlayerUnsafe = 0; }
|
||||
static bool IsCountdownToMakePlayerUnsafeOn() { return CountdownToMakePlayerUnsafe != 0; }
|
||||
|
||||
static int32 Read4BytesFromScript(uint32* pIp) {
|
||||
int32 retval = ScriptSpace[*pIp + 3] << 24 | ScriptSpace[*pIp + 2] << 16 | ScriptSpace[*pIp + 1] << 8 | ScriptSpace[*pIp];
|
||||
*pIp += 4;
|
||||
|
@ -371,6 +366,7 @@ private:
|
|||
static int32 AddScriptSphere(int32 id, CVector pos, float radius);
|
||||
static int32 GetNewUniqueScriptSphereIndex(int32 index);
|
||||
static void RemoveScriptSphere(int32 index);
|
||||
static void RemoveScriptTextureDictionary();
|
||||
|
||||
friend class CRunningScript;
|
||||
friend class CHud;
|
||||
|
@ -414,6 +410,7 @@ class CRunningScript
|
|||
uint32 m_anStack[MAX_STACK_DEPTH];
|
||||
uint16 m_nStackPointer;
|
||||
int32 m_anLocalVariables[NUM_LOCAL_VARS + NUM_TIMERS];
|
||||
bool m_bIsActive;
|
||||
bool m_bCondResult;
|
||||
bool m_bIsMissionScript;
|
||||
bool m_bSkipWakeTime;
|
||||
|
@ -507,4 +504,6 @@ private:
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami);
|
||||
};
|
||||
|
|
|
@ -61,6 +61,8 @@ enum
|
|||
CCamera TheCamera;
|
||||
bool CCamera::m_bUseMouse3rdPerson = true;
|
||||
bool bDidWeProcessAnyCinemaCam;
|
||||
float CCamera::m_f3rdPersonCHairMultX;
|
||||
float CCamera::m_f3rdPersonCHairMultY;
|
||||
|
||||
#ifdef IMPROVED_CAMERA
|
||||
#define KEYJUSTDOWN(k) ControlsManager.GetIsKeyboardKeyJustDown((RsKeyCodes)k)
|
||||
|
|
|
@ -472,8 +472,8 @@ public:
|
|||
// not static yet
|
||||
float m_fMouseAccelHorzntl;// acceleration multiplier for 1st person controls
|
||||
float m_fMouseAccelVertical;// acceleration multiplier for 1st person controls
|
||||
float m_f3rdPersonCHairMultX;
|
||||
float m_f3rdPersonCHairMultY;
|
||||
static float m_f3rdPersonCHairMultX;
|
||||
static float m_f3rdPersonCHairMultY;
|
||||
|
||||
|
||||
CCam Cams[3];
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "common.h"
|
||||
#include <ctype.h>
|
||||
#include "main.h"
|
||||
|
||||
#include "Quaternion.h"
|
||||
|
@ -26,6 +27,9 @@
|
|||
#include "FileLoader.h"
|
||||
#include "Streaming.h"
|
||||
#include "ColStore.h"
|
||||
#include "Occlusion.h"
|
||||
|
||||
//--MIAMI: file done
|
||||
|
||||
char CFileLoader::ms_line[256];
|
||||
|
||||
|
@ -159,7 +163,6 @@ struct ColHeader
|
|||
uint32 size;
|
||||
};
|
||||
|
||||
//--MIAMI: done
|
||||
void
|
||||
CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot)
|
||||
{
|
||||
|
@ -196,7 +199,6 @@ CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot)
|
|||
}
|
||||
|
||||
|
||||
//--MIAMI: done
|
||||
bool
|
||||
CFileLoader::LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot)
|
||||
{
|
||||
|
@ -298,13 +300,15 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
|
|||
model.numLines = *(int16*)buf;
|
||||
buf += 4;
|
||||
if(model.numLines > 0){
|
||||
model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine));
|
||||
//model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine));
|
||||
for(i = 0; i < model.numLines; i++){
|
||||
model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12));
|
||||
//model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12));
|
||||
buf += 24;
|
||||
}
|
||||
}else
|
||||
model.lines = nil;
|
||||
model.numLines = 0;
|
||||
model.lines = nil;
|
||||
|
||||
model.numBoxes = *(int16*)buf;
|
||||
buf += 4;
|
||||
|
@ -323,10 +327,12 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
|
|||
model.vertices = (CVector*)RwMalloc(numVertices*sizeof(CVector));
|
||||
for(i = 0; i < numVertices; i++){
|
||||
model.vertices[i] = *(CVector*)buf;
|
||||
#if 0
|
||||
if(Abs(model.vertices[i].x) >= 256.0f ||
|
||||
Abs(model.vertices[i].y) >= 256.0f ||
|
||||
Abs(model.vertices[i].z) >= 256.0f)
|
||||
printf("%s:Collision volume too big\n", modelname);
|
||||
#endif
|
||||
buf += 12;
|
||||
}
|
||||
}else
|
||||
|
@ -349,7 +355,7 @@ GetNameAndLOD(char *nodename, char *name, int *n)
|
|||
{
|
||||
char *underscore = nil;
|
||||
for(char *s = nodename; *s != '\0'; s++){
|
||||
if(s[0] == '_' && (s[1] == 'l' || s[1] == 'L'))
|
||||
if(s[0] == '_' && (s[1] == 'l' || s[1] == 'L') && isdigit(s[2]))
|
||||
underscore = s;
|
||||
}
|
||||
if(underscore){
|
||||
|
@ -1093,7 +1099,7 @@ CFileLoader::LoadScene(const char *filename)
|
|||
LoadCullZone(line);
|
||||
break;
|
||||
case OCCL:
|
||||
// TODO(MIAMI): occlusion
|
||||
LoadOcclusionVolume(line);
|
||||
break;
|
||||
case PICK:
|
||||
// unused
|
||||
|
@ -1187,7 +1193,9 @@ CFileLoader::LoadObjectInstance(const char *line)
|
|||
CColStore::GetBoundingBox(col->level).ContainRect(entity->GetBoundRect());
|
||||
}else
|
||||
entity->bUsesCollision = false;
|
||||
// TODO(MIAMI): set some flag here if col min is below 6
|
||||
|
||||
if(entity->GetPosition().z + col->boundingBox.min.z < 6.0f)
|
||||
entity->bUnderwater = true;
|
||||
}else{
|
||||
entity = new CDummyObject;
|
||||
entity->SetModelIndexNoCreate(id);
|
||||
|
@ -1241,6 +1249,21 @@ CFileLoader::LoadPickup(const char *line)
|
|||
sscanf(line, "%d %f %f %f", &id, &x, &y, &z);
|
||||
}
|
||||
|
||||
void
|
||||
CFileLoader::LoadOcclusionVolume(const char *line)
|
||||
{
|
||||
float x, y, z;
|
||||
float width, length, height;
|
||||
float angle;
|
||||
|
||||
sscanf(line, "%f %f %f %f %f %f %f",
|
||||
&x, &y, &z,
|
||||
&width, &length, &height,
|
||||
&angle);
|
||||
COcclusion::AddOne(x, y, z, width, length, z + height/2.0f, angle);
|
||||
}
|
||||
|
||||
|
||||
//--MIAMI: unused
|
||||
void
|
||||
CFileLoader::ReloadPaths(const char *filename)
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
static void LoadZone(const char *line);
|
||||
static void LoadCullZone(const char *line);
|
||||
static void LoadPickup(const char *line);
|
||||
static void LoadOcclusionVolume(const char *line);
|
||||
|
||||
static void ReloadPaths(const char *filename);
|
||||
static void ReloadObjectTypes(const char *filename);
|
||||
|
|
|
@ -37,6 +37,18 @@
|
|||
#include "Messages.h"
|
||||
#include "FileLoader.h"
|
||||
|
||||
// Similar story to Hud.cpp:
|
||||
// Game has colors inlined in code.
|
||||
// For easier modification we collect them here:
|
||||
CRGBA LABEL_COLOR(255, 150, 225, 255);
|
||||
CRGBA SELECTIONBORDER_COLOR(25, 130, 70, 255);
|
||||
CRGBA MENUOPTION_COLOR(255, 150, 225, 255);
|
||||
CRGBA SELECTEDMENUOPTION_COLOR(255, 150, 225, 255);
|
||||
CRGBA HEADER_COLOR(255, 150, 255, 255);
|
||||
CRGBA DARKMENUOPTION_COLOR(195, 90, 165, 255);
|
||||
CRGBA SLIDERON_COLOR(97, 194, 247, 255);
|
||||
CRGBA SLIDEROFF_COLOR(27, 89, 130, 255);
|
||||
|
||||
#define TIDY_UP_PBP // ProcessButtonPresses
|
||||
#define MAX_VISIBLE_LIST_ROW 30
|
||||
#define SCROLLBAR_MAX_HEIGHT 263.0f // not in end result
|
||||
|
@ -149,53 +161,7 @@ bool CMenuManager::m_PrefsMarketing = false;
|
|||
bool CMenuManager::m_PrefsDisableTutorials = false;
|
||||
#endif // !MASTER
|
||||
|
||||
// 0x5F311C
|
||||
const char* FrontendFilenames[][2] = {
|
||||
{"fe2_mainpanel_ul", "" },
|
||||
{"fe2_mainpanel_ur", "" },
|
||||
{"fe2_mainpanel_dl", "" },
|
||||
{"fe2_mainpanel_dr", "" },
|
||||
{"fe2_mainpanel_dr2", "" },
|
||||
{"fe2_tabactive", "" },
|
||||
{"fe_iconbrief", "" },
|
||||
{"fe_iconstats", "" },
|
||||
{"fe_iconcontrols", "" },
|
||||
{"fe_iconsave", "" },
|
||||
{"fe_iconaudio", "" },
|
||||
{"fe_icondisplay", "" },
|
||||
{"fe_iconlanguage", "" },
|
||||
{"fe_controller", "" },
|
||||
{"fe_controllersh", "" },
|
||||
{"fe_arrows1", "" },
|
||||
{"fe_arrows2", "" },
|
||||
{"fe_arrows3", "" },
|
||||
{"fe_arrows4", "" },
|
||||
{"fe_radio1", "" },
|
||||
{"fe_radio2", "" },
|
||||
{"fe_radio3", "" },
|
||||
{"fe_radio4", "" },
|
||||
{"fe_radio5", "" },
|
||||
{"fe_radio6", "" },
|
||||
{"fe_radio7", "" },
|
||||
{"fe_radio8", "" },
|
||||
{"fe_radio9", "" },
|
||||
};
|
||||
|
||||
#ifdef MENU_MAP
|
||||
const char* MapFilenames[][2] = {
|
||||
{"mapMid01", "mapMid01A"},
|
||||
{"mapMid02", "mapMid02A"},
|
||||
{"mapMid03", "mapMid03A"},
|
||||
{"mapBot01", "mapBot01A"},
|
||||
{"mapBot02", "mapBot02A"},
|
||||
{"mapBot03", "mapBot03A"},
|
||||
{"mapTop01", "mapTop01A"},
|
||||
{"mapTop02", "mapTop02A"},
|
||||
{"mapTop03", "mapTop03A"},
|
||||
};
|
||||
CSprite2d CMenuManager::m_aMapSprites[NUM_MAP_SPRITES];
|
||||
#endif
|
||||
|
||||
/*
|
||||
// 0x5F3344
|
||||
const char* MenuFilenames[][2] = {
|
||||
{"connection24", ""},
|
||||
|
@ -219,6 +185,37 @@ const char* MenuFilenames[][2] = {
|
|||
{"gta3logo256", "gta3logo256m"},
|
||||
{ nil, nil }
|
||||
};
|
||||
*/
|
||||
|
||||
// 0x68C144
|
||||
const char* FrontendFilenames[][2] = {
|
||||
{"background", ""},
|
||||
{"vc_logo", "vc_logom"},
|
||||
{"mouse", "mousea"},
|
||||
{"mapTop01", "mapTop01A"},
|
||||
{"mapTop02", "mapTop02A"},
|
||||
{"mapTop03", "mapTop03A"},
|
||||
{"mapMid01", "mapMid01A"},
|
||||
{"mapMid02", "mapMid02A"},
|
||||
{"mapMid03", "mapMid03A"},
|
||||
{"mapBot01", "mapBot01A"},
|
||||
{"mapBot02", "mapBot02A"},
|
||||
{"mapBot03", "mapBot03A"},
|
||||
{"wildstyle", "wildstyleA"},
|
||||
{"flash", "flashA"},
|
||||
{"kchat", "kchatA"},
|
||||
{"fever", "feverA"},
|
||||
{"vrock", "vrockA"},
|
||||
{"vcpr", "vcprA"},
|
||||
{"espantoso", "espantosoA"},
|
||||
{"emotion", "emotionA"},
|
||||
{"wave103", "wave103A"},
|
||||
{"mp3", "mp3A"},
|
||||
{"downOff", "buttonA"},
|
||||
{"downOn", "buttonA"},
|
||||
{"upOff", "buttonA"},
|
||||
{"upOn", "buttonA"}
|
||||
};
|
||||
|
||||
#ifdef ASPECT_RATIO_SCALE
|
||||
// All of the defines below replace the StretchX function. Otherwise use SCREEN_SCALE_X.
|
||||
|
@ -284,7 +281,7 @@ ScaleAndCenterX(float x)
|
|||
#endif
|
||||
|
||||
#define PREPARE_MENU_HEADER \
|
||||
CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); \
|
||||
CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); \
|
||||
CFont::SetRightJustifyOn(); \
|
||||
CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT)); \
|
||||
CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
|
||||
|
@ -306,9 +303,10 @@ ScaleAndCenterX(float x)
|
|||
m_nHoverOption = HOVEROPTION_NOT_HOVERING; \
|
||||
} while(0)
|
||||
|
||||
// TODO: this is COMPLETELY different in VC
|
||||
#define ProcessRadioIcon(sprite, x, y, radioId, hoverOpt) \
|
||||
do { \
|
||||
sprite.Draw(x, y, MENU_X(MENURADIO_ICON_SCALE), MENU_Y(MENURADIO_ICON_SCALE), radioId == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(225, 0, 0, 170)); \
|
||||
sprite.Draw(x, y, MENU_X(MENURADIO_ICON_SCALE), MENU_Y(MENURADIO_ICON_SCALE), radioId == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(255, 255, 255, 100)); \
|
||||
if (CheckHover(x, x + MENU_X(MENURADIO_ICON_SCALE), y, y + MENU_Y(MENURADIO_ICON_SCALE))) \
|
||||
m_nHoverOption = hoverOpt; \
|
||||
} while (0)
|
||||
|
@ -651,15 +649,15 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR
|
|||
|
||||
int lastActiveBarX = 0;
|
||||
float curBarX = 0.0f;
|
||||
float spacing = SCREEN_SCALE_X(10.0f);
|
||||
float spacing = SCREEN_SCALE_X(4.0f); // TODO: find actual numbers used in the game
|
||||
for (int i = 0; i < 16; i++) {
|
||||
curBarX = i * rectSize/16.0f + x;
|
||||
curBarX = i * rectSize/32.0f + x;
|
||||
|
||||
if (i / 16.0f + 1 / 32.0f < progress) {
|
||||
color = CRGBA(255, 217, 106, FadeIn(255));
|
||||
color = CRGBA(SLIDERON_COLOR.r, SLIDERON_COLOR.g, SLIDERON_COLOR.b, FadeIn(255));
|
||||
lastActiveBarX = curBarX;
|
||||
} else
|
||||
color = CRGBA(185, 120, 0, FadeIn(255));
|
||||
color = CRGBA(SLIDEROFF_COLOR.r, SLIDEROFF_COLOR.g, SLIDEROFF_COLOR.b, FadeIn(255));
|
||||
|
||||
maxBarHeight = Max(mostLeftBarSize, mostRightBarSize);
|
||||
|
||||
|
@ -700,8 +698,10 @@ CMenuManager::Draw()
|
|||
CFont::SetCentreOff();
|
||||
CFont::SetJustifyOn();
|
||||
CFont::SetBackGroundOnlyTextOn();
|
||||
#ifdef GTA3_1_1_PATCH
|
||||
CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
|
||||
|
||||
// no V1.1 text in vc obv
|
||||
#if 0 //def GTA3_1_1_PATCH
|
||||
CFont::SetColor(CRGBA(255, 150, 225, FadeIn(255)));
|
||||
CFont::SetRightJustifyOn();
|
||||
CFont::SetFontStyle(FONT_HEADING);
|
||||
CFont::SetScale(MENU_X(0.7f), MENU_Y(0.5f));
|
||||
|
@ -711,6 +711,7 @@ CMenuManager::Draw()
|
|||
AsciiToUnicode(gString, gUString);
|
||||
CFont::PrintString(SCREEN_WIDTH / 10, SCREEN_HEIGHT / 45, gUString);
|
||||
#endif
|
||||
|
||||
CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN));
|
||||
CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH));
|
||||
|
||||
|
@ -738,7 +739,11 @@ CMenuManager::Draw()
|
|||
if (aScreens[m_nCurrScreen].m_ScreenName[0] != '\0') {
|
||||
|
||||
PREPARE_MENU_HEADER
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
|
||||
CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255)));
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X + 7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
|
||||
|
||||
PREPARE_MENU_HEADER
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
|
||||
|
||||
// Weird place to put that.
|
||||
nextYToUse += 24.0f + 10.0f;
|
||||
|
@ -747,7 +752,7 @@ CMenuManager::Draw()
|
|||
CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
|
||||
CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT * MENU_TEXT_SIZE_X), MENU_Y(MENUACTION_SCALE_MULT * MENU_TEXT_SIZE_Y));
|
||||
CFont::SetRightJustifyOff();
|
||||
CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
|
||||
CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255)));
|
||||
|
||||
// Label
|
||||
wchar *str;
|
||||
|
@ -845,7 +850,7 @@ CMenuManager::Draw()
|
|||
break;
|
||||
case MENUPAGE_START_MENU:
|
||||
columnWidth = 320;
|
||||
headerHeight = 140;
|
||||
headerHeight = 110;
|
||||
lineHeight = 24;
|
||||
CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
|
||||
CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE));
|
||||
|
@ -898,7 +903,7 @@ CMenuManager::Draw()
|
|||
}
|
||||
|
||||
float usableLineHeight = lineHeight * 0.9f; // also height of biggest bar in slider
|
||||
float smallestSliderBar = lineHeight * 0.1f;
|
||||
float smallestSliderBar = lineHeight * 0.25f; // TODO: find actual number
|
||||
bool foundTheHoveringItem = false;
|
||||
wchar unicodeTemp[64];
|
||||
char asciiTemp[32];
|
||||
|
@ -1226,7 +1231,7 @@ CMenuManager::Draw()
|
|||
// We keep stretching, because we also stretch background image and we want that bar to be aligned with borders of background
|
||||
CSprite2d::DrawRect(CRect(StretchX(10.0f), MENU_Y(bitAboveNextItemY),
|
||||
SCREEN_STRETCH_FROM_RIGHT(11.0f), MENU_Y(usableLineHeight + nextItemY)),
|
||||
CRGBA(100, 200, 50, FadeIn(50)));
|
||||
CRGBA(SELECTIONBORDER_COLOR.r, SELECTIONBORDER_COLOR.g, SELECTIONBORDER_COLOR.b, FadeIn(255)));
|
||||
}
|
||||
|
||||
CFont::SetColor(CRGBA(0, 0, 0, FadeIn(90)));
|
||||
|
@ -1245,14 +1250,14 @@ CMenuManager::Draw()
|
|||
|
||||
if(!strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FED_RES")
|
||||
&& !m_bGameNotLoaded && textLayer == 1) {
|
||||
CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255)));
|
||||
CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255)));
|
||||
}
|
||||
CFont::PrintString(MENU_X_RIGHT_ALIGNED(columnWidth - textLayer), itemY, rightText);
|
||||
}
|
||||
if (i == m_nCurrOption && itemsAreSelectable){
|
||||
CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255)));
|
||||
CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255)));
|
||||
} else {
|
||||
CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
|
||||
CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1321,18 +1326,18 @@ CMenuManager::Draw()
|
|||
|
||||
// Radio icons
|
||||
if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_RADIO) {
|
||||
ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO1], MENU_X_LEFT_ALIGNED(30.0f), MENU_Y(nextYToUse), 0, HOVEROPTION_RADIO_0);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO2], MENU_X_LEFT_ALIGNED(90.0f), MENU_Y(nextYToUse), 1, HOVEROPTION_RADIO_1);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO5], MENU_X_LEFT_ALIGNED(150.0f), MENU_Y(nextYToUse), 2, HOVEROPTION_RADIO_2);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO7], MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(nextYToUse), 3, HOVEROPTION_RADIO_3);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO8], MENU_X_LEFT_ALIGNED(270.0f), MENU_Y(nextYToUse), 4, HOVEROPTION_RADIO_4);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO3], MENU_X_LEFT_ALIGNED(320.0f), MENU_Y(nextYToUse), 5, HOVEROPTION_RADIO_5);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO4], MENU_X_LEFT_ALIGNED(360.0f), MENU_Y(nextYToUse), 6, HOVEROPTION_RADIO_6);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO6], MENU_X_LEFT_ALIGNED(420.0f), MENU_Y(nextYToUse), 7, HOVEROPTION_RADIO_7);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO9], MENU_X_LEFT_ALIGNED(480.0f), MENU_Y(nextYToUse), 8, HOVEROPTION_RADIO_8);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_WILDSTYLE], MENU_X_LEFT_ALIGNED(30.0f), MENU_Y(nextYToUse), 0, HOVEROPTION_RADIO_0);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_FLASH], MENU_X_LEFT_ALIGNED(90.0f), MENU_Y(nextYToUse), 1, HOVEROPTION_RADIO_1);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_KCHAT], MENU_X_LEFT_ALIGNED(150.0f), MENU_Y(nextYToUse), 2, HOVEROPTION_RADIO_2);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_FEVER], MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(nextYToUse), 3, HOVEROPTION_RADIO_3);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_VROCK], MENU_X_LEFT_ALIGNED(270.0f), MENU_Y(nextYToUse), 4, HOVEROPTION_RADIO_4);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_VCPR], MENU_X_LEFT_ALIGNED(320.0f), MENU_Y(nextYToUse), 5, HOVEROPTION_RADIO_5);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_ESPANTOSO], MENU_X_LEFT_ALIGNED(360.0f), MENU_Y(nextYToUse), 6, HOVEROPTION_RADIO_6);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_EMOTION], MENU_X_LEFT_ALIGNED(420.0f), MENU_Y(nextYToUse), 7, HOVEROPTION_RADIO_7);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_WAVE], MENU_X_LEFT_ALIGNED(480.0f), MENU_Y(nextYToUse), 8, HOVEROPTION_RADIO_8);
|
||||
|
||||
if (DMAudio.IsMP3RadioChannelAvailable())
|
||||
ProcessRadioIcon(m_aMenuSprites[MENUSPRITE_MP3LOGO], MENU_X_LEFT_ALIGNED(540.0f), MENU_Y(nextYToUse), 9, HOVEROPTION_RADIO_9);
|
||||
ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_MP3], MENU_X_LEFT_ALIGNED(540.0f), MENU_Y(nextYToUse), 9, HOVEROPTION_RADIO_9);
|
||||
|
||||
nextYToUse += 70.0f;
|
||||
}
|
||||
|
@ -1813,11 +1818,21 @@ CMenuManager::DrawControllerSetupScreen()
|
|||
|
||||
switch (m_ControlMethod) {
|
||||
case CONTROL_STANDARD:
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y),
|
||||
CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255)));
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X + 7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f),
|
||||
TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
|
||||
|
||||
PREPARE_MENU_HEADER
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y),
|
||||
TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
|
||||
break;
|
||||
case CONTROL_CLASSIC:
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y),
|
||||
CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255)));
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X + 7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f),
|
||||
TheText.Get("FET_CTI"));
|
||||
|
||||
PREPARE_MENU_HEADER
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y),
|
||||
TheText.Get("FET_CTI"));
|
||||
break;
|
||||
default:
|
||||
|
@ -2079,13 +2094,13 @@ CMenuManager::DrawFrontEndSaveZone()
|
|||
mouse.Translate(m_nMousePosX, m_nMousePosY);
|
||||
shad.Translate(m_nMousePosX, m_nMousePosY);
|
||||
if(field_518 == 4){
|
||||
m_aMenuSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50));
|
||||
m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50));
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
m_aMenuSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255));
|
||||
m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255));
|
||||
}else{
|
||||
m_aMenuSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50));
|
||||
m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50));
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
m_aMenuSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255));
|
||||
m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2273,13 +2288,13 @@ CMenuManager::DrawFrontEndNormal()
|
|||
mouse.Translate(m_nMousePosX, m_nMousePosY);
|
||||
shad.Translate(m_nMousePosX, m_nMousePosY);
|
||||
if(field_518 == 4){
|
||||
m_aMenuSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50));
|
||||
m_aFrontEndSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50));
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
m_aMenuSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255));
|
||||
m_aFrontEndSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255));
|
||||
}else{
|
||||
m_aMenuSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50));
|
||||
m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50));
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
m_aMenuSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255));
|
||||
m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2293,65 +2308,24 @@ CMenuManager::DrawFrontEndNormal()
|
|||
|
||||
LoadSplash(nil);
|
||||
|
||||
eMenuSprites previousSprite;
|
||||
if (m_nMenuFadeAlpha < 255) {
|
||||
switch (m_nPrevScreen) {
|
||||
case MENUPAGE_STATS:
|
||||
case MENUPAGE_START_MENU:
|
||||
case MENUPAGE_PAUSE_MENU:
|
||||
previousSprite = MENUSPRITE_MAINMENU;
|
||||
break;
|
||||
case MENUPAGE_NEW_GAME:
|
||||
case MENUPAGE_CHOOSE_LOAD_SLOT:
|
||||
case MENUPAGE_CHOOSE_DELETE_SLOT:
|
||||
case MENUPAGE_NEW_GAME_RELOAD:
|
||||
case MENUPAGE_LOAD_SLOT_CONFIRM:
|
||||
case MENUPAGE_DELETE_SLOT_CONFIRM:
|
||||
case MENUPAGE_EXIT:
|
||||
previousSprite = MENUSPRITE_SINGLEPLAYER;
|
||||
break;
|
||||
case MENUPAGE_MULTIPLAYER_MAIN:
|
||||
previousSprite = MENUSPRITE_MULTIPLAYER;
|
||||
break;
|
||||
case MENUPAGE_MULTIPLAYER_MAP:
|
||||
case MENUPAGE_MULTIPLAYER_FIND_GAME:
|
||||
case MENUPAGE_SKIN_SELECT:
|
||||
case MENUPAGE_KEYBOARD_CONTROLS:
|
||||
case MENUPAGE_MOUSE_CONTROLS:
|
||||
previousSprite = MENUSPRITE_FINDGAME;
|
||||
break;
|
||||
case MENUPAGE_MULTIPLAYER_CONNECTION:
|
||||
case MENUPAGE_MULTIPLAYER_MODE:
|
||||
previousSprite = MENUSPRITE_CONNECTION;
|
||||
break;
|
||||
case MENUPAGE_MULTIPLAYER_CREATE:
|
||||
previousSprite = MENUSPRITE_HOSTGAME;
|
||||
break;
|
||||
case MENUPAGE_SKIN_SELECT_OLD:
|
||||
case MENUPAGE_OPTIONS:
|
||||
previousSprite = MENUSPRITE_PLAYERSET;
|
||||
break;
|
||||
default:
|
||||
previousSprite = MENUSPRITE_MAINMENU;
|
||||
break;
|
||||
}
|
||||
eMenuSprites previousSprite = MENUSPRITE_BACKGROUND;
|
||||
|
||||
if (m_nMenuFadeAlpha < 255) {
|
||||
if (m_nPrevScreen == m_nCurrScreen)
|
||||
CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, 255 - m_nMenuFadeAlpha));
|
||||
else
|
||||
m_aMenuSprites[previousSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255 - m_nMenuFadeAlpha));
|
||||
m_aFrontEndSprites[previousSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255 - m_nMenuFadeAlpha));
|
||||
}
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
|
||||
|
||||
eMenuSprites currentSprite = MENUSPRITE_MAINMENU; // actually uninitialized
|
||||
eMenuSprites currentSprite = MENUSPRITE_BACKGROUND; // actually uninitialized
|
||||
|
||||
switch (m_nCurrScreen) {
|
||||
case MENUPAGE_STATS:
|
||||
case MENUPAGE_START_MENU:
|
||||
case MENUPAGE_PAUSE_MENU:
|
||||
currentSprite = MENUSPRITE_MAINMENU;
|
||||
break;
|
||||
case MENUPAGE_NEW_GAME:
|
||||
case MENUPAGE_CHOOSE_LOAD_SLOT:
|
||||
case MENUPAGE_CHOOSE_DELETE_SLOT:
|
||||
|
@ -2359,28 +2333,18 @@ CMenuManager::DrawFrontEndNormal()
|
|||
case MENUPAGE_LOAD_SLOT_CONFIRM:
|
||||
case MENUPAGE_DELETE_SLOT_CONFIRM:
|
||||
case MENUPAGE_EXIT:
|
||||
currentSprite = MENUSPRITE_SINGLEPLAYER;
|
||||
break;
|
||||
case MENUPAGE_MULTIPLAYER_MAIN:
|
||||
currentSprite = MENUSPRITE_MULTIPLAYER;
|
||||
break;
|
||||
case MENUPAGE_MULTIPLAYER_MAP:
|
||||
case MENUPAGE_MULTIPLAYER_FIND_GAME:
|
||||
case MENUPAGE_SKIN_SELECT:
|
||||
case MENUPAGE_KEYBOARD_CONTROLS:
|
||||
case MENUPAGE_MOUSE_CONTROLS:
|
||||
currentSprite = MENUSPRITE_FINDGAME;
|
||||
break;
|
||||
case MENUPAGE_MULTIPLAYER_CONNECTION:
|
||||
case MENUPAGE_MULTIPLAYER_MODE:
|
||||
currentSprite = MENUSPRITE_CONNECTION;
|
||||
break;
|
||||
case MENUPAGE_MULTIPLAYER_CREATE:
|
||||
currentSprite = MENUSPRITE_HOSTGAME;
|
||||
break;
|
||||
case MENUPAGE_SKIN_SELECT_OLD:
|
||||
case MENUPAGE_OPTIONS:
|
||||
currentSprite = MENUSPRITE_PLAYERSET;
|
||||
currentSprite = MENUSPRITE_BACKGROUND;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2404,13 +2368,13 @@ CMenuManager::DrawFrontEndNormal()
|
|||
#endif
|
||||
|
||||
if (m_nMenuFadeAlpha > 255){
|
||||
m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
|
||||
m_aFrontEndSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
|
||||
} else {
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||||
m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, m_nMenuFadeAlpha));
|
||||
m_aFrontEndSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, m_nMenuFadeAlpha));
|
||||
}
|
||||
} else {
|
||||
m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
|
||||
m_aFrontEndSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
|
||||
// TODO: what is this? waiting mouse?
|
||||
if(field_518 == 4){
|
||||
if(m_nHoverOption == HOVEROPTION_3 || m_nHoverOption == HOVEROPTION_4 ||
|
||||
|
@ -2422,15 +2386,20 @@ CMenuManager::DrawFrontEndNormal()
|
|||
}
|
||||
}
|
||||
|
||||
m_aFrontEndSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
|
||||
|
||||
// GTA LOGO
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||
/*
|
||||
if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_PAUSE_MENU) {
|
||||
if (CGame::frenchGame || CGame::germanGame || !CGame::nastyGame)
|
||||
m_aMenuSprites[MENUSPRITE_GTA3LOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(205.0f), MENU_Y(70.0f), MENU_X_LEFT_ALIGNED(435.0f), MENU_Y(180.0f)), CRGBA(255, 255, 255, FadeIn(255)));
|
||||
m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(205.0f), MENU_Y(70.0f), MENU_X_LEFT_ALIGNED(435.0f), MENU_Y(180.0f)), CRGBA(255, 255, 255, FadeIn(255)));
|
||||
else
|
||||
m_aMenuSprites[MENUSPRITE_GTALOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(225.0f), MENU_Y(40.0f), MENU_X_LEFT_ALIGNED(415.0f), MENU_Y(210.0f)), CRGBA(255, 255, 255, FadeIn(255)));
|
||||
m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(225.0f), MENU_Y(40.0f), MENU_X_LEFT_ALIGNED(415.0f), MENU_Y(210.0f)), CRGBA(255, 255, 255, FadeIn(255)));
|
||||
}
|
||||
*/
|
||||
m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(SCREEN_SCALE_X(27.0f), MENU_Y(8.0f), SCREEN_SCALE_X(157.0f), MENU_Y(138.0f)), CRGBA(255, 255, 255, FadeIn(255)));
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
|
||||
|
@ -2457,19 +2426,19 @@ CMenuManager::DrawFrontEndNormal()
|
|||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||||
|
||||
CRect mouse(0.0f, 0.0f, MENU_X(75.0f), MENU_Y(75.0f));
|
||||
CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(85.0f), MENU_Y(78.0f));
|
||||
CRect mouse(0.0f, 0.0f, MENU_X(40.0f), MENU_Y(40.0f));
|
||||
CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(55.0f), MENU_Y(43.0f));
|
||||
|
||||
mouse.Translate(m_nMousePosX, m_nMousePosY);
|
||||
shad.Translate(m_nMousePosX, m_nMousePosY);
|
||||
if(field_518 == 4){
|
||||
m_aMenuSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50));
|
||||
m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50));
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
m_aMenuSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255));
|
||||
m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255));
|
||||
}else{
|
||||
m_aMenuSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50));
|
||||
m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50));
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
m_aMenuSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255));
|
||||
m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2711,21 +2680,21 @@ CMenuManager::DrawPlayerSetupScreen()
|
|||
// 2 - leaves gap between button and scrollbar
|
||||
if (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_UP) {
|
||||
#ifdef FIX_BUGS
|
||||
m_aMenuSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP),
|
||||
m_aFrontEndSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP),
|
||||
MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), MENU_Y(PLAYERSETUP_LIST_TOP + PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)),
|
||||
CRGBA(255, 255, 255, FadeIn(255)));
|
||||
#else
|
||||
m_aMenuSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP),
|
||||
m_aFrontEndSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP),
|
||||
MENU_X_RIGHT_ALIGNED(-20.0f), MENU_Y(PLAYERSETUP_LIST_TOP + 58)),
|
||||
CRGBA(255, 255, 255, FadeIn(255)));
|
||||
#endif
|
||||
} else {
|
||||
#ifdef FIX_BUGS
|
||||
m_aMenuSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP),
|
||||
m_aFrontEndSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP),
|
||||
MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), MENU_Y(PLAYERSETUP_LIST_TOP + PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)),
|
||||
CRGBA(255, 255, 255, FadeIn(255)));
|
||||
#else
|
||||
m_aMenuSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP),
|
||||
m_aFrontEndSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP),
|
||||
MENU_X_RIGHT_ALIGNED(-21.0f), MENU_Y(PLAYERSETUP_LIST_TOP + 58)),
|
||||
CRGBA(255, 255, 255, FadeIn(255)));
|
||||
#endif
|
||||
|
@ -2733,21 +2702,21 @@ CMenuManager::DrawPlayerSetupScreen()
|
|||
|
||||
if (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_DOWN) {
|
||||
#ifdef FIX_BUGS
|
||||
m_aMenuSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1),
|
||||
m_aFrontEndSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1),
|
||||
MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)),
|
||||
CRGBA(255, 255, 255, FadeIn(255)));
|
||||
#else
|
||||
m_aMenuSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(141.0f),
|
||||
m_aFrontEndSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(141.0f),
|
||||
MENU_X_RIGHT_ALIGNED(-20.0f), SCREEN_SCALE_FROM_BOTTOM(83.0f)),
|
||||
CRGBA(255, 255, 255, FadeIn(255)));
|
||||
#endif
|
||||
} else {
|
||||
#ifdef FIX_BUGS
|
||||
m_aMenuSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1),
|
||||
m_aFrontEndSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1),
|
||||
MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)),
|
||||
CRGBA(255, 255, 255, FadeIn(255)));
|
||||
#else
|
||||
m_aMenuSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(141.0f),
|
||||
m_aFrontEndSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(141.0f),
|
||||
MENU_X_RIGHT_ALIGNED(-21.0f), SCREEN_SCALE_FROM_BOTTOM(83.0f)),
|
||||
CRGBA(255, 255, 255, FadeIn(255)));
|
||||
#endif
|
||||
|
@ -3021,51 +2990,59 @@ CMenuManager::LoadAllTextures()
|
|||
CStreaming::ImGonnaUseStreamingMemory();
|
||||
CGame::TidyUpMemory(false, true);
|
||||
CTxdStore::PushCurrentTxd();
|
||||
int frontendTxdSlot = CTxdStore::FindTxdSlot("frontend");
|
||||
int frontendTxdSlot1 = CTxdStore::FindTxdSlot("frontend1");
|
||||
|
||||
if(frontendTxdSlot == -1)
|
||||
frontendTxdSlot = CTxdStore::AddTxdSlot("frontend");
|
||||
if(frontendTxdSlot1 == -1)
|
||||
frontendTxdSlot1 = CTxdStore::AddTxdSlot("frontend1");
|
||||
|
||||
printf("LOAD frontend\n");
|
||||
CTxdStore::LoadTxd(frontendTxdSlot, "MODELS/FRONTEND.TXD");
|
||||
CTxdStore::AddRef(frontendTxdSlot);
|
||||
CTxdStore::SetCurrentTxd(frontendTxdSlot);
|
||||
#ifndef GTA3_1_1_PATCH
|
||||
CStreaming::IHaveUsedStreamingMemory();
|
||||
CTimer::Update();
|
||||
#endif
|
||||
printf("LOAD frontend1\n");
|
||||
CTxdStore::LoadTxd(frontendTxdSlot1, "MODELS/FRONTEN1.TXD");
|
||||
CTxdStore::AddRef(frontendTxdSlot1);
|
||||
CTxdStore::SetCurrentTxd(frontendTxdSlot1);
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(FrontendFilenames); i++) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i][0], FrontendFilenames[i][1]);
|
||||
m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
|
||||
}
|
||||
|
||||
int menuTxdSlot = CTxdStore::FindTxdSlot("menu");
|
||||
CTxdStore::PopCurrentTxd();
|
||||
CStreaming::IHaveUsedStreamingMemory();
|
||||
|
||||
if (menuTxdSlot == -1)
|
||||
menuTxdSlot = CTxdStore::AddTxdSlot("menu");
|
||||
|
||||
printf("LOAD sprite\n");
|
||||
CTxdStore::LoadTxd(menuTxdSlot, "MODELS/MENU.TXD");
|
||||
CTxdStore::AddRef(menuTxdSlot);
|
||||
CTxdStore::SetCurrentTxd(menuTxdSlot);
|
||||
// if ( !*(_BYTE *)(v1 + 124) )
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(MenuFilenames); i++) {
|
||||
m_aMenuSprites[i].SetTexture(MenuFilenames[i][0], MenuFilenames[i][1]);
|
||||
m_aMenuSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
|
||||
CStreaming::MakeSpaceFor(350 * CDSTREAM_SECTOR_SIZE); // twice of it in mobile
|
||||
CStreaming::ImGonnaUseStreamingMemory();
|
||||
CTxdStore::PushCurrentTxd();
|
||||
|
||||
int frontendTxdSlot2 = CTxdStore::FindTxdSlot("frontend2");
|
||||
|
||||
if (frontendTxdSlot2 == -1)
|
||||
frontendTxdSlot2 = CTxdStore::AddTxdSlot("frontend2");
|
||||
|
||||
printf("LOAD frontend2\n");
|
||||
CTxdStore::LoadTxd(frontendTxdSlot2, "MODELS/FRONTEN2.TXD");
|
||||
CTxdStore::AddRef(frontendTxdSlot2);
|
||||
CTxdStore::SetCurrentTxd(frontendTxdSlot2);
|
||||
|
||||
for (int i = 3; i < NUM_MENU_SPRITES; i++) {
|
||||
m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i][0], FrontendFilenames[i][1]);
|
||||
m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
|
||||
}
|
||||
#ifdef MENU_MAP
|
||||
|
||||
CTxdStore::PopCurrentTxd();
|
||||
CStreaming::IHaveUsedStreamingMemory();
|
||||
|
||||
|
||||
#if 0 //MENU_MAP
|
||||
for (int i = 0; i < ARRAY_SIZE(MapFilenames); i++) {
|
||||
m_aMapSprites[i].SetTexture(MapFilenames[i][0], MapFilenames[i][1]);
|
||||
m_aMapSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
|
||||
}
|
||||
#endif
|
||||
#ifdef GTA3_1_1_PATCH
|
||||
CStreaming::IHaveUsedStreamingMemory();
|
||||
CTimer::Update();
|
||||
#endif
|
||||
|
||||
m_bSpritesLoaded = true;
|
||||
CTxdStore::PopCurrentTxd();
|
||||
CTimer::Update();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -5147,18 +5124,16 @@ CMenuManager::UnloadTextures()
|
|||
for (int i = 0; i < ARRAY_SIZE(FrontendFilenames); ++i)
|
||||
m_aFrontEndSprites[i].Delete();
|
||||
|
||||
int frontend = CTxdStore::FindTxdSlot("frontend");
|
||||
int frontend = CTxdStore::FindTxdSlot("frontend1");
|
||||
CTxdStore::RemoveTxd(frontend);
|
||||
|
||||
printf("REMOVE menu textures\n");
|
||||
for (int i = 0; i < ARRAY_SIZE(MenuFilenames); ++i)
|
||||
m_aMenuSprites[i].Delete();
|
||||
#ifdef MENU_MAP
|
||||
int frontend2 = CTxdStore::FindTxdSlot("frontend2");
|
||||
CTxdStore::RemoveTxd(frontend2);
|
||||
|
||||
#ifdef false //MENU_MAP
|
||||
for (int i = 0; i < ARRAY_SIZE(MapFilenames); ++i)
|
||||
m_aMapSprites[i].Delete();
|
||||
#endif
|
||||
int menu = CTxdStore::FindTxdSlot("menu");
|
||||
CTxdStore::RemoveTxd(menu);
|
||||
|
||||
m_bSpritesLoaded = false;
|
||||
}
|
||||
|
@ -5197,6 +5172,9 @@ CMenuManager::PrintController(void)
|
|||
// FIX: Originally this function doesn't have StretchX/Y, everything had constant pixel size (due to screen was abandoned early?)
|
||||
// Also texts and their alignment were very bad, so I tried to make them readable (commented out the original code, and marked the ones I added with X)
|
||||
|
||||
// sorry!
|
||||
|
||||
/*
|
||||
m_aFrontEndSprites[FE_CONTROLLERSH].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(240.0f), MENU_Y(180.0f), CRGBA(0, 0, 0, 255));
|
||||
m_aFrontEndSprites[FE_CONTROLLER].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255));
|
||||
if (m_DisplayControllerOnFoot) {
|
||||
|
@ -5210,6 +5188,7 @@ CMenuManager::PrintController(void)
|
|||
else
|
||||
m_aFrontEndSprites[FE_ARROWS4].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255));
|
||||
}
|
||||
*/
|
||||
|
||||
CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); // X
|
||||
|
||||
|
@ -5468,47 +5447,47 @@ CMenuManager::PrintMap(void)
|
|||
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
|
||||
|
||||
if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY - fMapSize) {
|
||||
m_aMapSprites[MAPTOP1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - fMapSize,
|
||||
m_aFrontEndSprites[MENUSPRITE_MAPTOP01].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - fMapSize,
|
||||
fMapCenterX - halfTile, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255)));
|
||||
}
|
||||
|
||||
if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY - fMapSize) {
|
||||
m_aMapSprites[MAPTOP2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - fMapSize,
|
||||
m_aFrontEndSprites[MENUSPRITE_MAPTOP02].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - fMapSize,
|
||||
fMapCenterX + halfTile, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255)));
|
||||
}
|
||||
|
||||
if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY - fMapSize) {
|
||||
m_aMapSprites[MAPTOP3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - fMapSize,
|
||||
m_aFrontEndSprites[MENUSPRITE_MAPTOP03].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - fMapSize,
|
||||
fMapCenterX + fMapSize, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255)));
|
||||
}
|
||||
|
||||
if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY - halfTile) {
|
||||
m_aMapSprites[MAPMID1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - halfTile,
|
||||
m_aFrontEndSprites[MENUSPRITE_MAPMID01].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - halfTile,
|
||||
fMapCenterX - halfTile, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255)));
|
||||
}
|
||||
|
||||
if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY - halfTile) {
|
||||
m_aMapSprites[MAPMID2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - halfTile,
|
||||
m_aFrontEndSprites[MENUSPRITE_MAPMID02].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - halfTile,
|
||||
fMapCenterX + halfTile, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255)));
|
||||
}
|
||||
|
||||
if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY - halfTile) {
|
||||
m_aMapSprites[MAPMID3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - halfTile,
|
||||
m_aFrontEndSprites[MENUSPRITE_MAPMID03].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - halfTile,
|
||||
fMapCenterX + fMapSize, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255)));
|
||||
}
|
||||
|
||||
if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY + halfTile) {
|
||||
m_aMapSprites[MAPBOT1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY + halfTile,
|
||||
m_aFrontEndSprites[MENUSPRITE_MAPBOT01].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY + halfTile,
|
||||
fMapCenterX - halfTile, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255)));
|
||||
}
|
||||
|
||||
if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY + halfTile) {
|
||||
m_aMapSprites[MAPBOT2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY + halfTile,
|
||||
m_aFrontEndSprites[MENUSPRITE_MAPBOT02].Draw(CRect(fMapCenterX - halfTile, fMapCenterY + halfTile,
|
||||
fMapCenterX + halfTile, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255)));
|
||||
}
|
||||
|
||||
if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY + halfTile) {
|
||||
m_aMapSprites[MAPBOT3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY + halfTile,
|
||||
m_aFrontEndSprites[MENUSPRITE_MAPBOT03].Draw(CRect(fMapCenterX + halfTile, fMapCenterY + halfTile,
|
||||
fMapCenterX + fMapSize, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255)));
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
#define MENUHEADER_POS_Y 75.0f
|
||||
#define MENUHEADER_HEIGHT 1.3f
|
||||
#else
|
||||
#define MENUHEADER_POS_X 35.0f
|
||||
#define MENUHEADER_POS_Y 93.0f
|
||||
#define MENUHEADER_POS_X 10.0f
|
||||
#define MENUHEADER_POS_Y 10.0f
|
||||
#define MENUHEADER_HEIGHT 1.6f
|
||||
#endif
|
||||
#define MENUHEADER_WIDTH 0.84f
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
#define MENURADIO_ICON_SCALE 60.0f
|
||||
|
||||
#define MENUSLIDER_X 256.0f
|
||||
#define MENUSLIDER_X 128.0f
|
||||
#define MENUSLIDER_UNK 256.0f
|
||||
|
||||
#define BIGTEXT_X_SCALE 0.75f
|
||||
|
@ -95,6 +95,7 @@ enum eLanguages
|
|||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
enum eFrontendSprites
|
||||
{
|
||||
FE2_MAINPANEL_UL,
|
||||
|
@ -128,29 +129,36 @@ enum eFrontendSprites
|
|||
|
||||
NUM_FE_SPRITES
|
||||
};
|
||||
*/
|
||||
|
||||
enum eMenuSprites
|
||||
{
|
||||
MENUSPRITE_CONNECTION,
|
||||
MENUSPRITE_FINDGAME,
|
||||
MENUSPRITE_HOSTGAME,
|
||||
MENUSPRITE_MAINMENU,
|
||||
MENUSPRITE_PLAYERSET,
|
||||
MENUSPRITE_SINGLEPLAYER,
|
||||
MENUSPRITE_MULTIPLAYER,
|
||||
MENUSPRITE_DMALOGO,
|
||||
MENUSPRITE_GTALOGO,
|
||||
MENUSPRITE_RSTARLOGO,
|
||||
MENUSPRITE_GAMESPY,
|
||||
MENUSPRITE_BACKGROUND,
|
||||
MENUSPRITE_VCLOGO,
|
||||
MENUSPRITE_MOUSE,
|
||||
MENUSPRITE_MOUSET,
|
||||
MENUSPRITE_MP3LOGO,
|
||||
MENUSPRITE_MAPTOP01,
|
||||
MENUSPRITE_MAPTOP02,
|
||||
MENUSPRITE_MAPTOP03,
|
||||
MENUSPRITE_MAPMID01,
|
||||
MENUSPRITE_MAPMID02,
|
||||
MENUSPRITE_MAPMID03,
|
||||
MENUSPRITE_MAPBOT01,
|
||||
MENUSPRITE_MAPBOT02,
|
||||
MENUSPRITE_MAPBOT03,
|
||||
MENUSPRITE_WILDSTYLE,
|
||||
MENUSPRITE_FLASH,
|
||||
MENUSPRITE_KCHAT,
|
||||
MENUSPRITE_FEVER,
|
||||
MENUSPRITE_VROCK,
|
||||
MENUSPRITE_VCPR,
|
||||
MENUSPRITE_ESPANTOSO,
|
||||
MENUSPRITE_EMOTION,
|
||||
MENUSPRITE_WAVE,
|
||||
MENUSPRITE_MP3,
|
||||
MENUSPRITE_DOWNOFF,
|
||||
MENUSPRITE_DOWNON,
|
||||
MENUSPRITE_UPOFF,
|
||||
MENUSPRITE_UPON,
|
||||
MENUSPRITE_GTA3LOGO,
|
||||
MENUSPRITE_UNUSED,
|
||||
NUM_MENU_SPRITES
|
||||
};
|
||||
|
||||
|
@ -509,8 +517,9 @@ public:
|
|||
char field_455;
|
||||
bool m_bStartWaitingForKeyBind;
|
||||
bool m_bSpritesLoaded;
|
||||
CSprite2d m_aFrontEndSprites[NUM_FE_SPRITES];
|
||||
CSprite2d m_aMenuSprites[NUM_MENU_SPRITES];
|
||||
//CSprite2d m_aFrontEndSprites[NUM_FE_SPRITES];
|
||||
//CSprite2d m_aMenuSprites[NUM_MENU_SPRITES];
|
||||
CSprite2d m_aFrontEndSprites[NUM_MENU_SPRITES];
|
||||
int32 field_518;
|
||||
int32 m_nMenuFadeAlpha;
|
||||
bool m_bPressedPgUpOnList;
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
#include "World.h"
|
||||
#include "ZoneCull.h"
|
||||
#include "Zones.h"
|
||||
#include "Occlusion.h"
|
||||
#include "debugmenu.h"
|
||||
|
||||
|
||||
|
@ -272,6 +273,7 @@ bool CGame::Initialise(const char* datFile)
|
|||
ThePaths.AllocatePathFindInfoMem(4500);
|
||||
CWeather::Init();
|
||||
CCullZones::Init();
|
||||
COcclusion::Init();
|
||||
CCollision::Init();
|
||||
CTheZones::Init();
|
||||
CUserDisplay::Init();
|
||||
|
|
|
@ -100,7 +100,7 @@ void WeaponCheat()
|
|||
void HealthCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT3"), true);
|
||||
FindPlayerPed()->m_fHealth = 100.0f;
|
||||
FindPlayerPed()->m_fHealth = CWorld::Players[0].m_nMaxHealth;
|
||||
if (FindPlayerVehicle()) {
|
||||
FindPlayerVehicle()->m_fHealth = 1000.0f;
|
||||
if (FindPlayerVehicle()->m_vehType == VEHICLE_TYPE_CAR)
|
||||
|
@ -224,7 +224,7 @@ void MoneyCheat()
|
|||
void ArmourCheat()
|
||||
{
|
||||
CHud::SetHelpMessage(TheText.Get("CHEAT4"), true);
|
||||
FindPlayerPed()->m_fArmour = 100.0f;
|
||||
FindPlayerPed()->m_fArmour = CWorld::Players[0].m_nMaxArmour;
|
||||
}
|
||||
|
||||
void WantedLevelUpCheat()
|
||||
|
|
|
@ -140,6 +140,7 @@ CPlayerInfo::Clear(void)
|
|||
m_nUpsideDownCounter = 0;
|
||||
m_bInfiniteSprint = false;
|
||||
m_bFastReload = false;
|
||||
m_nMaxHealth = m_nMaxArmour = 100;
|
||||
m_bGetOutOfJailFree = false;
|
||||
m_bGetOutOfHospitalFree = false;
|
||||
m_bDriveByAllowed = true;
|
||||
|
@ -172,7 +173,6 @@ void
|
|||
CPlayerInfo::MakePlayerSafe(bool toggle)
|
||||
{
|
||||
if (toggle) {
|
||||
CTheScripts::ResetCountdownToMakePlayerUnsafe();
|
||||
m_pPed->m_pWanted->m_bIgnoredByEveryone = true;
|
||||
CWorld::StopAllLawEnforcersInTheirTracks();
|
||||
CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_20;
|
||||
|
@ -193,7 +193,8 @@ CPlayerInfo::MakePlayerSafe(bool toggle)
|
|||
CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f);
|
||||
CReplay::DisableReplays();
|
||||
|
||||
} else if (!CGame::playingIntro && !CTheScripts::IsCountdownToMakePlayerUnsafeOn()) {
|
||||
}
|
||||
else {
|
||||
m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
|
||||
CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_20;
|
||||
m_pPed->bBulletProof = false;
|
||||
|
|
|
@ -52,6 +52,9 @@ public:
|
|||
int32 field_272;
|
||||
bool m_bInfiniteSprint;
|
||||
bool m_bFastReload;
|
||||
bool m_bFireproof;
|
||||
uint8 m_nMaxHealth;
|
||||
uint8 m_nMaxArmour;
|
||||
bool m_bGetOutOfJailFree;
|
||||
bool m_bGetOutOfHospitalFree;
|
||||
bool m_bDriveByAllowed;
|
||||
|
|
|
@ -61,6 +61,7 @@ int32 CStats::HighestScores[CStats::TOTAL_HIGHEST_SCORES];
|
|||
int32 CStats::Sprayings;
|
||||
float CStats::AutoPaintingBudget;
|
||||
int32 CStats::NoMoreHurricanes;
|
||||
float CStats::FashionBudget;
|
||||
|
||||
void CStats::Init()
|
||||
{
|
||||
|
@ -257,6 +258,11 @@ float CStats::GetPercentageProgress()
|
|||
return Min(percentCompleted, 100.0f);
|
||||
}
|
||||
|
||||
void CStats::MoneySpentOnFashion(int32 money)
|
||||
{
|
||||
FashionBudget += money;
|
||||
}
|
||||
|
||||
void CStats::SaveStats(uint8 *buf, uint32 *size)
|
||||
{
|
||||
CheckPointReachedSuccessfully();
|
||||
|
|
|
@ -65,6 +65,7 @@ public:
|
|||
static int32 Sprayings;
|
||||
static float AutoPaintingBudget;
|
||||
static int32 NoMoreHurricanes;
|
||||
static float FashionBudget;
|
||||
|
||||
public:
|
||||
static void Init(void);
|
||||
|
@ -91,4 +92,6 @@ public:
|
|||
static void SaveStats(uint8 *buf, uint32 *size);
|
||||
static void LoadStats(uint8 *buf, uint32 size);
|
||||
static float GetPercentageProgress();
|
||||
|
||||
static void MoneySpentOnFashion(int32);
|
||||
};
|
||||
|
|
|
@ -66,7 +66,7 @@ enum Config {
|
|||
// Cull zones
|
||||
NUMATTRIBZONES = 704,
|
||||
|
||||
NUMHANDLINGS = 106,
|
||||
NUMOCCLUSIONVOLUMES = 350,
|
||||
|
||||
PATHNODESIZE = 4500,
|
||||
|
||||
|
@ -194,7 +194,7 @@ enum Config {
|
|||
|
||||
#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more
|
||||
#define TOGGLEABLE_BETA_FEATURES // toggleable from debug menu. not too many things
|
||||
#define MORE_LANGUAGES // Add more translations to the game
|
||||
//#define MORE_LANGUAGES // Add more translations to the game
|
||||
#define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch)
|
||||
#define USE_TXD_CDIMAGE // generate and load textures from txd.img
|
||||
#define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number
|
||||
|
|
|
@ -20,3 +20,25 @@ CBuilding::ReplaceWithNewModel(int32 id)
|
|||
if(m_level == LEVEL_NONE || m_level == CGame::currLevel)
|
||||
CStreaming::RequestModel(id, STREAMFLAGS_DONT_REMOVE);
|
||||
}
|
||||
|
||||
bool
|
||||
IsBuildingPointerValid(CBuilding* pBuilding)
|
||||
{
|
||||
if (!pBuilding)
|
||||
return false;
|
||||
if (pBuilding->GetIsATreadable()) {
|
||||
int index = CPools::GetTreadablePool()->GetJustIndex((CTreadable*)pBuilding);
|
||||
#ifdef FIX_BUGS
|
||||
return index >= 0 && index < CPools::GetTreadablePool()->GetSize();
|
||||
#else
|
||||
return index >= 0 && index <= CPools::GetTreadablePool()->GetSize();
|
||||
#endif
|
||||
} else {
|
||||
int index = CPools::GetBuildingPool()->GetJustIndex(pBuilding);
|
||||
#ifdef FIX_BUGS
|
||||
return index >= 0 && index < CPools::GetBuildingPool()->GetSize();
|
||||
#else
|
||||
return index >= 0 && index <= CPools::GetBuildingPool()->GetSize();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,3 +16,5 @@ public:
|
|||
|
||||
virtual bool GetIsATreadable(void) { return false; }
|
||||
};
|
||||
|
||||
bool IsBuildingPointerValid(CBuilding*);
|
||||
|
|
|
@ -50,3 +50,18 @@ CDummy::Remove(void)
|
|||
m_entryInfoList.DeleteNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
IsDummyPointerValid(CDummy* pDummy)
|
||||
{
|
||||
if (!pDummy)
|
||||
return false;
|
||||
int index = CPools::GetDummyPool()->GetJustIndex(pDummy);
|
||||
#ifdef FIX_BUGS
|
||||
if (index < 0 || index >= CPools::GetDummyPool()->GetSize())
|
||||
#else
|
||||
if (index < 0 || index > CPools::GetDummyPool()->GetSize())
|
||||
#endif
|
||||
return false;
|
||||
return pDummy->m_entryInfoList.first;
|
||||
}
|
||||
|
|
|
@ -15,3 +15,5 @@ public:
|
|||
static void *operator new(size_t);
|
||||
static void operator delete(void*, size_t);
|
||||
};
|
||||
|
||||
bool IsDummyPointerValid(CDummy* pDummy);
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include "Bones.h"
|
||||
#include "Debug.h"
|
||||
#include "Renderer.h"
|
||||
#include "Ped.h"
|
||||
#include "Dummy.h"
|
||||
|
||||
int gBuildings;
|
||||
|
||||
|
@ -1028,3 +1030,18 @@ CEntity::LoadEntityFlags(uint8*& buf)
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool IsEntityPointerValid(CEntity* pEntity)
|
||||
{
|
||||
if (!pEntity)
|
||||
return false;
|
||||
switch (pEntity->GetType()) {
|
||||
case ENTITY_TYPE_NOTHING: return false;
|
||||
case ENTITY_TYPE_BUILDING: return IsBuildingPointerValid((CBuilding*)pEntity);
|
||||
case ENTITY_TYPE_VEHICLE: return IsVehiclePointerValid((CVehicle*)pEntity);
|
||||
case ENTITY_TYPE_PED: return IsPedPointerValid((CPed*)pEntity);
|
||||
case ENTITY_TYPE_OBJECT: return IsObjectPointerValid((CObject*)pEntity);
|
||||
case ENTITY_TYPE_DUMMY: return IsDummyPointerValid((CDummy*)pEntity);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -180,3 +180,5 @@ public:
|
|||
|
||||
static void AddSteamsFromGround(CPtrList& list);
|
||||
};
|
||||
|
||||
bool IsEntityPointerValid(CEntity*);
|
||||
|
|
|
@ -160,7 +160,9 @@
|
|||
X("subplatform_sub", MI_SUBPLATFORM_SUB2, 0x5F5BC0) \
|
||||
X("files", MI_FILES, 0x5F5BC4) \
|
||||
X("property_locked", MI_PICKUP_PROPERTY, 0x0) \
|
||||
X("property_fsale", MI_PICKUP_PROPERTY_FORSALE, 0x0)
|
||||
X("property_fsale", MI_PICKUP_PROPERTY_FORSALE, 0x0) \
|
||||
X("clothesp", MI_PICKUP_CLOTHES, 0x0) \
|
||||
X("bigdollar", MI_PICKUP_REVENUE, 0x0)
|
||||
|
||||
#define X(name, var, addr) extern int16 var;
|
||||
MODELINDICES
|
||||
|
|
|
@ -396,3 +396,18 @@ CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
IsObjectPointerValid(CObject* pObject)
|
||||
{
|
||||
if (!pObject)
|
||||
return false;
|
||||
int index = CPools::GetObjectPool()->GetJustIndex(pObject);
|
||||
#ifdef FIX_BUGS
|
||||
if (index < 0 || index >= CPools::GetObjectPool()->GetSize())
|
||||
#else
|
||||
if (index < 0 || index > CPools::GetObjectPool()->GetSize())
|
||||
#endif
|
||||
return false;
|
||||
return pObject->bIsBIGBuilding || pObject->m_entryInfoList.first;
|
||||
}
|
||||
|
|
|
@ -113,3 +113,5 @@ public:
|
|||
static void DeleteAllTempObjects();
|
||||
static void DeleteAllTempObjectsInArea(CVector point, float fRadius);
|
||||
};
|
||||
|
||||
bool IsObjectPointerValid(CObject* pObject);
|
||||
|
|
|
@ -325,7 +325,7 @@ CCivilianPed::ProcessControl(void)
|
|||
CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = Max(250, playerSexFrequency - 10);
|
||||
}
|
||||
|
||||
m_pMyVehicle->pDriver->m_fHealth = Min(125.0f, 1.0f + m_pMyVehicle->pDriver->m_fHealth);
|
||||
m_pMyVehicle->pDriver->m_fHealth = Min(CWorld::Players[0].m_nMaxHealth + 25.0f, 1.0f + m_pMyVehicle->pDriver->m_fHealth);
|
||||
if (CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency == 250)
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000;
|
||||
} else {
|
||||
|
@ -336,7 +336,7 @@ CCivilianPed::ProcessControl(void)
|
|||
} else {
|
||||
bWanderPathAfterExitingCar = true;
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
|
||||
m_pMyVehicle->pDriver->m_fHealth = 125.0f;
|
||||
m_pMyVehicle->pDriver->m_fHealth = CWorld::Players[0].m_nMaxHealth + 25.0f;
|
||||
SetObjective(OBJECTIVE_LEAVE_VEHICLE, m_pMyVehicle);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -513,6 +513,8 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
|
|||
m_fAirResistance = 0.4f / m_fMass;
|
||||
m_fElasticity = 0.05f;
|
||||
|
||||
m_ceaseAttackTimer = 0;
|
||||
|
||||
bIsStanding = false;
|
||||
bWasStanding = false;
|
||||
bIsAttacking = false;
|
||||
|
@ -18605,3 +18607,28 @@ CPed::CanBeDamagedByThisGangMember(CPed* who)
|
|||
{
|
||||
return m_gangFlags & (1 << (uint8)(who->m_nPedType - PEDTYPE_GANG1));
|
||||
}
|
||||
|
||||
bool
|
||||
IsPedPointerValid_NotInWorld(CPed* pPed)
|
||||
{
|
||||
if (!pPed)
|
||||
return false;
|
||||
int index = CPools::GetPedPool()->GetJustIndex(pPed);
|
||||
#ifdef FIX_BUGS
|
||||
if (index < 0 || index >= NUMPEDS)
|
||||
#else
|
||||
if (index < 0 || index > NUMPEDS)
|
||||
#endif
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IsPedPointerValid(CPed* pPed)
|
||||
{
|
||||
if (!IsPedPointerValid_NotInWorld(pPed))
|
||||
return false;
|
||||
if (pPed->bInVehicle && pPed->m_pMyVehicle)
|
||||
return IsEntityPointerValid(pPed->m_pMyVehicle);
|
||||
return pPed->m_entryInfoList.first || pPed == FindPlayerPed();
|
||||
}
|
|
@ -220,7 +220,7 @@ enum eObjective : uint32 {
|
|||
OBJECTIVE_LEAVE_CAR_AND_DIE,
|
||||
OBJECTIVE_USE_SEAT_ATTRACTOR,
|
||||
OBJECTIVE_USE_ATM_ATTRACTOR,
|
||||
OBJECTIVE_FLEE_CAR, // is it 41?
|
||||
OBJECTIVE_FLEE_CAR,
|
||||
OBJ_42,
|
||||
OBJECTIVE_USE_STOP_ATTRACTOR,
|
||||
OBJECTIVE_USE_PIZZA_ATTRACTOR,
|
||||
|
@ -563,7 +563,7 @@ public:
|
|||
uint32 m_duckAndCoverTimer;
|
||||
uint32 m_bloodyFootprintCountOrDeathTime; // Death time when bDoBloodyFootprints is false. Weird decision
|
||||
uint32 m_shotTime;
|
||||
uint32 m_shotTimeAdd;
|
||||
uint32 m_ceaseAttackTimer;
|
||||
uint8 m_panicCounter;
|
||||
bool m_deadBleeding;
|
||||
int8 m_bodyPartBleeding; // PedNode, but -1 if there isn't
|
||||
|
@ -1026,3 +1026,6 @@ void FinishFuckUCB(CAnimBlendAssociation *assoc, void *arg);
|
|||
#ifndef PED_SKIN
|
||||
VALIDATE_SIZE(CPed, 0x53C);
|
||||
#endif
|
||||
|
||||
bool IsPedPointerValid(CPed*);
|
||||
bool IsPedPointerValid_NotInWorld(CPed*);
|
||||
|
|
|
@ -64,6 +64,13 @@ CClouds::Update(void)
|
|||
float s = Sin(TheCamera.Orientation - 0.85f);
|
||||
CloudRotation += CWeather::Wind*s*0.001f;
|
||||
IndividualRotation += (CWeather::Wind*CTimer::GetTimeStep()*0.5f + 0.3f) * 60.0f;
|
||||
#ifdef FIX_BUGS
|
||||
CloudRotation += CWeather::Wind*s*0.001f*CTimer::GetTimeStepFix();
|
||||
IndividualRotation += (CWeather::Wind*CTimer::GetTimeStep()*0.5f + 0.3f*CTimer::GetTimeStepFix()) * 60.0f;
|
||||
#else
|
||||
CloudRotation += CWeather::Wind*s*0.001f;
|
||||
IndividualRotation += (CWeather::Wind*CTimer::GetTimeStep()*0.5f + 0.3f) * 60.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -593,15 +593,20 @@ void CHud::Draw()
|
|||
else
|
||||
CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f));
|
||||
|
||||
CFont::SetSlantRefPoint(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(128.0f));
|
||||
CFont::SetSlant(0.15f);
|
||||
|
||||
CFont::SetRightJustifyOn();
|
||||
CFont::SetRightJustifyWrap(0.0f);
|
||||
CFont::SetBackGroundOnlyTextOff();
|
||||
CFont::SetFontStyle(FONT_BANK);
|
||||
CFont::SetColor(CRGBA(0, 0, 0, fZoneAlpha));
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f) + SCREEN_SCALE_X(1.0f), SCREEN_SCALE_FROM_BOTTOM(30.0f) + SCREEN_SCALE_Y(1.0f), m_ZoneToPrint);
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f) + SCREEN_SCALE_X(1.0f), SCREEN_SCALE_FROM_BOTTOM(128.0f) + SCREEN_SCALE_Y(1.0f), m_ZoneToPrint);
|
||||
|
||||
CFont::SetColor(CRGBA(ZONE_COLOR.r, ZONE_COLOR.g, ZONE_COLOR.b, fZoneAlpha));
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(30.0f), m_ZoneToPrint);
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(128.0f), m_ZoneToPrint);
|
||||
|
||||
CFont::SetSlant(0.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -687,15 +692,20 @@ void CHud::Draw()
|
|||
else
|
||||
CFont::SetScale(SCREEN_SCALE_X(1.2f * 0.85f), SCREEN_SCALE_Y(1.2f));
|
||||
|
||||
CFont::SetSlantRefPoint(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(105.0f));
|
||||
CFont::SetSlant(0.15f);
|
||||
|
||||
CFont::SetRightJustifyOn();
|
||||
CFont::SetRightJustifyWrap(0.0f);
|
||||
CFont::SetBackGroundOnlyTextOff();
|
||||
CFont::SetFontStyle(FONT_BANK);
|
||||
CFont::SetColor(CRGBA(0, 0, 0, fVehicleAlpha));
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f) + SCREEN_SCALE_X(1.0f), SCREEN_SCALE_FROM_BOTTOM(55.0f) + SCREEN_SCALE_Y(1.0f), m_pVehicleNameToPrint);
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f) + SCREEN_SCALE_X(1.0f), SCREEN_SCALE_FROM_BOTTOM(105.f) + SCREEN_SCALE_Y(1.0f), m_pVehicleNameToPrint);
|
||||
|
||||
CFont::SetColor(CRGBA(VEHICLE_COLOR.r, VEHICLE_COLOR.g, VEHICLE_COLOR.b, fVehicleAlpha));
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(55.0f), m_pVehicleNameToPrint);
|
||||
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(105.0f), m_pVehicleNameToPrint);
|
||||
|
||||
CFont::SetSlant(0.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,42 @@
|
|||
|
||||
#include "Occlusion.h"
|
||||
|
||||
int32 COcclusion::NumOccludersOnMap;
|
||||
int16 COcclusion::FarAwayList;
|
||||
int16 COcclusion::NearbyList;
|
||||
int16 COcclusion::ListWalkThroughFA;
|
||||
int16 COcclusion::PreviousListWalkThroughFA;
|
||||
COccluder COcclusion::aOccluders[NUMOCCLUSIONVOLUMES];
|
||||
|
||||
void
|
||||
COcclusion::Init(void)
|
||||
{
|
||||
NumOccludersOnMap = 0;
|
||||
FarAwayList = -1;
|
||||
NearbyList = -1;
|
||||
ListWalkThroughFA = -1;
|
||||
PreviousListWalkThroughFA = -1;
|
||||
}
|
||||
|
||||
void
|
||||
COcclusion::AddOne(float x, float y, float z, float width, float length, float height, float angle)
|
||||
{
|
||||
if(NumOccludersOnMap >= NUMOCCLUSIONVOLUMES)
|
||||
return;
|
||||
|
||||
aOccluders[NumOccludersOnMap].x = x;
|
||||
aOccluders[NumOccludersOnMap].y = y;
|
||||
aOccluders[NumOccludersOnMap].z = z;
|
||||
aOccluders[NumOccludersOnMap].width = width;
|
||||
aOccluders[NumOccludersOnMap].length = length;
|
||||
aOccluders[NumOccludersOnMap].height = height;
|
||||
while(angle < 0.0f) angle += 360.0f;
|
||||
while(angle > 360.0f) angle -= 360.0f;
|
||||
aOccluders[NumOccludersOnMap].angle = angle * UINT16_MAX/360.0f;
|
||||
aOccluders[NumOccludersOnMap].listIndex = FarAwayList;
|
||||
FarAwayList = NumOccludersOnMap++;
|
||||
}
|
||||
|
||||
void
|
||||
COcclusion::ProcessBeforeRendering(void)
|
||||
{
|
||||
|
|
|
@ -1,7 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
class COccluder
|
||||
{
|
||||
public:
|
||||
int16 width, length, height;
|
||||
int16 x, y, z;
|
||||
uint16 angle;
|
||||
int16 listIndex;
|
||||
};
|
||||
|
||||
class COcclusion
|
||||
{
|
||||
public:
|
||||
static int32 NumOccludersOnMap;
|
||||
static int16 FarAwayList;
|
||||
static int16 NearbyList;
|
||||
static int16 ListWalkThroughFA;
|
||||
static int16 PreviousListWalkThroughFA;
|
||||
|
||||
static COccluder aOccluders[NUMOCCLUSIONVOLUMES];
|
||||
|
||||
static void Init(void);
|
||||
static void AddOne(float x, float y, float z, float width, float length, float height, float angle);
|
||||
static void ProcessBeforeRendering(void);
|
||||
};
|
||||
|
|
|
@ -7,27 +7,36 @@
|
|||
#include "Frontend.h"
|
||||
#include "Messages.h"
|
||||
#include "Text.h"
|
||||
#include "Timer.h"
|
||||
|
||||
static wchar WideErrorString[25];
|
||||
|
||||
CText TheText;
|
||||
|
||||
//--MIAMI: DONE
|
||||
CText::CText(void)
|
||||
{
|
||||
encoding = 'e';
|
||||
bHasMissionTextOffsets = false;
|
||||
bIsMissionTextLoaded = false;
|
||||
memset(szMissionTableName, 0, sizeof(szMissionTableName));
|
||||
memset(WideErrorString, 0, sizeof(WideErrorString));
|
||||
}
|
||||
|
||||
//--MIAMI: DONE
|
||||
void
|
||||
CText::Load(void)
|
||||
{
|
||||
uint8 *filedata;
|
||||
char filename[32], type[4];
|
||||
int length;
|
||||
int offset, sectlen;
|
||||
char filename[32];
|
||||
uint32 offset;
|
||||
int file;
|
||||
bool tkey_loaded = false, tdat_loaded = false;
|
||||
ChunkHeader m_ChunkHeader;
|
||||
|
||||
bIsMissionTextLoaded = false;
|
||||
bHasMissionTextOffsets = false;
|
||||
|
||||
Unload();
|
||||
filedata = new uint8[0x40000];
|
||||
|
||||
CFileMgr::SetDir("TEXT");
|
||||
switch(CMenuManager::m_PrefsLanguage){
|
||||
|
@ -59,49 +68,64 @@ CText::Load(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
length = CFileMgr::LoadFile(filename, filedata, 0x40000, "rb");
|
||||
CFileMgr::SetDir("");
|
||||
file = CFileMgr::OpenFile(filename, "rb");
|
||||
|
||||
offset = 0;
|
||||
while(offset < length){
|
||||
type[0] = filedata[offset++];
|
||||
type[1] = filedata[offset++];
|
||||
type[2] = filedata[offset++];
|
||||
type[3] = filedata[offset++];
|
||||
sectlen = (int)filedata[offset+3]<<24 | (int)filedata[offset+2]<<16 |
|
||||
(int)filedata[offset+1]<<8 | (int)filedata[offset+0];
|
||||
offset += 4;
|
||||
if(sectlen != 0){
|
||||
if(strncmp(type, "TKEY", 4) == 0)
|
||||
keyArray.Load(sectlen, filedata, &offset);
|
||||
else if(strncmp(type, "TDAT", 4) == 0)
|
||||
data.Load(sectlen, filedata, &offset);
|
||||
else
|
||||
offset += sectlen;
|
||||
while (!tkey_loaded || !tdat_loaded) {
|
||||
ReadChunkHeader(&m_ChunkHeader, file, &offset);
|
||||
if (m_ChunkHeader.size != 0) {
|
||||
if (strncmp(m_ChunkHeader.magic, "TABL", 4) == 0) {
|
||||
MissionTextOffsets.Load(m_ChunkHeader.size, file, &offset, 0x58000);
|
||||
bHasMissionTextOffsets = true;
|
||||
} else if (strncmp(m_ChunkHeader.magic, "TKEY", 4) == 0) {
|
||||
this->keyArray.Load(m_ChunkHeader.size, file, &offset);
|
||||
tkey_loaded = true;
|
||||
} else if (strncmp(m_ChunkHeader.magic, "TDAT", 4) == 0) {
|
||||
this->data.Load(m_ChunkHeader.size, file, &offset);
|
||||
tdat_loaded = true;
|
||||
} else {
|
||||
CFileMgr::Seek(file, m_ChunkHeader.size, SEEK_CUR);
|
||||
offset += m_ChunkHeader.size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keyArray.Update(data.chars);
|
||||
|
||||
delete[] filedata;
|
||||
CFileMgr::CloseFile(file);
|
||||
CFileMgr::SetDir("");
|
||||
}
|
||||
|
||||
//--MIAMI: DONE
|
||||
void
|
||||
CText::Unload(void)
|
||||
{
|
||||
CMessages::ClearAllMessagesDisplayedByGame();
|
||||
data.Unload();
|
||||
keyArray.Unload();
|
||||
data.Unload();
|
||||
mission_keyArray.Unload();
|
||||
mission_data.Unload();
|
||||
bIsMissionTextLoaded = false;
|
||||
memset(szMissionTableName, 0, sizeof(szMissionTableName));
|
||||
}
|
||||
|
||||
//--MIAMI: DONE
|
||||
wchar*
|
||||
CText::Get(const char *key)
|
||||
{
|
||||
uint8 result = false;
|
||||
#ifdef FIX_BUGS
|
||||
return keyArray.Search(key, data.chars);
|
||||
wchar *outstr = keyArray.Search(key, data.chars, &result);
|
||||
#else
|
||||
return keyArray.Search(key);
|
||||
wchar *outstr = keyArray.Search(key, &result);
|
||||
#endif
|
||||
|
||||
if (!result && bHasMissionTextOffsets && bIsMissionTextLoaded)
|
||||
#ifdef FIX_BUGS
|
||||
outstr = mission_keyArray.Search(key, mission_data.chars, &result);
|
||||
#else
|
||||
outstr = mission_keyArray.Search(key, &result);
|
||||
#endif
|
||||
return outstr;
|
||||
}
|
||||
|
||||
wchar UpperCaseTable[128] = {
|
||||
|
@ -134,6 +158,7 @@ wchar FrenchUpperCaseTable[128] = {
|
|||
253, 254, 255
|
||||
};
|
||||
|
||||
//--MIAMI: TODO (check tables)
|
||||
wchar
|
||||
CText::GetUpperCase(wchar c)
|
||||
{
|
||||
|
@ -165,6 +190,7 @@ CText::GetUpperCase(wchar c)
|
|||
return c;
|
||||
}
|
||||
|
||||
//--MIAMI: DONE
|
||||
void
|
||||
CText::UpperCase(wchar *s)
|
||||
{
|
||||
|
@ -174,21 +200,131 @@ CText::UpperCase(wchar *s)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//--MIAMI: DONE
|
||||
void
|
||||
CKeyArray::Load(uint32 length, uint8 *data, int *offset)
|
||||
CText::GetNameOfLoadedMissionText(char *outName)
|
||||
{
|
||||
uint32 i;
|
||||
uint8 *rawbytes;
|
||||
strcpy(outName, szMissionTableName);
|
||||
}
|
||||
|
||||
//--MIAMI: DONE
|
||||
void
|
||||
CText::ReadChunkHeader(ChunkHeader *buf, int32 file, uint32 *offset)
|
||||
{
|
||||
// original code loops 8 times to read 1 byte with CFileMgr::Read, that's retarded
|
||||
CFileMgr::Read(file, (char*)buf, sizeof(ChunkHeader));
|
||||
*offset += sizeof(ChunkHeader);
|
||||
}
|
||||
|
||||
//--MIAMI: DONE
|
||||
void
|
||||
CText::LoadMissionText(char *MissionTableName)
|
||||
{
|
||||
char filename[32];
|
||||
|
||||
mission_keyArray.Unload();
|
||||
mission_data.Unload();
|
||||
|
||||
bool search_result = false;
|
||||
int missionTableId = 0;
|
||||
|
||||
for (missionTableId = 0; missionTableId < MissionTextOffsets.size; missionTableId++) {
|
||||
if (strncmp(MissionTextOffsets.data[missionTableId].szMissionName, MissionTableName, strlen(MissionTextOffsets.data[missionTableId].szMissionName)) == 0) {
|
||||
search_result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!search_result) {
|
||||
printf("CText::LoadMissionText - couldn't find %s", MissionTableName);
|
||||
return;
|
||||
}
|
||||
|
||||
CFileMgr::SetDir("TEXT");
|
||||
switch (CMenuManager::m_PrefsLanguage) {
|
||||
case LANGUAGE_AMERICAN:
|
||||
sprintf(filename, "AMERICAN.GXT");
|
||||
break;
|
||||
case LANGUAGE_FRENCH:
|
||||
sprintf(filename, "FRENCH.GXT");
|
||||
break;
|
||||
case LANGUAGE_GERMAN:
|
||||
sprintf(filename, "GERMAN.GXT");
|
||||
break;
|
||||
case LANGUAGE_ITALIAN:
|
||||
sprintf(filename, "ITALIAN.GXT");
|
||||
break;
|
||||
case LANGUAGE_SPANISH:
|
||||
sprintf(filename, "SPANISH.GXT");
|
||||
break;
|
||||
#ifdef MORE_LANGUAGES
|
||||
case LANGUAGE_POLISH:
|
||||
sprintf(filename, "POLISH.GXT");
|
||||
break;
|
||||
case LANGUAGE_RUSSIAN:
|
||||
sprintf(filename, "RUSSIAN.GXT");
|
||||
break;
|
||||
case LANGUAGE_JAPANESE:
|
||||
sprintf(filename, "JAPANESE.GXT");
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
CTimer::Suspend();
|
||||
int file = CFileMgr::OpenFile(filename, "rb");
|
||||
CFileMgr::Seek(file, MissionTextOffsets.data[missionTableId].offset, SEEK_SET);
|
||||
|
||||
char TableCheck[8];
|
||||
CFileMgr::Read(file, TableCheck, 8);
|
||||
if (strncmp(TableCheck, MissionTableName, 8) != 0)
|
||||
printf("CText::LoadMissionText - expected to find %s in the text file", MissionTableName);
|
||||
|
||||
bool tkey_loaded = false, tdat_loaded = false;
|
||||
ChunkHeader m_ChunkHeader;
|
||||
while (!tkey_loaded || !tdat_loaded) {
|
||||
uint32 bytes_read = 0;
|
||||
ReadChunkHeader(&m_ChunkHeader, file, &bytes_read);
|
||||
if (m_ChunkHeader.size != 0) {
|
||||
if (strncmp(m_ChunkHeader.magic, "TKEY", 4) == 0) {
|
||||
uint32 bytes_read = 0;
|
||||
mission_keyArray.Load(m_ChunkHeader.size, file, &bytes_read);
|
||||
tkey_loaded = true;
|
||||
} else if (strncmp(m_ChunkHeader.magic, "TDAT", 4) == 0) {
|
||||
uint32 bytes_read = 0;
|
||||
mission_data.Load(m_ChunkHeader.size, file, &bytes_read);
|
||||
tdat_loaded = true;
|
||||
} else
|
||||
CFileMgr::Seek(file, m_ChunkHeader.size, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
mission_keyArray.Update(mission_data.chars);
|
||||
CFileMgr::CloseFile(file);
|
||||
CTimer::Resume();
|
||||
CFileMgr::SetDir("");
|
||||
strcpy(szMissionTableName, MissionTableName);
|
||||
bIsMissionTextLoaded = true;
|
||||
}
|
||||
|
||||
|
||||
//--MIAMI: DONE
|
||||
void
|
||||
CKeyArray::Load(uint32 length, int file, uint32 *offset)
|
||||
{
|
||||
char *rawbytes;
|
||||
|
||||
numEntries = length / sizeof(CKeyEntry);
|
||||
entries = new CKeyEntry[numEntries];
|
||||
rawbytes = (uint8*)entries;
|
||||
rawbytes = (char*)entries;
|
||||
|
||||
for(i = 0; i < length; i++)
|
||||
rawbytes[i] = data[(*offset)++];
|
||||
#if DUMB
|
||||
for (uint32 i = 0; i < length; i++)
|
||||
CFileMgr::Read(file, &rawbytes[i], 1);
|
||||
#else
|
||||
CFileMgr::Read(file, rawbytes, length);
|
||||
#endif
|
||||
}
|
||||
|
||||
//--MIAMI: DONE
|
||||
void
|
||||
CKeyArray::Unload(void)
|
||||
{
|
||||
|
@ -197,6 +333,7 @@ CKeyArray::Unload(void)
|
|||
numEntries = 0;
|
||||
}
|
||||
|
||||
//--MIAMI: DONE
|
||||
void
|
||||
CKeyArray::Update(wchar *chars)
|
||||
{
|
||||
|
@ -207,6 +344,7 @@ CKeyArray::Update(wchar *chars)
|
|||
#endif
|
||||
}
|
||||
|
||||
//--MIAMI: DONE
|
||||
CKeyEntry*
|
||||
CKeyArray::BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 high)
|
||||
{
|
||||
|
@ -227,11 +365,12 @@ CKeyArray::BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 hi
|
|||
return nil;
|
||||
}
|
||||
|
||||
//--MIAMI: DONE
|
||||
wchar*
|
||||
#ifdef FIX_BUGS
|
||||
CKeyArray::Search(const char *key, wchar *data)
|
||||
CKeyArray::Search(const char *key, wchar *data, uint8 *result)
|
||||
#else
|
||||
CKeyArray::Search(const char *key)
|
||||
CKeyArray::Search(const char *key, uint8 *result)
|
||||
#endif
|
||||
{
|
||||
CKeyEntry *found;
|
||||
|
@ -240,34 +379,47 @@ CKeyArray::Search(const char *key)
|
|||
|
||||
#ifdef FIX_BUGS
|
||||
found = BinarySearch(key, entries, 0, numEntries-1);
|
||||
if(found)
|
||||
if (found) {
|
||||
*result = true;
|
||||
return (wchar*)((uint8*)data + found->valueOffset);
|
||||
}
|
||||
#else
|
||||
found = BinarySearch(key, entries, 0, numEntries-1);
|
||||
if(found)
|
||||
if (found) {
|
||||
*result = true;
|
||||
return found->value;
|
||||
}
|
||||
#endif
|
||||
*result = false;
|
||||
#ifdef MASTER
|
||||
sprintf(errstr, "%");
|
||||
#else
|
||||
sprintf(errstr, "%s missing", key);
|
||||
#endif // MASTER
|
||||
for(i = 0; i < 25; i++)
|
||||
WideErrorString[i] = errstr[i];
|
||||
return WideErrorString;
|
||||
}
|
||||
|
||||
|
||||
//--MIAMI: DONE
|
||||
void
|
||||
CData::Load(uint32 length, uint8 *data, int *offset)
|
||||
CData::Load(uint32 length, int file, uint32 *offset)
|
||||
{
|
||||
uint32 i;
|
||||
uint8 *rawbytes;
|
||||
char *rawbytes;
|
||||
|
||||
numChars = length / sizeof(wchar);
|
||||
chars = new wchar[numChars];
|
||||
rawbytes = (uint8*)chars;
|
||||
rawbytes = (char*)chars;
|
||||
|
||||
for(i = 0; i < length; i++)
|
||||
rawbytes[i] = data[(*offset)++];
|
||||
#if DUMB
|
||||
for(uint32 i = 0; i < length; i++)
|
||||
CFileMgr::Read(file, &rawbytes[i], 1);
|
||||
#else
|
||||
CFileMgr::Read(file, rawbytes, length);
|
||||
#endif
|
||||
}
|
||||
|
||||
//--MIAMI: DONE
|
||||
void
|
||||
CData::Unload(void)
|
||||
{
|
||||
|
@ -276,6 +428,16 @@ CData::Unload(void)
|
|||
numChars = 0;
|
||||
}
|
||||
|
||||
//--MIAMI: DONE
|
||||
void
|
||||
CMissionTextOffsets::Load(uint32 table_size, int file, uint32 *offset, int)
|
||||
{
|
||||
// not exact VC code but smaller and better :P
|
||||
size = table_size / sizeof(CMissionTextOffsets::Entry);
|
||||
CFileMgr::Read(file, (char*)data, sizeof(CMissionTextOffsets::Entry) * size);
|
||||
*offset += sizeof(CMissionTextOffsets::Entry) * size;
|
||||
}
|
||||
|
||||
void
|
||||
AsciiToUnicode(const char *src, wchar *dst)
|
||||
{
|
||||
|
|
|
@ -28,14 +28,14 @@ public:
|
|||
|
||||
CKeyArray(void) : entries(nil), numEntries(0) {}
|
||||
~CKeyArray(void) { Unload(); }
|
||||
void Load(uint32 length, uint8 *data, int *offset);
|
||||
void Load(uint32 length, int file, uint32 *offset);
|
||||
void Unload(void);
|
||||
void Update(wchar *chars);
|
||||
CKeyEntry *BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 high);
|
||||
#ifdef FIX_BUGS
|
||||
wchar *Search(const char *key, wchar *data);
|
||||
wchar *Search(const char *key, wchar *data, uint8 *result);
|
||||
#else
|
||||
wchar *Search(const char *key);
|
||||
wchar *Search(const char *key, uint8* result);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -47,15 +47,45 @@ public:
|
|||
|
||||
CData(void) : chars(nil), numChars(0) {}
|
||||
~CData(void) { Unload(); }
|
||||
void Load(uint32 length, uint8 *data, int *offset);
|
||||
void Load(uint32 length, int file, uint32 *offset);
|
||||
void Unload(void);
|
||||
};
|
||||
|
||||
class CMissionTextOffsets
|
||||
{
|
||||
public:
|
||||
struct Entry
|
||||
{
|
||||
char szMissionName[8];
|
||||
uint32 offset;
|
||||
};
|
||||
|
||||
enum {MAX_MISSION_TEXTS = 90}; // beware that LCS has more
|
||||
|
||||
Entry data[MAX_MISSION_TEXTS];
|
||||
uint16 size;
|
||||
|
||||
CMissionTextOffsets(void) : size(0) {}
|
||||
void Load(uint32 table_size, int file, uint32* bytes_read, int);
|
||||
};
|
||||
|
||||
struct ChunkHeader
|
||||
{
|
||||
char magic[4];
|
||||
int size;
|
||||
};
|
||||
|
||||
class CText
|
||||
{
|
||||
CKeyArray keyArray;
|
||||
CData data;
|
||||
CKeyArray mission_keyArray;
|
||||
CData mission_data;
|
||||
char encoding;
|
||||
bool bHasMissionTextOffsets;
|
||||
bool bIsMissionTextLoaded;
|
||||
char szMissionTableName[8];
|
||||
CMissionTextOffsets MissionTextOffsets;
|
||||
public:
|
||||
CText(void);
|
||||
void Load(void);
|
||||
|
@ -63,6 +93,9 @@ public:
|
|||
wchar *Get(const char *key);
|
||||
wchar GetUpperCase(wchar c);
|
||||
void UpperCase(wchar *s);
|
||||
void GetNameOfLoadedMissionText(char *outName);
|
||||
void ReadChunkHeader(ChunkHeader *buf, int32 file, uint32 *bytes_read);
|
||||
void LoadMissionText(char *MissionTableName);
|
||||
};
|
||||
|
||||
extern CText TheText;
|
||||
|
|
|
@ -72,6 +72,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
|
|||
bFixedColour = false;
|
||||
bBigWheels = false;
|
||||
bWaterTight = false;
|
||||
bTankDetonateCars = true;
|
||||
|
||||
SetModelIndex(id);
|
||||
|
||||
|
@ -332,7 +333,7 @@ CAutomobile::ProcessControl(void)
|
|||
bool playerRemote = false;
|
||||
switch(GetStatus()){
|
||||
case STATUS_PLAYER_REMOTE:
|
||||
if(CPad::GetPad(0)->WeaponJustDown()){
|
||||
if(CPad::GetPad(0)->WeaponJustDown() && !bDisableRemoteDetonation){
|
||||
BlowUpCar(FindPlayerPed());
|
||||
CRemote::TakeRemoteControlledCarFromPlayer();
|
||||
}
|
||||
|
@ -864,8 +865,14 @@ CAutomobile::ProcessControl(void)
|
|||
CVector wheelFwd = GetForward();
|
||||
CVector wheelRight = GetRight();
|
||||
|
||||
#ifdef FIX_BUGS
|
||||
// Not sure if this is needed, but brake usually has timestep as a factor
|
||||
if(bIsHandbrakeOn)
|
||||
brake = 20000.0f * CTimer::GetTimeStepFix();
|
||||
#else
|
||||
if(bIsHandbrakeOn)
|
||||
brake = 20000.0f;
|
||||
#endif
|
||||
|
||||
if(m_aWheelTimer[CARWHEEL_REAR_LEFT] > 0.0f){
|
||||
if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier))
|
||||
|
@ -4148,7 +4155,7 @@ CAutomobile::BlowUpCarsInPath(void)
|
|||
{
|
||||
int i;
|
||||
|
||||
if(m_vecMoveSpeed.Magnitude() > 0.1f)
|
||||
if(m_vecMoveSpeed.Magnitude() > 0.1f && bTankDetonateCars)
|
||||
for(i = 0; i < m_nCollisionRecords; i++)
|
||||
if(m_aCollisionRecords[i] &&
|
||||
m_aCollisionRecords[i]->IsVehicle() &&
|
||||
|
@ -4610,6 +4617,18 @@ CAutomobile::SetAllTaxiLights(bool set)
|
|||
m_sAllTaxiLights = set;
|
||||
}
|
||||
|
||||
void
|
||||
CAutomobile::TellHeliToGoToCoors(float x, float y, float z, uint8 speed)
|
||||
{
|
||||
AutoPilot.m_nCarMission = MISSION_HELI_FLYTOCOORS;
|
||||
AutoPilot.m_vecDestinationCoors.x = x;
|
||||
AutoPilot.m_vecDestinationCoors.y = y;
|
||||
AutoPilot.m_vecDestinationCoors.z = z;
|
||||
AutoPilot.m_nCruiseSpeed = speed;
|
||||
SetStatus(STATUS_PHYSICS);
|
||||
//TODO(MIAMI)
|
||||
}
|
||||
|
||||
#ifdef COMPATIBLE_SAVES
|
||||
void
|
||||
CAutomobile::Save(uint8*& buf)
|
||||
|
|
|
@ -91,6 +91,7 @@ public:
|
|||
uint8 bWaterTight : 1; // no damage for non-player peds
|
||||
uint8 bNotDamagedUpsideDown : 1;
|
||||
uint8 bMoreResistantToDamage : 1;
|
||||
uint8 bTankDetonateCars : 1;
|
||||
int16 field_4E0;
|
||||
uint16 m_hydraulicState;
|
||||
uint32 m_nBusDoorTimerEnd;
|
||||
|
@ -178,6 +179,8 @@ public:
|
|||
void SetBumperDamage(int32 component, ePanels panel, bool noFlyingComponents = false);
|
||||
void SetDoorDamage(int32 component, eDoors door, bool noFlyingComponents = false);
|
||||
|
||||
void TellHeliToGoToCoors(float x, float y, float z, uint8 speed);
|
||||
|
||||
void Fix(void);
|
||||
void SetComponentVisibility(RwFrame *frame, uint32 flags);
|
||||
void SetupModelNodes(void);
|
||||
|
|
|
@ -127,7 +127,7 @@ cHandlingDataMgr::Initialise(void)
|
|||
{
|
||||
LoadHandlingData();
|
||||
field_0 = 0.1f;
|
||||
field_4 = 0.9f;
|
||||
fWheelFriction = 0.9f;
|
||||
field_8 = 1.0f;
|
||||
field_C = 0.8f;
|
||||
field_10 = 0.98f;
|
||||
|
@ -143,6 +143,9 @@ cHandlingDataMgr::LoadHandlingData(void)
|
|||
int field, handlingId;
|
||||
int keepGoing;
|
||||
tHandlingData *handling;
|
||||
tFlyingHandlingData *flyingHandling;
|
||||
tBoatHandlingData *boatHandling;
|
||||
tBikeHandlingData *bikeHandling;
|
||||
|
||||
CFileMgr::SetDir("DATA");
|
||||
CFileMgr::LoadFile(HandlingFilename, work_buff, sizeof(work_buff), "r");
|
||||
|
@ -151,6 +154,9 @@ cHandlingDataMgr::LoadHandlingData(void)
|
|||
start = (char*)work_buff;
|
||||
end = start+1;
|
||||
handling = nil;
|
||||
flyingHandling = nil;
|
||||
boatHandling = nil;
|
||||
bikeHandling = nil;
|
||||
keepGoing = 1;
|
||||
|
||||
while(keepGoing){
|
||||
|
@ -166,9 +172,107 @@ cHandlingDataMgr::LoadHandlingData(void)
|
|||
// yeah, this is kinda crappy
|
||||
if(strncmp(line, ";the end", 9) == 0)
|
||||
keepGoing = 0;
|
||||
// else if(line[0] != ';'){
|
||||
// TODO(MIAMI): read boat, bike, flying values
|
||||
else if(line[0] != ';' && line[0] != '%' && line[0] != '!' && line[0] != '$'){
|
||||
else if(line[0] != ';'){
|
||||
if(line[0] == '!'){
|
||||
// Bike data
|
||||
field = 0;
|
||||
strcpy(delim, " \t");
|
||||
// FIX: game seems to use a do-while loop here
|
||||
for(word = strtok(line, delim); word; word = strtok(nil, delim)){
|
||||
switch(field){
|
||||
case 0: break;
|
||||
case 1:
|
||||
handlingId = FindExactWord(word, (const char*)VehicleNames, 14, NUMHANDLINGS);
|
||||
assert(handlingId >= 0 && handlingId < NUMHANDLINGS);
|
||||
bikeHandling = GetBikePointer(handlingId);
|
||||
bikeHandling->nIdentifier = (eHandlingId)handlingId;
|
||||
break;
|
||||
case 2: bikeHandling->fLeanFwdCOM = atof(word); break;
|
||||
case 3: bikeHandling->fLeanFwdForce = atof(word); break;
|
||||
case 4: bikeHandling->fLeanBakCOM = atof(word); break;
|
||||
case 5: bikeHandling->fLeanBackForce = atof(word); break;
|
||||
case 6: bikeHandling->fMaxLean = atof(word); break;
|
||||
case 7: bikeHandling->fFullAnimLean = atof(word); break;
|
||||
case 8: bikeHandling->fDesLean = atof(word); break;
|
||||
case 9: bikeHandling->fSpeedSteer = atof(word); break;
|
||||
case 10: bikeHandling->fSlipSteer = atof(word); break;
|
||||
case 11: bikeHandling->fNoPlayerCOMz = atof(word); break;
|
||||
case 12: bikeHandling->fWheelieAng = atof(word); break;
|
||||
case 13: bikeHandling->fStoppieAng = atof(word); break;
|
||||
case 14: bikeHandling->fWheelieSteer = atof(word); break;
|
||||
case 15: bikeHandling->fWheelieStabMult = atof(word); break;
|
||||
case 16: bikeHandling->fStoppieStabMult = atof(word); break;
|
||||
}
|
||||
field++;
|
||||
}
|
||||
ConvertBikeDataToGameUnits(bikeHandling);
|
||||
}else if(line[0] == '$'){
|
||||
// Flying data
|
||||
field = 0;
|
||||
strcpy(delim, " \t");
|
||||
// FIX: game seems to use a do-while loop here
|
||||
for(word = strtok(line, delim); word; word = strtok(nil, delim)){
|
||||
switch(field){
|
||||
case 0: break;
|
||||
case 1:
|
||||
handlingId = FindExactWord(word, (const char*)VehicleNames, 14, NUMHANDLINGS);
|
||||
assert(handlingId >= 0 && handlingId < NUMHANDLINGS);
|
||||
flyingHandling = GetFlyingPointer(handlingId);
|
||||
flyingHandling->nIdentifier = (eHandlingId)handlingId;
|
||||
break;
|
||||
case 2: flyingHandling->fThrust = atof(word); break;
|
||||
case 3: flyingHandling->fThrustFallOff = atof(word); break;
|
||||
case 4: flyingHandling->fYaw = atof(word); break;
|
||||
case 5: flyingHandling->fYawStab = atof(word); break;
|
||||
case 6: flyingHandling->fSideSlip = atof(word); break;
|
||||
case 7: flyingHandling->fRoll = atof(word); break;
|
||||
case 8: flyingHandling->fRollStab = atof(word); break;
|
||||
case 9: flyingHandling->fPitch = atof(word); break;
|
||||
case 10: flyingHandling->fPitchStab = atof(word); break;
|
||||
case 11: flyingHandling->fFormLift = atof(word); break;
|
||||
case 12: flyingHandling->fAttackLift = atof(word); break;
|
||||
case 13: flyingHandling->fMoveRes = atof(word); break;
|
||||
case 14: flyingHandling->vecTurnRes.x = atof(word); break;
|
||||
case 15: flyingHandling->vecTurnRes.y = atof(word); break;
|
||||
case 16: flyingHandling->vecTurnRes.z = atof(word); break;
|
||||
case 17: flyingHandling->vecSpeedRes.x = atof(word); break;
|
||||
case 18: flyingHandling->vecSpeedRes.y = atof(word); break;
|
||||
case 19: flyingHandling->vecSpeedRes.z = atof(word); break;
|
||||
}
|
||||
field++;
|
||||
}
|
||||
}else if(line[0] == '%'){
|
||||
// Boat data
|
||||
field = 0;
|
||||
strcpy(delim, " \t");
|
||||
// FIX: game seems to use a do-while loop here
|
||||
for(word = strtok(line, delim); word; word = strtok(nil, delim)){
|
||||
switch(field){
|
||||
case 0: break;
|
||||
case 1:
|
||||
handlingId = FindExactWord(word, (const char*)VehicleNames, 14, NUMHANDLINGS);
|
||||
assert(handlingId >= 0 && handlingId < NUMHANDLINGS);
|
||||
boatHandling = GetBoatPointer(handlingId);
|
||||
boatHandling->nIdentifier = (eHandlingId)handlingId;
|
||||
break;
|
||||
case 2: boatHandling->fThrustY = atof(word); break;
|
||||
case 3: boatHandling->fThrustZ = atof(word); break;
|
||||
case 4: boatHandling->fThrustAppZ = atof(word); break;
|
||||
case 5: boatHandling->fAqPlaneForce = atof(word); break;
|
||||
case 6: boatHandling->fAqPlaneLimit = atof(word); break;
|
||||
case 7: boatHandling->fAqPlaneOffset = atof(word); break;
|
||||
case 8: boatHandling->fWaveAudioMult = atof(word); break;
|
||||
case 9: boatHandling->vecMoveRes.x = atof(word); break;
|
||||
case 10: boatHandling->vecMoveRes.y = atof(word); break;
|
||||
case 11: boatHandling->vecMoveRes.z = atof(word); break;
|
||||
case 12: boatHandling->vecTurnRes.x = atof(word); break;
|
||||
case 13: boatHandling->vecTurnRes.y = atof(word); break;
|
||||
case 14: boatHandling->vecTurnRes.z = atof(word); break;
|
||||
case 15: boatHandling->fLook_L_R_BehindCamHeight = atof(word); break;
|
||||
}
|
||||
field++;
|
||||
}
|
||||
}else{
|
||||
field = 0;
|
||||
strcpy(delim, " \t");
|
||||
// FIX: game seems to use a do-while loop here
|
||||
|
@ -180,37 +284,35 @@ cHandlingDataMgr::LoadHandlingData(void)
|
|||
handling = &HandlingData[handlingId];
|
||||
handling->nIdentifier = (eHandlingId)handlingId;
|
||||
break;
|
||||
case 1: handling->fMass = strtod(word, nil); break;
|
||||
case 2: handling->Dimension.x = strtod(word, nil); break;
|
||||
case 3: handling->Dimension.y = strtod(word, nil); break;
|
||||
case 4: handling->Dimension.z = strtod(word, nil); break;
|
||||
case 5: handling->CentreOfMass.x = strtod(word, nil); break;
|
||||
case 6: handling->CentreOfMass.y = strtod(word, nil); break;
|
||||
case 7: handling->CentreOfMass.z = strtod(word, nil); break;
|
||||
case 1: handling->fMass = atof(word); break;
|
||||
case 2: handling->Dimension.x = atof(word); break;
|
||||
case 3: handling->Dimension.y = atof(word); break;
|
||||
case 4: handling->Dimension.z = atof(word); break;
|
||||
case 5: handling->CentreOfMass.x = atof(word); break;
|
||||
case 6: handling->CentreOfMass.y = atof(word); break;
|
||||
case 7: handling->CentreOfMass.z = atof(word); break;
|
||||
case 8: handling->nPercentSubmerged = atoi(word); break;
|
||||
case 9: handling->fTractionMultiplier = strtod(word, nil); break;
|
||||
case 10: handling->fTractionLoss = strtod(word, nil); break;
|
||||
case 11: handling->fTractionBias = strtod(word, nil); break;
|
||||
case 9: handling->fTractionMultiplier = atof(word); break;
|
||||
case 10: handling->fTractionLoss = atof(word); break;
|
||||
case 11: handling->fTractionBias = atof(word); break;
|
||||
case 12: handling->Transmission.nNumberOfGears = atoi(word); break;
|
||||
case 13: handling->Transmission.fMaxVelocity = strtod(word, nil); break;
|
||||
case 14: handling->Transmission.fEngineAcceleration = strtod(word, nil) * 0.4f; break;
|
||||
case 13: handling->Transmission.fMaxVelocity = atof(word); break;
|
||||
case 14: handling->Transmission.fEngineAcceleration = atof(word) * 0.4f; break;
|
||||
case 15: handling->Transmission.nDriveType = word[0]; break;
|
||||
case 16: handling->Transmission.nEngineType = word[0]; break;
|
||||
case 17: handling->fBrakeDeceleration = strtod(word, nil); break;
|
||||
case 18: handling->fBrakeBias = strtod(word, nil); break;
|
||||
case 17: handling->fBrakeDeceleration = atof(word); break;
|
||||
case 18: handling->fBrakeBias = atof(word); break;
|
||||
case 19: handling->bABS = !!atoi(word); break;
|
||||
case 20: handling->fSteeringLock = strtod(word, nil); break;
|
||||
case 21: handling->fSuspensionForceLevel = strtod(word, nil); break;
|
||||
case 22: handling->fSuspensionDampingLevel = strtod(word, nil); break;
|
||||
case 23: handling->fSeatOffsetDistance = strtod(word, nil); break;
|
||||
case 24: handling->fCollisionDamageMultiplier = strtod(word, nil); break;
|
||||
case 20: handling->fSteeringLock = atof(word); break;
|
||||
case 21: handling->fSuspensionForceLevel = atof(word); break;
|
||||
case 22: handling->fSuspensionDampingLevel = atof(word); break;
|
||||
case 23: handling->fSeatOffsetDistance = atof(word); break;
|
||||
case 24: handling->fCollisionDamageMultiplier = atof(word); break;
|
||||
case 25: handling->nMonetaryValue = atoi(word); break;
|
||||
case 26: handling->fSuspensionUpperLimit = strtod(word, nil); break;
|
||||
case 27: handling->fSuspensionLowerLimit = strtod(word, nil); break;
|
||||
case 28: handling->fSuspensionBias = strtod(word, nil); break;
|
||||
case 29:
|
||||
// TODO(MIAMI): suspension anti-dive multiplier
|
||||
break;
|
||||
case 26: handling->fSuspensionUpperLimit = atof(word); break;
|
||||
case 27: handling->fSuspensionLowerLimit = atof(word); break;
|
||||
case 28: handling->fSuspensionBias = atof(word); break;
|
||||
case 29: handling->fSuspensionAntidiveMultiplier = atof(word); break;
|
||||
case 30:
|
||||
sscanf(word, "%x", &handling->Flags);
|
||||
handling->Transmission.Flags = handling->Flags;
|
||||
|
@ -224,6 +326,7 @@ cHandlingDataMgr::LoadHandlingData(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
cHandlingDataMgr::FindExactWord(const char *word, const char *words, int wordLen, int numWords)
|
||||
|
@ -253,6 +356,7 @@ cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling)
|
|||
if(handling->fTurnMass < 10.0f)
|
||||
handling->fTurnMass *= 5.0f;
|
||||
handling->fInvMass = 1.0f/handling->fMass;
|
||||
handling->fCollisionDamageMultiplier *= 2000.0f/handling->fMass;
|
||||
handling->fBuoyancy = 100.0f/handling->nPercentSubmerged * 0.008f*handling->fMass;
|
||||
|
||||
// What the hell is going on here?
|
||||
|
@ -268,11 +372,16 @@ cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling)
|
|||
|
||||
if(handling->nIdentifier == HANDLING_RCBANDIT){
|
||||
handling->Transmission.fUnkMaxVelocity = handling->Transmission.fMaxVelocity;
|
||||
handling->Transmission.fMaxReverseVelocity = -handling->Transmission.fMaxVelocity;
|
||||
}else if(handling->nIdentifier >= HANDLING_BIKE && handling->nIdentifier <= HANDLING_FREEWAY){
|
||||
handling->Transmission.fUnkMaxVelocity = velocity;
|
||||
handling->Transmission.fMaxVelocity = velocity * 1.2f;
|
||||
handling->Transmission.fMaxReverseVelocity = -0.05f;
|
||||
}else{
|
||||
handling->Transmission.fUnkMaxVelocity = velocity;
|
||||
handling->Transmission.fMaxVelocity = velocity * 1.2f;
|
||||
}
|
||||
handling->Transmission.fMaxReverseVelocity = -0.2f;
|
||||
}
|
||||
|
||||
if(handling->Transmission.nDriveType == '4')
|
||||
handling->Transmission.fEngineAcceleration /= 4.0f;
|
||||
|
@ -282,6 +391,15 @@ cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling)
|
|||
handling->Transmission.InitGearRatios();
|
||||
}
|
||||
|
||||
void
|
||||
cHandlingDataMgr::ConvertBikeDataToGameUnits(tBikeHandlingData *handling)
|
||||
{
|
||||
handling->fMaxLean = Sin(DEGTORAD(handling->fMaxLean));
|
||||
handling->fFullAnimLean = DEGTORAD(handling->fFullAnimLean);
|
||||
handling->fWheelieAng = Sin(DEGTORAD(handling->fWheelieAng));
|
||||
handling->fStoppieAng = Sin(DEGTORAD(handling->fStoppieAng));
|
||||
}
|
||||
|
||||
int32
|
||||
cHandlingDataMgr::GetHandlingId(const char *name)
|
||||
{
|
||||
|
@ -291,3 +409,19 @@ cHandlingDataMgr::GetHandlingId(const char *name)
|
|||
break;
|
||||
return i;
|
||||
}
|
||||
|
||||
tFlyingHandlingData*
|
||||
cHandlingDataMgr::GetFlyingPointer(uint8 id)
|
||||
{
|
||||
if(id >= HANDLING_SEAPLANE && id <= HANDLING_RCCOPTER)
|
||||
return &FlyingHandlingData[id-HANDLING_SEAPLANE];
|
||||
return &FlyingHandlingData[0];
|
||||
}
|
||||
|
||||
tBoatHandlingData*
|
||||
cHandlingDataMgr::GetBoatPointer(uint8 id)
|
||||
{
|
||||
if(id >= HANDLING_PREDATOR && id <= HANDLING_SEAPLANE)
|
||||
return &BoatHandlingData[id-HANDLING_PREDATOR];
|
||||
return &BoatHandlingData[0];
|
||||
}
|
||||
|
|
|
@ -85,11 +85,13 @@ enum eHandlingId
|
|||
HANDLING_LOVEFIST,
|
||||
HANDLING_BLOODRA,
|
||||
HANDLING_BLOODRB,
|
||||
|
||||
HANDLING_BIKE,
|
||||
HANDLING_MOPED,
|
||||
HANDLING_DIRTBIKE,
|
||||
HANDLING_ANGEL,
|
||||
HANDLING_FREEWAY,
|
||||
|
||||
HANDLING_PREDATOR,
|
||||
HANDLING_SPEEDER,
|
||||
HANDLING_REEFER,
|
||||
|
@ -100,7 +102,7 @@ enum eHandlingId
|
|||
HANDLING_DINGHY,
|
||||
HANDLING_MARQUIS,
|
||||
HANDLING_CUPBOAT,
|
||||
HANDLING_SEAPLANE,
|
||||
HANDLING_SEAPLANE, // both boat and plane!
|
||||
HANDLING_SPARROW,
|
||||
HANDLING_SEASPAR,
|
||||
HANDLING_MAVERICK,
|
||||
|
@ -109,7 +111,13 @@ enum eHandlingId
|
|||
HANDLING_HUNTER,
|
||||
HANDLING_RCBARON,
|
||||
HANDLING_RCGOBLIN,
|
||||
HANDLING_RCCOPTER
|
||||
HANDLING_RCCOPTER,
|
||||
|
||||
NUMHANDLINGS,
|
||||
|
||||
NUMBIKEHANDLINGS = HANDLING_FREEWAY+1 - HANDLING_BIKE,
|
||||
NUMFLYINGHANDLINGS = HANDLING_RCCOPTER+1 - HANDLING_SEAPLANE,
|
||||
NUMBOATHANDLINGS = HANDLING_SEAPLANE+1 - HANDLING_PREDATOR,
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -168,6 +176,7 @@ struct tHandlingData
|
|||
float fSuspensionUpperLimit;
|
||||
float fSuspensionLowerLimit;
|
||||
float fSuspensionBias;
|
||||
float fSuspensionAntidiveMultiplier;
|
||||
float fCollisionDamageMultiplier;
|
||||
uint32 Flags;
|
||||
float fSeatOffsetDistance;
|
||||
|
@ -175,19 +184,74 @@ struct tHandlingData
|
|||
int8 FrontLights;
|
||||
int8 RearLights;
|
||||
};
|
||||
VALIDATE_SIZE(tHandlingData, 0xD8);
|
||||
|
||||
struct tBikeHandlingData
|
||||
{
|
||||
eHandlingId nIdentifier;
|
||||
float fLeanFwdCOM;
|
||||
float fLeanFwdForce;
|
||||
float fLeanBakCOM;
|
||||
float fLeanBackForce;
|
||||
float fMaxLean;
|
||||
float fFullAnimLean;
|
||||
float fDesLean;
|
||||
float fSpeedSteer;
|
||||
float fSlipSteer;
|
||||
float fNoPlayerCOMz;
|
||||
float fWheelieAng;
|
||||
float fStoppieAng;
|
||||
float fWheelieSteer;
|
||||
float fWheelieStabMult;
|
||||
float fStoppieStabMult;
|
||||
};
|
||||
|
||||
struct tBoatHandlingData
|
||||
{
|
||||
eHandlingId nIdentifier;
|
||||
float fThrustY;
|
||||
float fThrustZ;
|
||||
float fThrustAppZ;
|
||||
float fAqPlaneForce;
|
||||
float fAqPlaneLimit;
|
||||
float fAqPlaneOffset;
|
||||
float fWaveAudioMult;
|
||||
float fLook_L_R_BehindCamHeight;
|
||||
CVector vecMoveRes;
|
||||
CVector vecTurnRes;
|
||||
};
|
||||
|
||||
struct tFlyingHandlingData
|
||||
{
|
||||
eHandlingId nIdentifier;
|
||||
float fThrust;
|
||||
float fThrustFallOff;
|
||||
float fYaw;
|
||||
float fYawStab;
|
||||
float fSideSlip;
|
||||
float fRoll;
|
||||
float fRollStab;
|
||||
float fPitch;
|
||||
float fPitchStab;
|
||||
float fFormLift;
|
||||
float fAttackLift;
|
||||
float fMoveRes;
|
||||
CVector vecTurnRes;
|
||||
CVector vecSpeedRes;
|
||||
};
|
||||
|
||||
class cHandlingDataMgr
|
||||
{
|
||||
float field_0; // unused it seems
|
||||
public:
|
||||
float field_4; // wheel related
|
||||
float fWheelFriction;
|
||||
private:
|
||||
float field_8; //
|
||||
float field_C; // unused it seems
|
||||
float field_10; //
|
||||
tHandlingData HandlingData[NUMHANDLINGS];
|
||||
uint32 field_302C; // unused it seems
|
||||
tBikeHandlingData BikeHandlingData[NUMBIKEHANDLINGS];
|
||||
tFlyingHandlingData FlyingHandlingData[NUMFLYINGHANDLINGS];
|
||||
tBoatHandlingData BoatHandlingData[NUMBOATHANDLINGS];
|
||||
|
||||
public:
|
||||
cHandlingDataMgr(void);
|
||||
|
@ -195,8 +259,12 @@ public:
|
|||
void LoadHandlingData(void);
|
||||
int FindExactWord(const char *word, const char *words, int wordLen, int numWords);
|
||||
void ConvertDataToGameUnits(tHandlingData *handling);
|
||||
void ConvertBikeDataToGameUnits(tBikeHandlingData *handling);
|
||||
int32 GetHandlingId(const char *name);
|
||||
tHandlingData *GetHandlingData(eHandlingId id) { return &HandlingData[id]; }
|
||||
tBikeHandlingData *GetBikePointer(uint8 id) { return &BikeHandlingData[id-HANDLING_BIKE]; }
|
||||
tFlyingHandlingData *GetFlyingPointer(uint8 id);
|
||||
tBoatHandlingData *GetBoatPointer(uint8 id);
|
||||
bool HasRearWheelDrive(eHandlingId id) { return HandlingData[id].Transmission.nDriveType == 'R'; }
|
||||
bool HasFrontWheelDrive(eHandlingId id) { return HandlingData[id].Transmission.nDriveType == 'F'; }
|
||||
};
|
||||
|
|
|
@ -29,6 +29,7 @@ bool CVehicle::bCheat5;
|
|||
bool CVehicle::bAltDodoCheat;
|
||||
#endif
|
||||
bool CVehicle::m_bDisableMouseSteering = true;
|
||||
bool CVehicle::bDisableRemoteDetonation;
|
||||
|
||||
void *CVehicle::operator new(size_t sz) { return CPools::GetVehiclePool()->New(); }
|
||||
void *CVehicle::operator new(size_t sz, int handle) { return CPools::GetVehiclePool()->New(handle); }
|
||||
|
@ -493,6 +494,11 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
|
|||
if(contactSpeedRight != 0.0f){
|
||||
// exert opposing force
|
||||
right = -contactSpeedRight/wheelsOnGround;
|
||||
#ifdef FIX_BUGS
|
||||
// contactSpeedRight is independent of framerate but right has timestep as a factor
|
||||
// so we probably have to fix this
|
||||
right *= CTimer::GetTimeStepFix();
|
||||
#endif
|
||||
|
||||
if(wheelStatus == WHEEL_STATUS_BURST){
|
||||
float fwdspeed = Min(contactSpeedFwd, 0.3f);
|
||||
|
@ -513,13 +519,21 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
|
|||
}
|
||||
}else if(contactSpeedFwd != 0.0f){
|
||||
fwd = -contactSpeedFwd/wheelsOnGround;
|
||||
#ifdef FIX_BUGS
|
||||
// contactSpeedFwd is independent of framerate but fwd has timestep as a factor
|
||||
// so we probably have to fix this
|
||||
fwd *= CTimer::GetTimeStepFix();
|
||||
#endif
|
||||
|
||||
if(!bBraking){
|
||||
if(m_fGasPedal < 0.01f){
|
||||
if(GetModelIndex() == MI_RCBANDIT)
|
||||
brake = 0.2f * mod_HandlingManager.field_4 / m_fMass;
|
||||
brake = 0.2f * mod_HandlingManager.fWheelFriction / m_fMass;
|
||||
else
|
||||
brake = mod_HandlingManager.field_4 / m_fMass;
|
||||
brake = mod_HandlingManager.fWheelFriction / m_fMass;
|
||||
#ifdef FIX_BUGS
|
||||
brake *= CTimer::GetTimeStepFix();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1080,14 +1094,14 @@ CVehicle::SetDriver(CPed *driver)
|
|||
|
||||
if(bFreebies && driver == FindPlayerPed()){
|
||||
if(GetModelIndex() == MI_AMBULAN)
|
||||
FindPlayerPed()->m_fHealth = Min(FindPlayerPed()->m_fHealth + 20.0f, 100.0f);
|
||||
FindPlayerPed()->m_fHealth = Min(FindPlayerPed()->m_fHealth + 20.0f, CWorld::Players[0].m_nMaxHealth);
|
||||
else if(GetModelIndex() == MI_TAXI)
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 25;
|
||||
else if (GetModelIndex() == MI_POLICE) {
|
||||
CStreaming::RequestModel(WEAPONTYPE_SHOTGUN, STREAMFLAGS_DONT_REMOVE);
|
||||
driver->GiveWeapon(WEAPONTYPE_SHOTGUN, 5);
|
||||
} else if (GetModelIndex() == MI_ENFORCER)
|
||||
driver->m_fArmour = Max(driver->m_fArmour, 100.0f);
|
||||
driver->m_fArmour = Max(driver->m_fArmour, CWorld::Players[0].m_nMaxArmour);
|
||||
else if(GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_ZEBRA) // TODO(MIAMI): check zebra
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 25;
|
||||
bFreebies = false;
|
||||
|
@ -1353,14 +1367,29 @@ eVehicleAppearance
|
|||
CVehicle::GetVehicleAppearance(void)
|
||||
{
|
||||
if (IsCar())
|
||||
return VEHICLE_CAR;
|
||||
return VEHICLE_APPEARANCE_CAR;
|
||||
if (IsBoat())
|
||||
return VEHICLE_BOAT;
|
||||
return VEHICLE_APPEARANCE_BOAT;
|
||||
if (IsBike())
|
||||
return VEHICLE_BIKE;
|
||||
return VEHICLE_APPEARANCE_BIKE;
|
||||
if (IsPlane())
|
||||
return VEHICLE_PLANE;
|
||||
return VEHICLE_APPEARANCE_PLANE;
|
||||
if (IsHeli())
|
||||
return VEHICLE_HELI;
|
||||
return VEHICLE_NONE;
|
||||
return VEHICLE_APPEARANCE_HELI;
|
||||
return VEHICLE_APPEARANCE_NONE;
|
||||
}
|
||||
|
||||
bool
|
||||
IsVehiclePointerValid(CVehicle* pVehicle)
|
||||
{
|
||||
if (!pVehicle)
|
||||
return false;
|
||||
int index = CPools::GetVehiclePool()->GetJustIndex(pVehicle);
|
||||
#ifdef FIX_BUGS
|
||||
if (index < 0 || index >= NUMVEHICLES)
|
||||
#else
|
||||
if (index < 0 || index > NUMVEHICLES)
|
||||
#endif
|
||||
return false;
|
||||
return pVehicle->m_vehType == VEHICLE_TYPE_PLANE || pVehicle->m_entryInfoList.first;
|
||||
}
|
||||
|
|
|
@ -112,12 +112,12 @@ enum eFlightModel
|
|||
|
||||
enum eVehicleAppearance
|
||||
{
|
||||
VEHICLE_NONE,
|
||||
VEHICLE_CAR,
|
||||
VEHICLE_BIKE,
|
||||
VEHICLE_HELI,
|
||||
VEHICLE_BOAT,
|
||||
VEHICLE_PLANE,
|
||||
VEHICLE_APPEARANCE_NONE,
|
||||
VEHICLE_APPEARANCE_CAR,
|
||||
VEHICLE_APPEARANCE_BIKE,
|
||||
VEHICLE_APPEARANCE_HELI,
|
||||
VEHICLE_APPEARANCE_BOAT,
|
||||
VEHICLE_APPEARANCE_PLANE,
|
||||
};
|
||||
|
||||
// Or Weapon.h?
|
||||
|
@ -311,6 +311,8 @@ public:
|
|||
static bool bAltDodoCheat;
|
||||
#endif
|
||||
static bool m_bDisableMouseSteering;
|
||||
static bool bDisableRemoteDetonation;
|
||||
};
|
||||
|
||||
void DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle);
|
||||
bool IsVehiclePointerValid(CVehicle* pVehicle);
|
||||
|
|
Loading…
Reference in a new issue