Merge branch 'master' into garages_dev

This commit is contained in:
Nikolay Korolev 2020-04-10 21:17:00 +03:00
commit be260b49b1
94 changed files with 12517 additions and 10402 deletions

View File

@ -16,12 +16,6 @@ such that we have a working game at all times.
- Since re3 is a DLL that works with original GTA III for now, you need Simple DLL Loader. You can get it [here](https://github.com/aap/simpledllloader).
- Build re3 or download it from one of the above links (Debug or Release).
- Make sure you included the re3 in `plugins.cfg` or `dlls.cfg`.
- re3 starts the script `main_freeroam.scm` that comes along with it by default, so you should copy it to from `gamefiles/` to your game's `data/` directory.
![#ffa500](https://placehold.it/15/ffa500/000000?text=+) **Notice**
If you want to load original script/story, press and hold G while game is loading.
This includes both starting new game and loading save game.
![#ffa500](https://placehold.it/15/ffa500/000000?text=+) **Notice if you will build it**
@ -41,21 +35,16 @@ to reverse at the time, calling the original functions is acceptable.
cAudioManager - WIP
CBoat
CBulletInfo
CExplosion
CMenuManager - WIP
CObject
CPacManPickups
CPad - only cheats
CPedPath
CPools - save/loading
CRecordDataForChase
CRecordDataForGame
CRoadBlocks
CSkidmarks
CStats
CTrafficLights
CWeapon
CWeather
CWorld
GenericLoad
```

View File

@ -134,8 +134,8 @@ uint32 &CCutsceneMgr::ms_cutsceneLoadStatus = *(uint32*)0x95CB40;
RpAtomic *
CalculateBoundingSphereRadiusCB(RpAtomic *atomic, void *data)
{
float radius = RpAtomicGetBoundingSphereMacro(atomic)->radius;
RwV3d center = RpAtomicGetBoundingSphereMacro(atomic)->center;
float radius = RpAtomicGetBoundingSphere(atomic)->radius;
RwV3d center = RpAtomicGetBoundingSphere(atomic)->center;
for (RwFrame *frame = RpAtomicGetFrame(atomic); RwFrameGetParent(frame); frame = RwFrameGetParent(frame))
RwV3dTransformPoints(&center, &center, 1, RwFrameGetMatrix(frame));
@ -326,7 +326,7 @@ CCutsceneMgr::CreateCutsceneObject(int modelId)
pModelInfo->SetColModel(pColModel);
clump = (RpClump*)pModelInfo->GetRwObject();
assert(RwObjectGetType(clump) == rpCLUMP);
assert(RwObjectGetType((RwObject*)clump) == rpCLUMP);
RpClumpForAllAtomics(clump, CalculateBoundingSphereRadiusCB, &radius);
pColModel->boundingSphere.radius = radius;
@ -352,6 +352,7 @@ CCutsceneMgr::DeleteCutsceneData(void)
CWorld::Remove(ms_pCutsceneObjects[ms_numCutsceneObjs]);
ms_pCutsceneObjects[ms_numCutsceneObjs]->DeleteRwObject();
delete ms_pCutsceneObjects[ms_numCutsceneObjs];
ms_pCutsceneObjects[ms_numCutsceneObjs] = nil;
}
ms_numCutsceneObjs = 0;

View File

@ -26,7 +26,7 @@ public:
static CDirectory *&ms_pCutsceneDir;
static uint32 &ms_cutsceneLoadStatus;
static void SetRunning(bool running) { ms_running = running; }
static void StartCutsceneProcessing() { ms_cutsceneProcessing = true; }
static bool IsRunning(void) { return ms_running; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
static bool UseLodMultiplier(void) { return ms_useLodMultiplier; }

View File

@ -1,4 +1,4 @@
#pragma once
#pragma once
#include "DMAudio.h"
#include "common.h"

View File

@ -90,7 +90,7 @@ uint32 (&aCarsToKeepTime)[MAX_CARS_TO_KEEP] = *(uint32(*)[MAX_CARS_TO_KEEP])*(ui
void
CCarCtrl::GenerateRandomCars()
{
if (CCutsceneMgr::IsCutsceneProcessing())
if (CCutsceneMgr::IsRunning())
return;
if (NumRandomCars < 30){
if (CountDownToCarsAtStart == 0){

View File

@ -242,7 +242,7 @@ void CCarGenerator::Load(uint8 *&buffer)
void CTheCarGenerators::Process()
{
if (FindPlayerTrain() || CCutsceneMgr::IsRunning())
if (FindPlayerTrain() || CCutsceneMgr::IsCutsceneProcessing())
return;
if (++CTheCarGenerators::ProcessCounter == 4)
CTheCarGenerators::ProcessCounter = 0;

View File

@ -1129,8 +1129,8 @@ void CReplay::StoreStuffInMem(void)
pEmptyReferences = CReferences::pEmptyList;
pStoredCam = new uint8[sizeof(CCamera)];
memcpy(pStoredCam, &TheCamera, sizeof(CCamera));
pRadarBlips = new uint8[sizeof(CBlip) * NUMRADARBLIPS];
memcpy(pRadarBlips, CRadar::ms_RadarTrace, NUMRADARBLIPS * sizeof(CBlip));
pRadarBlips = new uint8[sizeof(sRadarTrace) * NUMRADARBLIPS];
memcpy(pRadarBlips, CRadar::ms_RadarTrace, NUMRADARBLIPS * sizeof(sRadarTrace));
PlayerWanted = *FindPlayerPed()->m_pWanted;
PlayerInfo = CWorld::Players[0];
Time1 = CTimer::GetTimeInMilliseconds();
@ -1179,7 +1179,7 @@ void CReplay::RestoreStuffFromMem(void)
memcpy(&TheCamera, pStoredCam, sizeof(CCamera));
delete[] pStoredCam;
pStoredCam = nil;
memcpy(CRadar::ms_RadarTrace, pRadarBlips, sizeof(CBlip) * NUMRADARBLIPS);
memcpy(CRadar::ms_RadarTrace, pRadarBlips, sizeof(sRadarTrace) * NUMRADARBLIPS);
delete[] pRadarBlips;
pRadarBlips = nil;
FindPlayerPed()->m_pWanted = new CWanted(PlayerWanted);

View File

@ -91,10 +91,10 @@ uint8 (&CTheScripts::ScriptSpace)[SIZE_SCRIPT_SPACE] = *(uint8(*)[SIZE_SCRIPT_SP
CRunningScript(&CTheScripts::ScriptsArray)[MAX_NUM_SCRIPTS] = *(CRunningScript(*)[MAX_NUM_SCRIPTS])*(uintptr*)0x6F5C08;
int32(&CTheScripts::BaseBriefIdForContact)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x880200;
int32(&CTheScripts::OnAMissionForContactFlag)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x8622F0;
CTextLine (&CTheScripts::IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES] = *(CTextLine (*)[MAX_NUM_INTRO_TEXT_LINES])*(uintptr*)0x70EA68;
CScriptRectangle (&CTheScripts::IntroRectangles)[MAX_NUM_INTRO_RECTANGLES] = *(CScriptRectangle (*)[MAX_NUM_INTRO_RECTANGLES])*(uintptr*)0x72D108;
intro_text_line (&CTheScripts::IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES] = *(intro_text_line (*)[MAX_NUM_INTRO_TEXT_LINES])*(uintptr*)0x70EA68;
intro_script_rectangle (&CTheScripts::IntroRectangles)[MAX_NUM_INTRO_RECTANGLES] = *(intro_script_rectangle (*)[MAX_NUM_INTRO_RECTANGLES])*(uintptr*)0x72D108;
CSprite2d (&CTheScripts::ScriptSprites)[MAX_NUM_SCRIPT_SRPITES] = *(CSprite2d(*)[MAX_NUM_SCRIPT_SRPITES])*(uintptr*)0x72B090;
CScriptSphere(&CTheScripts::ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES] = *(CScriptSphere(*)[MAX_NUM_SCRIPT_SPHERES])*(uintptr*)0x727D60;
script_sphere_struct(&CTheScripts::ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES] = *(script_sphere_struct(*)[MAX_NUM_SCRIPT_SPHERES])*(uintptr*)0x727D60;
tCollectiveData(&CTheScripts::CollectiveArray)[MAX_NUM_COLLECTIVES] = *(tCollectiveData(*)[MAX_NUM_COLLECTIVES])*(uintptr*)0x6FA008;
tUsedObject(&CTheScripts::UsedObjectArray)[MAX_NUM_USED_OBJECTS] = *(tUsedObject(*)[MAX_NUM_USED_OBJECTS])*(uintptr*)0x6E69C8;
int32(&CTheScripts::MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS] = *(int32(*)[MAX_NUM_MISSION_SCRIPTS])*(uintptr*)0x6F0558;
@ -313,7 +313,7 @@ bool CUpsideDownCarCheck::HasCarBeenUpsideDownForAWhile(int32 id)
return false;
}
void CStuckCarCheckEntry::Reset()
void stuck_car_data::Reset()
{
m_nVehicleIndex = -1;
m_vecPos = CVector(-5000.0f, -5000.0f, -5000.0f);
@ -8442,7 +8442,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
CPad::GetPad(ScriptParams[0])->DisablePlayerControls |= PLAYERCONTROL_DISABLED_80;
pPlayerInfo->MakePlayerSafe(true);
CCutsceneMgr::SetRunning(true);
CCutsceneMgr::StartCutsceneProcessing();
return 0;
}
case COMMAND_USE_TEXT_COMMANDS:
@ -11373,15 +11373,15 @@ void CTheScripts::ClearSpaceForMissionEntity(const CVector& pos, CEntity* pEntit
continue;
CEntity* pFound = aEntities[i];
int cols;
if (CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel()->numLines <= 0)
cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel(),
pFound->GetMatrix(), *CModelInfo::GetModelInfo(pFound->GetModelIndex())->GetColModel(), aTempColPoints, nil, nil);
if (pEntity->GetColModel()->numLines <= 0)
cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *pEntity->GetColModel(),
pFound->GetMatrix(), *pFound->GetColModel(), aTempColPoints, nil, nil);
else {
float lines[4];
lines[0] = lines[1] = lines[2] = lines[3] = 1.0f;
CColPoint tmp;
cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel(),
pFound->GetMatrix(), *CModelInfo::GetModelInfo(pFound->GetModelIndex())->GetColModel(), aTempColPoints, &tmp, lines);
CColPoint tmp[4];
cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *pEntity->GetColModel(),
pFound->GetMatrix(), *pFound->GetColModel(), aTempColPoints,tmp, lines);
}
if (cols <= 0)
continue;

View File

@ -15,22 +15,25 @@ class CRunningScript;
#define KEY_LENGTH_IN_SCRIPT 8
struct CScriptRectangle
struct intro_script_rectangle
{
bool m_bIsUsed;
bool m_bBeforeFade;
int16 m_nTextureId;
CRect m_sRect;
CRGBA m_sColor;
intro_script_rectangle() { }
~intro_script_rectangle() { }
};
static_assert(sizeof(CScriptRectangle) == 0x18, "Script.h: error");
static_assert(sizeof(intro_script_rectangle) == 0x18, "Script.h: error");
enum {
SCRIPT_TEXT_MAX_LENGTH = 500
};
struct CTextLine
struct intro_text_line
{
float m_fScaleX;
float m_fScaleY;
@ -50,6 +53,9 @@ struct CTextLine
float m_fAtY;
wchar m_Text[SCRIPT_TEXT_MAX_LENGTH];
intro_text_line() { }
~intro_text_line() { }
void Reset()
{
m_fScaleX = 0.48f;
@ -72,15 +78,17 @@ struct CTextLine
}
};
static_assert(sizeof(CTextLine) == 0x414, "Script.h: error");
static_assert(sizeof(intro_text_line) == 0x414, "Script.h: error");
struct CScriptSphere
struct script_sphere_struct
{
bool m_bInUse;
uint16 m_Index;
uint32 m_Id;
CVector m_vecCenter;
float m_fRadius;
script_sphere_struct() { }
};
struct CStoredLine
@ -145,7 +153,7 @@ public:
bool HasCarBeenUpsideDownForAWhile(int32);
};
struct CStuckCarCheckEntry
struct stuck_car_data
{
int32 m_nVehicleIndex;
CVector m_vecPos;
@ -154,12 +162,13 @@ struct CStuckCarCheckEntry
uint32 m_nStuckTime;
bool m_bStuck;
stuck_car_data() { }
inline void Reset();
};
class CStuckCarCheck
{
CStuckCarCheckEntry m_sCars[MAX_STUCK_CAR_CHECKS];
stuck_car_data m_sCars[MAX_STUCK_CAR_CHECKS];
public:
void Init();
@ -235,10 +244,10 @@ class CTheScripts
static CRunningScript(&ScriptsArray)[MAX_NUM_SCRIPTS];
static int32(&BaseBriefIdForContact)[MAX_NUM_CONTACTS];
static int32(&OnAMissionForContactFlag)[MAX_NUM_CONTACTS];
static CTextLine(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES];
static CScriptRectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES];
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 CScriptSphere(&ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES];
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];

View File

@ -142,7 +142,7 @@ CCamera::Init(void)
PlayerExhaustion = 1.0f;
DebugCamMode = CCam::MODE_NONE;
m_PedOrientForBehindOrInFront = 0.0f;
if(!FrontEndMenuManager.m_bStartGameLoading){
if(!FrontEndMenuManager.m_bWantToRestart){
m_bFading = false;
CDraw::FadeValue = 0;
m_fFLOATingFade = 0.0f;
@ -151,7 +151,7 @@ CCamera::Init(void)
m_fFLOATingFadeMusic = 0.0f;
}
m_bMoveCamToAvoidGeom = false;
if(FrontEndMenuManager.m_bStartGameLoading)
if(FrontEndMenuManager.m_bWantToRestart)
m_bMoveCamToAvoidGeom = true;
m_bStartingSpline = false;
m_iTypeOfSwitch = INTERPOLATION;
@ -3269,7 +3269,7 @@ void
CCamera::SetRwCamera(RwCamera *cam)
{
m_pRwCamera = cam;
m_viewMatrix.Attach(&m_pRwCamera->viewMatrix, false);
m_viewMatrix.Attach(RwCameraGetViewMatrix(m_pRwCamera), false);
CMBlur::MotionBlurOpen(m_pRwCamera);
}

View File

@ -311,7 +311,7 @@ CFileLoader::FindRelatedModelInfoCB(RpAtomic *atomic, void *data)
int n;
RpClump *clump = (RpClump*)data;
nodename = GetFrameNodeName(RpClumpGetFrame(atomic));
nodename = GetFrameNodeName(RpAtomicGetFrame(atomic));
GetNameAndLOD(nodename, name, &n);
mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(name, nil);
if(mi){

View File

@ -555,7 +555,7 @@ void CMenuManager::DoSettingsBeforeStartingAGame()
m_PrefsVsync = m_PrefsVsyncDisp;
DMAudio.Service();
m_bStartGameLoading = true;
m_bWantToRestart = true;
ShutdownJustMenu();
UnloadTextures();
@ -2819,7 +2819,7 @@ void CMenuManager::Process(void)
if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus() != FADE_0)
return;
m_bStartGameLoading = false;
m_bWantToRestart = false;
InitialiseChangedLanguageSettings();
if (CPad::GetPad(0)->GetEscapeJustDown())
@ -2861,9 +2861,9 @@ void CMenuManager::Process(void)
if (m_PrefsVsyncDisp != m_PrefsVsync)
m_PrefsVsync = m_PrefsVsyncDisp;
DMAudio.Service();
m_bStartGameLoading = true;
m_bWantToRestart = true;
RequestFrontEndShutDown();
m_bLoadingSavedGame = true;
m_bWantToLoad = true;
b_FoundRecentSavedGameWantToLoad = true;
DMAudio.SetEffectsFadeVol(0);
DMAudio.SetMusicFadeVol(0);
@ -2960,7 +2960,7 @@ void CMenuManager::Process(void)
m_bWaitingForNewKeyBind = false;
}
if (!m_bStartGameLoading) {
if (!m_bWantToRestart) {
if (m_bGameNotLoaded)
DMAudio.Service();
}

View File

@ -464,7 +464,7 @@ public:
bool m_bMenuActive;
bool m_bMenuStateChanged;
bool m_bWaitingForNewKeyBind;
bool m_bStartGameLoading;
bool m_bWantToRestart;
bool m_bFirstTime;
bool m_bGameNotLoaded;
int32 m_nMousePosX;
@ -484,7 +484,7 @@ public:
bool m_bQuitGameNoCD;
bool m_bRenderGameInMenu;
bool m_bSaveMenuActive;
bool m_bLoadingSavedGame;
bool m_bWantToLoad;
char field_455;
bool m_bStartWaitingForKeyBind;
bool m_bSpritesLoaded;

View File

@ -89,8 +89,6 @@
#define DEFAULT_VIEWWINDOW (0.7f)
eLevelName &CGame::currLevel = *(eLevelName*)0x941514;
bool &CGame::bDemoMode = *(bool*)0x5F4DD0;
bool &CGame::nastyGame = *(bool*)0x5F4DD4;
@ -492,7 +490,7 @@ void CGame::ReInitGameObjectVariables(void)
CParticle::ReloadConfig();
CCullZones::ResolveVisibilities();
if ( !FrontEndMenuManager.m_bLoadingSavedGame )
if ( !FrontEndMenuManager.m_bWantToLoad )
{
CCranes::InitCranes();
CTheScripts::StartTestScript();
@ -566,7 +564,7 @@ void CGame::InitialiseWhenRestarting(void)
TheCamera.Init();
if ( FrontEndMenuManager.m_bLoadingSavedGame == true )
if ( FrontEndMenuManager.m_bWantToLoad == true )
{
RestoreForStartLoad();
CStreaming::LoadScene(TheCamera.GetPosition());
@ -574,7 +572,7 @@ void CGame::InitialiseWhenRestarting(void)
ReInitGameObjectVariables();
if ( FrontEndMenuManager.m_bLoadingSavedGame == true )
if ( FrontEndMenuManager.m_bWantToLoad == true )
{
if ( GenericLoad() == true )
{
@ -593,7 +591,7 @@ void CGame::InitialiseWhenRestarting(void)
ShutDownForRestart();
CTimer::Stop();
CTimer::Initialise();
FrontEndMenuManager.m_bLoadingSavedGame = false;
FrontEndMenuManager.m_bWantToLoad = false;
ReInitGameObjectVariables();
currLevel = LEVEL_INDUSTRIAL;
CCollision::SortOutCollisionAfterLoad();
@ -609,6 +607,9 @@ extern void (*DebugMenuProcess)(void);
void CGame::Process(void)
{
CPad::UpdatePads();
#ifdef GTA_PS2
ProcessTidyUpMemory();
#endif
TheCamera.SetMotionBlurAlpha(0);
if (TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_SNIPER || TheCamera.m_BlurType == MBLUR_NORMAL)
TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
@ -695,6 +696,13 @@ void CGame::TidyUpMemory(bool, bool)
#endif
}
void CGame::ProcessTidyUpMemory(void)
{
#ifdef PS2
// meow
#endif
}
STARTPATCHES
InjectHook(0x48BB80, CGame::InitialiseOnceBeforeRW, PATCH_JUMP);
InjectHook(0x48BBA0, CGame::InitialiseRenderWare, PATCH_JUMP);

View File

@ -39,4 +39,5 @@ public:
// NB: these do something on PS2
static void TidyUpMemory(bool, bool);
static void DrasticTidyUpMemory(bool);
static void ProcessTidyUpMemory(void);
};

View File

@ -29,12 +29,17 @@
#include "Replay.h"
#include "Weather.h"
#include "win.h"
#include "Streaming.h"
#include "PathFind.h"
#include "Wanted.h"
#include "General.h"
CPad *Pads = (CPad*)0x6F0360; // [2]
CMousePointerStateHelper &MousePointerStateHelper = *(CMousePointerStateHelper*)0x95CC8C;
bool &CPad::bDisplayNoControllerMessage = *(bool *)0x95CD52;
bool &CPad::bObsoleteControllerMessage = *(bool *)0x95CDB8;
bool CPad::bOldDisplayNoControllerMessage;
bool &CPad::m_bMapPadOneToPadTwo = *(bool *)0x95CD48;
CKeyboardState &CPad::OldKeyState = *(CKeyboardState*)0x6F1E70;
@ -50,29 +55,217 @@ CMouseControllerState &CPad::PCTempMouseControllerState = *(CMouseControllerStat
_TODO("gbFastTime");
extern bool &gbFastTime;
WRAPPER void WeaponCheat() { EAXJMP(0x490D90); }
WRAPPER void HealthCheat() { EAXJMP(0x490E70); }
WRAPPER void TankCheat() { EAXJMP(0x490EE0); }
WRAPPER void BlowUpCarsCheat() { EAXJMP(0x491040); }
WRAPPER void ChangePlayerCheat() { EAXJMP(0x4910B0); }
WRAPPER void MayhemCheat() { EAXJMP(0x4911C0); }
WRAPPER void EverybodyAttacksPlayerCheat() { EAXJMP(0x491270); }
WRAPPER void WeaponsForAllCheat() { EAXJMP(0x491370); }
WRAPPER void FastTimeCheat() { EAXJMP(0x4913A0); }
WRAPPER void SlowTimeCheat() { EAXJMP(0x4913F0); }
WRAPPER void MoneyCheat() { EAXJMP(0x491430); }
WRAPPER void ArmourCheat() { EAXJMP(0x491460); }
WRAPPER void WantedLevelUpCheat() { EAXJMP(0x491490); }
WRAPPER void WantedLevelDownCheat() { EAXJMP(0x4914F0); }
WRAPPER void SunnyWeatherCheat() { EAXJMP(0x491520); }
WRAPPER void CloudyWeatherCheat() { EAXJMP(0x491550); }
WRAPPER void RainyWeatherCheat() { EAXJMP(0x491580); }
WRAPPER void FoggyWeatherCheat() { EAXJMP(0x4915B0); }
WRAPPER void FastWeatherCheat() { EAXJMP(0x4915E0); }
WRAPPER void OnlyRenderWheelsCheat() { EAXJMP(0x491610); }
WRAPPER void ChittyChittyBangBangCheat() { EAXJMP(0x491640); }
WRAPPER void StrongGripCheat() { EAXJMP(0x491670); }
WRAPPER void NastyLimbsCheat() { EAXJMP(0x4916A0); }
void WeaponCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT2"), true);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_BASEBALLBAT, 0);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_COLT45, 100);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_UZI, 100);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_SHOTGUN, 20);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_AK47, 200);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_M16, 200);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_SNIPERRIFLE, 5);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_ROCKETLAUNCHER, 5);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_MOLOTOV, 5);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_GRENADE, 5);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_FLAMETHROWER, 200);
}
void HealthCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT3"), true);
FindPlayerPed()->m_fHealth = 100.0f;
if (FindPlayerVehicle()) {
FindPlayerVehicle()->m_fHealth = 1000.0f;
if (FindPlayerVehicle()->m_vehType == VEHICLE_TYPE_CAR)
((CAutomobile*)FindPlayerVehicle())->Damage.SetEngineStatus(0);
}
}
void TankCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CStreaming::RequestModel(MI_RHINO, 0);
CStreaming::LoadAllRequestedModels(false);
if (CStreaming::ms_aInfoForModel[MI_RHINO].m_loadState == STREAMSTATE_LOADED) {
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
int32 node = ThePaths.FindNodeClosestToCoors(FindPlayerCoors(), PATH_CAR, 100.0f);
if (node < 0) return;
#ifdef FIX_BUGS
CAutomobile* tank = new CAutomobile(MI_RHINO, RANDOM_VEHICLE);
#else
CAutomobile *tank = new CAutomobile(MI_RHINO, MISSION_VEHICLE);
#endif
if (tank != nil) {
CVector pos = ThePaths.m_pathNodes[node].pos;
pos.z += 4.0f;
tank->GetPosition() = pos;
tank->SetOrientation(0.0f, 0.0f, DEGTORAD(200.0f));
tank->m_status = STATUS_ABANDONED;
tank->m_nDoorLock = CARLOCK_UNLOCKED;
CWorld::Add(tank);
}
}
}
void BlowUpCarsCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
int i = CPools::GetVehiclePool()->GetSize();
while (i-- > 0) {
if (CVehicle *veh = CPools::GetVehiclePool()->GetSlot(i))
veh->BlowUpCar(nil);
}
}
void ChangePlayerCheat()
{
int modelId;
if (FindPlayerPed()->IsPedInControl() && CModelInfo::GetModelInfo("player", nil)) {
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CPlayerPed *ped = FindPlayerPed();
AssocGroupId AnimGrp = ped->m_animGroup;
do
{
do
modelId = CGeneral::GetRandomNumberInRange(0, MI_CAS_WOM+1);
while (!CModelInfo::GetModelInfo(modelId));
} while (modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL04 || modelId == MI_TAXI_D);
uint8 flags = CStreaming::ms_aInfoForModel[modelId].m_flags;
ped->DeleteRwObject();
CStreaming::RequestModel(modelId, STREAMFLAGS_DEPENDENCY| STREAMFLAGS_DONT_REMOVE);
CStreaming::LoadAllRequestedModels(false);
ped->m_modelIndex = -1;
ped->SetModelIndex(modelId);
ped->m_animGroup = AnimGrp;
if (modelId != MI_PLAYER) {
if (!(flags & STREAMFLAGS_DONT_REMOVE))
CStreaming::SetModelIsDeletable(modelId);
}
}
}
void MayhemCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
for (int i = PEDTYPE_CIVMALE; i < PEDTYPE_SPECIAL; i++)
CPedType::SetThreats(i, PED_FLAG_PLAYER1 | PED_FLAG_PLAYER2 | PED_FLAG_PLAYER3 | PED_FLAG_PLAYER4 |
PED_FLAG_CIVMALE | PED_FLAG_CIVFEMALE | PED_FLAG_COP | PED_FLAG_GANG1 |
PED_FLAG_GANG2 | PED_FLAG_GANG3 | PED_FLAG_GANG4 | PED_FLAG_GANG5 |
PED_FLAG_GANG6 | PED_FLAG_GANG7 | PED_FLAG_GANG8 | PED_FLAG_GANG9 |
PED_FLAG_EMERGENCY | PED_FLAG_PROSTITUTE | PED_FLAG_CRIMINAL | PED_FLAG_SPECIAL );
}
void EverybodyAttacksPlayerCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
for (int i = PEDTYPE_CIVMALE; i < PEDTYPE_SPECIAL; i++)
CPedType::AddThreat(i, PED_FLAG_PLAYER1);
}
void WeaponsForAllCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CPopulation::ms_bGivePedsWeapons = !CPopulation::ms_bGivePedsWeapons;
}
void FastTimeCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
if (CTimer::GetTimeScale() < 4.0f)
CTimer::SetTimeScale(CTimer::GetTimeScale() * 2.0f);
}
void SlowTimeCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
if (CTimer::GetTimeScale() > 0.25f)
CTimer::SetTimeScale(CTimer::GetTimeScale() * 0.5f);
}
void MoneyCheat()
{
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 250000;
CHud::SetHelpMessage(TheText.Get("CHEAT6"), true);
}
void ArmourCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT4"), true);
FindPlayerPed()->m_fArmour = 100.0f;
}
void WantedLevelUpCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT5"), true);
FindPlayerPed()->SetWantedLevel(min(FindPlayerPed()->m_pWanted->m_nWantedLevel + 2, 6));
}
void WantedLevelDownCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT5"), true);
FindPlayerPed()->SetWantedLevel(0);
}
void SunnyWeatherCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
CWeather::ForceWeatherNow(WEATHER_SUNNY);
}
void CloudyWeatherCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
CWeather::ForceWeatherNow(WEATHER_CLOUDY);
}
void RainyWeatherCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
CWeather::ForceWeatherNow(WEATHER_RAINY);
}
void FoggyWeatherCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
CWeather::ForceWeatherNow(WEATHER_FOGGY);
}
void FastWeatherCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
gbFastTime = !gbFastTime;
}
void OnlyRenderWheelsCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CVehicle::bWheelsOnlyCheat = !CVehicle::bWheelsOnlyCheat;
}
void ChittyChittyBangBangCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CVehicle::bAllDodosCheat = !CVehicle::bAllDodosCheat;
}
void StrongGripCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CVehicle::bCheat3 = !CVehicle::bCheat3;
}
void NastyLimbsCheat()
{
CPed::bNastyLimbsCheat = !CPed::bNastyLimbsCheat;
}
//////////////////////////////////////////////////////////////////////////
#ifdef KANGAROO_CHEAT
@ -89,7 +282,7 @@ void KangarooCheat()
string = TheText.Get("CHEAT1");
m_fMass = 15.0f;
}
CHud::SetHelpMessage(string, 1);
CHud::SetHelpMessage(string, true);
playerPed->m_ped_flagI80 = !playerPed->m_ped_flagI80;
playerPed->m_fMass = m_fMass;
@ -138,6 +331,21 @@ void CKeyboardState::Clear()
LWIN = RWIN = APPS = 0;
}
#ifdef GTA_PS2_STUFF
void CPad::Initialise(void)
{
for (int i = 0; i < MAX_PADS; i++)
{
CPad::GetPad(i)->Clear(true);
CPad::GetPad(i)->Mode = 0;
}
bObsoleteControllerMessage = false;
bOldDisplayNoControllerMessage = false;
bDisplayNoControllerMessage = false;
}
#endif
void CPad::Clear(bool bResetPlayerControls)
{
NewState.Clear();
@ -165,13 +373,13 @@ void CPad::Clear(bool bResetPlayerControls)
bApplyBrakes = false;
for ( int32 i = 0; i < _TODOCONST(5); i++ )
for ( int32 i = 0; i < HORNHISTORY_SIZE; i++ )
bHornHistory[i] = false;
iCurrHornHistory = 0;
for ( int32 i = 0; i < _TODOCONST(12); i++ )
_unk[i] = ' ';
for ( int32 i = 0; i < ARRAY_SIZE(CheatString); i++ )
CheatString[i] = ' ';
LastTimeTouched = CTimer::GetTimeInMilliseconds();
AverageWeapon = 0;
@ -430,6 +638,108 @@ void CPad::StartShake_Train(float fX, float fY)
}
}
#ifdef GTA_PS2_STUFF
void CPad::AddToCheatString(char c)
{
for ( int32 i = ARRAY_SIZE(CheatString) - 2; i >= 0; i-- )
CheatString[i + 1] = CheatString[i];
#define _CHEATCMP(str) strncmp(str, CheatString, sizeof(str)-1)
// "4414LDRULDRU" - R2 R2 L1 R2 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
if ( !_CHEATCMP("URDLURDL4144") )
WeaponCheat();
// "4411LDRULDRU" - R2 R2 L1 L1 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
else if ( !_CHEATCMP("URDLURDL1144") )
MoneyCheat();
// "4412LDRULDRU" - R2 R2 L1 L2 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
else if ( !_CHEATCMP("URDLURDL2144") )
ArmourCheat();
// "4413LDRULDRU" - R2 R2 L1 R1 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
else if ( !_CHEATCMP("URDLURDL3144") )
HealthCheat();
// "4414LRLRLR" - R2 R2 L1 R2 LEFT RIGHT LEFT RIGHT LEFT RIGHT
else if ( !_CHEATCMP("RLRLRL4144") )
WantedLevelUpCheat();
// "4414UDUDUD" - R2 R2 L1 R2 UP DOWN UP DOWN UP DOWN
else if ( !_CHEATCMP("DUDUDU4144") )
WantedLevelDownCheat();
// "1234432T" - L1 L2 R1 R2 R2 R1 L2 TRIANGLE
else if ( !_CHEATCMP("T2344321") )
SunnyWeatherCheat();
// "1234432S" - L1 L2 R1 R2 R2 R1 L2 SQUARE
else if ( !_CHEATCMP("S2344321") )
CloudyWeatherCheat();
// "1234432C" - L1 L2 R1 R2 R2 R1 L2 CIRCLE
else if ( !_CHEATCMP("C2344321") )
RainyWeatherCheat();
// "1234432X" - L1 L2 R1 R2 R2 R1 L2 CROSS
else if ( !_CHEATCMP("X2344321") )
FoggyWeatherCheat();
// "CCCCCC321TCT" - CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE R1 L2 L1 TRIANGLE CIRCLE TRIANGLE
else if ( !_CHEATCMP("TCT123CCCCCC") )
TankCheat();
// "CCCSSSSS1TCT" - CIRCLE CIRCLE CIRCLE SQUARE SQUARE SQUARE SQUARE SQUARE L1 TRIANGLE CIRCLE TRIANGLE
else if ( !_CHEATCMP("TCT1SSSSSCCC") )
FastWeatherCheat();
// "241324TSCT21" - L2 R2 L1 R1 L2 R2 TRIANGLE SQUARE CIRCLE TRIANGLE L2 L1
else if ( !_CHEATCMP("12TCST423142") )
BlowUpCarsCheat();
// "RDLU12ULDR" - RIGHT DOWN LEFT UP L1 L2 UP LEFT DOWN RIGHT
else if ( !_CHEATCMP("RDLU21ULDR") )
ChangePlayerCheat();
// "DULUX3421" - DOWN UP LEFT UP CROSS R1 R2 L2 L1
else if ( !_CHEATCMP("1243XULUD") )
MayhemCheat();
// "DULUX3412" - DOWN UP LEFT UP CROSS R1 R2 L1 L2
else if ( !_CHEATCMP("2143XULUD") )
EverybodyAttacksPlayerCheat();
// "43TX21UD" - R2 R1 TRIANGLE CROSS L2 L1 UP DOWN
else if ( !_CHEATCMP("DU12XT34") )
WeaponsForAllCheat();
// "TURDS12" - TRIANGLE UP RIGHT DOWN SQUARE L1 L2
else if ( !_CHEATCMP("21SDRUT") )
FastTimeCheat();
// "TURDS34" - TRIANGLE UP RIGHT DOWN SQUARE R1 R2
else if ( !_CHEATCMP("43SDRUT") )
SlowTimeCheat();
// "11S4T1T" - L1 L1 SQUARE R2 TRIANGLE L1 TRIANGLE
else if ( !_CHEATCMP("T1T4S11") )
OnlyRenderWheelsCheat();
// "R4C32D13" - RIGHT R2 CIRCLE R1 L2 DOWN L1 R1
else if ( !_CHEATCMP("31D23C4R") )
ChittyChittyBangBangCheat();
// "3141L33T" - R1 L1 R2 L1 LEFT R1 R1 TRIANGLE
else if ( !_CHEATCMP("T33L1413") )
StrongGripCheat();
// "S1CD13TR1X" - SQUARE L1 CIRCLE DOWN L1 R1 TRIANGLE RIGHT L1 CROSS
else if ( !_CHEATCMP("X1RT31DC1S") )
NastyLimbsCheat();
#undef _CHEATCMP
}
#endif
void CPad::AddToPCCheatString(char c)
{
for ( int32 i = ARRAY_SIZE(KeyBoardCheatString) - 2; i >= 0; i-- )
@ -672,7 +982,7 @@ void CPad::Update(int16 unk)
ProcessPCSpecificStuff();
if ( ++iCurrHornHistory >= _TODOCONST(5) )
if ( ++iCurrHornHistory >= HORNHISTORY_SIZE )
iCurrHornHistory = 0;
bHornHistory[iCurrHornHistory] = GetHorn();
@ -689,7 +999,7 @@ void CPad::DoCheats(void)
void CPad::DoCheats(int16 unk)
{
#ifdef PS2
#ifdef GTA_PS2_STUFF
if ( GetTriangleJustDown() )
AddToCheatString('T');
@ -2093,6 +2403,30 @@ int32 *CPad::EditCodesForControls(int32 *pRsKeys, int32 nSize)
}
STARTPATCHES
InjectHook(0x490D90, &WeaponCheat, PATCH_JUMP);
InjectHook(0x490E70, &HealthCheat, PATCH_JUMP);
InjectHook(0x490EE0, &TankCheat, PATCH_JUMP);
InjectHook(0x491040, &BlowUpCarsCheat, PATCH_JUMP);
InjectHook(0x4910B0, &ChangePlayerCheat, PATCH_JUMP);
InjectHook(0x4911C0, &MayhemCheat, PATCH_JUMP);
InjectHook(0x491270, &EverybodyAttacksPlayerCheat, PATCH_JUMP);
InjectHook(0x491370, &WeaponsForAllCheat, PATCH_JUMP);
InjectHook(0x4913A0, &FastTimeCheat, PATCH_JUMP);
InjectHook(0x4913F0, &SlowTimeCheat, PATCH_JUMP);
InjectHook(0x491430, &MoneyCheat, PATCH_JUMP);
InjectHook(0x491460, &ArmourCheat, PATCH_JUMP);
InjectHook(0x491490, &WantedLevelUpCheat, PATCH_JUMP);
InjectHook(0x4914F0, &WantedLevelDownCheat, PATCH_JUMP);
InjectHook(0x491520, &SunnyWeatherCheat, PATCH_JUMP);
InjectHook(0x491550, &CloudyWeatherCheat, PATCH_JUMP);
InjectHook(0x491580, &RainyWeatherCheat, PATCH_JUMP);
InjectHook(0x4915B0, &FoggyWeatherCheat, PATCH_JUMP);
InjectHook(0x4915E0, &FastWeatherCheat, PATCH_JUMP);
InjectHook(0x491610, &OnlyRenderWheelsCheat, PATCH_JUMP);
InjectHook(0x491640, &ChittyChittyBangBangCheat, PATCH_JUMP);
InjectHook(0x491670, &StrongGripCheat, PATCH_JUMP);
InjectHook(0x4916A0, &NastyLimbsCheat, PATCH_JUMP);
InjectHook(0x4916C0, &CControllerState::Clear, PATCH_JUMP);
InjectHook(0x491760, &CKeyboardState::Clear, PATCH_JUMP);
InjectHook(0x491A10, &CPad::Clear, PATCH_JUMP);

View File

@ -136,6 +136,10 @@ enum
class CPad
{
public:
enum
{
HORNHISTORY_SIZE = 5,
};
CControllerState NewState;
CControllerState OldState;
CControllerState PCTempKeyState;
@ -146,11 +150,11 @@ public:
int16 Mode;
int16 ShakeDur;
uint8 ShakeFreq;
bool bHornHistory[5];
bool bHornHistory[HORNHISTORY_SIZE];
uint8 iCurrHornHistory;
uint8 DisablePlayerControls;
int8 bApplyBrakes;
char _unk[12]; //int32 unk[3];
char CheatString[12];
char _pad0[3];
int32 LastTimeTouched;
int32 AverageWeapon;
@ -161,6 +165,7 @@ public:
static bool &bDisplayNoControllerMessage;
static bool &bObsoleteControllerMessage;
static bool bOldDisplayNoControllerMessage;
static bool &m_bMapPadOneToPadTwo;
static CKeyboardState &OldKeyState;
@ -172,8 +177,9 @@ public:
static CMouseControllerState &PCTempMouseControllerState;
#ifdef GTA_PS2_STUFF
static void Initialise(void);
#endif
void Clear(bool bResetPlayerControls);
void ClearMouseHistory();
void UpdateMouse();
@ -181,6 +187,9 @@ public:
void StartShake(int16 nDur, uint8 nFreq);
void StartShake_Distance(int16 nDur, uint8 nFreq, float fX, float fY, float fz);
void StartShake_Train(float fX, float fY);
#ifdef GTA_PS2_STUFF
void AddToCheatString(char c);
#endif
void AddToPCCheatString(char c);
static void UpdatePads(void);

View File

@ -17,7 +17,7 @@
#include "SpecialFX.h"
float &CRadar::m_radarRange = *(float*)0x8E281C;
CBlip (&CRadar::ms_RadarTrace)[NUMRADARBLIPS] = *(CBlip(*)[NUMRADARBLIPS]) * (uintptr*)0x6ED5E0;
sRadarTrace (&CRadar::ms_RadarTrace)[NUMRADARBLIPS] = *(sRadarTrace(*)[NUMRADARBLIPS]) * (uintptr*)0x6ED5E0;
CVector2D &vec2DRadarOrigin = *(CVector2D*)0x6299B8;
int32 gRadarTxdIds[64];// = (int*)0x6299C0;
@ -87,6 +87,134 @@ int CRadar::TargetMarkerId = -1;
float CRadar::cachedCos;
float CRadar::cachedSin;
void ClipRadarTileCoords(int32 &x, int32 &y)
{
if (x < 0)
x = 0;
if (x > RADAR_NUM_TILES-1)
x = RADAR_NUM_TILES-1;
if (y < 0)
y = 0;
if (y > RADAR_NUM_TILES-1)
y = RADAR_NUM_TILES-1;
}
void RequestMapSection(int32 x, int32 y)
{
ClipRadarTileCoords(x, y);
CStreaming::RequestTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y], STREAMFLAGS_DONT_REMOVE | STREAMFLAGS_DEPENDENCY);
}
void RemoveMapSection(int32 x, int32 y)
{
if (x >= 0 && x <= 7 && y >= 0 && y <= 7)
CStreaming::RemoveTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y]);
}
// Transform from section indices to world coordinates
void GetTextureCorners(int32 x, int32 y, CVector2D *out)
{
x = x - RADAR_NUM_TILES/2;
y = -(y - RADAR_NUM_TILES/2);
// bottom left
out[0].x = RADAR_TILE_SIZE * (x);
out[0].y = RADAR_TILE_SIZE * (y - 1);
// bottom right
out[1].x = RADAR_TILE_SIZE * (x + 1);
out[1].y = RADAR_TILE_SIZE * (y - 1);
// top right
out[2].x = RADAR_TILE_SIZE * (x + 1);
out[2].y = RADAR_TILE_SIZE * (y);
// top left
out[3].x = RADAR_TILE_SIZE * (x);
out[3].y = RADAR_TILE_SIZE * (y);
}
bool IsPointInsideRadar(const CVector2D &point)
{
if (point.x < -1.0f || point.x > 1.0f) return false;
if (point.y < -1.0f || point.y > 1.0f) return false;
return true;
}
// clip line p1,p2 against (-1.0, 1.0) in x and y, set out to clipped point closest to p1
int LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D &p2)
{
float d1, d2;
float t;
float x, y;
float shortest = 1.0f;
int edge = -1;
// clip against left edge, x = -1.0
d1 = -1.0f - p1.x;
d2 = -1.0f - p2.x;
if (d1 * d2 < 0.0f) {
// they are on opposite sides, get point of intersection
t = d1 / (d1 - d2);
y = (p2.y - p1.y)*t + p1.y;
if (y >= -1.0f && y <= 1.0f && t <= shortest) {
out.x = -1.0f;
out.y = y;
edge = 3;
shortest = t;
}
}
// clip against right edge, x = 1.0
d1 = p1.x - 1.0f;
d2 = p2.x - 1.0f;
if (d1 * d2 < 0.0f) {
// they are on opposite sides, get point of intersection
t = d1 / (d1 - d2);
y = (p2.y - p1.y)*t + p1.y;
if (y >= -1.0f && y <= 1.0f && t <= shortest) {
out.x = 1.0f;
out.y = y;
edge = 1;
shortest = t;
}
}
// clip against top edge, y = -1.0
d1 = -1.0f - p1.y;
d2 = -1.0f - p2.y;
if (d1 * d2 < 0.0f) {
// they are on opposite sides, get point of intersection
t = d1 / (d1 - d2);
x = (p2.x - p1.x)*t + p1.x;
if (x >= -1.0f && x <= 1.0f && t <= shortest) {
out.y = -1.0f;
out.x = x;
edge = 0;
shortest = t;
}
}
// clip against bottom edge, y = 1.0
d1 = p1.y - 1.0f;
d2 = p2.y - 1.0f;
if (d1 * d2 < 0.0f) {
// they are on opposite sides, get point of intersection
t = d1 / (d1 - d2);
x = (p2.x - p1.x)*t + p1.x;
if (x >= -1.0f && x <= 1.0f && t <= shortest) {
out.y = 1.0f;
out.x = x;
edge = 2;
shortest = t;
}
}
return edge;
}
uint8 CRadar::CalculateBlipAlpha(float dist)
{
#ifdef MENU_MAP
@ -645,15 +773,14 @@ void CRadar::DrawRadarMask()
};
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDZERO);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwD3D8SetRenderState(rwRENDERSTATESTENCILFUNCTION, rwSTENCILFUNCTIONALWAYS);
CVector2D out[8];
CVector2D in;
@ -675,8 +802,6 @@ void CRadar::DrawRadarMask()
CSprite2d::SetMaskVertices(8, (float *)out);
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), 8);
};
RwD3D8SetRenderState(rwRENDERSTATESTENCILFUNCTION, rwSTENCILFUNCTIONGREATER);
}
void CRadar::DrawRadarSection(int32 x, int32 y)
@ -892,7 +1017,7 @@ INITSAVEBUF
CheckSaveHeader(buf, 'R', 'D', 'R', '\0', size - SAVE_HEADER_SIZE);
for (int i = 0; i < NUMRADARBLIPS; i++)
ms_RadarTrace[i] = ReadSaveBuf<CBlip>(buf);
ms_RadarTrace[i] = ReadSaveBuf<sRadarTrace>(buf);
VALIDATESAVEBUF(size);
}
@ -925,12 +1050,6 @@ CRadar::LoadTextures()
CTxdStore::PopCurrentTxd();
}
void RemoveMapSection(int32 x, int32 y)
{
if (x >= 0 && x <= 7 && y >= 0 && y <= 7)
CStreaming::RemoveTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y]);
}
void CRadar::RemoveRadarSections()
{
for (int i = 0; i < 8; i++)
@ -938,12 +1057,6 @@ void CRadar::RemoveRadarSections()
RemoveMapSection(i, j);
}
void CRadar::RequestMapSection(int32 x, int32 y)
{
ClipRadarTileCoords(x, y);
CStreaming::RequestTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y], STREAMFLAGS_DONT_REMOVE | STREAMFLAGS_DEPENDENCY);
}
void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size)
{
*size = SAVE_HEADER_SIZE + sizeof(ms_RadarTrace);
@ -1242,121 +1355,6 @@ void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D
out.y = c * y - s * x;
}
// Transform from section indices to world coordinates
void CRadar::GetTextureCorners(int32 x, int32 y, CVector2D *out)
{
x = x - RADAR_NUM_TILES/2;
y = -(y - RADAR_NUM_TILES/2);
// bottom left
out[0].x = RADAR_TILE_SIZE * (x);
out[0].y = RADAR_TILE_SIZE * (y - 1);
// bottom right
out[1].x = RADAR_TILE_SIZE * (x + 1);
out[1].y = RADAR_TILE_SIZE * (y - 1);
// top right
out[2].x = RADAR_TILE_SIZE * (x + 1);
out[2].y = RADAR_TILE_SIZE * (y);
// top left
out[3].x = RADAR_TILE_SIZE * (x);
out[3].y = RADAR_TILE_SIZE * (y);
}
void CRadar::ClipRadarTileCoords(int32 &x, int32 &y)
{
if (x < 0)
x = 0;
if (x > RADAR_NUM_TILES-1)
x = RADAR_NUM_TILES-1;
if (y < 0)
y = 0;
if (y > RADAR_NUM_TILES-1)
y = RADAR_NUM_TILES-1;
}
bool CRadar::IsPointInsideRadar(const CVector2D &point)
{
if (point.x < -1.0f || point.x > 1.0f) return false;
if (point.y < -1.0f || point.y > 1.0f) return false;
return true;
}
// clip line p1,p2 against (-1.0, 1.0) in x and y, set out to clipped point closest to p1
int CRadar::LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D &p2)
{
float d1, d2;
float t;
float x, y;
float shortest = 1.0f;
int edge = -1;
// clip against left edge, x = -1.0
d1 = -1.0f - p1.x;
d2 = -1.0f - p2.x;
if (d1 * d2 < 0.0f) {
// they are on opposite sides, get point of intersection
t = d1 / (d1 - d2);
y = (p2.y - p1.y)*t + p1.y;
if (y >= -1.0f && y <= 1.0f && t <= shortest) {
out.x = -1.0f;
out.y = y;
edge = 3;
shortest = t;
}
}
// clip against right edge, x = 1.0
d1 = p1.x - 1.0f;
d2 = p2.x - 1.0f;
if (d1 * d2 < 0.0f) {
// they are on opposite sides, get point of intersection
t = d1 / (d1 - d2);
y = (p2.y - p1.y)*t + p1.y;
if (y >= -1.0f && y <= 1.0f && t <= shortest) {
out.x = 1.0f;
out.y = y;
edge = 1;
shortest = t;
}
}
// clip against top edge, y = -1.0
d1 = -1.0f - p1.y;
d2 = -1.0f - p2.y;
if (d1 * d2 < 0.0f) {
// they are on opposite sides, get point of intersection
t = d1 / (d1 - d2);
x = (p2.x - p1.x)*t + p1.x;
if (x >= -1.0f && x <= 1.0f && t <= shortest) {
out.y = -1.0f;
out.x = x;
edge = 0;
shortest = t;
}
}
// clip against bottom edge, y = 1.0
d1 = p1.y - 1.0f;
d2 = p2.y - 1.0f;
if (d1 * d2 < 0.0f) {
// they are on opposite sides, get point of intersection
t = d1 / (d1 - d2);
x = (p2.x - p1.x)*t + p1.x;
if (x >= -1.0f && x <= 1.0f && t <= shortest) {
out.y = 1.0f;
out.x = x;
edge = 2;
shortest = t;
}
}
return edge;
}
void
CRadar::CalculateCachedSinCos()
{
@ -1488,8 +1486,14 @@ STARTPATCHES
InjectHook(0x4A5C60, CRadar::SetRadarMarkerState, PATCH_JUMP);
InjectHook(0x4A5D10, CRadar::DrawRotatingRadarSprite, PATCH_JUMP);
InjectHook(0x4A5EF0, CRadar::DrawRadarSprite, PATCH_JUMP);
InjectHook(0x4A6020, ClipRadarTileCoords, PATCH_JUMP);
InjectHook(0x4A6060, RequestMapSection, PATCH_JUMP);
InjectHook(0x4A60A0, RemoveMapSection, PATCH_JUMP);
InjectHook(0x4A60E0, CRadar::RemoveRadarSections, PATCH_JUMP);
InjectHook(0x4A6100, (void (*)(int32, int32))&CRadar::StreamRadarSections, PATCH_JUMP);
InjectHook(0x4A6160, IsPointInsideRadar, PATCH_JUMP);
InjectHook(0x4A61C0, GetTextureCorners, PATCH_JUMP);
InjectHook(0x4A6250, LineRadarBoxCollision, PATCH_JUMP);
InjectHook(0x4A64A0, CRadar::ClipRadarPoly, PATCH_JUMP);
InjectHook(0x4A67E0, CRadar::DrawRadarSection, PATCH_JUMP);
InjectHook(0x4A69C0, CRadar::DrawRadarMask, PATCH_JUMP);
@ -1497,8 +1501,6 @@ STARTPATCHES
InjectHook(0x4A6C20, CRadar::DrawRadarMap, PATCH_JUMP);
InjectHook(0x4A6E30, CRadar::SaveAllRadarBlips, PATCH_JUMP);
InjectHook(0x4A6F30, CRadar::LoadAllRadarBlips, PATCH_JUMP);
InjectHook(0x4A61C0, CRadar::GetTextureCorners, PATCH_JUMP);
InjectHook(0x4A6160, CRadar::IsPointInsideRadar, PATCH_JUMP);
InjectHook(0x4A6250, CRadar::LineRadarBoxCollision, PATCH_JUMP);
//InjectHook(0x4A7000, `global constructor keyed to'Radar.cpp, PATCH_JUMP);
//InjectHook(0x4A7260, sRadarTrace::sRadarTrace, PATCH_JUMP);
ENDPATCHES

View File

@ -56,7 +56,7 @@ enum
BLIP_MODE_SQUARE,
};
struct CBlip
struct sRadarTrace
{
uint32 m_nColor;
uint32 m_eBlipType; // eBlipType
@ -71,7 +71,7 @@ struct CBlip
uint16 m_eBlipDisplay; // eBlipDisplay
uint16 m_eRadarSprite; // eRadarSprite
};
static_assert(sizeof(CBlip) == 0x30, "CBlip: error");
static_assert(sizeof(sRadarTrace) == 0x30, "sRadarTrace: error");
// Values for screen space
#define RADAR_LEFT (40.0f)
@ -83,7 +83,7 @@ class CRadar
{
public:
static float &m_radarRange;
static CBlip (&ms_RadarTrace)[NUMRADARBLIPS];
static sRadarTrace (&ms_RadarTrace)[NUMRADARBLIPS];
static CSprite2d AsukaSprite;
static CSprite2d BombSprite;
static CSprite2d CatSprite;
@ -144,7 +144,6 @@ public:
static void LoadAllRadarBlips(uint8 *buf, uint32 size);
static void LoadTextures();
static void RemoveRadarSections();
static void RequestMapSection(int32 x, int32 y);
static void SaveAllRadarBlips(uint8*, uint32*);
static void SetBlipSprite(int32 i, int32 icon);
static int32 SetCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay);
@ -162,9 +161,5 @@ public:
static void TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in);
// no in CRadar in the game:
static void GetTextureCorners(int32 x, int32 y, CVector2D *out);
static void ClipRadarTileCoords(int32 &x, int32 &y);
static bool IsPointInsideRadar(const CVector2D &);
static int LineRadarBoxCollision(CVector2D &, const CVector2D &, const CVector2D &);
static void CalculateCachedSinCos();
};

View File

@ -347,13 +347,6 @@ CameraCreate(RwInt32 width, RwInt32 height, RwBool zBuffer)
return (nil);
}
WRAPPER void ReadVideoCardCapsFile(uint32&, uint32&, uint32&, uint32&) { EAXJMP(0x5926C0); }
WRAPPER bool CheckVideoCardCaps(void) { EAXJMP(0x592740); }
WRAPPER void WriteVideoCardCapsFile(void) { EAXJMP(0x5927D0); }
WRAPPER void ConvertingTexturesScreen(uint32, uint32, const char*) { EAXJMP(0x592880); }
WRAPPER void DealWithTxdWriteError(uint32, uint32, const char*) { EAXJMP(0x592BF0); }
WRAPPER bool CreateTxdImageForVideoCard() { EAXJMP(0x592C70); }
void CreateDebugFont()
{
;

View File

@ -3,10 +3,24 @@
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#pragma warning( pop )
#define WITHWINDOWS
#include "common.h"
#include "win.h"
#include "patcher.h"
#include "Timer.h"
#ifdef GTA_PC
#include "FileMgr.h"
#include "Pad.h"
#include "main.h"
#include "Directory.h"
#include "Streaming.h"
#include "TxdStore.h"
#include "CdStream.h"
#include "Font.h"
#include "Sprite2d.h"
#include "Text.h"
#include "RwHelper.h"
#endif //GTA_PC
float &texLoadTime = *(float*)0x8F1B50;
int32 &texNumLoaded = *(int32*)0x8F252C;
@ -132,9 +146,198 @@ RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict)
return texDict;
}
#ifdef GTA_PC
WRAPPER RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags) { EAXJMP(0x59A350); }
void
ReadVideoCardCapsFile(uint32 &cap32, uint32 &cap24, uint32 &cap16, uint32 &cap8)
{
cap32 = UINT32_MAX;
cap24 = UINT32_MAX;
cap16 = UINT32_MAX;
cap8 = UINT32_MAX;
int32 file = CFileMgr::OpenFile("DATA\\CAPS.DAT", "rb");
if (file != 0) {
CFileMgr::Read(file, (char*)&cap32, 4);
CFileMgr::Read(file, (char*)&cap24, 4);
CFileMgr::Read(file, (char*)&cap16, 4);
CFileMgr::Read(file, (char*)&cap8, 4);
CFileMgr::CloseFile(file);
}
}
bool
CheckVideoCardCaps(void)
{
uint32 cap32 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT8888);
uint32 cap24 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT888);
uint32 cap16 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT1555);
uint32 cap8 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMATPAL8 | rwRASTERFORMAT8888);
uint32 fcap32, fcap24, fcap16, fcap8;
ReadVideoCardCapsFile(fcap32, fcap24, fcap16, fcap8);
return cap32 != fcap32 || cap24 != fcap24 || cap16 != fcap16 || cap8 != fcap8;
}
void
WriteVideoCardCapsFile(void)
{
uint32 cap32 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT8888);
uint32 cap24 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT888);
uint32 cap16 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT1555);
uint32 cap8 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMATPAL8 | rwRASTERFORMAT8888);
int32 file = CFileMgr::OpenFile("DATA\\CAPS.DAT", "wb");
if (file != 0) {
CFileMgr::Write(file, (char*)&cap32, 4);
CFileMgr::Write(file, (char*)&cap24, 4);
CFileMgr::Write(file, (char*)&cap16, 4);
CFileMgr::Write(file, (char*)&cap8, 4);
CFileMgr::CloseFile(file);
}
}
bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
void DoRWStuffEndOfFrame(void);
void
ConvertingTexturesScreen(uint32 num, uint32 count, const char *text)
{
HandleExit();
CSprite2d *splash = LoadSplash(nil);
if (!DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255))
return;
CSprite2d::SetRecipNearClip();
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
DefinedState();
RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), SCREEN_SCALE_FROM_RIGHT(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(64, 64, 64, 255));
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), (SCREEN_SCALE_FROM_RIGHT(200.0f) - SCREEN_SCALE_X(200.0f)) * ((float)num / (float)count) + SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(255, 217, 106, 255));
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(120.0f), SCREEN_SCALE_Y(150.0f), SCREEN_SCALE_FROM_RIGHT(120.0f), SCREEN_HEIGHT - SCREEN_SCALE_Y(220.0f)), CRGBA(50, 50, 50, 210));
CFont::SetBackgroundOff();
CFont::SetPropOn();
CFont::SetScale(SCREEN_SCALE_X(0.45f), SCREEN_SCALE_Y(0.7f));
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(170.0f));
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(255, 217, 106, 255));
CFont::SetBackGroundOnlyTextOff();
CFont::SetFontStyle(FONT_BANK);
CFont::PrintString(SCREEN_SCALE_X(170.0f), SCREEN_SCALE_Y(160.0f), TheText.Get(text));
CFont::DrawFonts();
DoRWStuffEndOfFrame();
}
void
DealWithTxdWriteError(uint32 num, uint32 count, const char *text)
{
while (!RsGlobal.quit) {
ConvertingTexturesScreen(num, count, text);
CPad::UpdatePads();
if (CPad::GetPad(0)->GetEscapeJustDown())
break;
}
RsGlobal.quit = false;
LoadingScreen(nil, nil, nil);
RsGlobal.quit = true;
}
bool
CreateTxdImageForVideoCard()
{
uint8 *buf = new uint8[CDSTREAM_SECTOR_SIZE];
CDirectory *pDir = new CDirectory(TXDSTORESIZE);
CDirectory::DirectoryInfo dirInfo;
CStreaming::FlushRequestList();
RwFileFunctions *filesys = RwOsGetFileInterface();
RwStream *img = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMWRITE, "models\\txd.img");
if (img == nil) {
if (_dwOperatingSystemVersion == OS_WINNT || _dwOperatingSystemVersion == OS_WIN2000 || _dwOperatingSystemVersion == OS_WINXP) {
DealWithTxdWriteError(0, TXDSTORESIZE, "CVT_CRT");
delete []buf;
delete pDir;
}
return false;
}
int32 i;
for (i = 0; i < TXDSTORESIZE; i++) {
ConvertingTexturesScreen(i, TXDSTORESIZE, "CVT_MSG");
if (CTxdStore::GetSlot(i) != nil && CStreaming::IsObjectInCdImage(i + STREAM_OFFSET_TXD)) {
CStreaming::RequestTxd(i, STREAMFLAGS_KEEP_IN_MEMORY);
CStreaming::RequestModelStream(0);
CStreaming::FlushChannels();
char filename[64];
sprintf(filename, "%s.txd", CTxdStore::GetTxdName(i));
if (CTxdStore::GetSlot(i)->texDict) {
int32 pos = filesys->rwftell(img->Type.file.fpFile);
if (RwTexDictionaryStreamWrite(CTxdStore::GetSlot(i)->texDict, img) == nil) {
DealWithTxdWriteError(i, TXDSTORESIZE, "CVT_ERR");
RwStreamClose(img, nil);
delete []buf;
delete pDir;
CStreaming::RemoveTxd(i);
return false;
}
int32 size = filesys->rwftell(img->Type.file.fpFile) - pos;
int32 num = size % CDSTREAM_SECTOR_SIZE;
size /= CDSTREAM_SECTOR_SIZE;
if (num != 0) {
size++;
num = CDSTREAM_SECTOR_SIZE - num;
RwStreamWrite(img, buf, num);
}
dirInfo.offset = pos / CDSTREAM_SECTOR_SIZE;
dirInfo.size = size;
strncpy(dirInfo.name, filename, sizeof(dirInfo.name));
pDir->AddItem(dirInfo);
CStreaming::RemoveTxd(i);
}
CStreaming::FlushRequestList();
}
}
RwStreamClose(img, nil);
delete []buf;
if (!pDir->WriteDirFile("models\\txd.dir")) {
DealWithTxdWriteError(i, TXDSTORESIZE, "CVT_ERR");
delete pDir;
return false;
}
delete pDir;
WriteVideoCardCapsFile();
return true;
}
#endif // GTA_PC
STARTPATCHES
InjectHook(0x592380, RwTextureGtaStreamRead, PATCH_JUMP);
InjectHook(0x5924A0, RwTexDictionaryGtaStreamRead, PATCH_JUMP);
InjectHook(0x592550, RwTexDictionaryGtaStreamRead1, PATCH_JUMP);
InjectHook(0x592650, RwTexDictionaryGtaStreamRead2, PATCH_JUMP);
InjectHook(0x5926C0, ReadVideoCardCapsFile, PATCH_JUMP);
InjectHook(0x592740, CheckVideoCardCaps, PATCH_JUMP);
InjectHook(0x5927D0, WriteVideoCardCapsFile, PATCH_JUMP);
InjectHook(0x592880, ConvertingTexturesScreen, PATCH_JUMP);
InjectHook(0x592BF0, DealWithTxdWriteError, PATCH_JUMP);
InjectHook(0x592C70, CreateTxdImageForVideoCard, PATCH_JUMP);
ENDPATCHES

View File

@ -1,14 +1,14 @@
#include "common.h"
#include "patcher.h"
#include "Stats.h"
WRAPPER void CStats::SaveStats(uint8 *buf, uint32 *size) { EAXJMP(0x4ab3e0); }
#include "Text.h"
#include "World.h"
int32 &CStats::DaysPassed = *(int32*)0x8F2BB8;
int32 &CStats::HeadsPopped = *(int32*)0x8F647C;
bool& CStats::CommercialPassed = *(bool*)0x8F4334;
bool& CStats::IndustrialPassed = *(bool*)0x8E2A68;
bool& CStats::SuburbanPassed = *(bool*)0x8F2740;
int32& CStats::CommercialPassed = *(int32*)0x8F4334;
int32& CStats::IndustrialPassed = *(int32*)0x8E2A68;
int32& CStats::SuburbanPassed = *(int32*)0x8F2740;
int32 &CStats::NumberKillFrenziesPassed = *(int32*)0x8E287C;
int32 &CStats::PeopleKilledByOthers = *(int32*)0x8E2C50;
int32 &CStats::HelisDestroyed = *(int32*)0x8E2A64;
@ -48,7 +48,7 @@ int32& CStats::LongestFlightInDodo = *(int32*)0x8F5FE4;
int32& CStats::TimeTakenDefuseMission = *(int32*)0x880E24;
int32& CStats::TotalNumberKillFrenzies = *(int32*)0x8E2884;
int32& CStats::TotalNumberMissions = *(int32*)0x8E2820;
int32& CStats::ShotsMade = *(int32*)0x8E2BE8;
int32& CStats::RoundsFiredByPlayer = *(int32*)0x8E2BE8;
int32& CStats::KgsOfExplosivesUsed = *(int32*)0x8F2510;
int32& CStats::InstantHitsFiredByPlayer = *(int32*)0x943070;
int32& CStats::InstantHitsHitByPlayer = *(int32*)0x95CB8C;
@ -62,7 +62,7 @@ void CStats::Init()
{
PeopleKilledByOthers = 0;
PeopleKilledByPlayer = 0;
ShotsMade = 0;
RoundsFiredByPlayer = 0;
CarsExploded = 0;
HelisDestroyed = 0;
ProgressMade = 0;
@ -200,6 +200,229 @@ void CStats::SetTotalNumberMissions(int32 total)
TotalNumberMissions = total;
}
wchar *CStats::FindCriminalRatingString()
{
int rating = FindCriminalRatingNumber();
if (rating < 10) return TheText.Get("RATNG1");
if (rating < 25) return TheText.Get("RATNG2");
if (rating < 70) return TheText.Get("RATNG3");
if (rating < 150) return TheText.Get("RATNG4");
if (rating < 250) return TheText.Get("RATNG5");
if (rating < 450) return TheText.Get("RATNG6");
if (rating < 700) return TheText.Get("RATNG7");
if (rating < 1000) return TheText.Get("RATNG8");
if (rating < 1400) return TheText.Get("RATNG9");
if (rating < 1900) return TheText.Get("RATNG10");
if (rating < 2500) return TheText.Get("RATNG11");
if (rating < 3200) return TheText.Get("RATNG12");
if (rating < 4000) return TheText.Get("RATNG13");
if (rating < 5000) return TheText.Get("RATNG14");
return TheText.Get("RATNG15");
}
int32 CStats::FindCriminalRatingNumber()
{
int32 rating;
rating = FiresExtinguished + 10 * HighestLevelAmbulanceMission + CriminalsCaught + LivesSavedWithAmbulance
+ 30 * HelisDestroyed + TotalLegitimateKills - 3 * TimesArrested - 3 * TimesDied
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney / 5000;
if (rating <= 0) rating = 0;
if (InstantHitsFiredByPlayer > 100)
rating += (float)CStats::InstantHitsHitByPlayer / (float)CStats::InstantHitsFiredByPlayer * 500.0f;
if (TotalProgressInGame)
rating += (float)CStats::ProgressMade / (float)CStats::TotalProgressInGame * 1000.0f;
if (!IndustrialPassed && rating >= 3521)
rating = 3521;
if (!CommercialPassed && rating >= 4552)
rating = 4552;
return rating;
}
void CStats::SaveStats(uint8 *buf, uint32 *size)
{
CheckPointReachedSuccessfully();
uint8 *buf_start = buf;
*size = sizeof(PeopleKilledByPlayer) +
sizeof(PeopleKilledByOthers) +
sizeof(CarsExploded) +
sizeof(RoundsFiredByPlayer) +
sizeof(PedsKilledOfThisType) +
sizeof(HelisDestroyed) +
sizeof(ProgressMade) +
sizeof(TotalProgressInGame) +
sizeof(KgsOfExplosivesUsed) +
sizeof(InstantHitsFiredByPlayer) +
sizeof(InstantHitsHitByPlayer) +
sizeof(CarsCrushed) +
sizeof(HeadsPopped) +
sizeof(TimesArrested) +
sizeof(TimesDied) +
sizeof(DaysPassed) +
sizeof(mmRain) +
sizeof(MaximumJumpDistance) +
sizeof(MaximumJumpHeight) +
sizeof(MaximumJumpFlips) +
sizeof(MaximumJumpSpins) +
sizeof(BestStuntJump) +
sizeof(NumberOfUniqueJumpsFound) +
sizeof(TotalNumberOfUniqueJumps) +
sizeof(MissionsGiven) +
sizeof(MissionsPassed) +
sizeof(PassengersDroppedOffWithTaxi) +
sizeof(MoneyMadeWithTaxi) +
sizeof(IndustrialPassed) +
sizeof(CommercialPassed) +
sizeof(SuburbanPassed) +
sizeof(ElBurroTime) +
sizeof(DistanceTravelledOnFoot) +
sizeof(DistanceTravelledInVehicle) +
sizeof(Record4x4One) +
sizeof(Record4x4Two) +
sizeof(Record4x4Three) +
sizeof(Record4x4Mayhem) +
sizeof(LivesSavedWithAmbulance) +
sizeof(CriminalsCaught) +
sizeof(HighestLevelAmbulanceMission) +
sizeof(FiresExtinguished) +
sizeof(LongestFlightInDodo) +
sizeof(TimeTakenDefuseMission) +
sizeof(NumberKillFrenziesPassed) +
sizeof(TotalNumberKillFrenzies) +
sizeof(TotalNumberMissions) +
sizeof(FastestTimes) +
sizeof(HighestScores) +
sizeof(KillsSinceLastCheckpoint) +
sizeof(TotalLegitimateKills) +
sizeof(LastMissionPassedName);
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data);
CopyToBuf(buf, PeopleKilledByPlayer);
CopyToBuf(buf, PeopleKilledByOthers);
CopyToBuf(buf, CarsExploded);
CopyToBuf(buf, RoundsFiredByPlayer);
CopyToBuf(buf, PedsKilledOfThisType);
CopyToBuf(buf, HelisDestroyed);
CopyToBuf(buf, ProgressMade);
CopyToBuf(buf, TotalProgressInGame);
CopyToBuf(buf, KgsOfExplosivesUsed);
CopyToBuf(buf, InstantHitsFiredByPlayer);
CopyToBuf(buf, InstantHitsHitByPlayer);
CopyToBuf(buf, CarsCrushed);
CopyToBuf(buf, HeadsPopped);
CopyToBuf(buf, TimesArrested);
CopyToBuf(buf, TimesDied);
CopyToBuf(buf, DaysPassed);
CopyToBuf(buf, mmRain);
CopyToBuf(buf, MaximumJumpDistance);
CopyToBuf(buf, MaximumJumpHeight);
CopyToBuf(buf, MaximumJumpFlips);
CopyToBuf(buf, MaximumJumpSpins);
CopyToBuf(buf, BestStuntJump);
CopyToBuf(buf, NumberOfUniqueJumpsFound);
CopyToBuf(buf, TotalNumberOfUniqueJumps);
CopyToBuf(buf, MissionsGiven);
CopyToBuf(buf, MissionsPassed);
CopyToBuf(buf, PassengersDroppedOffWithTaxi);
CopyToBuf(buf, MoneyMadeWithTaxi);
CopyToBuf(buf, IndustrialPassed);
CopyToBuf(buf, CommercialPassed);
CopyToBuf(buf, SuburbanPassed);
CopyToBuf(buf, ElBurroTime);
CopyToBuf(buf, DistanceTravelledOnFoot);
CopyToBuf(buf, DistanceTravelledInVehicle);
CopyToBuf(buf, Record4x4One);
CopyToBuf(buf, Record4x4Two);
CopyToBuf(buf, Record4x4Three);
CopyToBuf(buf, Record4x4Mayhem);
CopyToBuf(buf, LivesSavedWithAmbulance);
CopyToBuf(buf, CriminalsCaught);
CopyToBuf(buf, HighestLevelAmbulanceMission);
CopyToBuf(buf, FiresExtinguished);
CopyToBuf(buf, LongestFlightInDodo);
CopyToBuf(buf, TimeTakenDefuseMission);
CopyToBuf(buf, NumberKillFrenziesPassed);
CopyToBuf(buf, TotalNumberKillFrenzies);
CopyToBuf(buf, TotalNumberMissions);
CopyToBuf(buf, FastestTimes);
CopyToBuf(buf, HighestScores);
CopyToBuf(buf, KillsSinceLastCheckpoint);
CopyToBuf(buf, TotalLegitimateKills);
CopyToBuf(buf, LastMissionPassedName);
assert(buf - buf_start == *size);
#undef CopyToBuf
}
void CStats::LoadStats(uint8 *buf, uint32 size)
{
uint8* buf_start = buf;
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data);
CopyFromBuf(buf, PeopleKilledByPlayer);
CopyFromBuf(buf, PeopleKilledByOthers);
CopyFromBuf(buf, CarsExploded);
CopyFromBuf(buf, RoundsFiredByPlayer);
CopyFromBuf(buf, PedsKilledOfThisType);
CopyFromBuf(buf, HelisDestroyed);
CopyFromBuf(buf, ProgressMade);
CopyFromBuf(buf, TotalProgressInGame);
CopyFromBuf(buf, KgsOfExplosivesUsed);
CopyFromBuf(buf, InstantHitsFiredByPlayer);
CopyFromBuf(buf, InstantHitsHitByPlayer);
CopyFromBuf(buf, CarsCrushed);
CopyFromBuf(buf, HeadsPopped);
CopyFromBuf(buf, TimesArrested);
CopyFromBuf(buf, TimesDied);
CopyFromBuf(buf, DaysPassed);
CopyFromBuf(buf, mmRain);
CopyFromBuf(buf, MaximumJumpDistance);
CopyFromBuf(buf, MaximumJumpHeight);
CopyFromBuf(buf, MaximumJumpFlips);
CopyFromBuf(buf, MaximumJumpSpins);
CopyFromBuf(buf, BestStuntJump);
CopyFromBuf(buf, NumberOfUniqueJumpsFound);
CopyFromBuf(buf, TotalNumberOfUniqueJumps);
CopyFromBuf(buf, MissionsGiven);
CopyFromBuf(buf, MissionsPassed);
CopyFromBuf(buf, PassengersDroppedOffWithTaxi);
CopyFromBuf(buf, MoneyMadeWithTaxi);
CopyFromBuf(buf, IndustrialPassed);
CopyFromBuf(buf, CommercialPassed);
CopyFromBuf(buf, SuburbanPassed);
CopyFromBuf(buf, ElBurroTime);
CopyFromBuf(buf, DistanceTravelledOnFoot);
CopyFromBuf(buf, DistanceTravelledInVehicle);
CopyFromBuf(buf, Record4x4One);
CopyFromBuf(buf, Record4x4Two);
CopyFromBuf(buf, Record4x4Three);
CopyFromBuf(buf, Record4x4Mayhem);
CopyFromBuf(buf, LivesSavedWithAmbulance);
CopyFromBuf(buf, CriminalsCaught);
CopyFromBuf(buf, HighestLevelAmbulanceMission);
CopyFromBuf(buf, FiresExtinguished);
CopyFromBuf(buf, LongestFlightInDodo);
CopyFromBuf(buf, TimeTakenDefuseMission);
CopyFromBuf(buf, NumberKillFrenziesPassed);
CopyFromBuf(buf, TotalNumberKillFrenzies);
CopyFromBuf(buf, TotalNumberMissions);
CopyFromBuf(buf, FastestTimes);
CopyFromBuf(buf, HighestScores);
CopyFromBuf(buf, KillsSinceLastCheckpoint);
CopyFromBuf(buf, TotalLegitimateKills);
CopyFromBuf(buf, LastMissionPassedName);
assert(buf - buf_start == size);
#undef CopyFromBuf
}
STARTPATCHES
InjectHook(0x48C5A3, CStats::Init, PATCH_JUMP); // CGame::ReInitGameObjectVariables
InjectHook(0x4AB3E0, CStats::SaveStats, PATCH_JUMP);
InjectHook(0x4AB670, CStats::LoadStats, PATCH_JUMP);
InjectHook(0x4AB090, CStats::FindCriminalRatingString, PATCH_JUMP);
InjectHook(0x4AB2A0, CStats::FindCriminalRatingNumber, PATCH_JUMP);
ENDPATCHES

View File

@ -11,9 +11,9 @@ public:
};
static int32 &DaysPassed;
static int32 &HeadsPopped;
static bool& CommercialPassed;
static bool& IndustrialPassed;
static bool& SuburbanPassed;
static int32& CommercialPassed;
static int32& IndustrialPassed;
static int32& SuburbanPassed;
static int32 &NumberKillFrenziesPassed;
static int32 &PeopleKilledByOthers;
static int32 &HelisDestroyed;
@ -53,7 +53,7 @@ public:
static int32 &TimeTakenDefuseMission;
static int32 &TotalNumberKillFrenzies;
static int32 &TotalNumberMissions;
static int32 &ShotsMade;
static int32 &RoundsFiredByPlayer;
static int32 &KgsOfExplosivesUsed;
static int32 &InstantHitsFiredByPlayer;
static int32 &InstantHitsHitByPlayer;
@ -64,24 +64,27 @@ public:
static int32(&HighestScores)[TOTAL_HIGHEST_SCORES];
public:
static void Init(void);
static void RegisterFastestTime(int32, int32);
static void RegisterHighestScore(int32, int32);
static void AnotherKillFrenzyPassed();
static void AnotherLifeSavedWithAmbulance();
static void AnotherCriminalCaught();
static void RegisterLevelAmbulanceMission(int32);
static void AnotherFireExtinguished();
static void RegisterElBurroTime(int32);
static void Register4x4OneTime(int32);
static void Register4x4TwoTime(int32);
static void Register4x4ThreeTime(int32);
static void Register4x4MayhemTime(int32);
static void AnotherLifeSavedWithAmbulance();
static void AnotherCriminalCaught();
static void RegisterLevelAmbulanceMission(int32);
static void AnotherFireExtinguished();
static wchar *FindCriminalRatingString();
static void RegisterLongestFlightInDodo(int32);
static void RegisterTimeTakenDefuseMission(int32);
static void AnotherKillFrenzyPassed();
static void SetTotalNumberKillFrenzies(int32);
static void SetTotalNumberMissions(int32);
static void CheckPointReachedUnsuccessfully() { KillsSinceLastCheckpoint = 0; };
static void CheckPointReachedSuccessfully() { TotalLegitimateKills += KillsSinceLastCheckpoint; KillsSinceLastCheckpoint = 0; };
static void RegisterElBurroTime(int32);
static void CheckPointReachedUnsuccessfully() { KillsSinceLastCheckpoint = 0; };
static int32 FindCriminalRatingNumber();
static void SaveStats(uint8 *buf, uint32 *size);
static void Init(void);
static void LoadStats(uint8 *buf, uint32 size);
};

View File

@ -56,6 +56,8 @@ WRAPPER void CWorld::FindMissionEntitiesIntersectingCube(const CVector&, const C
WRAPPER void CWorld::ClearCarsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B50E0); }
WRAPPER void CWorld::ClearPedsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B52B0); }
WRAPPER void CWorld::CallOffChaseForArea(float, float, float, float) { EAXJMP(0x4B5530); }
WRAPPER void CWorld::TriggerExplosion(const CVector& a1, float a2, float a3, CEntity *a4, bool a5) { EAXJMP(0x4B1140); }
WRAPPER void CWorld::SetPedsOnFire(float, float, float, float, CEntity*) { EAXJMP(0x4B3D30); }
void
CWorld::Initialise()

View File

@ -132,6 +132,7 @@ public:
static void SetAllCarsCanBeDamaged(bool);
static void ExtinguishAllCarFiresInArea(CVector, float);
static void SetCarsOnFire(float, float, float, float, CEntity*);
static void SetPedsOnFire(float, float, float, float, CEntity*);
static void Initialise();
static void AddParticles();
@ -140,6 +141,7 @@ public:
static void RepositionCertainDynamicObjects();
static void RemoveStaticObjects();
static void Process();
static void TriggerExplosion(const CVector &, float, float, CEntity*, bool);
};
extern CColPoint *gaTempSphereColPoints;

View File

@ -84,12 +84,14 @@ extern void **rwengine;
#define DEFAULT_SCREEN_WIDTH (640)
#define DEFAULT_SCREEN_HEIGHT (448)
#define DEFAULT_ASPECT_RATIO (4.0f/3.0f)
#define DEFAULT_VIEWWINDOW (0.7f)
// game uses maximumWidth/Height, but this probably won't work
// with RW windowed mode
#define SCREEN_WIDTH ((float)RsGlobal.width)
#define SCREEN_HEIGHT ((float)RsGlobal.height)
#define SCREEN_ASPECT_RATIO (CDraw::GetAspectRatio())
#define SCREEN_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetFOV() * 0.5f)))
// This scales from PS2 pixel coordinates to the real resolution
#define SCREEN_STRETCH_X(a) ((a) * (float) SCREEN_WIDTH / DEFAULT_SCREEN_WIDTH)
@ -105,10 +107,8 @@ extern void **rwengine;
#ifdef ASPECT_RATIO_SCALE
#define SCREEN_SCALE_AR(a) ((a) * DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO)
#define SCREEN_SCALE_AR2(a) ((a) / (DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO))
#else
#define SCREEN_SCALE_AR(a) (a)
#define SCREEN_SCALE_AR2(a) (a)
#endif
#include "maths.h"

View File

@ -79,6 +79,7 @@ enum Config {
NUMPICKUPMESSAGES = 16,
NUMBULLETTRACES = 16,
NUMMBLURSTREAKS = 4,
NUMSKIDMARKS = 32,
NUMONSCREENTIMERENTRIES = 1,
NUMRADARBLIPS = 32,
@ -125,7 +126,9 @@ enum Config {
NUM_GARAGE_STORED_CARS = 6,
NUM_CRANES = 8
NUM_CRANES = 8,
NUM_EXPLOSIONS = 48,
};
// We'll use this once we're ready to become independent of the game
@ -150,6 +153,7 @@ enum Config {
//#define MASTER
#if defined GTA_PS2
# define GTA_PS2_STUFF
# define RANDOMSPLASH
#elif defined GTA_PC
# define GTA3_1_1_PATCH

File diff suppressed because it is too large Load Diff

View File

@ -275,9 +275,9 @@ CEntity::CreateRwObject(void)
if(IsBuilding())
gBuildings++;
if(RwObjectGetType(m_rwObject) == rpATOMIC)
m_matrix.AttachRW(RwFrameGetMatrix(RpAtomicGetFrame(m_rwObject)), false);
m_matrix.AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false);
else if(RwObjectGetType(m_rwObject) == rpCLUMP)
m_matrix.AttachRW(RwFrameGetMatrix(RpClumpGetFrame(m_rwObject)), false);
m_matrix.AttachRW(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false);
mi->AddRef();
}
}
@ -290,7 +290,7 @@ CEntity::DeleteRwObject(void)
m_matrix.Detach();
if(m_rwObject){
if(RwObjectGetType(m_rwObject) == rpATOMIC){
f = RpAtomicGetFrame(m_rwObject);
f = RpAtomicGetFrame((RpAtomic*)m_rwObject);
RpAtomicDestroy((RpAtomic*)m_rwObject);
RwFrameDestroy(f);
}else if(RwObjectGetType(m_rwObject) == rpCLUMP)
@ -307,9 +307,9 @@ CEntity::UpdateRwFrame(void)
{
if(m_rwObject){
if(RwObjectGetType(m_rwObject) == rpATOMIC)
RwFrameUpdateObjects(RpAtomicGetFrame(m_rwObject));
RwFrameUpdateObjects(RpAtomicGetFrame((RpAtomic*)m_rwObject));
else if(RwObjectGetType(m_rwObject) == rpCLUMP)
RwFrameUpdateObjects(RpClumpGetFrame(m_rwObject));
RwFrameUpdateObjects(RpClumpGetFrame((RpClump*)m_rwObject));
}
}
@ -482,9 +482,9 @@ CEntity::AttachToRwObject(RwObject *obj)
m_rwObject = obj;
if(m_rwObject){
if(RwObjectGetType(m_rwObject) == rpATOMIC)
m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame(m_rwObject)), false);
m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false);
else if(RwObjectGetType(m_rwObject) == rpCLUMP)
m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame(m_rwObject)), false);
m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false);
CModelInfo::GetModelInfo(m_modelIndex)->AddRef();
}
}

View File

@ -216,7 +216,7 @@ CPedModelInfo::AnimatePedColModel(CColModel* colmodel, RwFrame* frame)
RwMatrixCopy(mat, RwFrameGetMatrix(f));
for (f = RwFrameGetParent(f); f; f = RwFrameGetParent(f)) {
RwMatrixTransform(mat, &f->modelling, rwCOMBINEPOSTCONCAT);
RwMatrixTransform(mat, RwFrameGetMatrix(f), rwCOMBINEPOSTCONCAT);
if (RwFrameGetParent(f) == frame)
break;
}

View File

@ -707,7 +707,7 @@ RpMaterial*
CVehicleModelInfo::GetEditableMaterialListCB(RpMaterial *material, void *data)
{
static RwRGBA white = { 255, 255, 255, 255 };
RwRGBA *col;
const RwRGBA *col;
editableMatCBData *cbdata;
cbdata = (editableMatCBData*)data;
@ -758,8 +758,8 @@ CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2)
col = ms_vehicleColourTable[c1];
coltex = ms_colourTextureTable[c1];
for(matp = m_materials1; *matp; matp++){
if(RpMaterialGetTexture(*matp) && RpMaterialGetTexture(*matp)->name[0] != '@'){
colp = RpMaterialGetColor(*matp);
if(RpMaterialGetTexture(*matp) && RwTextureGetName(RpMaterialGetTexture(*matp))[0] != '@'){
colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
colp->red = col.red;
colp->green = col.green;
colp->blue = col.blue;
@ -773,8 +773,8 @@ CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2)
col = ms_vehicleColourTable[c2];
coltex = ms_colourTextureTable[c2];
for(matp = m_materials2; *matp; matp++){
if(RpMaterialGetTexture(*matp) && RpMaterialGetTexture(*matp)->name[0] != '@'){
colp = RpMaterialGetColor(*matp);
if(RpMaterialGetTexture(*matp) && RwTextureGetName(RpMaterialGetTexture(*matp))[0] != '@'){
colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
colp->red = col.red;
colp->green = col.green;
colp->blue = col.blue;
@ -861,7 +861,7 @@ CreateCarColourTexture(uint8 r, uint8 g, uint8 b)
RwImageDestroy(img);
RwFree(pixels);
tex = RwTextureCreate(ras);
tex->name[0] = '@';
RwTextureGetName(tex)[0] = '@';
return tex;
}
@ -1058,7 +1058,7 @@ CVehicleModelInfo::LoadEnvironmentMaps(void)
}
if(gpWhiteTexture == nil){
gpWhiteTexture = RwTextureRead("white", nil);
gpWhiteTexture->name[0] = '@';
RwTextureGetName(gpWhiteTexture)[0] = '@';
RwTextureSetFilterMode(gpWhiteTexture, rwFILTERLINEAR);
}
CTxdStore::PopCurrentTxd();

View File

@ -20,7 +20,7 @@ CCutsceneHead::CCutsceneHead(CObject *obj)
m_pHeadNode = RpAnimBlendClumpFindFrame((RpClump*)obj->m_rwObject, "Shead")->frame;
atm = (RpAtomic*)GetFirstObject(m_pHeadNode);
if(atm){
assert(RwObjectGetType(atm) == rpATOMIC);
assert(RwObjectGetType((RwObject*)atm) == rpATOMIC);
RpAtomicSetFlags(atm, RpAtomicGetFlags(atm) & ~rpATOMICRENDER);
}
}

View File

@ -154,7 +154,7 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
pobj->m_nRemoveTimer = 0;
if ( color.alpha != 0 )
RwRGBAAssign(&pobj->m_Color, &color);
pobj->m_Color, color;
else
pobj->m_Color.alpha = 0;

View File

@ -676,7 +676,7 @@ RemoveAllModelCB(RwObject *object, void *data)
{
RpAtomic *atomic = (RpAtomic*)object;
if (CVisibilityPlugins::GetAtomicModelInfo(atomic)) {
RpClumpRemoveAtomic(atomic->clump, atomic);
RpClumpRemoveAtomic(RpAtomicGetClump(atomic), atomic);
RpAtomicDestroy(atomic);
}
return object;
@ -902,7 +902,7 @@ static RwObject*
SetPedAtomicVisibilityCB(RwObject* object, void* data)
{
if (data == nil)
RpAtomicSetFlags(object, 0);
RpAtomicSetFlags((RpAtomic*)object, 0);
return object;
}

View File

@ -340,7 +340,7 @@ CPedIK::RestoreLookAt(void)
}
void
CPedIK::ExtractYawAndPitchWorld(RwMatrixTag *mat, float *yaw, float *pitch)
CPedIK::ExtractYawAndPitchWorld(RwMatrix *mat, float *yaw, float *pitch)
{
float f = clamp(DotProduct(mat->up, CVector(0.0f, 1.0f, 0.0f)), -1.0f, 1.0f);
*yaw = Acos(f);
@ -352,7 +352,7 @@ CPedIK::ExtractYawAndPitchWorld(RwMatrixTag *mat, float *yaw, float *pitch)
}
void
CPedIK::ExtractYawAndPitchLocal(RwMatrixTag *mat, float *yaw, float *pitch)
CPedIK::ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch)
{
float f = clamp(DotProduct(mat->at, CVector(0.0f, 0.0f, 1.0f)), -1.0f, 1.0f);
*yaw = Acos(f);

View File

@ -54,8 +54,8 @@ public:
void GetComponentPosition(RwV3d *pos, uint32 node);
static RwMatrix *GetWorldMatrix(RwFrame *source, RwMatrix *destination);
void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll);
void ExtractYawAndPitchLocal(RwMatrixTag *mat, float *yaw, float *pitch);
void ExtractYawAndPitchWorld(RwMatrixTag *mat, float *yaw, float *pitch);
void ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch);
void ExtractYawAndPitchWorld(RwMatrix *mat, float *yaw, float *pitch);
LimbMoveStatus MoveLimb(LimbOrientation &limb, float approxPhi, float approxTheta, LimbMovementInfo &moveInfo);
bool RestoreGunPosn(void);
bool LookInDirection(float phi, float theta);

View File

@ -85,6 +85,7 @@ public:
static uint32 GetFlag(int type) { return ms_apPedType[type]->m_flag; }
static uint32 GetAvoid(int type) { return ms_apPedType[type]->m_avoid; }
static uint32 GetThreats(int type) { return ms_apPedType[type]->m_threats; }
static void SetThreats(int type, uint32 threat) { ms_apPedType[type]->m_threats = threat; }
static void AddThreat(int type, int threat) { ms_apPedType[type]->m_threats |= threat; }
static void RemoveThreat(int type, int threat) { ms_apPedType[type]->m_threats &= ~threat; }
static bool IsThreat(int type, int threat) { return ms_apPedType[type]->m_threats & threat; }

View File

@ -704,12 +704,15 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
if (i != 0) {
// Gang member
newPed->SetLeader(gangLeader);
#ifndef FIX_BUGS
// seems to be a miami leftover (this code is not on PS2) but gang peds end up just being frozen
newPed->m_nPedState = PED_UNKNOWN;
gangLeader->m_nPedState = PED_UNKNOWN;
newPed->m_fRotationCur = CGeneral::GetRadianAngleBetweenPoints(
gangLeader->GetPosition().x, gangLeader->GetPosition().y,
newPed->GetPosition().x, newPed->GetPosition().y);
newPed->m_fRotationDest = newPed->m_fRotationCur;
#endif
} else {
gangLeader = newPed;
}

View File

@ -87,7 +87,7 @@ CClouds::Render(void)
RwV3d pos = { 0.0f, -100.0f, 15.0f };
RwV3dAdd(&worldpos, &campos, &pos);
if(CSprite::CalcScreenCoors(worldpos, &screenpos, &szx, &szy, false)){
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[2]->raster);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[2]));
if(CCoronas::bSmallMoon){
szx *= 4.0f;
szy *= 4.0f;
@ -116,7 +116,7 @@ CClouds::Render(void)
static float StarCoorsY[9] = { 0.0f, 0.45f, 0.9f, 1.0f, 0.85f, 0.52f, 0.48f, 0.35f, 0.2f };
static float StarSizes[9] = { 1.0f, 1.4f, 0.9f, 1.0f, 0.6f, 1.5f, 1.3f, 1.0f, 0.8f };
int brightness = (1.0f - coverage) * starintens;
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
for(i = 0; i < 11; i++){
RwV3d pos = { 100.0f, 0.0f, 10.0f };
if(i >= 9) pos.x = -pos.x;
@ -132,7 +132,7 @@ CClouds::Render(void)
CSprite::FlushSpriteBuffer();
// *
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
RwV3d pos = { 100.0f, 0.0f, 10.0f };
RwV3dAdd(&worldpos, &campos, &pos);
worldpos.y -= 90.0f;
@ -156,7 +156,7 @@ CClouds::Render(void)
int b = CTimeCycle::GetLowCloudsBlue() * lowcloudintensity;
for(int cloudtype = 0; cloudtype < 3; cloudtype++){
for(i = cloudtype; i < 12; i += 3){
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[cloudtype]->raster);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[cloudtype]));
RwV3d pos = { 800.0f*LowCloudsX[i], 800.0f*LowCloudsY[i], 60.0f*LowCloudsZ[i] };
worldpos.x = campos.x + pos.x;
worldpos.y = campos.y + pos.y;
@ -202,7 +202,7 @@ CClouds::Render(void)
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[4]->raster);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[4]));
for(i = 0; i < 37; i++){
RwV3d pos = { 2.0f*CoorsOffsetX[i], 2.0f*CoorsOffsetY[i], 40.0f*CoorsOffsetZ[i] + 40.0f };
worldpos.x = pos.x*rot_cos + pos.y*rot_sin + campos.x;
@ -244,7 +244,7 @@ CClouds::Render(void)
// Highlights
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[3]->raster);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[3]));
for(i = 0; i < 37; i++){
RwV3d pos = { 2.0f*CoorsOffsetX[i], 2.0f*CoorsOffsetY[i], 40.0f*CoorsOffsetZ[i] + 40.0f };
@ -269,7 +269,7 @@ CClouds::Render(void)
static uint8 BowRed[6] = { 30, 30, 30, 10, 0, 15 };
static uint8 BowGreen[6] = { 0, 15, 30, 30, 0, 0 };
static uint8 BowBlue[6] = { 0, 0, 0, 10, 30, 30 };
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
for(i = 0; i < 6; i++){
RwV3d pos = { i*1.5f, 100.0f, 5.0f };
RwV3dAdd(&worldpos, &campos, &pos);

View File

@ -320,7 +320,7 @@ CCoronas::Render(void)
CSprite::RenderOneXLUSprite(spriteCoors.x, spriteCoors.y, spriteCoors.z,
spritew * aCoronas[i].size * wscale,
spriteh * SCREEN_SCALE_AR2(aCoronas[i].size * fogscale * hscale),
spriteh * aCoronas[i].size * fogscale * hscale,
CCoronas::aCoronas[i].red / fogscale,
CCoronas::aCoronas[i].green / fogscale,
CCoronas::aCoronas[i].blue / fogscale,
@ -331,7 +331,7 @@ CCoronas::Render(void)
CSprite::RenderOneXLUSprite_Rotate_Aspect(
spriteCoors.x, spriteCoors.y, spriteCoors.z,
spritew * aCoronas[i].size * fogscale,
spriteh * SCREEN_SCALE_AR2(aCoronas[i].size * fogscale),
spriteh * aCoronas[i].size * fogscale,
CCoronas::aCoronas[i].red / fogscale,
CCoronas::aCoronas[i].green / fogscale,
CCoronas::aCoronas[i].blue / fogscale,

View File

@ -755,14 +755,14 @@ void CTowerClock::Render()
&TempV[1],
m_Position.x + Sin(angleMinute) * m_fScale * m_Size.x,
m_Position.y + Sin(angleMinute) * m_fScale * m_Size.y,
m_Position.z + Cos(angleMinute) * m_fScale;
m_Position.z + Cos(angleMinute) * m_fScale
);
RwIm3DVertexSetPos(&TempV[2], m_Position.x, m_Position.y, m_Position.z);
RwIm3DVertexSetPos(
&TempV[3],
m_Position.x + Sin(angleHour) * 0.75f * m_fScale * m_Size.x,
m_Position.y + Sin(angleHour) * 0.75f * m_fScale * m_Size.y,
m_Position.z + Cos(angleHour) * 0.75f * m_fScale;
m_Position.z + Cos(angleHour) * 0.75f * m_fScale
);
LittleTest();

View File

@ -815,7 +815,7 @@ void CHud::Draw()
DrawScriptText
*/
if (!CTimer::GetIsUserPaused()) {
CTextLine* IntroText = CTheScripts::IntroTextLines;
intro_text_line* IntroText = CTheScripts::IntroTextLines;
for (int i = 0; i < MAX_NUM_INTRO_TEXT_LINES; i++) {
if (CTheScripts::IntroTextLines[i].m_Text[0] && CTheScripts::IntroTextLines[i].m_bTextBeforeFade) {
@ -862,7 +862,7 @@ void CHud::Draw()
}
}
CScriptRectangle* IntroRect = CTheScripts::IntroRectangles;
intro_script_rectangle* IntroRect = CTheScripts::IntroRectangles;
for (int i = 0; i < 16; i++) {
if (CTheScripts::IntroRectangles[i].m_bIsUsed && CTheScripts::IntroRectangles[i].m_bBeforeFade) {

View File

@ -4,12 +4,13 @@
#include "Camera.h"
#include "MBlur.h"
// Originally taken from RW example 'mblur'
RwRaster *&CMBlur::pFrontBuffer = *(RwRaster**)0x8E2C48;
bool &CMBlur::ms_bJustInitialised = *(bool*)0x95CDAB;
bool &CMBlur::BlurOn = *(bool*)0x95CDAD;
static RwIm2DVertex Vertex[4];
//static RwIm2DVertex *Vertex = (RwIm2DVertex*)0x62F780;
static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 };
void

View File

@ -15,6 +15,9 @@
#include "Timer.h"
#include "Lights.h"
RpClump *gpPlayerClump;
float gOldFov;
int CPlayerSkin::m_txdSlot;
void
@ -92,7 +95,7 @@ CPlayerSkin::GetSkinTexture(const char *texName)
CTxdStore::SetCurrentTxd(m_txdSlot);
tex = RwTextureRead(texName, NULL);
CTxdStore::PopCurrentTxd();
if (tex) return tex;
if (tex != nil) return tex;
if (strcmp(DEFAULT_SKIN_NAME, texName) == 0)
sprintf(gString, "models\\generic\\player.bmp");
@ -106,7 +109,9 @@ CPlayerSkin::GetSkinTexture(const char *texName)
tex = RwTextureCreate(raster);
RwTextureSetName(tex, texName);
#ifdef FIX_BUGS
RwTextureSetFilterMode(tex, rwFILTERLINEAR); // filtering bugfix from VC
#endif
RwTexDictionaryAddTexture(CTxdStore::GetSlot(m_txdSlot)->texDict, tex);
RwImageDestroy(image);
@ -137,7 +142,7 @@ CPlayerSkin::RenderFrontendSkinEdit(void)
{
static float rotation = 0.0f;
RwRGBAReal AmbientColor = { 0.65f, 0.65f, 0.65f, 1.0f };
RwV3d pos = { 1.35f, 0.35f, 7.725f };
const RwV3d pos = { 1.35f, 0.35f, 7.725f };
const RwV3d axis1 = { 1.0f, 0.0f, 0.0f };
const RwV3d axis2 = { 0.0f, 0.0f, 1.0f };
static uint32 LastFlash = 0;

View File

@ -2,12 +2,6 @@
#define DEFAULT_SKIN_NAME "$$\"\""
static RpClump *gpPlayerClump;// = *(RpClump**)0x660FF8;
static float gOldFov;// = *(float*)0x660FFC;
void LoadPlayerDff(void);
void FindPlayerDff(uint32 &offset, uint32 &size);
class CPlayerSkin
{
static int m_txdSlot;

View File

@ -1,12 +1,247 @@
#include "common.h"
#include "patcher.h"
#include "main.h"
#include "TxdStore.h"
#include "Timer.h"
#include "Replay.h"
#include "Skidmarks.h"
WRAPPER void CSkidmarks::Clear(void) { EAXJMP(0x518130); }
WRAPPER void CSkidmarks::Update() { EAXJMP(0x518200); }
CSkidmark CSkidmarks::aSkidmarks[NUMSKIDMARKS];
WRAPPER void CSkidmarks::Render(void) { EAXJMP(0x5182E0); }
WRAPPER void CSkidmarks::RegisterOne(uint32 id, CVector pos, float fwdx, float fwdY, bool *isMuddy, bool *isBloddy) { EAXJMP(0x5185C0); }
RwImVertexIndex SkidmarkIndexList[SKIDMARK_LENGTH * 6];
RwIm3DVertex SkidmarkVertices[SKIDMARK_LENGTH * 2];
RwTexture *gpSkidTex;
RwTexture *gpSkidBloodTex;
RwTexture *gpSkidMudTex;
WRAPPER void CSkidmarks::Init(void) { EAXJMP(0x517D70); }
WRAPPER void CSkidmarks::Shutdown(void) { EAXJMP(0x518100); }
void
CSkidmarks::Init(void)
{
int i, ix, slot;
CTxdStore::PushCurrentTxd();
slot = CTxdStore::FindTxdSlot("particle");
CTxdStore::SetCurrentTxd(slot);
gpSkidTex = RwTextureRead("particleskid", nil);
gpSkidBloodTex = RwTextureRead("particleskidblood", nil);
gpSkidMudTex = RwTextureRead("particleskidmud", nil);
CTxdStore::PopCurrentTxd();
for(i = 0; i < NUMSKIDMARKS; i++){
aSkidmarks[i].m_state = 0;
aSkidmarks[i].m_wasUpdated = false;
}
ix = 0;
for(i = 0; i < SKIDMARK_LENGTH; i++){
SkidmarkIndexList[i*6+0] = ix+0;
SkidmarkIndexList[i*6+1] = ix+2;
SkidmarkIndexList[i*6+2] = ix+1;
SkidmarkIndexList[i*6+3] = ix+1;
SkidmarkIndexList[i*6+4] = ix+2;
SkidmarkIndexList[i*6+5] = ix+3;
ix += 2;
}
for(i = 0; i < SKIDMARK_LENGTH; i++){
RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 0], 0.0f);
RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 0], i*5.01f);
RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 1], 1.0f);
RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 1], i*5.01f);
}
}
void
CSkidmarks::Shutdown(void)
{
RwTextureDestroy(gpSkidTex);
RwTextureDestroy(gpSkidBloodTex);
RwTextureDestroy(gpSkidMudTex);
}
void
CSkidmarks::Clear(void)
{
int i;
for(i = 0; i < NUMSKIDMARKS; i++){
aSkidmarks[i].m_state = 0;
aSkidmarks[i].m_wasUpdated = false;
}
}
void
CSkidmarks::Update(void)
{
int i;
uint32 t1 = CTimer::GetTimeInMilliseconds() + 2500;
uint32 t2 = CTimer::GetTimeInMilliseconds() + 5000;
uint32 t3 = CTimer::GetTimeInMilliseconds() + 10000;
uint32 t4 = CTimer::GetTimeInMilliseconds() + 20000;
for(i = 0; i < NUMSKIDMARKS; i++){
switch(aSkidmarks[i].m_state){
case 1:
if(!aSkidmarks[i].m_wasUpdated){
// Didn't continue this one last time, so finish it and set fade times
aSkidmarks[i].m_state = 2;
if(aSkidmarks[i].m_last < 4){
aSkidmarks[i].m_fadeStart = t1;
aSkidmarks[i].m_fadeEnd = t2;
}else if(aSkidmarks[i].m_last < 9){
aSkidmarks[i].m_fadeStart = t2;
aSkidmarks[i].m_fadeEnd = t3;
}else{
aSkidmarks[i].m_fadeStart = t3;
aSkidmarks[i].m_fadeEnd = t4;
}
}
break;
case 2:
if(CTimer::GetTimeInMilliseconds() > aSkidmarks[i].m_fadeEnd)
aSkidmarks[i].m_state = 0;
break;
}
aSkidmarks[i].m_wasUpdated = false;
}
}
void
CSkidmarks::Render(void)
{
int i, j;
RwTexture *lastTex = nil;
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
for(i = 0; i < NUMSKIDMARKS; i++){
if(aSkidmarks[i].m_state == 0 || aSkidmarks[i].m_last < 1)
continue;
if(aSkidmarks[i].m_isBloody){
if(lastTex != gpSkidBloodTex){
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidBloodTex));
lastTex = gpSkidBloodTex;
}
}else if(aSkidmarks[i].m_isMuddy){
if(lastTex != gpSkidMudTex){
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidMudTex));
lastTex = gpSkidMudTex;
}
}else{
if(lastTex != gpSkidTex){
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidTex));
lastTex = gpSkidTex;
}
}
uint32 fade, alpha;
if(aSkidmarks[i].m_state == 1 || CTimer::GetTimeInMilliseconds() < aSkidmarks[i].m_fadeStart)
fade = 255;
else
fade = 255*(aSkidmarks[i].m_fadeEnd - CTimer::GetTimeInMilliseconds()) / (aSkidmarks[i].m_fadeEnd - aSkidmarks[i].m_fadeStart);
for(j = 0; j <= aSkidmarks[i].m_last; j++){
alpha = 128;
if(j == 0 || j == aSkidmarks[i].m_last && aSkidmarks[i].m_state == 2)
alpha = 0;
alpha = alpha*fade/256;
CVector p1 = aSkidmarks[i].m_pos[j] + aSkidmarks[i].m_side[j];
CVector p2 = aSkidmarks[i].m_pos[j] - aSkidmarks[i].m_side[j];
RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+0], 255, 255, 255, alpha);
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+0], p1.x, p1.y, p1.z+0.1f);
RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+1], 255, 255, 255, alpha);
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+1], p2.x, p2.y, p2.z+0.1f);
}
LittleTest();
if(RwIm3DTransform(SkidmarkVertices, 2*(aSkidmarks[i].m_last+1), nil, rwIM3D_VERTEXUV)){
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, SkidmarkIndexList, 6*aSkidmarks[i].m_last);
RwIm3DEnd();
}
}
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
}
void
CSkidmarks::RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody)
{
int i;
CVector2D fwd(fwdX, fwdY);
if(CReplay::IsPlayingBack())
return;
// Find a skidmark to continue
for(i = 0; i < NUMSKIDMARKS; i++)
if(aSkidmarks[i].m_state == 1 && aSkidmarks[i].m_id == id)
break;
if(i < NUMSKIDMARKS){
// Continue this one
if(aSkidmarks[i].m_isBloody != *isBloody){
// Blood-status changed, end this one
aSkidmarks[i].m_state = 2;
aSkidmarks[i].m_fadeStart = CTimer::GetTimeInMilliseconds() + 10000;
aSkidmarks[i].m_fadeEnd = CTimer::GetTimeInMilliseconds() + 20000;
return;
}
aSkidmarks[i].m_wasUpdated = true;
if(CTimer::GetTimeInMilliseconds() - aSkidmarks[i].m_lastUpdate <= 100){
// Last update was recently, just change last coords
aSkidmarks[i].m_pos[aSkidmarks[i].m_last] = pos;
return;
}
aSkidmarks[i].m_lastUpdate = CTimer::GetTimeInMilliseconds();
if(aSkidmarks[i].m_last >= SKIDMARK_LENGTH-1){
// No space to continue, end it
aSkidmarks[i].m_state = 2;
aSkidmarks[i].m_fadeStart = CTimer::GetTimeInMilliseconds() + 10000;
aSkidmarks[i].m_fadeEnd = CTimer::GetTimeInMilliseconds() + 20000;
*isBloody = false; // stpo blood marks at end
return;
}
aSkidmarks[i].m_last++;
aSkidmarks[i].m_pos[aSkidmarks[i].m_last] = pos;
CVector2D dist = aSkidmarks[i].m_pos[aSkidmarks[i].m_last] - aSkidmarks[i].m_pos[aSkidmarks[i].m_last-1];
dist.Normalise();
CVector2D right(dist.y, -dist.x);
float turn = DotProduct2D(fwd, right);
turn = Abs(turn) + 1.0f;
aSkidmarks[i].m_side[aSkidmarks[i].m_last] = CVector(right.x, right.y, 0.0f) * turn * 0.125f;
if(aSkidmarks[i].m_last == 1)
aSkidmarks[i].m_side[0] = aSkidmarks[i].m_side[1];
if(aSkidmarks[i].m_last > 8)
*isBloody = false; // stop blood marks after 8
return;
}
// Start a new one
for(i = 0; i < NUMSKIDMARKS; i++)
if(aSkidmarks[i].m_state == 0)
break;
if(i < NUMSKIDMARKS){
// Found a free slot
aSkidmarks[i].m_state = 1;
aSkidmarks[i].m_id = id;
aSkidmarks[i].m_pos[0] = pos;
aSkidmarks[i].m_side[0] = CVector(0.0f, 0.0f, 0.0f);
aSkidmarks[i].m_wasUpdated = true;
aSkidmarks[i].m_last = 0;
aSkidmarks[i].m_lastUpdate = CTimer::GetTimeInMilliseconds() - 1000;
aSkidmarks[i].m_isBloody = *isBloody;
aSkidmarks[i].m_isMuddy = *isMuddy;
}else
*isBloody = false; // stop blood marks if no space
}

View File

@ -1,12 +1,32 @@
#pragma once
enum { SKIDMARK_LENGTH = 16 };
class CSkidmark
{
public:
uint8 m_state;
bool m_wasUpdated;
bool m_isBloody;
bool m_isMuddy;
uintptr m_id;
int16 m_last;
uint32 m_lastUpdate;;
uint32 m_fadeStart;
uint32 m_fadeEnd;
CVector m_pos[SKIDMARK_LENGTH];
CVector m_side[SKIDMARK_LENGTH];
};
class CSkidmarks
{
static CSkidmark aSkidmarks[NUMSKIDMARKS];
public:
static void Init(void);
static void Shutdown(void);
static void Clear(void);
static void Update(void);
static void Render(void);
static void RegisterOne(uint32 id, CVector pos, float fwdx, float fwdY, bool *isMuddy, bool *isBloddy);
static void Init(void);
static void Shutdown(void);
static void RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody);
};

View File

@ -22,10 +22,10 @@
#include "Shadows.h"
#include "main.h"
RxObjSpace3DVertex StreakVertices[4];
RwIm3DVertex StreakVertices[4];
RwImVertexIndex StreakIndexList[12];
RxObjSpace3DVertex TraceVertices[6];
RwIm3DVertex TraceVertices[6];
RwImVertexIndex TraceIndexList[12];
@ -291,10 +291,10 @@ void CBulletTraces::Render(void)
for (int i = 0; i < NUMBULLETTRACES; i++) {
if (!aTraces[i].m_bInUse)
continue;
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)0);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)2);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)2);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpShadowExplosionTex->raster);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpShadowExplosionTex));
CVector inf = aTraces[i].m_vecCurrentPos;
CVector sup = aTraces[i].m_vecTargetPos;
CVector center = (inf + sup) / 2;
@ -316,9 +316,9 @@ void CBulletTraces::Render(void)
RwIm3DEnd();
}
}
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)1);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)5);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)6);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
}
void CBulletTraces::Update(void)
@ -414,8 +414,7 @@ C3dMarker::Render()
{
if (m_pAtomic == nil) return;
RwRGBA *color = RpMaterialGetColor(m_pMaterial);
*color = m_Color;
RpMaterialSetColor(m_pMaterial, &m_Color);
m_Matrix.UpdateRW();

View File

@ -30,10 +30,12 @@ CSprite::CalcScreenCoors(const RwV3d &in, RwV3d *out, float *outw, float *outh,
out->x *= SCREEN_WIDTH * recip;
out->y *= SCREEN_HEIGHT * recip;
// What is this? size?
*outw = 70.0f/CDraw::GetFOV();
*outh = 70.0f/CDraw::GetFOV();
*outw *= SCREEN_WIDTH * recip;
*outh *= SCREEN_HEIGHT * recip;
*outw = 70.0f/CDraw::GetFOV() * SCREEN_WIDTH * recip;
#ifdef ASPECT_RATIO_SCALE
*outh = 70.0f/CDraw::GetFOV() / (DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO) * SCREEN_HEIGHT * recip;
#else
*outh = 70.0f/CDraw::GetFOV() * SCREEN_HEIGHT * recip;
#endif
return true;
}
@ -432,6 +434,7 @@ void
CSprite::Set6Vertices2D(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
float screenz, recipz;
float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
screenz = m_f2DNearScreenZ;
recipz = m_fRecipNearClipPlane;
@ -496,6 +499,7 @@ CSprite::Set6Vertices2D(RwIm2DVertex *verts, float x1, float y1, float x2, float
const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
float screenz, recipz;
float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
screenz = m_f2DNearScreenZ;
recipz = m_fRecipNearClipPlane;

View File

@ -267,6 +267,7 @@ CSprite2d::SetVertices(float x1, float y1, float x2, float y2, float x3, float y
const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
float screenz, recipz;
float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
screenz = RwIm2DGetNearScreenZ();
recipz = RecipNearClip;
@ -312,10 +313,11 @@ void
CSprite2d::SetVertices(int n, float *positions, float *uvs, const CRGBA &col)
{
int i;
float screenz, recipz;
float screenz, recipz, z;
screenz = RwIm2DGetNearScreenZ();
recipz = RecipNearClip;
z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
for(i = 0; i < n; i++){
@ -334,10 +336,11 @@ void
CSprite2d::SetMaskVertices(int n, float *positions)
{
int i;
float screenz, recipz;
float screenz, recipz, z;
screenz = RwIm2DGetNearScreenZ();
recipz = RecipNearClip;
z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
for(i = 0; i < n; i++){
RwIm2DVertexSetScreenX(&maVertices[i], positions[i*2 + 0]);
@ -345,7 +348,7 @@ CSprite2d::SetMaskVertices(int n, float *positions)
RwIm2DVertexSetScreenZ(&maVertices[i], screenz);
RwIm2DVertexSetCameraZ(&maVertices[i], z);
RwIm2DVertexSetRecipCameraZ(&maVertices[i], recipz);
RwIm2DVertexSetIntRGBA(&maVertices[i], 0, 0, 0, 0);
RwIm2DVertexSetIntRGBA(&maVertices[i], 255, 255, 255, 255); // 0, 0, 0, 0 on PC
}
}
@ -353,10 +356,11 @@ void
CSprite2d::SetVertices(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3,
float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2)
{
float screenz, recipz;
float screenz, recipz, z;
screenz = RwIm2DGetNearScreenZ();
recipz = RecipNearClip;
z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
RwIm2DVertexSetScreenX(&verts[0], r.left);
RwIm2DVertexSetScreenY(&verts[0], r.top);

41
src/render/TexList.cpp Normal file
View File

@ -0,0 +1,41 @@
#include "common.h"
#include "TexList.h"
#include "rtbmp.h"
#include "FileMgr.h"
bool CTexList::ms_nTexUsed[MAX_TEXUSED];
void
CTexList::Initialise()
{}
void
CTexList::Shutdown()
{}
RwTexture *
CTexList::SetTexture(int32 slot, char *name)
{
return nil;
}
int32
CTexList::GetFirstFreeTexture()
{
for (int32 i = 0; i < MAX_TEXUSED; i++)
if (!ms_nTexUsed[i])
return i;
return -1;
}
RwTexture *
CTexList::LoadFileNameTexture(char *name)
{
return SetTexture(GetFirstFreeTexture(), name);
}
void
CTexList::LoadGlobalTextureList()
{
CFileMgr::SetDir("TEXTURES");
}

14
src/render/TexList.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
class CTexList
{
enum { MAX_TEXUSED = 400, };
static bool ms_nTexUsed[MAX_TEXUSED];
public:
static void Initialise();
static void Shutdown();
static RwTexture *SetTexture(int32 slot, char *name);
static int32 GetFirstFreeTexture();
static RwTexture *LoadFileNameTexture(char *name);
static void LoadGlobalTextureList();
};

View File

@ -117,7 +117,7 @@ CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera)
RpMaterial*
SetAlphaCB(RpMaterial *material, void *data)
{
material->color.alpha = (uint8)(uint32)data;
((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uint32)data;
return material;
}

View File

@ -83,7 +83,7 @@ CWeaponEffects::Render(void)
{
float recipz = 1.0f / pos.z;
CSprite::RenderOneXLUSprite(pos.x, pos.y, pos.z,
gCrossHair.m_fSize * w, gCrossHair.m_fSize * SCREEN_SCALE_AR2(h),
gCrossHair.m_fSize * w, gCrossHair.m_fSize * h,
gCrossHair.m_nRed, gCrossHair.m_nGreen, gCrossHair.m_nBlue, 255,
recipz, 255);
}

View File

@ -71,8 +71,8 @@ const int16 WeatherTypesList[] = {
const float Windiness[] = {
0.0f, // WEATHER_SUNNY
0.7f, // WEATHER_RAINY
1.0f, // WEATHER_CLOUDY
0.7f, // WEATHER_CLOUDY
1.0f, // WEATHER_RAINY
0.5f // WEATHER_FOGGY
};
@ -106,7 +106,7 @@ void CWeather::Init(void)
{
NewWeatherType = WEATHER_SUNNY;
bScriptsForceRain = false;
OldWeatherType = WEATHER_RAINY;
OldWeatherType = WEATHER_CLOUDY;
Stored_StateStored = false;
InterpolationValue = 0.0f;
WhenToPlayLightningSound = 0;
@ -475,7 +475,7 @@ void CWeather::RenderRainStreaks(void)
// 1/16 probability
Streaks[i].direction = CVector(4.0f, 4.0f, -4.0f);
Streaks[i].position = 6.0f * TheCamera.GetForward() + TheCamera.GetPosition() + CVector(-1.8f * Streaks[i].direction.x, -1.8f * Streaks[i].direction.y, 8.0f);
if (!CCutsceneMgr::IsCutsceneProcessing()) {
if (!CCutsceneMgr::IsRunning()) {
Streaks[i].position.x += 2.0f * FindPlayerSpeed().x * 60.0f;
Streaks[i].position.y += 2.0f * FindPlayerSpeed().y * 60.0f;
}

View File

@ -48,6 +48,13 @@ char SaveFileNameJustSaved[260];
int (&Slots)[SLOT_COUNT+1] = *(int(*)[SLOT_COUNT+1])*(uintptr*)0x72803C;
CDate &CompileDateAndTime = *(CDate*)0x72BCB8;
bool &b_FoundRecentSavedGameWantToLoad = *(bool*)0x95CDA8;
bool &JustLoadedDontFadeInYet = *(bool*)0x95CDB4;
bool &StillToFadeOut = *(bool*)0x95CD99;
uint32 &TimeStartedCountingForFade = *(uint32*)0x9430EC;
uint32 &TimeToStayFadedBeforeFadeOut = *(uint32*)0x611564;
#define ReadDataFromBufferPointer(buf, to) memcpy(&to, buf, sizeof(to)); buf += align4bytes(sizeof(to));
#define WriteDataToBufferPointer(buf, from) memcpy(buf, &from, sizeof(from)); buf += align4bytes(sizeof(from));

View File

@ -32,6 +32,12 @@ extern int &CheckSum;
extern enum eLevelName &m_LevelToLoad;
extern int (&Slots)[SLOT_COUNT+1];
extern bool &b_FoundRecentSavedGameWantToLoad;
extern bool &JustLoadedDontFadeInYet;
extern bool &StillToFadeOut;
extern uint32 &TimeStartedCountingForFade;
extern uint32 &TimeToStayFadedBeforeFadeOut;
extern char SaveFileNameJustSaved[260]; // 8F2570
const char TopLineEmptyFile[] = "THIS FILE IS NOT VALID YET";

View File

@ -1927,7 +1927,7 @@ _WinMain(HINSTANCE instance,
* Enter the message processing loop...
*/
while( !RsGlobal.quit && !FrontEndMenuManager.m_bStartGameLoading )
while( !RsGlobal.quit && !FrontEndMenuManager.m_bWantToRestart )
{
if( PeekMessage(&message, nil, 0U, 0U, PM_REMOVE|PM_NOYIELD) )
{
@ -2059,13 +2059,13 @@ _WinMain(HINSTANCE instance,
if (wp.showCmd != SW_SHOWMINIMIZED)
RsEventHandler(rsFRONTENDIDLE, nil);
if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bLoadingSavedGame )
if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bWantToLoad )
{
gGameState = GS_INIT_PLAYING_GAME;
TRACE("gGameState = GS_INIT_PLAYING_GAME;");
}
if ( FrontEndMenuManager.m_bLoadingSavedGame )
if ( FrontEndMenuManager.m_bWantToLoad )
{
InitialiseGame();
FrontEndMenuManager.m_bGameNotLoaded = false;
@ -2128,7 +2128,7 @@ _WinMain(HINSTANCE instance,
RwInitialised = FALSE;
FrontEndMenuManager.UnloadTextures();
if ( !FrontEndMenuManager.m_bStartGameLoading )
if ( !FrontEndMenuManager.m_bWantToRestart )
break;
CPad::ResetCheats();
@ -2138,13 +2138,13 @@ _WinMain(HINSTANCE instance,
CTimer::Stop();
if ( FrontEndMenuManager.m_bLoadingSavedGame )
if ( FrontEndMenuManager.m_bWantToLoad )
{
CGame::ShutDownForRestart();
CGame::InitialiseWhenRestarting();
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
LoadSplash(GetLevelSplashScreen(CGame::currLevel));
FrontEndMenuManager.m_bLoadingSavedGame = false;
FrontEndMenuManager.m_bWantToLoad = false;
}
else
{
@ -2168,7 +2168,7 @@ _WinMain(HINSTANCE instance,
}
FrontEndMenuManager.m_bFirstTime = false;
FrontEndMenuManager.m_bStartGameLoading = false;
FrontEndMenuManager.m_bWantToRestart = false;
}

View File

@ -182,17 +182,17 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_weaponDoorTimerRight = m_weaponDoorTimerLeft;
if(GetModelIndex() == MI_DODO){
RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
CMatrix mat1;
mat1.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF]));
CMatrix mat2(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LF]));
mat1.GetPosition() += CVector(mat2.GetPosition().x + 0.1f, 0.0f, mat2.GetPosition().z);
mat1.UpdateRW();
}else if(GetModelIndex() == MI_MIAMI_SPARROW || GetModelIndex() == MI_MIAMI_RCRAIDER){
RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]), 0);
RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0);
RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0);
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]), 0);
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0);
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0);
}else if(GetModelIndex() == MI_RHINO){
bExplosionProof = true;
bBulletProof = true;

15
src/vehicles/Bike.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
// some miami bike leftovers
enum eBikeNodes {
BIKE_NODE_NONE,
BIKE_CHASSIS,
BIKE_FORKS_FRONT,
BIKE_FORKS_REAR,
BIKE_WHEEL_FRONT,
BIKE_WHEEL_REAR,
BIKE_MUDGUARD,
BIKE_HANDLEBARS,
BIKE_NUM_NODES
};

View File

@ -94,7 +94,7 @@ CBoat::GetComponentWorldPosition(int32 component, CVector &pos)
pos = *RwMatrixGetPos(RwFrameGetLTM(m_aBoatNodes[component]));
}
RxObjSpace3DVertex KeepWaterOutVertices[4];
RwIm3DVertex KeepWaterOutVertices[4];
RwImVertexIndex KeepWaterOutIndices[6];
void
@ -103,7 +103,7 @@ CBoat::Render()
CMatrix matrix;
if (m_aBoatNodes[1] != nil) {
matrix.Attach(&m_aBoatNodes[1]->modelling);
matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[1]));
CVector pos = matrix.GetPosition();
matrix.SetRotateZ(m_fMovingHiRotation);
@ -111,7 +111,7 @@ CBoat::Render()
matrix.UpdateRW();
if (CVehicle::bWheelsOnlyCheat) {
RpAtomicRenderMacro((RpAtomic*)GetFirstObject(m_aBoatNodes[1]));
RpAtomicRender((RpAtomic*)GetFirstObject(m_aBoatNodes[1]));
}
}
m_fMovingHiRotation += 0.05f;
@ -130,47 +130,23 @@ CBoat::Render()
KeepWaterOutIndices[5] = 3;
switch (GetModelIndex()) {
case MI_SPEEDER:
KeepWaterOutVertices[0].objVertex.x = -1.15f;
KeepWaterOutVertices[0].objVertex.y = 3.61f;
KeepWaterOutVertices[0].objVertex.z = 1.03f;
KeepWaterOutVertices[1].objVertex.x = 1.15f;
KeepWaterOutVertices[1].objVertex.y = 3.61f;
KeepWaterOutVertices[1].objVertex.z = 1.03f;
KeepWaterOutVertices[2].objVertex.x = -1.15f;
KeepWaterOutVertices[2].objVertex.y = 0.06f;
KeepWaterOutVertices[2].objVertex.z = 1.03f;
KeepWaterOutVertices[3].objVertex.x = 1.15f;
KeepWaterOutVertices[3].objVertex.y = 0.06f;
KeepWaterOutVertices[3].objVertex.z = 1.03f;
RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.15f, 3.61f, 1.03f);
RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.15f, 3.61f, 1.03f);
RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.15f, 0.06f, 1.03f);
RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.15f, 0.06f, 1.03f);
break;
case MI_REEFER:
KeepWaterOutVertices[2].objVertex.x = -1.9f;
KeepWaterOutVertices[2].objVertex.y = 2.83f;
KeepWaterOutVertices[2].objVertex.z = 1.0f;
KeepWaterOutVertices[3].objVertex.x = 1.9f;
KeepWaterOutVertices[3].objVertex.y = 2.83f;
KeepWaterOutVertices[3].objVertex.z = 1.0f;
KeepWaterOutVertices[0].objVertex.x = -1.66f;
KeepWaterOutVertices[0].objVertex.y = -4.48f;
KeepWaterOutVertices[0].objVertex.z = 0.83f;
KeepWaterOutVertices[1].objVertex.x = 1.66f;
KeepWaterOutVertices[1].objVertex.y = -4.48f;
KeepWaterOutVertices[1].objVertex.z = 0.83f;
RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.9f, 2.83f, 1.0f);
RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.9f, 2.83f, 1.0f);
RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.66f, -4.48f, 0.83f);
RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.66f, -4.48f, 0.83f);
break;
case MI_PREDATOR:
default:
KeepWaterOutVertices[0].objVertex.x = -1.45f;
KeepWaterOutVertices[0].objVertex.y = 1.9f;
KeepWaterOutVertices[0].objVertex.z = 0.96f;
KeepWaterOutVertices[1].objVertex.x = 1.45f;
KeepWaterOutVertices[1].objVertex.y = 1.9f;
KeepWaterOutVertices[1].objVertex.z = 0.96f;
KeepWaterOutVertices[2].objVertex.x = -1.45f;
KeepWaterOutVertices[2].objVertex.y = -3.75f;
KeepWaterOutVertices[2].objVertex.z = 0.96f;
KeepWaterOutVertices[3].objVertex.x = 1.45f;
KeepWaterOutVertices[3].objVertex.y = -3.75f;
KeepWaterOutVertices[3].objVertex.z = 0.96f;
RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.45f, 1.9f, 0.96f);
RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.45f, 1.9f, 0.96f);
RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.45f, -3.75f, 0.96f);
RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.45f, -3.75f, 0.96f);
break;
}
KeepWaterOutVertices[0].u = 0.0f;

View File

@ -238,6 +238,7 @@ public:
bool IsTrain(void) { return m_vehType == VEHICLE_TYPE_TRAIN; }
bool IsHeli(void) { return m_vehType == VEHICLE_TYPE_HELI; }
bool IsPlane(void) { return m_vehType == VEHICLE_TYPE_PLANE; }
bool IsBike(void) { return m_vehType == VEHICLE_TYPE_BIKE; }
void FlyingControl(eFlightModel flightModel);
void ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint,

View File

@ -1,11 +1,29 @@
#include "common.h"
#include "patcher.h"
#include "Automobile.h"
#include "Bike.h"
#include "Camera.h"
#include "Coronas.h"
#include "DMAudio.h"
#include "Entity.h"
#include "EventList.h"
#include "Explosion.h"
#include "General.h"
#include "Fire.h"
#include "Pad.h"
#include "Particle.h"
#include "PointLights.h"
#include "Shadows.h"
#include "Timer.h"
#include "Vehicle.h"
#include "WaterLevel.h"
#include "World.h"
CExplosion(&gaExplosion)[48] = *(CExplosion(*)[48])*(uintptr*)0x64E208;
CExplosion(&gaExplosion)[NUM_EXPLOSIONS] = *(CExplosion(*)[NUM_EXPLOSIONS])*(uintptr*)0x64E208;
WRAPPER void CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32) { EAXJMP(0x5591C0); }
// these two were not initialised in original code, I'm really not sure what were they meant to be
RwRGBA colMedExpl = { 0, 0, 0, 0 };
RwRGBA colUpdate = { 0, 0, 0, 0 };
int AudioHandle = AEHANDLE_NONE;
@ -15,26 +33,25 @@ CExplosion::Initialise()
debug("Initialising CExplosion...\n");
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
gaExplosion[i].m_ExplosionType = EXPLOSION_GRENADE;
gaExplosion[i].m_vecPosition.x = 0.0f;
gaExplosion[i].m_vecPosition.y = 0.0f;
gaExplosion[i].m_vecPosition.z = 0.0f;
gaExplosion[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
gaExplosion[i].m_fRadius = 1.0f;
gaExplosion[i].m_fPropagationRate = 0.0f;
gaExplosion[i].field_38 = 0;
gaExplosion[i].m_fZshift = 0.0f;
gaExplosion[i].m_pCreatorEntity = nil;
gaExplosion[i].m_pVictimEntity = nil;
gaExplosion[i].m_fStopTime = 0.0f;
gaExplosion[i].m_bActive = false;
gaExplosion[i].m_nStartTime = 0;
gaExplosion[i].field_34 = 0;
gaExplosion[i].m_nIteration = 0;
gaExplosion[i].m_fStartTime = 0.0f;
gaExplosion[i].m_bIsBoat = false;
}
AudioHandle = DMAudio.CreateEntity(AUDIOTYPE_EXPLOSION, (void*)1);
if (AudioHandle >= 0)
DMAudio.SetEntityStatus(AudioHandle, 1);
DMAudio.SetEntityStatus(AudioHandle, true);
debug("CExplosion ready\n");
}
void CExplosion::Shutdown()
void
CExplosion::Shutdown()
{
debug("Shutting down CExplosion...\n");
if (AudioHandle >= 0) {
@ -44,27 +61,16 @@ void CExplosion::Shutdown()
debug("CExplosion shut down\n");
}
void
CExplosion::RemoveAllExplosionsInArea(CVector pos, float radius)
{
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
if (gaExplosion[i].m_bActive) {
if ((pos - gaExplosion[i].m_vecPosition).MagnitudeSqr() < SQR(radius))
gaExplosion[i].m_bActive = false;
}
}
}
int8
CExplosion::GetExplosionActiveCounter(uint8 id)
{
return gaExplosion[id].m_bActiveCounter;
return gaExplosion[id].m_nActiveCounter;
}
CVector *
CExplosion::GetExplosionPosition(uint8 id)
void
CExplosion::ResetExplosionActiveCounter(uint8 id)
{
return &gaExplosion[id].m_vecPosition;
gaExplosion[id].m_nActiveCounter = 0;
}
uint8
@ -73,18 +79,363 @@ CExplosion::GetExplosionType(uint8 id)
return gaExplosion[id].m_ExplosionType;
}
void
CExplosion::ResetExplosionActiveCounter(uint8 id)
CVector *
CExplosion::GetExplosionPosition(uint8 id)
{
gaExplosion[id].m_bActiveCounter = 0;
return &gaExplosion[id].m_vecPosition;
}
bool
CExplosion::TestForExplosionInArea(eExplosionType a1, float x1, float x2, float y1, float y2, float z1, float z2)
CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32 lifetime)
{
CVector pPosn;
CVector posGround;
RwRGBA colorMedium = colMedExpl;
bool bDontExplode = false;
const RwRGBA color = { 160, 160, 160, 255 };
pPosn = pos;
pPosn.z += 5.0f;
#ifdef FIX_BUGS
CShadows::AddPermanentShadow(SHADOWTEX_CAR, gpShadowHeliTex, &pPosn, 8.0f, 0.0f, 0.0f, -8.0f, 200, 0, 0, 0, 10.0f, 30000, 1.0f);
#else
// last two arguments are swapped resulting in no shadow
CShadows::AddPermanentShadow(SHADOWTEX_CAR, gpShadowHeliTex, &pPosn, 8.0f, 0.0f, 0.0f, -8.0f, 200, 0, 0, 0, 10.0f, 1, 30000.0f);
#endif
int n = 0;
while (gaExplosion[n].m_nIteration != 0 && n < ARRAY_SIZE(gaExplosion))
n++;
if (n == ARRAY_SIZE(gaExplosion))
return false;
CExplosion &explosion = gaExplosion[n];
explosion.m_ExplosionType = type;
explosion.m_vecPosition = pos;
explosion.m_fRadius = 1.0f;
explosion.m_fZshift = 0.0f;
explosion.m_pCreatorEntity = culprit;
if (culprit != nil)
culprit->RegisterReference(&explosion.m_pCreatorEntity);
explosion.m_pVictimEntity = explodingEntity;
if (explodingEntity != nil)
explodingEntity->RegisterReference(&explosion.m_pVictimEntity);
explosion.m_nIteration = 1;
explosion.m_nActiveCounter = 1;
explosion.m_bIsBoat = false;
explosion.m_nParticlesExpireTime = lifetime != 0 ? CTimer::GetTimeInMilliseconds() + lifetime : 0;
switch (type)
{
case EXPLOSION_GRENADE:
explosion.m_fRadius = 9.0f;
explosion.m_fPower = 300.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
posGround = pos;
posGround.z = CWorld::FindGroundZFor3DCoord(posGround.x, posGround.y, posGround.z + 3.0f, nil);
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
if (Distance(explosion.m_vecPosition, TheCamera.GetPosition()) < 40.0f)
CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
break;
case EXPLOSION_MOLOTOV:
{
explosion.m_fRadius = 6.0f;
explosion.m_fPower = 0.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 3000;
explosion.m_fPropagationRate = 0.5f;
posGround = pos;
bool found;
posGround.z = CWorld::FindGroundZFor3DCoord(posGround.x, posGround.y, posGround.z + 3.0f, &found);
if (found) {
float waterLevel;
if (CWaterLevel::GetWaterLevelNoWaves(posGround.x, posGround.y, posGround.z, &waterLevel)
&& posGround.z < waterLevel
&& waterLevel - 6.0f < posGround.z) // some subway/tunnels check?
bDontExplode = true;
else
gFireManager.StartFire(posGround, 1.8f, false);
}
else
bDontExplode = true;
break;
}
case EXPLOSION_ROCKET:
explosion.m_fRadius = 10.0f;
explosion.m_fPower = 300.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
CEventList::RegisterEvent(EVENT_EXPLOSION, pos, 250);
if (Distance(explosion.m_vecPosition, TheCamera.GetPosition()) < 40.0f)
CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
break;
case EXPLOSION_CAR:
case EXPLOSION_CAR_QUICK:
explosion.m_fRadius = 9.0f;
explosion.m_fPower = 300.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 4250;
explosion.m_fPropagationRate = 0.5f;
explosion.m_fStartTime = CTimer::GetTimeInMilliseconds();
if (explosion.m_pVictimEntity != nil) {
if (explosion.m_pVictimEntity->IsVehicle() && ((CVehicle*)explosion.m_pVictimEntity)->IsBoat())
explosion.m_bIsBoat = true;
CEventList::RegisterEvent(EVENT_EXPLOSION, EVENT_ENTITY_VEHICLE, explosion.m_pVictimEntity, nil, 1000);
} else
CEventList::RegisterEvent(EVENT_EXPLOSION, pos, 1000);
if (explosion.m_pVictimEntity != nil && !explosion.m_bIsBoat) {
int rn = (CGeneral::GetRandomNumber() & 1) + 2;
for (int i = 0; i < rn; i++) {
CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, explosion.m_pVictimEntity->GetPosition(), CVector(0.0f, 0.0f, 0.0f), nil, 3.5f, colMedExpl);
CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, explosion.m_pVictimEntity->GetPosition(), CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
}
CVehicle *veh = (CVehicle*)explosion.m_pVictimEntity;
int32 component = CAR_WING_LR;
// miami leftover
if (veh->IsBike())
component = BIKE_FORKS_REAR;
if (veh->IsComponentPresent(component)) {
CVector componentPos;
veh->GetComponentWorldPosition(component, componentPos);
rn = (CGeneral::GetRandomNumber() & 1) + 1;
for (int i = 0; i < rn; i++)
CParticle::AddJetExplosion(componentPos, 1.4f, 0.0f);
}
}
break;
case EXPLOSION_HELI:
explosion.m_fRadius = 6.0f;
explosion.m_fPower = 300.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
explosion.m_fStartTime = CTimer::GetTimeInMilliseconds();
for (int i = 0; i < 10; i++) {
CVector randpos;
uint8 x, y, z;
x = CGeneral::GetRandomNumber();
y = CGeneral::GetRandomNumber();
z = CGeneral::GetRandomNumber();
randpos = pos + CVector(x - 128, y - 128, z - 128) / 20.0f;
CParticle::AddParticle(PARTICLE_EXPLOSION_MFAST, randpos, CVector(0.0f, 0.0f, 0.0f), nil, 2.5f, color);
x = CGeneral::GetRandomNumber();
y = CGeneral::GetRandomNumber();
z = CGeneral::GetRandomNumber();
randpos = pos + CVector(x - 128, y - 128, z - 128) / 20.0f;
CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, randpos, CVector(0.0f, 0.0f, 0.0f), nil, 5.0f, color);
x = CGeneral::GetRandomNumber();
y = CGeneral::GetRandomNumber();
z = CGeneral::GetRandomNumber();
randpos = pos + CVector(x - 128, y - 128, z - 128) / 20.0f;
CParticle::AddJetExplosion(randpos, 1.4f, 3.0f);
}
CEventList::RegisterEvent(EVENT_EXPLOSION, pos, 1000);
break;
case EXPLOSION_MINE:
explosion.m_fRadius = 10.0f;
explosion.m_fPower = 150.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
posGround = pos;
//posGround.z =
CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
break;
case EXPLOSION_BARREL:
explosion.m_fRadius = 7.0f;
explosion.m_fPower = 150.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
for (int i = 0; i < 6; i++) {
CVector randpos;
uint8 x, y, z;
x = CGeneral::GetRandomNumber();
y = CGeneral::GetRandomNumber();
z = CGeneral::GetRandomNumber();
randpos = CVector(x - 128, y - 128, z - 128);
randpos.x /= 50.0f;
randpos.y /= 50.0f;
randpos.z /= 25.0f;
randpos += pos;
CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, randpos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colorMedium);
}
posGround = pos;
//posGround.z =
CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
break;
case EXPLOSION_TANK_GRENADE:
explosion.m_fRadius = 10.0f;
explosion.m_fPower = 150.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
posGround = pos;
//posGround.z =
CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
break;
case EXPLOSION_HELI_BOMB:
explosion.m_fRadius = 8.0f;
explosion.m_fPower = 50.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
posGround = pos;
//posGround.z =
CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
break;
}
if (bDontExplode) {
explosion.m_nIteration = 0;
return false;
}
if (explosion.m_fPower != 0.0f && explosion.m_nParticlesExpireTime == 0)
CWorld::TriggerExplosion(pos, explosion.m_fRadius, explosion.m_fPower, culprit, (type == EXPLOSION_ROCKET || type == EXPLOSION_CAR_QUICK || type == EXPLOSION_MINE || type == EXPLOSION_BARREL || type == EXPLOSION_TANK_GRENADE || type == EXPLOSION_HELI_BOMB));
TheCamera.CamShake(0.6f, pos.x, pos.y, pos.z);
CPad::GetPad(0)->StartShake_Distance(300, 128, pos.x, pos.y, pos.z);
return true;
}
void
CExplosion::Update()
{
RwRGBA color = colUpdate;
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
CExplosion &explosion = gaExplosion[i];
if (explosion.m_nIteration == 0) continue;
if (explosion.m_nParticlesExpireTime != 0) {
if (CTimer::GetTimeInMilliseconds() > explosion.m_nParticlesExpireTime) {
explosion.m_nParticlesExpireTime = 0;
if (explosion.m_fPower != 0.0f)
CWorld::TriggerExplosion(explosion.m_vecPosition, explosion.m_fRadius, explosion.m_fPower, explosion.m_pCreatorEntity, (explosion.m_ExplosionType == EXPLOSION_ROCKET || explosion.m_ExplosionType == EXPLOSION_CAR_QUICK || explosion.m_ExplosionType == EXPLOSION_MINE || explosion.m_ExplosionType == EXPLOSION_BARREL || explosion.m_ExplosionType == EXPLOSION_TANK_GRENADE || explosion.m_ExplosionType == EXPLOSION_HELI_BOMB));
}
} else {
explosion.m_fRadius += explosion.m_fPropagationRate * CTimer::GetTimeStep();
int32 someTime = explosion.m_fStopTime - CTimer::GetTimeInMilliseconds();
switch (explosion.m_ExplosionType)
{
case EXPLOSION_GRENADE:
case EXPLOSION_ROCKET:
case EXPLOSION_HELI:
case EXPLOSION_MINE:
case EXPLOSION_BARREL:
if (CTimer::GetFrameCounter() & 1) {
CPointLights::AddLight(CPointLights::LIGHT_POINT, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), 20.0f, 1.0f, 1.0f, 0.5f, CPointLights::FOG_NONE, true);
CCoronas::RegisterCorona((uintptr)&explosion, 255, 255, 200, 255, explosion.m_vecPosition, 8.0f, 120.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
} else
CCoronas::RegisterCorona((uintptr)&explosion, 128, 128, 100, 255, explosion.m_vecPosition, 8.0f, 120.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
CCoronas::RegisterCorona((uintptr)&explosion + 1, 30, 30, 25, 255, explosion.m_vecPosition, explosion.m_fRadius, 120.0f, gpCoronaTexture[7], CCoronas::TYPE_STAR, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
break;
case EXPLOSION_MOLOTOV:
CWorld::SetPedsOnFire(explosion.m_vecPosition.x, explosion.m_vecPosition.y, explosion.m_vecPosition.z, 6.0f, explosion.m_pCreatorEntity);
CWorld::SetCarsOnFire(explosion.m_vecPosition.x, explosion.m_vecPosition.y, explosion.m_vecPosition.z, 6.0f, explosion.m_pCreatorEntity);
if (explosion.m_nIteration < 10) {
if (explosion.m_nIteration == 1) {
CVector point1 = explosion.m_vecPosition;
point1.z += 5.0f;
CColPoint colPoint;
CEntity *pEntity;
CWorld::ProcessVerticalLine(point1, -1000.0f, colPoint, pEntity, true, false, false, false, true, false, nil);
explosion.m_fZshift = colPoint.point.z;
}
float ff = ((float)explosion.m_nIteration * 0.55f);
for (int i = 0; i < 5 * ff; i++) {
float angle = CGeneral::GetRandomNumber() / 256.0f * 6.28f;
CVector pos = explosion.m_vecPosition;
pos.x += ff * Sin(angle);
pos.y += ff * Cos(angle);
pos.z += 5.0f; // what is the point of this?
pos.z = explosion.m_fZshift + 0.5f;
CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, CGeneral::GetRandomNumberInRange(-3.0f, 3.0f), CGeneral::GetRandomNumberInRange(-180.0f, 180.0f));
}
}
break;
case EXPLOSION_CAR:
case EXPLOSION_CAR_QUICK:
if (someTime >= 3500) {
if (explosion.m_pVictimEntity != nil && !explosion.m_bIsBoat) {
if ((CGeneral::GetRandomNumber() & 0xF) == 0) {
CVehicle *veh = (CVehicle*)explosion.m_pVictimEntity;
uint8 component = CAR_WING_LR;
// miami leftover
if (veh->IsBike())
component = BIKE_FORKS_REAR;
if (veh->IsComponentPresent(component)) {
CVector componentPos;
veh->GetComponentWorldPosition(component, componentPos);
CParticle::AddJetExplosion(componentPos, 1.5f, 0.0f);
}
}
if (CTimer::GetTimeInMilliseconds() > explosion.m_fStartTime) {
explosion.m_fStartTime = CTimer::GetTimeInMilliseconds() + 125 + (CGeneral::GetRandomNumber() & 0x7F);
CVector pos = explosion.m_pVictimEntity->GetPosition();
for (int i = 0; i < (CGeneral::GetRandomNumber() & 1) + 1; i++) {
CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, CVector(0.0f, 0.0f, 0.0f), nil, 3.5f, color);
CParticle::AddParticle(PARTICLE_EXPLOSION_LARGE, pos, CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
}
}
}
if (CTimer::GetFrameCounter() & 1) {
CPointLights::AddLight(CPointLights::LIGHT_POINT, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), 15.0f, 1.0f, 0.0f, 0.0f, CPointLights::FOG_NONE, true);
CCoronas::RegisterCorona((uintptr)&explosion, 200, 100, 0, 255, explosion.m_vecPosition, 6.0f, 80.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
} else
CCoronas::RegisterCorona((uintptr)&explosion, 128, 0, 0, 255, explosion.m_vecPosition, 8.0f, 80.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
CCoronas::RegisterCorona((uintptr)&explosion + 1, 30, 15, 0, 255, explosion.m_vecPosition, explosion.m_fRadius, 80.0f, gpCoronaTexture[7], CCoronas::TYPE_STAR, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
} else if (explosion.m_nIteration & 1) {
if (explosion.m_pVictimEntity != nil)
CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, explosion.m_pVictimEntity->GetPosition(), CVector(0.0f, 0.0f, 0.0f), nil, CGeneral::GetRandomNumberInRange(0.5f, 0.8f), color);
CVector pos = explosion.m_vecPosition;
pos.z += 1.0f;
CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, pos, CVector(0.0f, 0.0f, 0.11f), nil, CGeneral::GetRandomNumberInRange(0.5f, 2.0f), color);
}
break;
case EXPLOSION_TANK_GRENADE:
case EXPLOSION_HELI_BOMB:
if (explosion.m_nIteration < 5) {
float ff = ((float)explosion.m_nIteration * 0.65f);
for (int i = 0; i < 10 * ff; i++) {
uint8 x = CGeneral::GetRandomNumber(), y = CGeneral::GetRandomNumber(), z = CGeneral::GetRandomNumber();
CVector pos(x - 128, y - 128, (z % 128) + 1);
pos.Normalise();
pos *= ff / 5.0f;
pos += explosion.m_vecPosition;
pos.z += 0.5f;
CParticle::AddParticle(PARTICLE_EXPLOSION_LARGE, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, CGeneral::GetRandomNumberInRange(-3.0f, 3.0f), CGeneral::GetRandomNumberInRange(-180.0f, 180.0f));
}
}
break;
}
if (someTime > 0)
explosion.m_nIteration++;
else
explosion.m_nIteration = 0;
}
}
}
bool
CExplosion::TestForExplosionInArea(eExplosionType type, float x1, float x2, float y1, float y2, float z1, float z2)
{
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
if (gaExplosion[i].m_bActive) {
if (a1 == gaExplosion[i].m_ExplosionType) {
if (gaExplosion[i].m_nIteration != 0) {
if (type == gaExplosion[i].m_ExplosionType) {
if (gaExplosion[i].m_vecPosition.x >= x1 && gaExplosion[i].m_vecPosition.x <= x2) {
if (gaExplosion[i].m_vecPosition.y >= y1 && gaExplosion[i].m_vecPosition.y <= y2) {
if (gaExplosion[i].m_vecPosition.z >= z1 && gaExplosion[i].m_vecPosition.z <= z2)
@ -97,13 +448,26 @@ CExplosion::TestForExplosionInArea(eExplosionType a1, float x1, float x2, float
return false;
}
void
CExplosion::RemoveAllExplosionsInArea(CVector pos, float radius)
{
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
if (gaExplosion[i].m_nIteration != 0) {
if ((pos - gaExplosion[i].m_vecPosition).MagnitudeSqr() < SQR(radius))
gaExplosion[i].m_nIteration = 0;
}
}
}
STARTPATCHES
InjectHook(0x559030, &CExplosion::Initialise, PATCH_JUMP);
InjectHook(0x559100, &CExplosion::Shutdown, PATCH_JUMP);
InjectHook(0x55AD40, &CExplosion::RemoveAllExplosionsInArea, PATCH_JUMP);
InjectHook(0x559140, &CExplosion::GetExplosionActiveCounter, PATCH_JUMP);
InjectHook(0x5591A0, &CExplosion::GetExplosionPosition, PATCH_JUMP);
InjectHook(0x559180, &CExplosion::GetExplosionType, PATCH_JUMP);
InjectHook(0x559160, &CExplosion::ResetExplosionActiveCounter, PATCH_JUMP);
InjectHook(0x559180, &CExplosion::GetExplosionType, PATCH_JUMP);
InjectHook(0x5591A0, &CExplosion::GetExplosionPosition, PATCH_JUMP);
InjectHook(0x5591C0, &CExplosion::AddExplosion, PATCH_JUMP);
InjectHook(0x55A0C0, &CExplosion::Update, PATCH_JUMP);
InjectHook(0x55AC80, &CExplosion::TestForExplosionInArea, PATCH_JUMP);
InjectHook(0x55AD40, &CExplosion::RemoveAllExplosionsInArea, PATCH_JUMP);
ENDPATCHES

View File

@ -26,25 +26,24 @@ class CExplosion
CEntity *m_pCreatorEntity;
CEntity *m_pVictimEntity;
float m_fStopTime;
bool m_bActive;
int8 m_bActiveCounter;
int32 m_nStartTime;
uint8 m_nIteration;
uint8 m_nActiveCounter;
float m_fStartTime;
uint32 m_nParticlesExpireTime;
float m_fPower;
int32 field_34;
int32 field_38;
bool m_bIsBoat;
float m_fZshift;
public:
static void Initialise();
static void Shutdown();
static void AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type,
const CVector &pos, uint32);
static int8 GetExplosionActiveCounter(uint8 id);
static CVector *GetExplosionPosition(uint8 id);
static uint8 GetExplosionType(uint8 id);
static void ResetExplosionActiveCounter(uint8 id);
static void RemoveAllExplosionsInArea(CVector, float);
static bool TestForExplosionInArea(eExplosionType, float, float, float, float, float, float);
static uint8 GetExplosionType(uint8 id);
static CVector *GetExplosionPosition(uint8 id);
static bool AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32 lifetime);
static void Update();
static bool TestForExplosionInArea(eExplosionType type, float x1, float x2, float y1, float y2, float z1, float z2);
static void RemoveAllExplosionsInArea(CVector pos, float radius);
};
extern CExplosion (&gaExplosion)[48];
extern CExplosion (&gaExplosion)[NUM_EXPLOSIONS];