mirror of https://github.com/Nofated095/re-GTA.git
Merge branch 'master' of github.com:GTAmodding/re3
This commit is contained in:
commit
7da8184b37
|
@ -0,0 +1,308 @@
|
|||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "CarGen.h"
|
||||
|
||||
#include "Automobile.h"
|
||||
#include "Boat.h"
|
||||
#include "Camera.h"
|
||||
#include "CarCtrl.h"
|
||||
#include "CutsceneMgr.h"
|
||||
#include "General.h"
|
||||
#include "Pools.h"
|
||||
#include "Streaming.h"
|
||||
#include "Timer.h"
|
||||
#include "Vehicle.h"
|
||||
#include "World.h"
|
||||
|
||||
uint8 &CTheCarGenerators::ProcessCounter = *(uint8*)0x95CDAF;
|
||||
uint32 &CTheCarGenerators::NumOfCarGenerators = *(uint32*)0x8E2C1C;
|
||||
CCarGenerator (&CTheCarGenerators::CarGeneratorArray)[NUM_CARGENS] = *(CCarGenerator(*)[NUM_CARGENS])*(uintptr*)0x87CB18;
|
||||
uint8 &CTheCarGenerators::GenerateEvenIfPlayerIsCloseCounter = *(uint8*)0x95CDC6;
|
||||
uint32 &CTheCarGenerators::CurrentActiveCount = *(uint32*)0x8F2C5C;
|
||||
|
||||
void CCarGenerator::SwitchOff()
|
||||
{
|
||||
m_nUsesRemaining = 0;
|
||||
--CTheCarGenerators::CurrentActiveCount;
|
||||
}
|
||||
|
||||
void CCarGenerator::SwitchOn()
|
||||
{
|
||||
m_nUsesRemaining = -1;
|
||||
m_nTimer = CalcNextGen();
|
||||
++CTheCarGenerators::CurrentActiveCount;
|
||||
}
|
||||
|
||||
uint32 CCarGenerator::CalcNextGen()
|
||||
{
|
||||
return CTimer::GetTimeInMilliseconds() + 4;
|
||||
}
|
||||
|
||||
void CCarGenerator::DoInternalProcessing()
|
||||
{
|
||||
if (CheckForBlockage()) {
|
||||
m_nTimer += 4;
|
||||
if (m_nUsesRemaining == 0)
|
||||
--CTheCarGenerators::CurrentActiveCount;
|
||||
return;
|
||||
}
|
||||
if (CCarCtrl::NumParkedCars >= 10)
|
||||
return;
|
||||
CStreaming::RequestModel(m_nModelIndex, STREAMFLAGS_DEPENDENCY);
|
||||
if (!CStreaming::HasModelLoaded(m_nModelIndex))
|
||||
return;
|
||||
if (CModelInfo::IsBoatModel(m_nModelIndex)){
|
||||
CBoat* pBoat = new CBoat(m_nModelIndex, PARKED_VEHICLE);
|
||||
pBoat->bIsStatic = false;
|
||||
pBoat->bEngineOn = false;
|
||||
CVector pos = m_vecPos;
|
||||
if (pos.z <= -100.0f)
|
||||
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
|
||||
pos.z += pBoat->GetDistanceFromCentreOfMassToBaseOfModel();
|
||||
pBoat->GetPosition() = pos;
|
||||
pBoat->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle));
|
||||
pBoat->m_status = STATUS_ABANDONED;
|
||||
pBoat->m_nDoorLock = CARLOCK_UNLOCKED;
|
||||
CWorld::Add(pBoat);
|
||||
if (CGeneral::GetRandomNumberInRange(0, 100) < m_nAlarm)
|
||||
pBoat->m_nAlarmState = -1;
|
||||
if (CGeneral::GetRandomNumberInRange(0, 100) < m_nDoorlock)
|
||||
pBoat->m_nDoorLock = CARLOCK_LOCKED;
|
||||
if (m_nColor1 != -1 && m_nColor2){
|
||||
pBoat->m_currentColour1 = m_nColor1;
|
||||
pBoat->m_currentColour2 = m_nColor2;
|
||||
}
|
||||
m_nVehicleHandle = CPools::GetVehiclePool()->GetIndex(pBoat);
|
||||
}else{
|
||||
bool groundFound = false;
|
||||
CVector pos = m_vecPos;
|
||||
if (pos.z > -100.0f){
|
||||
pos.z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, &groundFound);
|
||||
}else{
|
||||
CColPoint cp;
|
||||
CEntity* pEntity;
|
||||
groundFound = CWorld::ProcessVerticalLine(CVector(pos.x, pos.y, 1000.0f), -1000.0f,
|
||||
cp, pEntity, true, false, false, false, false, false, nil);
|
||||
if (groundFound)
|
||||
pos.z = cp.point.z;
|
||||
}
|
||||
if (!groundFound) {
|
||||
debug("CCarGenerator::DoInternalProcessing - can't find ground z for new car x = %f y = %f \n", m_vecPos.x, m_vecPos.y);
|
||||
}else{
|
||||
CAutomobile* pCar = new CAutomobile(m_nModelIndex, PARKED_VEHICLE);
|
||||
pCar->bIsStatic = false;
|
||||
pCar->bEngineOn = false;
|
||||
pos.z += pCar->GetDistanceFromCentreOfMassToBaseOfModel();
|
||||
pCar->GetPosition() = pos;
|
||||
pCar->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle));
|
||||
pCar->m_status = STATUS_ABANDONED;
|
||||
pCar->bLightsOn = false;
|
||||
pCar->m_nDoorLock = CARLOCK_UNLOCKED;
|
||||
CWorld::Add(pCar);
|
||||
if (CGeneral::GetRandomNumberInRange(0, 100) < m_nAlarm)
|
||||
pCar->m_nAlarmState = -1;
|
||||
if (CGeneral::GetRandomNumberInRange(0, 100) < m_nDoorlock)
|
||||
pCar->m_nDoorLock = CARLOCK_LOCKED;
|
||||
if (m_nColor1 != -1 && m_nColor2) {
|
||||
pCar->m_currentColour1 = m_nColor1;
|
||||
pCar->m_currentColour2 = m_nColor2;
|
||||
}
|
||||
m_nVehicleHandle = CPools::GetVehiclePool()->GetIndex(pCar);
|
||||
}
|
||||
}
|
||||
if (m_nUsesRemaining < -1) /* I don't think this is a correct comparasion */
|
||||
--m_nUsesRemaining;
|
||||
m_nTimer = CalcNextGen();
|
||||
if (m_nUsesRemaining == 0)
|
||||
--CTheCarGenerators::CurrentActiveCount;
|
||||
}
|
||||
|
||||
void CCarGenerator::Process()
|
||||
{
|
||||
if (m_nVehicleHandle == -1 &&
|
||||
(CTheCarGenerators::GenerateEvenIfPlayerIsCloseCounter || CTimer::GetTimeInMilliseconds() >= m_nTimer) &&
|
||||
m_nUsesRemaining != 0 && CheckIfWithinRangeOfAnyPlayer())
|
||||
DoInternalProcessing();
|
||||
if (m_nVehicleHandle == -1)
|
||||
return;
|
||||
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(m_nVehicleHandle);
|
||||
if (!pVehicle){
|
||||
m_nVehicleHandle = -1;
|
||||
return;
|
||||
}
|
||||
if (pVehicle->m_status != STATUS_PLAYER)
|
||||
return;
|
||||
m_nTimer += 60000;
|
||||
m_nVehicleHandle = -1;
|
||||
m_bIsBlocking = true;
|
||||
pVehicle->bExtendedRange = false;
|
||||
}
|
||||
|
||||
void CCarGenerator::Setup(float x, float y, float z, float angle, int32 mi, int16 color1, int16 color2, uint8 force, uint8 alarm, uint8 lock, uint16 min_delay, uint16 max_delay)
|
||||
{
|
||||
CMatrix m1, m2, m3; /* Unused but present on stack, so I'll leave them. */
|
||||
m_vecPos = CVector(x, y, z);
|
||||
m_fAngle = angle;
|
||||
m_nModelIndex = mi;
|
||||
m_nColor1 = color1;
|
||||
m_nColor2 = color2;
|
||||
m_bForceSpawn = force;
|
||||
m_nAlarm = alarm;
|
||||
m_nDoorlock = lock;
|
||||
m_nMinDelay = min_delay;
|
||||
m_nMaxDelay = max_delay;
|
||||
m_nVehicleHandle = -1;
|
||||
m_nTimer = CTimer::GetTimeInMilliseconds() + 1;
|
||||
m_nUsesRemaining = 0;
|
||||
m_bIsBlocking = false;
|
||||
m_vecInf = CModelInfo::GetModelInfo(m_nModelIndex)->GetColModel()->boundingBox.min;
|
||||
m_vecSup = CModelInfo::GetModelInfo(m_nModelIndex)->GetColModel()->boundingBox.max;
|
||||
m_fSize = max(m_vecInf.Magnitude(), m_vecSup.Magnitude());
|
||||
}
|
||||
|
||||
bool CCarGenerator::CheckForBlockage()
|
||||
{
|
||||
int16 entities;
|
||||
CWorld::FindObjectsKindaColliding(CVector(m_vecPos), m_fSize, 1, &entities, 2, nil, false, true, true, false, false);
|
||||
return entities > 0;
|
||||
}
|
||||
|
||||
bool CCarGenerator::CheckIfWithinRangeOfAnyPlayer()
|
||||
{
|
||||
CVector2D direction = FindPlayerCentreOfWorld(CWorld::PlayerInFocus) - m_vecPos;
|
||||
float distance = direction.Magnitude();
|
||||
float farclip = 120.0f * TheCamera.GenerationDistMultiplier;
|
||||
float nearclip = farclip - 20.0f;
|
||||
if (distance >= farclip){
|
||||
if (m_bIsBlocking)
|
||||
m_bIsBlocking = false;
|
||||
return false;
|
||||
}
|
||||
if (CTheCarGenerators::GenerateEvenIfPlayerIsCloseCounter)
|
||||
return true;
|
||||
if (m_bIsBlocking)
|
||||
return false;
|
||||
if (distance < nearclip)
|
||||
return false;
|
||||
return DotProduct2D(direction, FindPlayerSpeed()) <= 0;
|
||||
}
|
||||
|
||||
void CCarGenerator::Save(uint8* buffer)
|
||||
{
|
||||
*(uint32*)(buffer) = m_nModelIndex;
|
||||
*(CVector*)(buffer + 4) = m_vecPos;
|
||||
*(float*)(buffer + 16) = m_fAngle;
|
||||
*(int16*)(buffer + 20) = m_nColor1;
|
||||
*(int16*)(buffer + 22) = m_nColor2;
|
||||
*(bool*)(buffer + 24) = m_bForceSpawn;
|
||||
*(uint8*)(buffer + 25) = m_nAlarm;
|
||||
*(uint8*)(buffer + 26) = m_nDoorlock;
|
||||
*(uint8*)(buffer + 27) = 0;
|
||||
*(uint16*)(buffer + 28) = m_nMinDelay;
|
||||
*(uint16*)(buffer + 30) = m_nMaxDelay;
|
||||
*(uint32*)(buffer + 32) = m_nTimer;
|
||||
*(int32*)(buffer + 36) = m_nVehicleHandle;
|
||||
*(uint16*)(buffer + 40) = m_nUsesRemaining;
|
||||
*(bool*)(buffer + 42) = m_bIsBlocking;
|
||||
*(uint8*)(buffer + 43) = 0;
|
||||
*(CVector*)(buffer + 44) = m_vecInf;
|
||||
*(CVector*)(buffer + 56) = m_vecSup;
|
||||
*(float*)(buffer + 68) = m_fSize;
|
||||
}
|
||||
|
||||
void CCarGenerator::Load(uint8* buffer)
|
||||
{
|
||||
m_nModelIndex = *(uint32*)(buffer);
|
||||
m_vecPos = *(CVector*)(buffer + 4);
|
||||
m_fAngle = *(float*)(buffer + 16);
|
||||
m_nColor1 = *(int16*)(buffer + 20);
|
||||
m_nColor2 = *(int16*)(buffer + 22);
|
||||
m_bForceSpawn = *(bool*)(buffer + 24);
|
||||
m_nAlarm = *(uint8*)(buffer + 25);
|
||||
m_nDoorlock = *(uint8*)(buffer + 26);
|
||||
m_nMinDelay = *(uint16*)(buffer + 28);
|
||||
m_nMaxDelay = *(uint16*)(buffer + 30);
|
||||
m_nTimer = *(uint32*)(buffer + 32);
|
||||
m_nVehicleHandle = *(int32*)(buffer + 36);
|
||||
m_nUsesRemaining = *(uint16*)(buffer + 40);
|
||||
m_bIsBlocking = *(bool*)(buffer + 42);
|
||||
m_vecInf = *(CVector*)(buffer + 44);
|
||||
m_vecSup = *(CVector*)(buffer + 56);
|
||||
m_fSize = *(float*)(buffer + 68);
|
||||
}
|
||||
|
||||
void CTheCarGenerators::Process()
|
||||
{
|
||||
if (FindPlayerTrain() || CCutsceneMgr::IsRunning())
|
||||
return;
|
||||
if (++CTheCarGenerators::ProcessCounter == 4)
|
||||
CTheCarGenerators::ProcessCounter = 0;
|
||||
for (uint32 i = ProcessCounter; i < NumOfCarGenerators; i += 4)
|
||||
CTheCarGenerators::CarGeneratorArray[i].Process();
|
||||
if (GenerateEvenIfPlayerIsCloseCounter)
|
||||
GenerateEvenIfPlayerIsCloseCounter--;
|
||||
}
|
||||
|
||||
int32 CTheCarGenerators::CreateCarGenerator(float x, float y, float z, float angle, int32 mi, int16 color1, int16 color2, uint8 force, uint8 alarm, uint8 lock, uint16 min_delay, uint16 max_delay)
|
||||
{
|
||||
CarGeneratorArray[NumOfCarGenerators].Setup(x, y, z, angle, mi, color1, color2, force, alarm, lock, min_delay, max_delay);
|
||||
return NumOfCarGenerators++;
|
||||
}
|
||||
|
||||
void CTheCarGenerators::Init()
|
||||
{
|
||||
GenerateEvenIfPlayerIsCloseCounter = 0;
|
||||
NumOfCarGenerators = 0;
|
||||
ProcessCounter = 0;
|
||||
CurrentActiveCount = 0;
|
||||
}
|
||||
|
||||
void CTheCarGenerators::SaveAllCarGenerators(uint8 *buffer, uint32 *size)
|
||||
{
|
||||
*size = 28 + 72 * NUM_CARGENS;
|
||||
buffer[0] = 'C';
|
||||
buffer[1] = 'G';
|
||||
buffer[2] = 'N';
|
||||
buffer[3] = '\0';
|
||||
*(uint32*)(buffer + 4) = *size - 8;
|
||||
*(uint32*)(buffer + 8) = 12; /* what is this? */
|
||||
*(uint32*)(buffer + 12) = NumOfCarGenerators;
|
||||
*(uint32*)(buffer + 16) = CurrentActiveCount;
|
||||
*(uint8*)(buffer + 20) = ProcessCounter;
|
||||
*(uint8*)(buffer + 21) = GenerateEvenIfPlayerIsCloseCounter;
|
||||
*(uint16*)(buffer + 22) = 0;
|
||||
*(uint32*)(buffer + 24) = 72 * NUM_CARGENS;
|
||||
buffer += 28;
|
||||
for (int i = 0; i < NUM_CARGENS; i++){
|
||||
CarGeneratorArray[i].Save(buffer);
|
||||
buffer += 72;
|
||||
}
|
||||
}
|
||||
|
||||
void CTheCarGenerators::LoadAllCarGenerators(uint8* buffer, uint32 size)
|
||||
{
|
||||
Init();
|
||||
assert(size == 28 + NUM_CARGENS * 72);
|
||||
assert(buffer[0] == 'C');
|
||||
assert(buffer[1] == 'G');
|
||||
assert(buffer[2] == 'N');
|
||||
assert(buffer[3] == '\0');
|
||||
assert(*(uint32*)(buffer + 4) == size - 8);
|
||||
NumOfCarGenerators = *(uint32*)(buffer + 12);
|
||||
CurrentActiveCount = *(uint32*)(buffer + 16);
|
||||
ProcessCounter = *(uint8*)(buffer + 20);
|
||||
GenerateEvenIfPlayerIsCloseCounter = *(uint8*)(buffer + 21);
|
||||
assert(*(uint32*)(buffer + 24) == 72 * NUM_CARGENS);
|
||||
buffer += 28;
|
||||
for (int i = 0; i < NUM_CARGENS; i++) {
|
||||
CarGeneratorArray[i].Load(buffer);
|
||||
buffer += 72;
|
||||
}
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x543020, CTheCarGenerators::Init, PATCH_JUMP);
|
||||
InjectHook(0x542F40, CTheCarGenerators::Process, PATCH_JUMP);
|
||||
InjectHook(0x543050, CTheCarGenerators::SaveAllCarGenerators, PATCH_JUMP);
|
||||
InjectHook(0x5431E0, CTheCarGenerators::LoadAllCarGenerators, PATCH_JUMP);
|
||||
ENDPATCHES
|
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
|
||||
enum {
|
||||
CARGEN_MAXACTUALLIMIT = 100
|
||||
};
|
||||
|
||||
class CCarGenerator
|
||||
{
|
||||
int32 m_nModelIndex;
|
||||
CVector m_vecPos;
|
||||
float m_fAngle;
|
||||
int16 m_nColor1;
|
||||
int16 m_nColor2;
|
||||
uint8 m_bForceSpawn;
|
||||
uint8 m_nAlarm;
|
||||
uint8 m_nDoorlock;
|
||||
int16 m_nMinDelay;
|
||||
int16 m_nMaxDelay;
|
||||
uint32 m_nTimer;
|
||||
int32 m_nVehicleHandle;
|
||||
uint16 m_nUsesRemaining;
|
||||
bool m_bIsBlocking;
|
||||
CVector m_vecInf;
|
||||
CVector m_vecSup;
|
||||
float m_fSize;
|
||||
public:
|
||||
void SwitchOff();
|
||||
void SwitchOn();
|
||||
uint32 CalcNextGen();
|
||||
void DoInternalProcessing();
|
||||
void Process();
|
||||
void Setup(float x, float y, float z, float angle, int32 mi, int16 color1, int16 color2, uint8 force, uint8 alarm, uint8 lock, uint16 min_delay, uint16 max_delay);
|
||||
bool CheckForBlockage();
|
||||
bool CheckIfWithinRangeOfAnyPlayer();
|
||||
void Save(uint8*);
|
||||
void Load(uint8*);
|
||||
void SetUsesRemaining(uint16 uses) { m_nUsesRemaining = uses; }
|
||||
};
|
||||
|
||||
class CTheCarGenerators
|
||||
{
|
||||
public:
|
||||
static uint8 &ProcessCounter;
|
||||
static uint32 &NumOfCarGenerators;
|
||||
static CCarGenerator (&CarGeneratorArray)[NUM_CARGENS];
|
||||
static uint8 &GenerateEvenIfPlayerIsCloseCounter;
|
||||
static uint32 &CurrentActiveCount;
|
||||
|
||||
static void Process();
|
||||
static int32 CreateCarGenerator(float x, float y, float z, float angle, int32 mi, int16 color1, int16 color2, uint8 force, uint8 alarm, uint8 lock, uint16 min_delay, uint16 max_delay);
|
||||
static void Init();
|
||||
static void SaveAllCarGenerators(uint8 *, uint32 *);
|
||||
static void LoadAllCarGenerators(uint8 *, uint32);
|
||||
};
|
|
@ -63,6 +63,11 @@ CGarages::IsModelIndexADoor(uint32 id)
|
|||
id == MI_CRUSHERLID;
|
||||
}
|
||||
|
||||
bool CGarages::HasCarBeenCrushed(int32 handle)
|
||||
{
|
||||
return CrushedCarId == handle;
|
||||
}
|
||||
|
||||
WRAPPER void CGarages::TriggerMessage(char *text, int16, uint16 time, int16) { EAXJMP(0x426B20); }
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -24,4 +24,5 @@ public:
|
|||
static bool IsModelIndexADoor(uint32 id);
|
||||
static void TriggerMessage(char *text, int16, uint16 time, int16);
|
||||
static void PrintMessages(void);
|
||||
static bool HasCarBeenCrushed(int32);
|
||||
};
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
#include "Boat.h"
|
||||
#include "Camera.h"
|
||||
#include "CarCtrl.h"
|
||||
#include "CarGen.h"
|
||||
#include "CivilianPed.h"
|
||||
#include "Clock.h"
|
||||
#include "CopPed.h"
|
||||
#include "DMAudio.h"
|
||||
#include "EmergencyPed.h"
|
||||
#include "FileMgr.h"
|
||||
#include "Garages.h"
|
||||
#include "General.h"
|
||||
#include "HandlingMgr.h"
|
||||
#include "Hud.h"
|
||||
|
@ -2428,7 +2430,7 @@ int8 CRunningScript::ProcessCommandsFrom200To299(int32 command)
|
|||
{
|
||||
CollectParameters(&m_nIp, 2);
|
||||
bool value = GetPadState(ScriptParams[0], ScriptParams[1]) != 0;
|
||||
if (CGame::playingIntro && ScriptParams[0] && ScriptParams[1] == 12){ /* pad1, start */
|
||||
if (CGame::playingIntro && ScriptParams[0] == 0 && ScriptParams[1] == 12){ /* pad1, start */
|
||||
if (CPad::GetPad(0)->GetLeftMouseJustDown() ||
|
||||
CPad::GetPad(0)->GetPadEnterJustDown() ||
|
||||
CPad::GetPad(0)->GetCharJustDown(' '))
|
||||
|
@ -2801,6 +2803,281 @@ int8 CRunningScript::ProcessCommandsFrom200To299(int32 command)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if 1
|
||||
WRAPPER int8 CRunningScript::ProcessCommandsFrom300To399(int32 command) { EAXJMP(0x43ED30); }
|
||||
#else
|
||||
int8 CRunningScript::ProcessCommandsFrom300To399(int32 command)
|
||||
{
|
||||
switch (command) {
|
||||
/* Not implemented.
|
||||
case COMMAND_SET_CHAR_INVINCIBLE:
|
||||
case COMMAND_SET_PLAYER_INVINCIBLE:
|
||||
case COMMAND_SET_CHAR_GRAPHIC_TYPE:
|
||||
case COMMAND_SET_PLAYER_GRAPHIC_TYPE:
|
||||
*/
|
||||
case COMMAND_HAS_PLAYER_BEEN_ARRESTED:
|
||||
CollectParameters(&m_nIp, 1);
|
||||
UpdateCompareFlag(CWorld::Players[ScriptParams[0]].m_WBState == WBSTATE_BUSTED);
|
||||
return 0;
|
||||
/* Not implemented.
|
||||
case COMMAND_STOP_CHAR_DRIVING:
|
||||
case COMMAND_KILL_CHAR:
|
||||
case COMMAND_SET_FAVOURITE_CAR_MODEL_FOR_CHAR:
|
||||
case COMMAND_SET_CHAR_OCCUPATION:
|
||||
*/
|
||||
case COMMAND_CHANGE_CAR_LOCK:
|
||||
{
|
||||
CollectParameters(&m_nIp, 2);
|
||||
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
|
||||
assert(pVehicle);
|
||||
pVehicle->m_nDoorLock = (eCarLock)ScriptParams[1];
|
||||
return 0;
|
||||
}
|
||||
case COMMAND_SHAKE_CAM_WITH_POINT:
|
||||
CollectParameters(&m_nIp, 4);
|
||||
TheCamera.CamShake(ScriptParams[0] / 1000.0f,
|
||||
*(float*)&ScriptParams[1],
|
||||
*(float*)&ScriptParams[2],
|
||||
*(float*)&ScriptParams[3]);
|
||||
return 0;
|
||||
case COMMAND_IS_CAR_MODEL:
|
||||
{
|
||||
CollectParameters(&m_nIp, 2);
|
||||
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
|
||||
assert(pVehicle);
|
||||
UpdateCompareFlag(pVehicle->GetModelIndex() == ScriptParams[1]);
|
||||
}
|
||||
/* Not implemented.
|
||||
case COMMAND_IS_CAR_REMAP:
|
||||
case COMMAND_HAS_CAR_JUST_SUNK:
|
||||
case COMMAND_SET_CAR_NO_COLLIDE:
|
||||
*/
|
||||
case COMMAND_IS_CAR_DEAD_IN_AREA_2D:
|
||||
{
|
||||
CollectParameters(&m_nIp, 6);
|
||||
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
|
||||
assert(pVehicle);
|
||||
float x1, y1, x2, y2;
|
||||
x1 = *(float*)&ScriptParams[1];
|
||||
y1 = *(float*)&ScriptParams[2];
|
||||
x2 = *(float*)&ScriptParams[3];
|
||||
y2 = *(float*)&ScriptParams[4];
|
||||
UpdateCompareFlag(pVehicle->m_status == STATUS_WRECKED &&
|
||||
pVehicle->IsWithinArea(x1, y1, x2, y2));
|
||||
if (!ScriptParams[5])
|
||||
return 0;
|
||||
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, -100.0f);
|
||||
if (CTheScripts::DbgFlag)
|
||||
CTheScripts::DrawDebugSquare(x1, y1, x2, y2);
|
||||
return 0;
|
||||
}
|
||||
case COMMAND_IS_CAR_DEAD_IN_AREA_3D:
|
||||
{
|
||||
CollectParameters(&m_nIp, 8);
|
||||
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
|
||||
assert(pVehicle);
|
||||
float x1, y1, z1, x2, y2, z2;
|
||||
x1 = *(float*)&ScriptParams[1];
|
||||
y1 = *(float*)&ScriptParams[2];
|
||||
z1 = *(float*)&ScriptParams[3];
|
||||
x2 = *(float*)&ScriptParams[4];
|
||||
y2 = *(float*)&ScriptParams[5];
|
||||
z2 = *(float*)&ScriptParams[6];
|
||||
UpdateCompareFlag(pVehicle->m_status == STATUS_WRECKED &&
|
||||
pVehicle->IsWithinArea(x1, y1, z1, x2, y2, z2));
|
||||
if (!ScriptParams[7])
|
||||
return 0;
|
||||
CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, (z1 + z2) / 2);
|
||||
if (CTheScripts::DbgFlag)
|
||||
CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2);
|
||||
return 0;
|
||||
}
|
||||
/* Not implemented.
|
||||
case COMMAND_IS_TRAILER_ATTACHED:
|
||||
case COMMAND_IS_CAR_ON_TRAILER:
|
||||
case COMMAND_HAS_CAR_GOT_WEAPON:
|
||||
case COMMAND_PARK:
|
||||
case COMMAND_HAS_PARK_FINISHED:
|
||||
case COMMAND_KILL_ALL_PASSENGERS:
|
||||
case COMMAND_SET_CAR_BULLETPROOF:
|
||||
case COMMAND_SET_CAR_FLAMEPROOF:
|
||||
case COMMAND_SET_CAR_ROCKETPROOF:
|
||||
case COMMAND_IS_CARBOMB_ACTIVE:
|
||||
case COMMAND_GIVE_CAR_ALARM:
|
||||
case COMMAND_PUT_CAR_ON_TRAILER:
|
||||
*/
|
||||
case COMMAND_IS_CAR_CRUSHED:
|
||||
CollectParameters(&m_nIp, 1);
|
||||
UpdateCompareFlag(CGarages::HasCarBeenCrushed(ScriptParams[0]));
|
||||
return 0;
|
||||
/* Not implemented.
|
||||
case COMMAND_CREATE_GANG_CAR:
|
||||
*/
|
||||
case COMMAND_CREATE_CAR_GENERATOR:
|
||||
CollectParameters(&m_nIp, 12);
|
||||
ScriptParams[0] = CTheCarGenerators::CreateCarGenerator(
|
||||
*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2], *(float*)&ScriptParams[3],
|
||||
ScriptParams[4], ScriptParams[5], ScriptParams[6], ScriptParams[7],
|
||||
ScriptParams[8], ScriptParams[9], ScriptParams[10], ScriptParams[11]);
|
||||
StoreParameters(&m_nIp, 1);
|
||||
return 0;
|
||||
case COMMAND_SWITCH_CAR_GENERATOR:
|
||||
{
|
||||
CollectParameters(&m_nIp, 2);
|
||||
CCarGenerator* pCarGen = &CTheCarGenerators::CarGeneratorArray[ScriptParams[0]];
|
||||
if (ScriptParams[1] == 0){
|
||||
pCarGen->SwitchOff();
|
||||
}else if (ScriptParams[1] <= 100){
|
||||
pCarGen->SwitchOn();
|
||||
}else{
|
||||
pCarGen->SwitchOn();
|
||||
pCarGen->SetUsesRemaining(ScriptParams[1]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case COMMAND_ADD_PAGER_MESSAGE:
|
||||
{
|
||||
wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
|
||||
CollectParameters(&m_nIp, 3);
|
||||
CUserDisplay::Pager.AddMessage(text, ScriptParams[0], ScriptParams[1], ScriptParams[2]);
|
||||
return 0;
|
||||
}
|
||||
case COMMAND_DISPLAY_ONSCREEN_TIMER:
|
||||
{
|
||||
assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
|
||||
m_nIp++;
|
||||
CUserDisplay::OnscnTimer.AddClock(CTheScripts::Read2BytesFromScript(&m_nIp), nil);
|
||||
return 0;
|
||||
}
|
||||
case COMMAND_CLEAR_ONSCREEN_TIMER:
|
||||
{
|
||||
assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
|
||||
m_nIp++;
|
||||
CUserDisplay::OnscnTimer.ClearClock(CTheScripts::Read2BytesFromScript(&m_nIp));
|
||||
return 0;
|
||||
}
|
||||
case COMMAND_DISPLAY_ONSCREEN_COUNTER:
|
||||
{
|
||||
assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
|
||||
m_nIp++;
|
||||
int32 counter = CTheScripts::Read2BytesFromScript(&m_nIp);
|
||||
CollectParameters(&m_nIp, 1);
|
||||
CUserDisplay::OnscnTimer.AddCounter(counter, ScriptParams[0], nil);
|
||||
return 0;
|
||||
}
|
||||
case COMMAND_CLEAR_ONSCREEN_COUNTER:
|
||||
{
|
||||
assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
|
||||
m_nIp++;
|
||||
CUserDisplay::OnscnTimer.ClearCounter(CTheScripts::Read2BytesFromScript(&m_nIp));
|
||||
return 0;
|
||||
}
|
||||
case COMMAND_SET_ZONE_CAR_INFO:
|
||||
{
|
||||
char label[12];
|
||||
CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
|
||||
m_nIp += 8;
|
||||
CollectParameters(&m_nIp, 16);
|
||||
int zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
|
||||
if (zone < 0) {
|
||||
debug("Couldn't find zone - %s\n", label);
|
||||
return 0;
|
||||
}
|
||||
CTheZones::SetZoneCarInfo(zone, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3],
|
||||
ScriptParams[4], ScriptParams[5], ScriptParams[6], ScriptParams[7], ScriptParams[8], 0, 0,
|
||||
ScriptParams[9], ScriptParams[10], ScriptParams[11], ScriptParams[12],
|
||||
ScriptParams[13], ScriptParams[14], ScriptParams[15]);
|
||||
return 0;
|
||||
}
|
||||
/* Not implemented.
|
||||
case COMMAND_IS_CHAR_IN_GANG_ZONE:
|
||||
*/
|
||||
case COMMAND_IS_CHAR_IN_ZONE:
|
||||
{
|
||||
CollectParameters(&m_nIp, 1);
|
||||
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
|
||||
assert(pPed);
|
||||
char label[12];
|
||||
CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
|
||||
int zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
|
||||
if (zone != -1)
|
||||
m_nIp += 8;
|
||||
CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
|
||||
UpdateCompareFlag(CTheZones::PointLiesWithinZone(pos, CTheZones::GetZone(zone)));
|
||||
return 0;
|
||||
}
|
||||
case COMMAND_SET_CAR_DENSITY:
|
||||
{
|
||||
char label[12];
|
||||
CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
|
||||
m_nIp += 8;
|
||||
|
||||
}
|
||||
case COMMAND_SET_PED_DENSITY:
|
||||
case COMMAND_POINT_CAMERA_AT_PLAYER:
|
||||
case COMMAND_POINT_CAMERA_AT_CAR:
|
||||
case COMMAND_POINT_CAMERA_AT_CHAR:
|
||||
case COMMAND_RESTORE_CAMERA:
|
||||
case COMMAND_SHAKE_PAD:
|
||||
case COMMAND_SET_ZONE_PED_INFO:
|
||||
case COMMAND_SET_TIME_SCALE:
|
||||
case COMMAND_IS_CAR_IN_AIR:
|
||||
case COMMAND_SET_FIXED_CAMERA_POSITION:
|
||||
case COMMAND_POINT_CAMERA_AT_POINT:
|
||||
case COMMAND_ADD_BLIP_FOR_CAR_OLD:
|
||||
case COMMAND_ADD_BLIP_FOR_CHAR_OLD:
|
||||
case COMMAND_ADD_BLIP_FOR_OBJECT_OLD:
|
||||
case COMMAND_REMOVE_BLIP:
|
||||
case COMMAND_CHANGE_BLIP_COLOUR:
|
||||
case COMMAND_DIM_BLIP:
|
||||
case COMMAND_ADD_BLIP_FOR_COORD_OLD:
|
||||
case COMMAND_CHANGE_BLIP_SCALE:
|
||||
case COMMAND_SET_FADING_COLOUR:
|
||||
case COMMAND_DO_FADE:
|
||||
case COMMAND_GET_FADING_STATUS:
|
||||
case COMMAND_ADD_HOSPITAL_RESTART:
|
||||
case COMMAND_ADD_POLICE_RESTART:
|
||||
case COMMAND_OVERRIDE_NEXT_RESTART:
|
||||
case COMMAND_DRAW_SHADOW:
|
||||
case COMMAND_GET_PLAYER_HEADING:
|
||||
case COMMAND_SET_PLAYER_HEADING:
|
||||
case COMMAND_GET_CHAR_HEADING:
|
||||
case COMMAND_SET_CHAR_HEADING:
|
||||
case COMMAND_GET_CAR_HEADING:
|
||||
case COMMAND_SET_CAR_HEADING:
|
||||
case COMMAND_GET_OBJECT_HEADING:
|
||||
case COMMAND_SET_OBJECT_HEADING:
|
||||
case COMMAND_IS_PLAYER_TOUCHING_OBJECT:
|
||||
case COMMAND_IS_CHAR_TOUCHING_OBJECT:
|
||||
case COMMAND_SET_PLAYER_AMMO:
|
||||
case COMMAND_SET_CHAR_AMMO:
|
||||
case COMMAND_SET_CAR_AMMO:
|
||||
case COMMAND_LOAD_CAMERA_SPLINE:
|
||||
case COMMAND_MOVE_CAMERA_ALONG_SPLINE:
|
||||
case COMMAND_GET_CAMERA_POSITION_ALONG_SPLINE:
|
||||
case COMMAND_DECLARE_MISSION_FLAG:
|
||||
case COMMAND_DECLARE_MISSION_FLAG_FOR_CONTACT:
|
||||
case COMMAND_DECLARE_BASE_BRIEF_ID_FOR_CONTACT:
|
||||
case COMMAND_IS_PLAYER_HEALTH_GREATER:
|
||||
case COMMAND_IS_CHAR_HEALTH_GREATER:
|
||||
case COMMAND_IS_CAR_HEALTH_GREATER:
|
||||
case COMMAND_ADD_BLIP_FOR_CAR:
|
||||
case COMMAND_ADD_BLIP_FOR_CHAR:
|
||||
case COMMAND_ADD_BLIP_FOR_OBJECT:
|
||||
case COMMAND_ADD_BLIP_FOR_CONTACT_POINT:
|
||||
case COMMAND_ADD_BLIP_FOR_COORD:
|
||||
case COMMAND_CHANGE_BLIP_DISPLAY:
|
||||
case COMMAND_ADD_ONE_OFF_SOUND:
|
||||
case COMMAND_ADD_CONTINUOUS_SOUND:
|
||||
case COMMAND_REMOVE_SOUND:
|
||||
case COMMAND_IS_CAR_STUCK_ON_ROOF:
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int16 CRunningScript::GetPadState(uint16 pad, uint16 button)
|
||||
{
|
||||
CPad* pPad = CPad::GetPad(pad);
|
||||
|
@ -2830,7 +3107,6 @@ int16 CRunningScript::GetPadState(uint16 pad, uint16 button)
|
|||
return 0;
|
||||
}
|
||||
|
||||
WRAPPER int8 CRunningScript::ProcessCommandsFrom300To399(int32 command) { EAXJMP(0x43ED30); }
|
||||
WRAPPER int8 CRunningScript::ProcessCommandsFrom400To499(int32 command) { EAXJMP(0x440CB0); }
|
||||
WRAPPER int8 CRunningScript::ProcessCommandsFrom500To599(int32 command) { EAXJMP(0x4429C0); }
|
||||
WRAPPER int8 CRunningScript::ProcessCommandsFrom600To699(int32 command) { EAXJMP(0x444B20); }
|
||||
|
@ -2893,4 +3169,4 @@ InjectHook(0x439000, &CTheScripts::StartNewScript, PATCH_JUMP);
|
|||
InjectHook(0x439040, &CTheScripts::Process, PATCH_JUMP);
|
||||
InjectHook(0x439400, &CTheScripts::StartTestScript, PATCH_JUMP);
|
||||
InjectHook(0x439410, &CTheScripts::IsPlayerOnAMission, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
ENDPATCHES
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include "common.h"
|
||||
#include "Text.h"
|
||||
#include "Sprite2d.h"
|
||||
|
||||
class CEntity;
|
||||
|
@ -373,6 +374,11 @@ public:
|
|||
return Read2BytesFromScript(pIp) / 16.0f;
|
||||
}
|
||||
static void ReadTextLabelFromScript(uint32* pIp, char* buf){
|
||||
strncpy(buf, (const char*)&CTheScripts::ScriptSpace[*pIp], 8);
|
||||
strncpy(buf, (const char*)&ScriptSpace[*pIp], 8);
|
||||
}
|
||||
static wchar* GetTextByKeyFromScript(uint32* pIp) {
|
||||
wchar* text = TheText.Get((const char*)&ScriptSpace[*pIp]);
|
||||
*pIp += 8;
|
||||
return text;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -13,6 +13,8 @@ COnscreenTimer& CUserDisplay::OnscnTimer = *(COnscreenTimer*)0x862238;
|
|||
CPager& CUserDisplay::Pager = *(CPager*)0x8F2744;
|
||||
CCurrentVehicle& CUserDisplay::CurrentVehicle = *(CCurrentVehicle*)0x8F5FE8;
|
||||
|
||||
WRAPPER void CPager::AddMessage(wchar*, uint16, uint16, uint16) { EAXJMP(0x52B940); }
|
||||
|
||||
void COnscreenTimer::Init() {
|
||||
m_bDisabled = false;
|
||||
for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) {
|
||||
|
|
|
@ -52,6 +52,8 @@ class CCurrentVehicle
|
|||
|
||||
class CPager
|
||||
{
|
||||
public:
|
||||
void AddMessage(wchar*, uint16, uint16, uint16);
|
||||
};
|
||||
|
||||
class CUserDisplay
|
||||
|
|
|
@ -275,6 +275,9 @@ CWanted::UpdateWantedLevel()
|
|||
{
|
||||
int32 CurrWantedLevel = m_nWantedLevel;
|
||||
|
||||
if (m_nChaos > nMaximumWantedLevel)
|
||||
m_nChaos = nMaximumWantedLevel;
|
||||
|
||||
if (m_nChaos >= 0 && m_nChaos < 40) {
|
||||
m_nWantedLevel = 0;
|
||||
m_MaximumLawEnforcerVehicles = 0;
|
||||
|
|
|
@ -29,6 +29,7 @@ bool &CWorld::bForceProcessControl = *(bool*)0x95CD6C;
|
|||
bool &CWorld::bProcessCutsceneOnly = *(bool*)0x95CD8B;
|
||||
|
||||
WRAPPER void CWorld::RemoveReferencesToDeletedObject(CEntity*) { EAXJMP(0x4B3BF0); }
|
||||
WRAPPER void CWorld::FindObjectsKindaColliding(const CVector &, float, bool, int16*, int16, CEntity **, bool, bool, bool, bool, bool){ EAXJMP(0x4B2A30); }
|
||||
|
||||
void
|
||||
CWorld::Add(CEntity *ent)
|
||||
|
|
|
@ -103,6 +103,7 @@ public:
|
|||
static float FindGroundZFor3DCoord(float x, float y, float z, bool *found);
|
||||
static float FindRoofZFor3DCoord(float x, float y, float z, bool *found);
|
||||
static void RemoveReferencesToDeletedObject(CEntity*);
|
||||
static void FindObjectsKindaColliding(const CVector &, float, bool, int16*, int16, CEntity **, bool, bool, bool, bool, bool);
|
||||
|
||||
static float GetSectorX(float f) { return ((f - WORLD_MIN_X)/SECTOR_SIZE_X); }
|
||||
static float GetSectorY(float f) { return ((f - WORLD_MIN_Y)/SECTOR_SIZE_Y); }
|
||||
|
|
|
@ -64,6 +64,8 @@ enum Config {
|
|||
NUMRADARBLIPS = 32,
|
||||
NUMPICKUPS = 336,
|
||||
NUMEVENTS = 64,
|
||||
|
||||
NUM_CARGENS = 160
|
||||
};
|
||||
|
||||
// We'll use this once we're ready to become independent of the game
|
||||
|
|
|
@ -59,8 +59,8 @@ CVehicle::CVehicle(uint8 CreatedBy)
|
|||
m_pBlowUpEntity = nil;
|
||||
field_1FB = 0;
|
||||
bComedyControls = false;
|
||||
m_veh_flagB40 = false;
|
||||
m_veh_flagB80 = false;
|
||||
bCraneMessageDone = false;
|
||||
bExtendedRange = false;
|
||||
bTakeLessDamage = false;
|
||||
bIsDamaged = false;
|
||||
bFadeOut = false;
|
||||
|
|
|
@ -181,8 +181,8 @@ public:
|
|||
uint8 bLowVehicle: 1; // Need this for sporty type cars to use low getting-in/out anims
|
||||
uint8 bComedyControls : 1; // Will make the car hard to control (hopefully in a funny way)
|
||||
uint8 bWarnedPeds : 1; // Has scan and warn peds of danger been processed?
|
||||
uint8 m_veh_flagB40 : 1;
|
||||
uint8 m_veh_flagB80 : 1;
|
||||
uint8 bCraneMessageDone : 1; // A crane message has been printed for this car allready
|
||||
uint8 bExtendedRange : 1; // This vehicle needs to be a bit further away to get deleted
|
||||
|
||||
uint8 bTakeLessDamage : 1; // This vehicle is stronger (takes about 1/4 of damage)
|
||||
uint8 bIsDamaged : 1; // This vehicle has been damaged and is displaying all its components
|
||||
|
|
Loading…
Reference in New Issue