Merge branch 'master' of github.com:Fire-Head/re3
This commit is contained in:
commit
73e2a4b035
@ -4037,7 +4037,7 @@ cAudioManager::ProcessEntity(int32 id)
|
||||
case AUDIOTYPE_BRIDGE:
|
||||
if(!m_bUserPause) {
|
||||
m_sQueueSample.m_bReverbFlag = 1;
|
||||
cAudioManager::ProcessBridgeOneShots();
|
||||
cAudioManager::ProcessBridge();
|
||||
}
|
||||
break;
|
||||
case AUDIOTYPE_FRONTEND:
|
||||
|
@ -20,9 +20,9 @@ enum eSound : int16
|
||||
SOUND_F = 15,
|
||||
SOUND_CAR_ENGINE_START = 16,
|
||||
SOUND_CAR_LIGHT_BREAK = 17,
|
||||
SOUND_CAR_HYDRALIC_1 = 18,
|
||||
SOUND_CAR_HYDRALIC_2 = 19,
|
||||
SOUND_CAR_HYDRALIC_3 = 20,
|
||||
SOUND_CAR_HYDRAULIC_1 = 18,
|
||||
SOUND_CAR_HYDRAULIC_2 = 19,
|
||||
SOUND_CAR_HYDRAULIC_3 = 20,
|
||||
SOUND_CAR_JERK = 21,
|
||||
SOUND_CAR_SPLASH = 22,
|
||||
SOUND_17 = 23,
|
||||
@ -35,18 +35,18 @@ enum eSound : int16
|
||||
SOUND_STEP_END = 30,
|
||||
SOUND_FALL_LAND = 31,
|
||||
SOUND_FALL_COLLAPSE = 32,
|
||||
SOUND_21 = 33,
|
||||
SOUND_22 = 34,
|
||||
SOUND_23 = 35,
|
||||
SOUND_24 = 36,
|
||||
SOUND_25 = 37,
|
||||
SOUND_26 = 38,
|
||||
SOUND_WEAPON_PUNCH_ATTACK = 39,
|
||||
SOUND_28 = 40,
|
||||
SOUND_29 = 41,
|
||||
SOUND_2A = 42,
|
||||
SOUND_2B = 43,
|
||||
SOUND_2C = 44,
|
||||
SOUND_FIGHT_PUNCH_33 = 33,
|
||||
SOUND_FIGHT_KICK_34 = 34,
|
||||
SOUND_FIGHT_HEADBUTT_35 = 35,
|
||||
SOUND_FIGHT_PUNCH_36 = 36,
|
||||
SOUND_FIGHT_PUNCH_37 = 37,
|
||||
SOUND_FIGHT_CLOSE_PUNCH_38 = 38,
|
||||
SOUND_FIGHT_PUNCH_39 = 39,
|
||||
SOUND_FIGHT_PUNCH_OR_KICK_BELOW_40 = 40,
|
||||
SOUND_FIGHT_PUNCH_41 = 41,
|
||||
SOUND_FIGHT_PUNCH_FROM_BEHIND_42 = 42,
|
||||
SOUND_FIGHT_KNEE_OR_KICK_43 = 43,
|
||||
SOUND_FIGHT_KICK_44 = 44,
|
||||
SOUND_2D = 45,
|
||||
SOUND_WEAPON_BAT_ATTACK = 46,
|
||||
SOUND_WEAPON_SHOT_FIRED = 47,
|
||||
|
@ -7,6 +7,9 @@ int &CCarCtrl::NumAmbulancesOnDuty = *(int*)0x885BB0;
|
||||
int &CCarCtrl::NumFiretrucksOnDuty = *(int*)0x9411F0;
|
||||
bool &CCarCtrl::bCarsGeneratedAroundCamera = *(bool*)0x95CD8A;
|
||||
float& CCarCtrl::CarDensityMultiplier = *(float*)0x5EC8B4;
|
||||
int32 &CCarCtrl::NumMissionCars = *(int32*)0x8F1B54;
|
||||
int32 &CCarCtrl::NumRandomCars = *(int32*)0x943118;
|
||||
int32 &CCarCtrl::NumParkedCars = *(int32*)0x8F29E0;
|
||||
|
||||
WRAPPER void CCarCtrl::SwitchVehicleToRealPhysics(CVehicle*) { EAXJMP(0x41F7F0); }
|
||||
WRAPPER void CCarCtrl::AddToCarArray(int32 id, int32 vehclass) { EAXJMP(0x4182F0); }
|
||||
@ -17,6 +20,7 @@ WRAPPER void CCarCtrl::JoinCarWithRoadSystem(CVehicle*) { EAXJMP(0x41F820); }
|
||||
WRAPPER void CCarCtrl::SteerAICarWithPhysics(CVehicle*) { EAXJMP(0x41DA60); }
|
||||
WRAPPER void CCarCtrl::UpdateCarOnRails(CVehicle*) { EAXJMP(0x418880); }
|
||||
WRAPPER void CCarCtrl::ScanForPedDanger(CVehicle *veh) { EAXJMP(0x418F40); }
|
||||
WRAPPER void CCarCtrl::RemoveFromInterestingVehicleList(CVehicle* v) { EAXJMP(0x41F7A0); }
|
||||
|
||||
bool
|
||||
CCarCtrl::MapCouldMoveInThisArea(float x, float y)
|
||||
|
@ -15,10 +15,14 @@ public:
|
||||
static void UpdateCarOnRails(CVehicle*);
|
||||
static bool MapCouldMoveInThisArea(float x, float y);
|
||||
static void ScanForPedDanger(CVehicle *veh);
|
||||
static void RemoveFromInterestingVehicleList(CVehicle*);
|
||||
|
||||
static int32 &NumLawEnforcerCars;
|
||||
static int32 &NumAmbulancesOnDuty;
|
||||
static int32 &NumFiretrucksOnDuty;
|
||||
static int32 &NumRandomCars;
|
||||
static int32 &NumMissionCars;
|
||||
static int32 &NumParkedCars;
|
||||
static bool &bCarsGeneratedAroundCamera;
|
||||
static float &CarDensityMultiplier;
|
||||
};
|
||||
|
308
src/control/CarGen.cpp
Normal file
308
src/control/CarGen.cpp
Normal file
@ -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
|
56
src/control/CarGen.h
Normal file
56
src/control/CarGen.h
Normal file
@ -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);
|
||||
};
|
||||
|
@ -76,6 +76,7 @@ CPhoneInfo::Load(CPhoneInfo *source, uint8 buffer)
|
||||
|
||||
m_aPhones[phoneId].m_vecPos = phone->m_vecPos;
|
||||
memcpy(m_aPhones[phoneId].m_apMessages, phone->m_apMessages, sizeof(wchar*) * 6);
|
||||
m_aPhones[phoneId].m_lastTimeRepeatedMsgShown = phone->m_lastTimeRepeatedMsgShown;
|
||||
m_aPhones[phoneId].m_pEntity = phone->m_pEntity;
|
||||
m_aPhones[phoneId].m_nState = phone->m_nState;
|
||||
m_aPhones[phoneId].field_30 = phone->field_30;
|
||||
@ -183,13 +184,14 @@ CPhoneInfo::Save(CPhoneInfo *destination, uint32 *size)
|
||||
|
||||
phone->m_vecPos = m_aPhones[phoneId].m_vecPos;
|
||||
memcpy(phone->m_apMessages, m_aPhones[phoneId].m_apMessages, sizeof(wchar*) * 6);
|
||||
phone->m_lastTimeRepeatedMsgShown = m_aPhones[phoneId].m_lastTimeRepeatedMsgShown;
|
||||
phone->m_pEntity = m_aPhones[phoneId].m_pEntity;
|
||||
phone->m_nState = m_aPhones[phoneId].m_nState;
|
||||
phone->field_30 = m_aPhones[phoneId].field_30;
|
||||
|
||||
// Convert entity pointer to building pool index while saving
|
||||
if (phone->m_pEntity) {
|
||||
phone->m_pEntity = (CEntity*) CPools::GetBuildingPool()->GetJustIndex((CBuilding*)phone->m_pEntity) + 1;
|
||||
phone->m_pEntity = (CEntity*) (CPools::GetBuildingPool()->GetJustIndex((CBuilding*)phone->m_pEntity) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,7 +212,7 @@ PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg)
|
||||
CPed *ped = (CPed*)arg;
|
||||
|
||||
if (assoc->blendAmount > 0.5f)
|
||||
ped->m_ped_flagC10 = true;
|
||||
ped->bUpdateAnimHeading = true;
|
||||
|
||||
if (ped->m_nPedState == PED_MAKE_CALL)
|
||||
ped->m_nPedState = PED_IDLE;
|
||||
@ -244,10 +246,10 @@ PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg)
|
||||
|
||||
CPed *ped = CPhoneInfo::pedWhoPickingUpPhone;
|
||||
ped->m_nMoveState = PEDMOVE_STILL;
|
||||
CAnimManager::BlendAnimation((RpClump*)ped->m_rwObject, ASSOCGRP_STD, ANIM_IDLE_STANCE, 8.0f);
|
||||
CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_IDLE_STANCE, 8.0f);
|
||||
|
||||
if (assoc->blendAmount > 0.5f && ped)
|
||||
CAnimManager::BlendAnimation((RpClump*)ped->m_rwObject, ASSOCGRP_STD, ANIM_PHONE_TALK, 8.0f);
|
||||
CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_PHONE_TALK, 8.0f);
|
||||
|
||||
CPhoneInfo::pedWhoPickingUpPhone = nil;
|
||||
}
|
||||
|
@ -9,5 +9,6 @@ WRAPPER void CPickups::DoCollectableEffects(CEntity *ent) { EAXJMP(0x431C30); }
|
||||
WRAPPER void CPickups::DoMoneyEffects(CEntity *ent) { EAXJMP(0x431F40); }
|
||||
WRAPPER void CPickups::DoMineEffects(CEntity *ent) { EAXJMP(0x4321C0); }
|
||||
WRAPPER void CPickups::DoPickUpEffects(CEntity *ent) { EAXJMP(0x431520); }
|
||||
WRAPPER void CPickups::RemoveAllFloatingPickups() { EAXJMP(0x430800); }
|
||||
|
||||
WRAPPER void CPacManPickups::Render(void) { EAXJMP(0x432F60); }
|
||||
|
@ -41,6 +41,7 @@ public:
|
||||
static void DoMoneyEffects(CEntity *ent);
|
||||
static void DoMineEffects(CEntity *ent);
|
||||
static void DoPickUpEffects(CEntity *ent);
|
||||
static void RemoveAllFloatingPickups();
|
||||
|
||||
static CPickup (&aPickUps)[NUMPICKUPS];
|
||||
};
|
||||
|
@ -2,4 +2,5 @@
|
||||
#include "patcher.h"
|
||||
#include "Remote.h"
|
||||
|
||||
WRAPPER void CRemote::GivePlayerRemoteControlledCar(float, float, float, float, uint16) { EAXJMP(0x435C30); }
|
||||
WRAPPER void CRemote::TakeRemoteControlledCarFromPlayer(void) { EAXJMP(0x435DA0); }
|
||||
|
@ -3,5 +3,6 @@
|
||||
class CRemote
|
||||
{
|
||||
public:
|
||||
static void GivePlayerRemoteControlledCar(float, float, float, float, uint16);
|
||||
static void TakeRemoteControlledCarFromPlayer(void);
|
||||
};
|
||||
|
@ -240,15 +240,15 @@ void CReplay::Update(void)
|
||||
if (CDraw::FadeValue || !bReplayEnabled)
|
||||
return;
|
||||
if (Mode == MODE_PLAYBACK){
|
||||
if (CPad::NewKeyState.F[0] && !CPad::OldKeyState.F[0])
|
||||
if (CPad::GetPad(0)->GetFJustDown(0))
|
||||
FinishPlayback();
|
||||
}
|
||||
else if (Mode == MODE_RECORD){
|
||||
if (CPad::NewKeyState.F[0] && !CPad::OldKeyState.F[0])
|
||||
if (CPad::GetPad(0)->GetFJustDown(0))
|
||||
TriggerPlayback(REPLAYCAMMODE_ASSTORED, 0.0f, 0.0f, 0.0f, false);
|
||||
if (CPad::NewKeyState.F[1] && !CPad::OldKeyState.F[1])
|
||||
if (CPad::GetPad(0)->GetFJustDown(1))
|
||||
SaveReplayToHD();
|
||||
if (CPad::NewKeyState.F[2] && !CPad::OldKeyState.F[2])
|
||||
if (CPad::GetPad(0)->GetFJustDown(2))
|
||||
PlayReplayFromHD();
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "common.h"
|
||||
#include "Text.h"
|
||||
#include "Sprite2d.h"
|
||||
|
||||
class CEntity;
|
||||
@ -78,8 +79,8 @@ class CRunningScript
|
||||
uint32 m_nWakeTime;
|
||||
uint16 m_nAndOrState;
|
||||
bool m_bNotFlag;
|
||||
bool m_bWBCheckEnabled;
|
||||
bool m_bWBChecked;
|
||||
bool m_bDeatharrestEnabled;
|
||||
bool m_bDeatharrestExecuted;
|
||||
bool m_bMissionFlag;
|
||||
|
||||
public:
|
||||
@ -113,6 +114,40 @@ public:
|
||||
int8 ProcessCommandsFrom1000To1099(int32);
|
||||
int8 ProcessCommandsFrom1100To1199(int32);
|
||||
void UpdateCompareFlag(bool);
|
||||
int16 GetPadState(uint16, uint16);
|
||||
void LocatePlayerCommand(int32, uint32*);
|
||||
void LocatePlayerCharCommand(int32, uint32*);
|
||||
void LocatePlayerCarCommand(int32, uint32*);
|
||||
void LocateCharCommand(int32, uint32*);
|
||||
void LocateCharCharCommand(int32, uint32*);
|
||||
void LocateCharCarCommand(int32, uint32*);
|
||||
void LocateCharObjectCommand(int32, uint32*);
|
||||
void LocateCarCommand(int32, uint32*);
|
||||
void LocateSniperBulletCommand(int32, uint32*);
|
||||
void LocatePlayerInAreaCheckCommand(int32, uint32*);
|
||||
void LocatePlayerInAngledAreaCheckCommand(int32, uint32*);
|
||||
void LocateCharInAreaCheckCommand(int32, uint32*);
|
||||
void LocateCharInAngledAreaCheckCommand(int32, uint32*);
|
||||
private:
|
||||
enum {
|
||||
ANDOR_NONE = 0,
|
||||
ANDS_1 = 1,
|
||||
ANDS_2,
|
||||
ANDS_3,
|
||||
ANDS_4,
|
||||
ANDS_5,
|
||||
ANDS_6,
|
||||
ANDS_7,
|
||||
ANDS_8,
|
||||
ORS_1 = 21,
|
||||
ORS_2,
|
||||
ORS_3,
|
||||
ORS_4,
|
||||
ORS_5,
|
||||
ORS_6,
|
||||
ORS_7,
|
||||
ORS_8
|
||||
};
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -338,4 +373,12 @@ public:
|
||||
static float ReadFloatFromScript(uint32* pIp){
|
||||
return Read2BytesFromScript(pIp) / 16.0f;
|
||||
}
|
||||
static void ReadTextLabelFromScript(uint32* pIp, char* buf){
|
||||
strncpy(buf, (const char*)&ScriptSpace[*pIp], 8);
|
||||
}
|
||||
static wchar* GetTextByKeyFromScript(uint32* pIp) {
|
||||
wchar* text = TheText.Get((const char*)&ScriptSpace[*pIp]);
|
||||
*pIp += 8;
|
||||
return text;
|
||||
}
|
||||
};
|
||||
|
@ -208,7 +208,7 @@ enum {
|
||||
COMMAND_RBRACKET,
|
||||
COMMAND_REPEAT,
|
||||
COMMAND_ENDREPEAT,
|
||||
COMMAND_IF_,
|
||||
COMMAND_IF,
|
||||
COMMAND_IFNOT,
|
||||
COMMAND_ELSE,
|
||||
COMMAND_ENDIF,
|
||||
|
@ -1304,6 +1304,17 @@ CCam::GetWeaponFirstPersonOn()
|
||||
return false;
|
||||
}
|
||||
|
||||
float
|
||||
CCamera::Find3rdPersonQuickAimPitch(void)
|
||||
{
|
||||
float clampedFrontZ = clamp(Cams[ActiveCam].Front.z, -1.0f, 1.0f);
|
||||
|
||||
// float rot = atan2(clampedFrontZ, sqrt(1.0f - sq(clampedFrontZ)));
|
||||
float rot = Asin(clampedFrontZ);
|
||||
|
||||
return -(DEGTORAD(((0.5f - m_f3rdPersonCHairMultY) * 1.8f * 0.5f * Cams[ActiveCam].FOV)) + rot);
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x42C760, (bool (CCamera::*)(const CVector ¢er, float radius, const CMatrix *mat))&CCamera::IsSphereVisible, PATCH_JUMP);
|
||||
InjectHook(0x46FD00, &CCamera::SetFadeColour, PATCH_JUMP);
|
||||
|
@ -469,6 +469,8 @@ int m_iModeObbeCamIsInForCar;
|
||||
void Restore(void);
|
||||
void SetWidescreenOff(void);
|
||||
|
||||
float Find3rdPersonQuickAimPitch(void);
|
||||
|
||||
void dtor(void) { this->CCamera::~CCamera(); }
|
||||
};
|
||||
static_assert(offsetof(CCamera, m_WideScreenOn) == 0x70, "CCamera: error");
|
||||
|
@ -2023,11 +2023,11 @@ CColModel::operator=(const CColModel &other)
|
||||
numVerts = 0;
|
||||
for(i = 0; i < other.numTriangles; i++){
|
||||
if(other.triangles[i].a > numVerts)
|
||||
other.triangles[i].a = numVerts;
|
||||
numVerts = other.triangles[i].a;
|
||||
if(other.triangles[i].b > numVerts)
|
||||
other.triangles[i].b = numVerts;
|
||||
numVerts = other.triangles[i].b;
|
||||
if(other.triangles[i].c > numVerts)
|
||||
other.triangles[i].c = numVerts;
|
||||
numVerts = other.triangles[i].c;
|
||||
}
|
||||
numVerts++;
|
||||
if(vertices)
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
int32 m_ContSetOrder;
|
||||
};
|
||||
|
||||
bool field_0;
|
||||
bool firstCapture;
|
||||
char _pad0[3];
|
||||
DIJOYSTATE2 m_OldState;
|
||||
DIJOYSTATE2 m_NewState;
|
||||
|
@ -4,8 +4,16 @@ class CEntity;
|
||||
|
||||
enum eExplosionType
|
||||
{
|
||||
EXPLOSION_3 = 3,
|
||||
EXPLOSION_4
|
||||
EXPLOSION_GRENADE,
|
||||
EXPLOSION_MOLOTOV,
|
||||
EXPLOSION_ROCKET,
|
||||
EXPLOSION_CAR,
|
||||
EXPLOSION_CAR_QUICK,
|
||||
EXPLOSION_HELI,
|
||||
EXPLOSION_MINE,
|
||||
EXPLOSION_BARREL,
|
||||
EXPLOSION_TANK_GRENADE,
|
||||
EXPLOSION_HELI_BOMB
|
||||
};
|
||||
|
||||
class CExplosion
|
||||
|
@ -7,3 +7,4 @@ CFireManager &gFireManager = *(CFireManager*)0x8F31D0;
|
||||
WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); }
|
||||
|
||||
WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); }
|
||||
WRAPPER CFire *CFireManager::FindFurthestFire_NeverMindFireMen(CVector coors, float, float) { EAXJMP(0x479430); }
|
||||
|
@ -4,6 +4,7 @@ class CEntity;
|
||||
|
||||
class CFire
|
||||
{
|
||||
public:
|
||||
bool m_bIsOngoing;
|
||||
bool m_bExists;
|
||||
bool m_bPropogationFlag;
|
||||
@ -18,7 +19,6 @@ class CFire
|
||||
int field_28;
|
||||
float field_2C;
|
||||
|
||||
public:
|
||||
void Extinguish(void);
|
||||
};
|
||||
|
||||
@ -26,5 +26,6 @@ class CFireManager
|
||||
{
|
||||
public:
|
||||
void StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32);
|
||||
CFire *FindFurthestFire_NeverMindFireMen(CVector coors, float, float);
|
||||
};
|
||||
extern CFireManager &gFireManager;
|
||||
|
@ -1,7 +1,9 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "PlayerPed.h"
|
||||
#include "PlayerInfo.h"
|
||||
#include "Frontend.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
WRAPPER void CPlayerInfo::MakePlayerSafe(bool) { EAXJMP(0x4A1400); }
|
||||
WRAPPER void CPlayerInfo::LoadPlayerSkin() { EAXJMP(0x4A1700); }
|
||||
@ -12,3 +14,10 @@ void CPlayerInfo::SetPlayerSkin(char *skin)
|
||||
strncpy(m_aSkinName, skin, 32);
|
||||
LoadPlayerSkin();
|
||||
}
|
||||
|
||||
CVector& CPlayerInfo::GetPos()
|
||||
{
|
||||
if (m_pPed->bInVehicle && m_pPed->m_pMyVehicle)
|
||||
return m_pPed->m_pMyVehicle->GetPosition();
|
||||
return m_pPed->GetPosition();
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
CPlayerPed *m_pPed;
|
||||
CVehicle *m_pRemoteVehicle;
|
||||
CColModel m_ColModel;
|
||||
CVehicle *m_pVehicleEx;
|
||||
CVehicle *m_pVehicleEx; // vehicle using the col model above
|
||||
char m_aPlayerName[70];
|
||||
int32 m_nMoney;
|
||||
int32 m_nVisibleMoney;
|
||||
@ -45,10 +45,10 @@ public:
|
||||
int8 field_225;
|
||||
int8 field_226;
|
||||
int8 field_227;
|
||||
int32 m_nTimeLostRemoteCar;
|
||||
int32 m_nTimeLastHealthLoss;
|
||||
int32 m_nTimeLastArmourLoss;
|
||||
int32 field_240;
|
||||
uint32 m_nTimeLostRemoteCar;
|
||||
uint32 m_nTimeLastHealthLoss;
|
||||
uint32 m_nTimeLastArmourLoss;
|
||||
uint32 m_nTimeTankShotGun;
|
||||
int32 m_nUpsideDownCounter;
|
||||
int32 field_248;
|
||||
int16 m_nTrafficMultiplier;
|
||||
@ -70,6 +70,7 @@ public:
|
||||
void LoadPlayerSkin();
|
||||
void AwardMoneyForExplosion(CVehicle *vehicle);
|
||||
void SetPlayerSkin(char* skin);
|
||||
CVector& GetPos();
|
||||
};
|
||||
|
||||
static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerInfo: error");
|
||||
|
@ -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
|
||||
|
@ -40,19 +40,19 @@ CWanted::Initialise()
|
||||
bool
|
||||
CWanted::AreSwatRequired()
|
||||
{
|
||||
return m_nWantedLevel >= 4;
|
||||
return m_nWantedLevel == 4 || m_bSwatRequired;
|
||||
}
|
||||
|
||||
bool
|
||||
CWanted::AreFbiRequired()
|
||||
{
|
||||
return m_nWantedLevel >= 5;
|
||||
return m_nWantedLevel == 5 || m_bFbiRequired;
|
||||
}
|
||||
|
||||
bool
|
||||
CWanted::AreArmyRequired()
|
||||
{
|
||||
return m_nWantedLevel >= 6;
|
||||
return m_nWantedLevel == 6 || m_bArmyRequired;
|
||||
}
|
||||
|
||||
int32
|
||||
@ -77,6 +77,8 @@ void
|
||||
CWanted::SetWantedLevel(int32 level)
|
||||
{
|
||||
ClearQdCrimes();
|
||||
if (level > MaximumWantedLevel)
|
||||
level = MaximumWantedLevel;
|
||||
switch (level) {
|
||||
case 0:
|
||||
m_nChaos = 0;
|
||||
@ -100,8 +102,6 @@ CWanted::SetWantedLevel(int32 level)
|
||||
m_nChaos = 3220;
|
||||
break;
|
||||
default:
|
||||
if (level > MaximumWantedLevel)
|
||||
m_nChaos = MaximumWantedLevel;
|
||||
break;
|
||||
}
|
||||
UpdateWantedLevel();
|
||||
@ -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
|
||||
@ -117,7 +119,7 @@ enum Config {
|
||||
# define CHATTYSPLASH // print what the game is loading
|
||||
#endif
|
||||
|
||||
//#define FIX_BUGS // fix bugs in the game, TODO: use this more
|
||||
#define FIX_BUGS // fix bugs in the game, TODO: use this more
|
||||
#define KANGAROO_CHEAT
|
||||
#define ASPECT_RATIO_SCALE
|
||||
#define USE_DEBUG_SCRIPT_LOADER
|
||||
#define USE_DEBUG_SCRIPT_LOADER
|
||||
|
@ -150,6 +150,18 @@ FixCar(void)
|
||||
((CAutomobile*)veh)->Fix();
|
||||
}
|
||||
|
||||
static int engineStatus;
|
||||
static void
|
||||
SetEngineStatus(void)
|
||||
{
|
||||
CVehicle *veh = FindPlayerVehicle();
|
||||
if(veh == nil)
|
||||
return;
|
||||
if(!veh->IsCar())
|
||||
return;
|
||||
((CAutomobile*)veh)->Damage.SetEngineStatus(engineStatus);
|
||||
}
|
||||
|
||||
static void
|
||||
ToggleComedy(void)
|
||||
{
|
||||
@ -295,9 +307,13 @@ DebugMenuPopulate(void)
|
||||
DebugMenuAddCmd("Spawn", "Spawn Enforcer", [](){ SpawnCar(MI_ENFORCER); });
|
||||
DebugMenuAddCmd("Spawn", "Spawn Banshee", [](){ SpawnCar(MI_BANSHEE); });
|
||||
DebugMenuAddCmd("Spawn", "Spawn Yakuza", [](){ SpawnCar(MI_YAKUZA); });
|
||||
DebugMenuAddCmd("Spawn", "Spawn Yardie", [](){ SpawnCar(MI_YARDIE); });
|
||||
DebugMenuAddCmd("Spawn", "Spawn Dodo", [](){ SpawnCar(MI_DODO); });
|
||||
DebugMenuAddCmd("Spawn", "Spawn Rhino", [](){ SpawnCar(MI_RHINO); });
|
||||
DebugMenuAddCmd("Spawn", "Spawn Firetruck", [](){ SpawnCar(MI_FIRETRUCK); });
|
||||
|
||||
|
||||
DebugMenuAddVar("Debug", "Engine Status", &engineStatus, nil, 1, 0, 226, nil);
|
||||
DebugMenuAddCmd("Debug", "Set Engine Status", SetEngineStatus);
|
||||
DebugMenuAddCmd("Debug", "Fix Car", FixCar);
|
||||
DebugMenuAddCmd("Debug", "Toggle Comedy Controls", ToggleComedy);
|
||||
DebugMenuAddCmd("Debug", "Place Car on Road", PlaceOnRoad);
|
||||
|
@ -65,7 +65,7 @@ CEntity::CEntity(void)
|
||||
m_flagD8 = false;
|
||||
bIsSubway = false;
|
||||
bDrawLast = false;
|
||||
m_flagD40 = false;
|
||||
bNoBrightHeadLights = false;
|
||||
m_flagD80 = false;
|
||||
|
||||
bDistanceFade = false;
|
||||
|
@ -76,7 +76,7 @@ public:
|
||||
uint32 m_flagD8 : 1; // used by cBuoyancy::ProcessBuoyancy
|
||||
uint32 bIsSubway : 1; // set when subway, but maybe different meaning?
|
||||
uint32 bDrawLast : 1;
|
||||
uint32 m_flagD40 : 1;
|
||||
uint32 bNoBrightHeadLights : 1;
|
||||
uint32 m_flagD80 : 1; // CObject visibility?
|
||||
|
||||
// flagsE
|
||||
|
@ -125,6 +125,24 @@ public:
|
||||
m_matrix.pos.y = 0.0f;
|
||||
m_matrix.pos.z = 0.0f;
|
||||
}
|
||||
void Scale(float scale)
|
||||
{
|
||||
// GTA treats this as 4x4 floats
|
||||
m_matrix.right.x *= scale;
|
||||
m_matrix.right.y *= scale;
|
||||
m_matrix.right.z *= scale;
|
||||
m_matrix.up.x *= scale;
|
||||
m_matrix.up.y *= scale;
|
||||
m_matrix.up.z *= scale;
|
||||
m_matrix.at.x *= scale;
|
||||
m_matrix.at.y *= scale;
|
||||
m_matrix.at.z *= scale;
|
||||
m_matrix.pos.x *= scale;
|
||||
m_matrix.pos.y *= scale;
|
||||
m_matrix.pos.z *= scale;
|
||||
m_matrix.flags = 0;
|
||||
}
|
||||
|
||||
|
||||
void SetRotateXOnly(float angle){
|
||||
float c = Cos(angle);
|
||||
@ -192,40 +210,10 @@ public:
|
||||
m_matrix.pos.y = 0.0f;
|
||||
m_matrix.pos.z = 0.0f;
|
||||
}
|
||||
void SetRotate(float xAngle, float yAngle, float zAngle) {
|
||||
float cX = Cos(xAngle);
|
||||
float sX = Sin(xAngle);
|
||||
float cY = Cos(yAngle);
|
||||
float sY = Sin(yAngle);
|
||||
float cZ = Cos(zAngle);
|
||||
float sZ = Sin(zAngle);
|
||||
void SetRotate(float xAngle, float yAngle, float zAngle);
|
||||
void Rotate(float x, float y, float z);
|
||||
|
||||
m_matrix.right.x = cZ * cY - (sZ * sX) * sY;
|
||||
m_matrix.right.y = (cZ * sX) * sY + sZ * cY;
|
||||
m_matrix.right.z = -cX * sY;
|
||||
|
||||
m_matrix.up.x = -sZ * cX;
|
||||
m_matrix.up.y = cZ * cX;
|
||||
m_matrix.up.z = sX;
|
||||
|
||||
m_matrix.at.x = (sZ * sX) * cY + cZ * sY;
|
||||
m_matrix.at.y = sZ * sY - (cZ * sX) * cY;
|
||||
m_matrix.at.z = cX * cY;
|
||||
|
||||
m_matrix.pos.x = 0.0f;
|
||||
m_matrix.pos.y = 0.0f;
|
||||
m_matrix.pos.z = 0.0f;
|
||||
}
|
||||
void Reorthogonalise(void){
|
||||
CVector &r = GetRight();
|
||||
CVector &f = GetForward();
|
||||
CVector &u = GetUp();
|
||||
u = CrossProduct(r, f);
|
||||
u.Normalise();
|
||||
r = CrossProduct(f, u);
|
||||
r.Normalise();
|
||||
f = CrossProduct(u, r);
|
||||
}
|
||||
void Reorthogonalise(void);
|
||||
void CopyOnlyMatrix(CMatrix *other){
|
||||
m_matrix = other->m_matrix;
|
||||
}
|
||||
@ -245,35 +233,13 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
inline CMatrix&
|
||||
Invert(const CMatrix &src, CMatrix &dst)
|
||||
{
|
||||
// GTA handles this as a raw 4x4 orthonormal matrix
|
||||
// and trashes the RW flags, let's not do that
|
||||
// actual copy of librw code:
|
||||
RwMatrix *d = &dst.m_matrix;
|
||||
const RwMatrix *s = &src.m_matrix;
|
||||
d->right.x = s->right.x;
|
||||
d->right.y = s->up.x;
|
||||
d->right.z = s->at.x;
|
||||
d->up.x = s->right.y;
|
||||
d->up.y = s->up.y;
|
||||
d->up.z = s->at.y;
|
||||
d->at.x = s->right.z;
|
||||
d->at.y = s->up.z;
|
||||
d->at.z = s->at.z;
|
||||
d->pos.x = -(s->pos.x*s->right.x +
|
||||
s->pos.y*s->right.y +
|
||||
s->pos.z*s->right.z);
|
||||
d->pos.y = -(s->pos.x*s->up.x +
|
||||
s->pos.y*s->up.y +
|
||||
s->pos.z*s->up.z);
|
||||
d->pos.z = -(s->pos.x*s->at.x +
|
||||
s->pos.y*s->at.y +
|
||||
s->pos.z*s->at.z);
|
||||
d->flags = rwMATRIXTYPEORTHONORMAL;
|
||||
return dst;
|
||||
}
|
||||
|
||||
CMatrix &Invert(const CMatrix &src, CMatrix &dst);
|
||||
CVector operator*(const CMatrix &mat, const CVector &vec);
|
||||
CMatrix operator*(const CMatrix &m1, const CMatrix &m2);
|
||||
CVector MultiplyInverse(const CMatrix &mat, const CVector &vec);
|
||||
CVector Multiply3x3(const CMatrix &mat, const CVector &vec);
|
||||
CVector Multiply3x3(const CVector &vec, const CMatrix &mat);
|
||||
|
||||
inline CMatrix
|
||||
Invert(const CMatrix &matrix)
|
||||
@ -282,64 +248,6 @@ Invert(const CMatrix &matrix)
|
||||
return Invert(matrix, inv);
|
||||
}
|
||||
|
||||
inline CVector
|
||||
operator*(const CMatrix &mat, const CVector &vec)
|
||||
{
|
||||
return CVector(
|
||||
mat.m_matrix.right.x * vec.x + mat.m_matrix.up.x * vec.y + mat.m_matrix.at.x * vec.z + mat.m_matrix.pos.x,
|
||||
mat.m_matrix.right.y * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.at.y * vec.z + mat.m_matrix.pos.y,
|
||||
mat.m_matrix.right.z * vec.x + mat.m_matrix.up.z * vec.y + mat.m_matrix.at.z * vec.z + mat.m_matrix.pos.z);
|
||||
}
|
||||
|
||||
inline CMatrix
|
||||
operator*(const CMatrix &m1, const CMatrix &m2)
|
||||
{
|
||||
CMatrix out;
|
||||
RwMatrix *dst = &out.m_matrix;
|
||||
const RwMatrix *src1 = &m1.m_matrix;
|
||||
const RwMatrix *src2 = &m2.m_matrix;
|
||||
dst->right.x = src1->right.x*src2->right.x + src1->up.x*src2->right.y + src1->at.x*src2->right.z;
|
||||
dst->right.y = src1->right.y*src2->right.x + src1->up.y*src2->right.y + src1->at.y*src2->right.z;
|
||||
dst->right.z = src1->right.z*src2->right.x + src1->up.z*src2->right.y + src1->at.z*src2->right.z;
|
||||
dst->up.x = src1->right.x*src2->up.x + src1->up.x*src2->up.y + src1->at.x*src2->up.z;
|
||||
dst->up.y = src1->right.y*src2->up.x + src1->up.y*src2->up.y + src1->at.y*src2->up.z;
|
||||
dst->up.z = src1->right.z*src2->up.x + src1->up.z*src2->up.y + src1->at.z*src2->up.z;
|
||||
dst->at.x = src1->right.x*src2->at.x + src1->up.x*src2->at.y + src1->at.x*src2->at.z;
|
||||
dst->at.y = src1->right.y*src2->at.x + src1->up.y*src2->at.y + src1->at.y*src2->at.z;
|
||||
dst->at.z = src1->right.z*src2->at.x + src1->up.z*src2->at.y + src1->at.z*src2->at.z;
|
||||
dst->pos.x = src1->right.x*src2->pos.x + src1->up.x*src2->pos.y + src1->at.x*src2->pos.z + src1->pos.x;
|
||||
dst->pos.y = src1->right.y*src2->pos.x + src1->up.y*src2->pos.y + src1->at.y*src2->pos.z + src1->pos.y;
|
||||
dst->pos.z = src1->right.z*src2->pos.x + src1->up.z*src2->pos.y + src1->at.z*src2->pos.z + src1->pos.z;
|
||||
return out;
|
||||
}
|
||||
|
||||
inline CVector
|
||||
MultiplyInverse(const CMatrix &mat, const CVector &vec)
|
||||
{
|
||||
CVector v(vec.x - mat.m_matrix.pos.x, vec.y - mat.m_matrix.pos.y, vec.z - mat.m_matrix.pos.z);
|
||||
return CVector(
|
||||
mat.m_matrix.right.x * v.x + mat.m_matrix.right.y * v.y + mat.m_matrix.right.z * v.z,
|
||||
mat.m_matrix.up.x * v.x + mat.m_matrix.up.y * v.y + mat.m_matrix.up.z * v.z,
|
||||
mat.m_matrix.at.x * v.x + mat.m_matrix.at.y * v.y + mat.m_matrix.at.z * v.z);
|
||||
}
|
||||
|
||||
inline CVector
|
||||
Multiply3x3(const CMatrix &mat, const CVector &vec)
|
||||
{
|
||||
return CVector(
|
||||
mat.m_matrix.right.x * vec.x + mat.m_matrix.up.x * vec.y + mat.m_matrix.at.x * vec.z,
|
||||
mat.m_matrix.right.y * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.at.y * vec.z,
|
||||
mat.m_matrix.right.z * vec.x + mat.m_matrix.up.z * vec.y + mat.m_matrix.at.z * vec.z);
|
||||
}
|
||||
|
||||
inline CVector
|
||||
Multiply3x3(const CVector &vec, const CMatrix &mat)
|
||||
{
|
||||
return CVector(
|
||||
mat.m_matrix.right.x * vec.x + mat.m_matrix.right.y * vec.y + mat.m_matrix.right.z * vec.z,
|
||||
mat.m_matrix.up.x * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.up.z * vec.z,
|
||||
mat.m_matrix.at.x * vec.x + mat.m_matrix.at.y * vec.y + mat.m_matrix.at.z * vec.z);
|
||||
}
|
||||
|
||||
class CCompressedMatrixNotAligned
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
void Normalise(void) {
|
||||
float sq = MagnitudeSqr();
|
||||
if(sq > 0.0f){
|
||||
float invsqrt = 1.0f/Sqrt(sq); // CMaths::RecipSqrt
|
||||
float invsqrt = RecipSqrt(sq);
|
||||
x *= invsqrt;
|
||||
y *= invsqrt;
|
||||
z *= invsqrt;
|
||||
@ -71,6 +71,10 @@ public:
|
||||
return CVector(-x, -y, -z);
|
||||
}
|
||||
|
||||
const bool operator==(CVector const &right) {
|
||||
return x == right.x && y == right.y && z == right.z;
|
||||
}
|
||||
|
||||
bool IsZero(void) { return x == 0.0f && y == 0.0f && z == 0.0f; }
|
||||
};
|
||||
|
||||
|
@ -7,13 +7,14 @@ public:
|
||||
CVector2D(void) {}
|
||||
CVector2D(float x, float y) : x(x), y(y) {}
|
||||
CVector2D(const CVector &v) : x(v.x), y(v.y) {}
|
||||
float Heading(void) const { return Atan2(-x, y); }
|
||||
float Magnitude(void) const { return Sqrt(x*x + y*y); }
|
||||
float MagnitudeSqr(void) const { return x*x + y*y; }
|
||||
|
||||
void Normalise(void){
|
||||
float sq = MagnitudeSqr();
|
||||
if(sq > 0.0f){
|
||||
float invsqrt = 1.0f/Sqrt(sq);
|
||||
float invsqrt = RecipSqrt(sq);
|
||||
x *= invsqrt;
|
||||
y *= invsqrt;
|
||||
}else
|
||||
|
@ -4,6 +4,145 @@
|
||||
|
||||
// TODO: move more stuff into here
|
||||
|
||||
void
|
||||
CMatrix::SetRotate(float xAngle, float yAngle, float zAngle)
|
||||
{
|
||||
float cX = Cos(xAngle);
|
||||
float sX = Sin(xAngle);
|
||||
float cY = Cos(yAngle);
|
||||
float sY = Sin(yAngle);
|
||||
float cZ = Cos(zAngle);
|
||||
float sZ = Sin(zAngle);
|
||||
|
||||
m_matrix.right.x = cZ * cY - (sZ * sX) * sY;
|
||||
m_matrix.right.y = (cZ * sX) * sY + sZ * cY;
|
||||
m_matrix.right.z = -cX * sY;
|
||||
|
||||
m_matrix.up.x = -sZ * cX;
|
||||
m_matrix.up.y = cZ * cX;
|
||||
m_matrix.up.z = sX;
|
||||
|
||||
m_matrix.at.x = (sZ * sX) * cY + cZ * sY;
|
||||
m_matrix.at.y = sZ * sY - (cZ * sX) * cY;
|
||||
m_matrix.at.z = cX * cY;
|
||||
|
||||
m_matrix.pos.x = 0.0f;
|
||||
m_matrix.pos.y = 0.0f;
|
||||
m_matrix.pos.z = 0.0f;
|
||||
}
|
||||
|
||||
void
|
||||
CMatrix::Rotate(float x, float y, float z)
|
||||
{
|
||||
// TODO? do this directly without creating another matrix
|
||||
CMatrix rot;
|
||||
rot.SetRotate(x, y, z);
|
||||
*this = rot * *this;
|
||||
}
|
||||
|
||||
void
|
||||
CMatrix::Reorthogonalise(void)
|
||||
{
|
||||
CVector &r = GetRight();
|
||||
CVector &f = GetForward();
|
||||
CVector &u = GetUp();
|
||||
u = CrossProduct(r, f);
|
||||
u.Normalise();
|
||||
r = CrossProduct(f, u);
|
||||
r.Normalise();
|
||||
f = CrossProduct(u, r);
|
||||
}
|
||||
|
||||
CMatrix&
|
||||
Invert(const CMatrix &src, CMatrix &dst)
|
||||
{
|
||||
// GTA handles this as a raw 4x4 orthonormal matrix
|
||||
// and trashes the RW flags, let's not do that
|
||||
// actual copy of librw code:
|
||||
RwMatrix *d = &dst.m_matrix;
|
||||
const RwMatrix *s = &src.m_matrix;
|
||||
d->right.x = s->right.x;
|
||||
d->right.y = s->up.x;
|
||||
d->right.z = s->at.x;
|
||||
d->up.x = s->right.y;
|
||||
d->up.y = s->up.y;
|
||||
d->up.z = s->at.y;
|
||||
d->at.x = s->right.z;
|
||||
d->at.y = s->up.z;
|
||||
d->at.z = s->at.z;
|
||||
d->pos.x = -(s->pos.x*s->right.x +
|
||||
s->pos.y*s->right.y +
|
||||
s->pos.z*s->right.z);
|
||||
d->pos.y = -(s->pos.x*s->up.x +
|
||||
s->pos.y*s->up.y +
|
||||
s->pos.z*s->up.z);
|
||||
d->pos.z = -(s->pos.x*s->at.x +
|
||||
s->pos.y*s->at.y +
|
||||
s->pos.z*s->at.z);
|
||||
d->flags = rwMATRIXTYPEORTHONORMAL;
|
||||
return dst;
|
||||
}
|
||||
|
||||
CVector
|
||||
operator*(const CMatrix &mat, const CVector &vec)
|
||||
{
|
||||
return CVector(
|
||||
mat.m_matrix.right.x * vec.x + mat.m_matrix.up.x * vec.y + mat.m_matrix.at.x * vec.z + mat.m_matrix.pos.x,
|
||||
mat.m_matrix.right.y * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.at.y * vec.z + mat.m_matrix.pos.y,
|
||||
mat.m_matrix.right.z * vec.x + mat.m_matrix.up.z * vec.y + mat.m_matrix.at.z * vec.z + mat.m_matrix.pos.z);
|
||||
}
|
||||
|
||||
CMatrix
|
||||
operator*(const CMatrix &m1, const CMatrix &m2)
|
||||
{
|
||||
CMatrix out;
|
||||
RwMatrix *dst = &out.m_matrix;
|
||||
const RwMatrix *src1 = &m1.m_matrix;
|
||||
const RwMatrix *src2 = &m2.m_matrix;
|
||||
dst->right.x = src1->right.x*src2->right.x + src1->up.x*src2->right.y + src1->at.x*src2->right.z;
|
||||
dst->right.y = src1->right.y*src2->right.x + src1->up.y*src2->right.y + src1->at.y*src2->right.z;
|
||||
dst->right.z = src1->right.z*src2->right.x + src1->up.z*src2->right.y + src1->at.z*src2->right.z;
|
||||
dst->up.x = src1->right.x*src2->up.x + src1->up.x*src2->up.y + src1->at.x*src2->up.z;
|
||||
dst->up.y = src1->right.y*src2->up.x + src1->up.y*src2->up.y + src1->at.y*src2->up.z;
|
||||
dst->up.z = src1->right.z*src2->up.x + src1->up.z*src2->up.y + src1->at.z*src2->up.z;
|
||||
dst->at.x = src1->right.x*src2->at.x + src1->up.x*src2->at.y + src1->at.x*src2->at.z;
|
||||
dst->at.y = src1->right.y*src2->at.x + src1->up.y*src2->at.y + src1->at.y*src2->at.z;
|
||||
dst->at.z = src1->right.z*src2->at.x + src1->up.z*src2->at.y + src1->at.z*src2->at.z;
|
||||
dst->pos.x = src1->right.x*src2->pos.x + src1->up.x*src2->pos.y + src1->at.x*src2->pos.z + src1->pos.x;
|
||||
dst->pos.y = src1->right.y*src2->pos.x + src1->up.y*src2->pos.y + src1->at.y*src2->pos.z + src1->pos.y;
|
||||
dst->pos.z = src1->right.z*src2->pos.x + src1->up.z*src2->pos.y + src1->at.z*src2->pos.z + src1->pos.z;
|
||||
return out;
|
||||
}
|
||||
|
||||
CVector
|
||||
MultiplyInverse(const CMatrix &mat, const CVector &vec)
|
||||
{
|
||||
CVector v(vec.x - mat.m_matrix.pos.x, vec.y - mat.m_matrix.pos.y, vec.z - mat.m_matrix.pos.z);
|
||||
return CVector(
|
||||
mat.m_matrix.right.x * v.x + mat.m_matrix.right.y * v.y + mat.m_matrix.right.z * v.z,
|
||||
mat.m_matrix.up.x * v.x + mat.m_matrix.up.y * v.y + mat.m_matrix.up.z * v.z,
|
||||
mat.m_matrix.at.x * v.x + mat.m_matrix.at.y * v.y + mat.m_matrix.at.z * v.z);
|
||||
}
|
||||
|
||||
CVector
|
||||
Multiply3x3(const CMatrix &mat, const CVector &vec)
|
||||
{
|
||||
return CVector(
|
||||
mat.m_matrix.right.x * vec.x + mat.m_matrix.up.x * vec.y + mat.m_matrix.at.x * vec.z,
|
||||
mat.m_matrix.right.y * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.at.y * vec.z,
|
||||
mat.m_matrix.right.z * vec.x + mat.m_matrix.up.z * vec.y + mat.m_matrix.at.z * vec.z);
|
||||
}
|
||||
|
||||
CVector
|
||||
Multiply3x3(const CVector &vec, const CMatrix &mat)
|
||||
{
|
||||
return CVector(
|
||||
mat.m_matrix.right.x * vec.x + mat.m_matrix.right.y * vec.y + mat.m_matrix.right.z * vec.z,
|
||||
mat.m_matrix.up.x * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.up.z * vec.z,
|
||||
mat.m_matrix.at.x * vec.x + mat.m_matrix.at.y * vec.y + mat.m_matrix.at.z * vec.z);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CQuaternion::Slerp(const CQuaternion &q1, const CQuaternion &q2, float theta, float invSin, float t)
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ RwObjectNameIdAssocation boatIds[] = {
|
||||
{ "boat_moving_hi", 1, VEHICLE_FLAG_COLLAPSE },
|
||||
{ "boat_rudder_hi", 3, VEHICLE_FLAG_COLLAPSE },
|
||||
{ "windscreen", 2, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_COLLAPSE },
|
||||
{ "ped_frontseat", 0, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID },
|
||||
{ "ped_frontseat", BOAT_POS_FRONTSEAT, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID },
|
||||
{ nil, 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -47,9 +47,6 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
VEHICLE_DUMMY_BOAT_RUDDER = 0,
|
||||
VEHICLE_DUMMY_FRONT_SEATS = 2,
|
||||
VEHICLE_DUMMY_REAR_SEATS = 3,
|
||||
NUM_VEHICLE_POSITIONS = 10
|
||||
};
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
WRAPPER void CObject::ObjectDamage(float amount) { EAXJMP(0x4BB240); }
|
||||
WRAPPER void CObject::DeleteAllTempObjectInArea(CVector, float) { EAXJMP(0x4BBED0); }
|
||||
WRAPPER void CObject::Init(void) { EAXJMP(0x4BAEC0); }
|
||||
|
||||
int16 &CObject::nNoTempObjects = *(int16*)0x95CCA2;
|
||||
int16 &CObject::nBodyCastHealth = *(int16*)0x5F7D4C; // 1000
|
||||
@ -41,6 +42,15 @@ CObject::CObject(void)
|
||||
m_pCollidingEntity = nil;
|
||||
}
|
||||
|
||||
CObject::CObject(int32 mi, bool createRW)
|
||||
{
|
||||
if (createRW)
|
||||
SetModelIndex(mi);
|
||||
else
|
||||
SetModelIndexNoCreate(mi);
|
||||
Init();
|
||||
}
|
||||
|
||||
CObject::~CObject(void)
|
||||
{
|
||||
CRadar::ClearBlipForEntity(BLIP_OBJECT, CPools::GetObjectPool()->GetIndex(this));
|
||||
|
@ -66,6 +66,7 @@ public:
|
||||
static void operator delete(void*, size_t);
|
||||
|
||||
CObject(void);
|
||||
CObject(int32, bool);
|
||||
~CObject(void);
|
||||
|
||||
void Render(void);
|
||||
@ -74,6 +75,7 @@ public:
|
||||
|
||||
void ObjectDamage(float amount);
|
||||
void RefModelInfo(int32 modelId);
|
||||
void Init(void);
|
||||
|
||||
static void DeleteAllTempObjectInArea(CVector, float);
|
||||
};
|
||||
|
@ -2,9 +2,10 @@
|
||||
#include "patcher.h"
|
||||
#include "ParticleObject.h"
|
||||
|
||||
WRAPPER void CParticleObject::AddObject(uint16 type, const CVector &pos, bool remove) { EAXJMP(0x4BC4D0); }
|
||||
WRAPPER void CParticleObject::AddObject(uint16 type, const CVector &pos, float size, bool remove) { EAXJMP(0x4BC520); }
|
||||
WRAPPER void CParticleObject::AddObject(uint16 type, const CVector &pos, const CVector &dir, float size, bool remove) { EAXJMP(0x4BC570); }
|
||||
WRAPPER void CParticleObject::AddObject(uint16 type, const CVector &pos, uint8 remove) { EAXJMP(0x4BC4D0); }
|
||||
WRAPPER void CParticleObject::AddObject(uint16 type, const CVector &pos, float size, uint8 remove) { EAXJMP(0x4BC520); }
|
||||
WRAPPER void CParticleObject::AddObject(uint16 type, const CVector &pos, const CVector &dir, float size, uint8 remove) { EAXJMP(0x4BC570); }
|
||||
WRAPPER void CParticleObject::AddObject(uint16 type, const CVector &pos, const CVector &dir, float size, uint32, const RwRGBA &col, uint8 remove) { EAXJMP(0x4BC5B0); }
|
||||
|
||||
// Converted from static void __cdecl CParticleObject::Initialise() 0x42C760
|
||||
void CParticleObject::Initialise()
|
||||
|
@ -29,9 +29,10 @@ enum eParticleObjectType
|
||||
class CParticleObject : CPlaceable
|
||||
{
|
||||
public:
|
||||
static void AddObject(uint16 type, const CVector &pos, bool remove);
|
||||
static void AddObject(uint16 type, const CVector &pos, float size, bool remove);
|
||||
static void AddObject(uint16 type, const CVector &pos, const CVector &dir, float size, bool remove);
|
||||
static void AddObject(uint16 type, const CVector &pos, uint8 remove);
|
||||
static void AddObject(uint16 type, const CVector &pos, float size, uint8 remove);
|
||||
static void AddObject(uint16 type, const CVector &pos, const CVector &dir, float size, uint8 remove);
|
||||
static void AddObject(uint16 type, const CVector &pos, const CVector &dir, float size, uint32, const RwRGBA &col, uint8 remove);
|
||||
static void Initialise();
|
||||
static void UpdateAll();
|
||||
};
|
||||
|
@ -28,7 +28,7 @@ CCivilianPed::ProcessNearestFreePhone(int unused)
|
||||
if (gPhoneInfo.m_aPhones[phoneId].m_nState != PHONE_STATE_FREE)
|
||||
return false;
|
||||
|
||||
field_31C = 1;
|
||||
bRunningToPhone = true;
|
||||
SetMoveState(PEDMOVE_RUN);
|
||||
SetSeek(gPhoneInfo.m_aPhones[phoneId].m_vecPos, 0.3f);
|
||||
m_phoneId = phoneId;
|
||||
|
1511
src/peds/Ped.cpp
1511
src/peds/Ped.cpp
File diff suppressed because it is too large
Load Diff
141
src/peds/Ped.h
141
src/peds/Ped.h
@ -10,9 +10,78 @@
|
||||
#include "AnimBlendAssociation.h"
|
||||
#include "WeaponInfo.h"
|
||||
#include "Fire.h"
|
||||
#include "DMAudio.h"
|
||||
|
||||
struct CPathNode;
|
||||
|
||||
struct CPedAudioData
|
||||
{
|
||||
int m_nFixedDelayTime;
|
||||
int m_nOverrideFixedDelayTime;
|
||||
int m_nOverrideMaxRandomDelayTime;
|
||||
int m_nMaxRandomDelayTime;
|
||||
};
|
||||
|
||||
// For hit sounds in fight
|
||||
enum {
|
||||
S33 = SOUND_FIGHT_PUNCH_33,
|
||||
S34 = SOUND_FIGHT_KICK_34,
|
||||
S35 = SOUND_FIGHT_HEADBUTT_35,
|
||||
S36 = SOUND_FIGHT_PUNCH_36,
|
||||
S37 = SOUND_FIGHT_PUNCH_37,
|
||||
S38 = SOUND_FIGHT_CLOSE_PUNCH_38,
|
||||
S39 = SOUND_FIGHT_PUNCH_39,
|
||||
S40 = SOUND_FIGHT_PUNCH_OR_KICK_BELOW_40 ,
|
||||
S41 = SOUND_FIGHT_PUNCH_41,
|
||||
S42 = SOUND_FIGHT_PUNCH_FROM_BEHIND_42,
|
||||
S43 = SOUND_FIGHT_KNEE_OR_KICK_43,
|
||||
S44 = SOUND_FIGHT_KICK_44,
|
||||
NO_SND = SOUND_TOTAL_PED_SOUNDS
|
||||
};
|
||||
|
||||
struct FightMove
|
||||
{
|
||||
AnimationId animId;
|
||||
float startFireTime;
|
||||
float endFireTime;
|
||||
float comboFollowOnTime;
|
||||
float strikeRadius;
|
||||
uint8 hitLevel;
|
||||
uint8 damage;
|
||||
uint8 flags;
|
||||
};
|
||||
static_assert(sizeof(FightMove) == 0x18, "FightMove: error");
|
||||
|
||||
enum PedFightMoves
|
||||
{
|
||||
FIGHTMOVE_NULL,
|
||||
// Attacker
|
||||
FIGHTMOVE_STDPUNCH,
|
||||
FIGHTMOVE_IDLE,
|
||||
FIGHTMOVE_SHUFFLE_F,
|
||||
FIGHTMOVE_KNEE,
|
||||
FIGHTMOVE_HEADBUTT,
|
||||
FIGHTMOVE_PUNCHJAB,
|
||||
FIGHTMOVE_PUNCHHOOK,
|
||||
FIGHTMOVE_KICK,
|
||||
FIGHTMOVE_LONGKICK,
|
||||
FIGHTMOVE_ROUNDHOUSE,
|
||||
FIGHTMOVE_BODYBLOW,
|
||||
FIGHTMOVE_GROUNDKICK,
|
||||
// Opponent
|
||||
FIGHTMOVE_HITFRONT,
|
||||
FIGHTMOVE_HITBACK,
|
||||
FIGHTMOVE_HITRIGHT,
|
||||
FIGHTMOVE_HITLEFT,
|
||||
FIGHTMOVE_HITBODY,
|
||||
FIGHTMOVE_HITCHEST,
|
||||
FIGHTMOVE_HITHEAD,
|
||||
FIGHTMOVE_HITBIGSTEP,
|
||||
FIGHTMOVE_HITONFLOOR,
|
||||
FIGHTMOVE_HITBEHIND,
|
||||
FIGHTMOVE_IDLE2NORM
|
||||
};
|
||||
|
||||
enum ePedPieceTypes
|
||||
{
|
||||
PEDPIECE_TORSO,
|
||||
@ -209,7 +278,7 @@ public:
|
||||
uint8 bRespondsToThreats : 1;
|
||||
uint8 bRenderPedInCar : 1;
|
||||
uint8 bChangedSeat : 1;
|
||||
uint8 m_ped_flagC10 : 1; // related with phone
|
||||
uint8 bUpdateAnimHeading : 1;
|
||||
uint8 bBodyPartJustCameOff : 1;
|
||||
uint8 m_ped_flagC40 : 1;
|
||||
uint8 m_ped_flagC80 : 1;
|
||||
@ -219,16 +288,16 @@ public:
|
||||
uint8 m_ped_flagD4 : 1;
|
||||
uint8 m_ped_flagD8 : 1;
|
||||
uint8 bIsPedDieAnimPlaying : 1;
|
||||
uint8 m_ped_flagD20 : 1;
|
||||
uint8 bIsFleeing : 1;
|
||||
uint8 m_ped_flagD40 : 1; // reset when objective changes
|
||||
uint8 m_bScriptObjectiveCompleted : 1;
|
||||
uint8 bScriptObjectiveCompleted : 1;
|
||||
|
||||
uint8 m_ped_flagE1 : 1;
|
||||
uint8 bKindaStayInSamePlace : 1;
|
||||
uint8 m_ped_flagE2 : 1;
|
||||
uint8 bNotAllowedToDuck : 1;
|
||||
uint8 bCrouchWhenShooting : 1;
|
||||
uint8 bIsDucking : 1; // set if you don't want ped to attack
|
||||
uint8 m_ped_flagE20 : 1; // getup complete?
|
||||
uint8 bGetUpAnimStarted : 1;
|
||||
uint8 bDoBloodyFootprints : 1;
|
||||
uint8 m_ped_flagE80 : 1;
|
||||
|
||||
@ -253,17 +322,17 @@ public:
|
||||
uint8 m_ped_flagH1 : 1;
|
||||
uint8 m_ped_flagH2 : 1;
|
||||
uint8 m_ped_flagH4 : 1;
|
||||
uint8 m_ped_flagH8 : 1;
|
||||
uint8 bClearObjective : 1;
|
||||
uint8 m_ped_flagH10 : 1;
|
||||
uint8 m_ped_flagH20 : 1;
|
||||
uint8 m_ped_flagH40 : 1;
|
||||
uint8 m_ped_flagH80 : 1;
|
||||
|
||||
uint8 m_ped_flagI1 : 1;
|
||||
uint8 m_ped_flagI2 : 1; // if set, limbs won't came off
|
||||
uint8 bNoCriticalHits : 1; // if set, limbs won't came off
|
||||
uint8 m_ped_flagI4 : 1;
|
||||
uint8 bHasAlreadyBeenRecorded : 1;
|
||||
uint8 m_ped_flagI10 : 1;
|
||||
uint8 bIsFell : 1;
|
||||
uint8 m_ped_flagI20 : 1;
|
||||
uint8 m_ped_flagI40 : 1;
|
||||
uint8 m_ped_flagI80 : 1;
|
||||
@ -283,7 +352,7 @@ public:
|
||||
uint32 m_pedFormation;
|
||||
uint32 m_fearFlags;
|
||||
CEntity *m_threatEntity;
|
||||
CVector2D m_eventOrThread;
|
||||
CVector2D m_eventOrThreat;
|
||||
uint32 m_eventType;
|
||||
CEntity* m_pEventEntity;
|
||||
float m_fAngleToEvent;
|
||||
@ -299,8 +368,8 @@ public:
|
||||
PedState m_nPedState;
|
||||
PedState m_nLastPedState;
|
||||
eMoveState m_nMoveState;
|
||||
int32 m_nStoredActionState;
|
||||
int32 m_nPrevActionState;
|
||||
int32 m_nStoredMoveState;
|
||||
int32 m_nPrevMoveState;
|
||||
eWaitState m_nWaitState;
|
||||
uint32 m_nWaitTimer;
|
||||
void *m_pPathNodesStates[8]; // seems unused
|
||||
@ -336,7 +405,7 @@ public:
|
||||
bool bInVehicle;
|
||||
uint8 pad_315[3];
|
||||
float field_318;
|
||||
uint8 field_31C; // may be cutscene or phone cutscene status
|
||||
bool bRunningToPhone;
|
||||
uint8 field_31D;
|
||||
int16 m_phoneId;
|
||||
uint32 m_lookingForPhone; // unused
|
||||
@ -363,11 +432,12 @@ public:
|
||||
uint8 m_wepAccuracy;
|
||||
CEntity *m_pPointGunAt;
|
||||
CVector m_vecHitLastPos;
|
||||
uint32 m_lastHitState;
|
||||
uint8 m_fightFlags1;
|
||||
uint8 m_fightFlags2;
|
||||
uint8 pad_4B2[2];
|
||||
CFire* m_pFire;
|
||||
PedFightMoves m_lastFightMove;
|
||||
uint8 m_fightButtonPressure;
|
||||
int8 m_fightUnk2; // TODO
|
||||
uint8 m_fightUnk1; // TODO
|
||||
uint8 pad_4B3;
|
||||
CFire *m_pFire;
|
||||
CEntity *m_pLookTarget;
|
||||
float m_fLookDirection;
|
||||
int32 m_wepModelID;
|
||||
@ -382,18 +452,18 @@ public:
|
||||
uint32 m_duckTimer;
|
||||
uint32 field_4E8;
|
||||
int32 m_bloodyFootprintCount;
|
||||
uint8 stuff9[2];
|
||||
uint8 m_panicCounter;
|
||||
uint8 m_deadBleeding;
|
||||
int8 m_bodyPartBleeding; // PedNode
|
||||
uint8 m_field_4F3;
|
||||
CPed *m_nearPeds[10];
|
||||
uint16 m_numNearPeds;
|
||||
int8 m_lastWepDam;
|
||||
uint8 pad_51F;
|
||||
uint8 field_520;
|
||||
uint8 pad_521[3];
|
||||
uint32 m_talkTimer;
|
||||
uint16 m_talkTypeLast;
|
||||
uint16 m_talkType;
|
||||
uint32 m_lastSoundStart;
|
||||
uint32 m_soundStart;
|
||||
uint16 m_lastQueuedSound;
|
||||
uint16 m_queuedSound;
|
||||
CVector m_vecSeekPosEx;
|
||||
float m_seekExAngle;
|
||||
|
||||
@ -503,11 +573,27 @@ public:
|
||||
void SetAimFlag(float angle);
|
||||
void SetAmmo(eWeaponType weaponType, uint32 ammo);
|
||||
void SetEvasiveStep(CEntity*, uint8);
|
||||
void GrantAmmo(eWeaponType, uint32);
|
||||
void SetEvasiveDive(CPhysical*, uint8);
|
||||
void SetAttack(CEntity*);
|
||||
void StartFightAttack(uint8);
|
||||
void LoadFightData(void);
|
||||
void SetWaitState(eWaitState, void*);
|
||||
bool FightStrike(CVector&);
|
||||
int GetLocalDirection(CVector2D&);
|
||||
void StartFightDefend(uint8, uint8, uint8);
|
||||
void PlayHitSound(CPed*);
|
||||
void SetFall(int, AnimationId, uint8);
|
||||
void SetFlee(CEntity*, int);
|
||||
void SetFlee(CVector2D&, int);
|
||||
void RemoveInCarAnims(void);
|
||||
void CollideWithPed(CPed*);
|
||||
void SetDirectionToWalkAroundObject(CEntity*);
|
||||
|
||||
// Static methods
|
||||
static void GetLocalPositionToOpenCarDoor(CVector *output, CVehicle *veh, uint32 enterType, float offset);
|
||||
static void GetPositionToOpenCarDoor(CVector *output, CVehicle *veh, uint32 enterType, float seatPosMult);
|
||||
static void GetPositionToOpenCarDoor(CVector* output, CVehicle* veh, uint32 enterType);
|
||||
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset);
|
||||
static CVector GetPositionToOpenCarDoor(CVehicle *veh, uint32 component, float seatPosMult);
|
||||
static CVector GetPositionToOpenCarDoor(CVehicle* veh, uint32 component);
|
||||
|
||||
// Callbacks
|
||||
static RwObject *SetPedAtomicVisibilityCB(RwObject *object, void *data);
|
||||
@ -577,6 +663,9 @@ public:
|
||||
static bool &bPedCheat2;
|
||||
static bool &bPedCheat3;
|
||||
static CColPoint &ms_tempColPoint;
|
||||
static uint16 &unknownFightThing; // TODO
|
||||
static FightMove (&ms_fightMoves)[24];
|
||||
static CPedAudioData (&PedAudioData)[38];
|
||||
};
|
||||
|
||||
void FinishFuckUCB(CAnimBlendAssociation *assoc, void *arg);
|
||||
|
@ -8,6 +8,7 @@ WRAPPER bool CPedIK::PointGunAtPosition(CVector *position) { EAXJMP(0x4ED920); }
|
||||
WRAPPER void CPedIK::ExtractYawAndPitchLocal(RwMatrixTag*, float*, float*) { EAXJMP(0x4ED2C0); }
|
||||
WRAPPER void CPedIK::ExtractYawAndPitchWorld(RwMatrixTag*, float*, float*) { EAXJMP(0x4ED140); }
|
||||
|
||||
// TODO: Hardcoded into exe, reverse it.
|
||||
LimbMovementInfo &CPedIK::ms_torsoInfo = *(LimbMovementInfo*)0x5F9F8C;
|
||||
|
||||
CPedIK::CPedIK(CPed *ped)
|
||||
@ -104,8 +105,7 @@ CPedIK::GetWorldMatrix(RwFrame *source, RwMatrix *destination)
|
||||
return destination;
|
||||
}
|
||||
|
||||
// A helper function that adjusts "limb" parameter according to limitations. Doesn't move the limb.
|
||||
int8
|
||||
uint32
|
||||
CPedIK::MoveLimb(LimbOrientation &limb, float approxPhi, float approxTheta, LimbMovementInfo &moveInfo)
|
||||
{
|
||||
int result = 1;
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll);
|
||||
void ExtractYawAndPitchLocal(RwMatrixTag*, float*, float*);
|
||||
void ExtractYawAndPitchWorld(RwMatrixTag*, float*, float*);
|
||||
int8 MoveLimb(LimbOrientation &a1, float a2, float a3, LimbMovementInfo &a4);
|
||||
uint32 MoveLimb(LimbOrientation &a1, float a2, float a3, LimbMovementInfo &a4);
|
||||
bool RestoreGunPosn(void);
|
||||
};
|
||||
static_assert(sizeof(CPedIK) == 0x28, "CPedIK: error");
|
||||
|
@ -203,7 +203,7 @@ CCoronas::RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 al
|
||||
}
|
||||
|
||||
void
|
||||
CCoronas::UpdateCoronaCoors(int id, const CVector &coors, float drawDist, float someAngle)
|
||||
CCoronas::UpdateCoronaCoors(uint32 id, const CVector &coors, float drawDist, float someAngle)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -93,7 +93,7 @@ public:
|
||||
static void RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha,
|
||||
const CVector &coors, float size, float drawDist, uint8 type,
|
||||
int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle);
|
||||
static void UpdateCoronaCoors(int id, const CVector &coors, float drawDist, float someAngle);
|
||||
static void UpdateCoronaCoors(uint32 id, const CVector &coors, float drawDist, float someAngle);
|
||||
static void Render(void);
|
||||
static void RenderReflections(void);
|
||||
static void DoSunAndMoon(void);
|
||||
|
@ -359,10 +359,10 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
|
||||
ent->GetModelIndex() == MI_RHINO ||
|
||||
ent->GetModelIndex() == MI_COACH ||
|
||||
TheCamera.m_bInATunnelAndABigVehicle){
|
||||
ent->m_flagD40 = true;
|
||||
ent->bNoBrightHeadLights = true;
|
||||
}else{
|
||||
m_pFirstPersonVehicle = (CVehicle*)ent;
|
||||
ent->m_flagD40 = false;
|
||||
ent->bNoBrightHeadLights = false;
|
||||
}
|
||||
return VIS_OFFSCREEN;
|
||||
}else{
|
||||
|
@ -177,3 +177,4 @@ public:
|
||||
|
||||
extern RwTexture *&gpBloodPoolTex;
|
||||
extern RwTexture *&gpShadowExplosionTex;
|
||||
extern RwTexture *&gpShadowHeadLightsTex;
|
||||
|
@ -5,3 +5,4 @@
|
||||
WRAPPER void CSkidmarks::Clear(void) { EAXJMP(0x518130); }
|
||||
|
||||
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); }
|
||||
|
@ -5,4 +5,5 @@ class CSkidmarks
|
||||
public:
|
||||
static void Clear(void);
|
||||
static void Render(void);
|
||||
static void RegisterOne(uint32 id, CVector pos, float fwdx, float fwdY, bool *isMuddy, bool *isBloddy);
|
||||
};
|
||||
|
@ -11,5 +11,6 @@ CBulletTrace (&CBulletTraces::aTraces)[16] = *(CBulletTrace(*)[16])*(uintptr*)0x
|
||||
|
||||
WRAPPER void CBulletTraces::Init(void) { EAXJMP(0x518DE0); }
|
||||
|
||||
WRAPPER void CBrightLights::RegisterOne(CVector pos, CVector up, CVector right, CVector fwd, uint8 type, uint8 unk1, uint8 unk2, uint8 unk3) { EAXJMP(0x51A410); }
|
||||
|
||||
WRAPPER void C3dMarkers::PlaceMarkerSet(uint32 id, uint16 type, CVector& pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate) { EAXJMP(0x51BB80); }
|
@ -29,8 +29,15 @@ public:
|
||||
static void Init(void);
|
||||
};
|
||||
|
||||
class CBrightLights
|
||||
{
|
||||
public:
|
||||
static void RegisterOne(CVector pos, CVector up, CVector right, CVector fwd, uint8 type, uint8 unk1 = 0, uint8 unk2 = 0, uint8 unk3 = 0);
|
||||
};
|
||||
|
||||
class C3dMarkers
|
||||
{
|
||||
public:
|
||||
static void PlaceMarkerSet(uint32 id, uint16 type, CVector& pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -2,4 +2,5 @@
|
||||
#include "patcher.h"
|
||||
#include "WaterCannon.h"
|
||||
|
||||
WRAPPER void CWaterCannons::UpdateOne(uint32 id, CVector *pos, CVector *dir) { EAXJMP(0x522470); }
|
||||
WRAPPER void CWaterCannons::Render(void) { EAXJMP(0x522550); }
|
||||
|
@ -3,5 +3,6 @@
|
||||
class CWaterCannons
|
||||
{
|
||||
public:
|
||||
static void UpdateOne(uint32 id, CVector *pos, CVector *dir);
|
||||
static void Render(void);
|
||||
};
|
||||
|
@ -2265,9 +2265,6 @@ HRESULT _InputInitialiseMouse()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)
|
||||
//#define FAILED(Status) ((HRESULT)(Status)<0)
|
||||
|
||||
RwV2d leftStickPos;
|
||||
RwV2d rightStickPos;
|
||||
|
||||
@ -2275,15 +2272,20 @@ HRESULT CapturePad(RwInt32 padID)
|
||||
{
|
||||
HRESULT hr;
|
||||
DIJOYSTATE2 js;
|
||||
LPDIRECTINPUTDEVICE8 pPad = nil;
|
||||
LPDIRECTINPUTDEVICE8 *pPad = nil;
|
||||
|
||||
if( padID == 0 )
|
||||
pPad = &PSGLOBAL(joy1);
|
||||
else if( padID == 1)
|
||||
pPad = &PSGLOBAL(joy2);
|
||||
else
|
||||
assert("invalid padID");
|
||||
|
||||
pPad = ( padID == 0 ) ? PSGLOBAL(joy1) : PSGLOBAL(joy2);
|
||||
|
||||
if ( nil == pPad )
|
||||
if ( nil == (*pPad) )
|
||||
return S_OK;
|
||||
|
||||
// Poll the device to read the current state
|
||||
hr = pPad->Poll();
|
||||
hr = (*pPad)->Poll();
|
||||
|
||||
if( FAILED(hr) )
|
||||
{
|
||||
@ -2291,9 +2293,9 @@ HRESULT CapturePad(RwInt32 padID)
|
||||
// interrupted. We aren't tracking any state between polls, so
|
||||
// we don't have any special reset that needs to be done. We
|
||||
// just re-acquire and try again.
|
||||
hr = pPad->Acquire();
|
||||
hr = (*pPad)->Acquire();
|
||||
while( hr == DIERR_INPUTLOST )
|
||||
hr = pPad->Acquire();
|
||||
hr = (*pPad)->Acquire();
|
||||
|
||||
// hr may be DIERR_OTHERAPPHASPRIO or other errors. This
|
||||
// may occur when the app is minimized or in the process of
|
||||
@ -2302,26 +2304,26 @@ HRESULT CapturePad(RwInt32 padID)
|
||||
if( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
hr = pPad->Poll();
|
||||
hr = (*pPad)->Poll();
|
||||
if( FAILED(hr) )
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Get the input's device state
|
||||
if( FAILED( hr = pPad->GetDeviceState( sizeof(DIJOYSTATE2), &js ) ) )
|
||||
if( FAILED( hr = (*pPad)->GetDeviceState( sizeof(DIJOYSTATE2), &js ) ) )
|
||||
return hr; // The device should have been acquired during the Poll()
|
||||
|
||||
if ( ControlsManager.field_0 == true )
|
||||
if ( ControlsManager.firstCapture == true )
|
||||
{
|
||||
memcpy(&ControlsManager.m_OldState, &js, sizeof(DIJOYSTATE2));
|
||||
memcpy(&ControlsManager.m_NewState, &js, sizeof(DIJOYSTATE2));
|
||||
|
||||
ControlsManager.field_0 = false;
|
||||
ControlsManager.firstCapture = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&ControlsManager.m_OldState, &ControlsManager.m_NewState, sizeof(DIJOYSTATE2));
|
||||
memcpy(&ControlsManager.m_NewState, &js, sizeof(DIJOYSTATE2));
|
||||
memcpy(&ControlsManager.m_NewState, &js, sizeof(DIJOYSTATE2));
|
||||
}
|
||||
|
||||
RsPadButtonStatus bs;
|
||||
@ -2329,14 +2331,14 @@ HRESULT CapturePad(RwInt32 padID)
|
||||
|
||||
RsPadEventHandler(rsPADBUTTONUP, (void *)&bs);
|
||||
|
||||
bool deviceAvailable = pPad != nil;
|
||||
bool deviceAvailable = (*pPad) != nil;
|
||||
|
||||
if ( deviceAvailable )
|
||||
{
|
||||
leftStickPos.x = (float)js.lX / (float)((DEVICE_AXIS_MAX - DEVICE_AXIS_MIN) / 2);
|
||||
leftStickPos.y = (float)js.lY / (float)((DEVICE_AXIS_MAX - DEVICE_AXIS_MIN) / 2);
|
||||
|
||||
if (LOWORD(js.rgdwPOV[0]) != -1)
|
||||
if (LOWORD(js.rgdwPOV[0]) != 0xFFFF)
|
||||
{
|
||||
float angle = DEGTORAD((float)js.rgdwPOV[0] / 100.0f);
|
||||
|
||||
@ -2548,40 +2550,49 @@ BOOL CALLBACK _InputEnumDevicesCallback( const DIDEVICEINSTANCE* pdidInstance, V
|
||||
|
||||
static INT Count = 0;
|
||||
|
||||
LPDIRECTINPUTDEVICE8 pJoystick = nil;
|
||||
LPDIRECTINPUTDEVICE8 *pJoystick = nil;
|
||||
|
||||
if ( Count == 0 )
|
||||
pJoystick = PSGLOBAL(joy1);
|
||||
pJoystick = &PSGLOBAL(joy1);
|
||||
else if ( Count == 1 )
|
||||
pJoystick = PSGLOBAL(joy2);
|
||||
pJoystick = &PSGLOBAL(joy2);
|
||||
else
|
||||
assert("too many pads");
|
||||
|
||||
// Obtain an interface to the enumerated joystick.
|
||||
hr = PSGLOBAL(dinterface)->CreateDevice( pdidInstance->guidInstance, &pJoystick, nil );
|
||||
hr = PSGLOBAL(dinterface)->CreateDevice( pdidInstance->guidInstance, pJoystick, nil );
|
||||
|
||||
// If it failed, then we can't use this joystick. (Maybe the user unplugged
|
||||
// it while we were in the middle of enumerating it.)
|
||||
if( FAILED(hr) )
|
||||
if( hr != S_OK )
|
||||
return DIENUM_CONTINUE;
|
||||
|
||||
if( FAILED( hr = pJoystick->SetDataFormat( &c_dfDIJoystick2 ) ) )
|
||||
|
||||
hr = (*pJoystick)->SetDataFormat( &c_dfDIJoystick2 );
|
||||
if( hr != S_OK )
|
||||
{
|
||||
pJoystick->Release();
|
||||
(*pJoystick)->Release();
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
++Count;
|
||||
|
||||
if( FAILED( hr = pJoystick->SetCooperativeLevel( PSGLOBAL(window), DISCL_NONEXCLUSIVE) ) )
|
||||
|
||||
hr = (*pJoystick)->SetCooperativeLevel( PSGLOBAL(window), DISCL_NONEXCLUSIVE|DISCL_FOREGROUND );
|
||||
if( hr != S_OK )
|
||||
{
|
||||
pJoystick->Release();
|
||||
(*pJoystick)->Release();
|
||||
#ifdef FIX_BUGS
|
||||
// BUG: enum will be called with Count == 2, which will write to a null pointer
|
||||
// So decrement count again since we're not using this pad
|
||||
--Count;
|
||||
#endif
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
// Stop enumeration. Note: we're just taking the first two joysticks we get. You
|
||||
// could store all the enumerated joysticks and let the user pick.
|
||||
if ( Count == 2 )
|
||||
return DIENUM_STOP;
|
||||
|
||||
// Stop enumeration. Note: we're just taking the first joystick we get. You
|
||||
// could store all the enumerated joysticks and let the user pick.
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -48,13 +48,13 @@ public:
|
||||
uint8 bHadDriver : 1; // for bombs
|
||||
uint8 m_auto_flagA20 : 1;
|
||||
uint8 m_auto_flagA40 : 1;
|
||||
uint8 m_auto_flagA80 : 1;
|
||||
uint8 bWaterTight : 1; // no damage for non-player peds
|
||||
uint8 bNotDamagedUpsideDown : 1;
|
||||
uint8 bMoreResistantToDamage : 1;
|
||||
uint8 field_4DB;
|
||||
CEntity *m_pBombRigger;
|
||||
int16 field_4E0;
|
||||
int16 field_4E2;
|
||||
uint16 m_hydraulicState;
|
||||
uint32 m_nBusDoorTimerEnd;
|
||||
uint32 m_nBusDoorTimerStart;
|
||||
float m_aSuspensionSpringLength[4];
|
||||
@ -71,7 +71,7 @@ public:
|
||||
float m_weaponDoorTimerRight;
|
||||
float m_fCarGunLR;
|
||||
float m_fCarGunUD;
|
||||
float m_fWindScreenRotation;
|
||||
float m_fPropellerRotation;
|
||||
uint8 stuff4[4];
|
||||
uint8 m_nWheelsOnGround;
|
||||
uint8 m_nDriveWheelsOnGround;
|
||||
@ -108,7 +108,7 @@ public:
|
||||
void BlowUpCar(CEntity *ent);
|
||||
bool SetUpWheelColModel(CColModel *colModel);
|
||||
void BurstTyre(uint8 tyre);
|
||||
bool IsRoomForPedToLeaveCar(uint32, CVector *);
|
||||
bool IsRoomForPedToLeaveCar(uint32 component, CVector *doorOffset);
|
||||
float GetHeightAboveRoad(void);
|
||||
void PlayCarHorn(void);
|
||||
|
||||
@ -122,6 +122,8 @@ public:
|
||||
int32 RcbanditCheck1CarWheels(CPtrList &list);
|
||||
void PlaceOnRoadProperly(void);
|
||||
void dmgDrawCarCollidingParticles(const CVector &pos, float amount);
|
||||
void AddDamagedVehicleParticles(void);
|
||||
int32 AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed);
|
||||
void PlayHornIfNecessary(void);
|
||||
void ResetSuspension(void);
|
||||
void SetupSuspensionLines(void);
|
||||
|
@ -5,7 +5,7 @@
|
||||
float &fShapeLength = *(float*)0x600E78;
|
||||
float &fShapeTime = *(float*)0x600E7C;
|
||||
float &fRangeMult = *(float*)0x600E80; //0.6f; // 0.75f gta 3
|
||||
float &fTimeMult = *(float*)0xA0FCF4;
|
||||
float &fTimeMult = *(float*)0x943008;
|
||||
|
||||
float MAX_WAKE_LENGTH = 50.0f;
|
||||
float MIN_WAKE_INTERVAL = 1.0f;
|
||||
|
@ -6,6 +6,9 @@
|
||||
|
||||
enum eEngineStatus
|
||||
{
|
||||
ENGINE_STATUS_STEAM1 = 100,
|
||||
ENGINE_STATUS_STEAM2 = 150,
|
||||
ENGINE_STATUS_SMOKE = 200,
|
||||
ENGINE_STATUS_ON_FIRE = 225
|
||||
};
|
||||
|
||||
@ -32,6 +35,12 @@ enum eWheelStatus
|
||||
WHEEL_STATUS_MISSING
|
||||
};
|
||||
|
||||
enum eLightStatus
|
||||
{
|
||||
LIGHT_STATUS_OK,
|
||||
LIGHT_STATUS_BROKEN
|
||||
};
|
||||
|
||||
enum tComponent
|
||||
{
|
||||
COMPONENT_DEFAULT,
|
||||
|
@ -22,7 +22,7 @@ static float fBoatVolumeDistribution[9] = {
|
||||
};
|
||||
|
||||
bool
|
||||
cBuoyancy::ProcessBuoyancy(CPhysical *phys, float buoyancy, CVector *impulse, CVector *point)
|
||||
cBuoyancy::ProcessBuoyancy(CPhysical *phys, float buoyancy, CVector *point, CVector *impulse)
|
||||
{
|
||||
m_numSteps = 2.0f;
|
||||
|
||||
@ -32,7 +32,7 @@ cBuoyancy::ProcessBuoyancy(CPhysical *phys, float buoyancy, CVector *impulse, CV
|
||||
|
||||
PreCalcSetup(phys, buoyancy);
|
||||
SimpleCalcBuoyancy();
|
||||
float f = CalcBuoyancyForce(phys, impulse, point);
|
||||
float f = CalcBuoyancyForce(phys, point, impulse);
|
||||
if(m_isBoat)
|
||||
return true;
|
||||
return f != 0.0f;
|
||||
@ -82,7 +82,7 @@ cBuoyancy::PreCalcSetup(CPhysical *phys, float buoyancy)
|
||||
m_haveVolume = false;
|
||||
m_numPartialVolumes = 1.0f;
|
||||
m_volumeUnderWater = 0.0f;
|
||||
m_impulse = CVector(0.0f, 0.0f, 0.0f);
|
||||
m_impulsePoint = CVector(0.0f, 0.0f, 0.0f);
|
||||
m_position = phys->GetPosition();
|
||||
m_positionZ = CVector(0.0f, 0.0f, m_position.z);
|
||||
m_buoyancy = buoyancy;
|
||||
@ -148,7 +148,7 @@ cBuoyancy::SimpleSumBuoyancyData(CVector &waterLevel, tWaterLevel waterPosition)
|
||||
|
||||
fFraction = 1.0f/m_numPartialVolumes;
|
||||
fRemainingSlice = 1.0f - fFraction;
|
||||
m_impulse = m_impulse*fRemainingSlice + AverageOfWaterLevel*fThisVolume*fFraction;
|
||||
m_impulsePoint = m_impulsePoint*fRemainingSlice + AverageOfWaterLevel*fThisVolume*fFraction;
|
||||
m_numPartialVolumes += 1.0f;
|
||||
m_haveVolume = true;
|
||||
return fThisVolume;
|
||||
@ -175,13 +175,13 @@ cBuoyancy::FindWaterLevel(const CVector &zpos, CVector *waterLevel, tWaterLevel
|
||||
}
|
||||
|
||||
bool
|
||||
cBuoyancy::CalcBuoyancyForce(CPhysical *phys, CVector *impulse, CVector *point)
|
||||
cBuoyancy::CalcBuoyancyForce(CPhysical *phys, CVector *point, CVector *impulse)
|
||||
{
|
||||
if(!m_haveVolume)
|
||||
return false;
|
||||
|
||||
*impulse = Multiply3x3(m_matrix, m_impulse);
|
||||
*point = CVector(0.0f, 0.0f, m_volumeUnderWater*m_buoyancy*CTimer::GetTimeStep());
|
||||
*point = Multiply3x3(m_matrix, m_impulsePoint);
|
||||
*impulse = CVector(0.0f, 0.0f, m_volumeUnderWater*m_buoyancy*CTimer::GetTimeStep());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
class Physical;
|
||||
class CPhysical;
|
||||
|
||||
enum tWaterLevel
|
||||
{
|
||||
@ -33,7 +33,7 @@ public:
|
||||
char m_field_B9;
|
||||
bool m_isBoat;
|
||||
float m_volumeUnderWater;
|
||||
CVector m_impulse;
|
||||
CVector m_impulsePoint;
|
||||
|
||||
bool ProcessBuoyancy(CPhysical *phys, float buoyancy, CVector *impulse, CVector *point);
|
||||
void PreCalcSetup(CPhysical *phys, float buoyancy);
|
||||
|
@ -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;
|
||||
@ -70,7 +70,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
|
||||
bHasBeenOwnedByPlayer = false;
|
||||
m_veh_flagC20 = false;
|
||||
bCanBeDamaged = true;
|
||||
m_veh_flagC80 = false;
|
||||
bUsingSpecialColModel = false;
|
||||
m_veh_flagD1 = false;
|
||||
m_veh_flagD2 = false;
|
||||
m_nGunFiringTime = 0;
|
||||
@ -255,9 +255,9 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
|
||||
float contactSpeedFwd = DotProduct(wheelContactSpeed, wheelFwd);
|
||||
float contactSpeedRight = DotProduct(wheelContactSpeed, wheelRight);
|
||||
|
||||
if(*wheelState != WHEEL_STATE_0)
|
||||
if(*wheelState != WHEEL_STATE_NORMAL)
|
||||
bAlreadySkidding = true;
|
||||
*wheelState = WHEEL_STATE_0;
|
||||
*wheelState = WHEEL_STATE_NORMAL;
|
||||
|
||||
adhesion *= CTimer::GetTimeStep();
|
||||
if(bAlreadySkidding)
|
||||
@ -299,7 +299,7 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
|
||||
|
||||
if(brake > adhesion){
|
||||
if(Abs(contactSpeedFwd) > 0.005f)
|
||||
*wheelState = WHEEL_STATE_STATIC;
|
||||
*wheelState = WHEEL_STATE_FIXED;
|
||||
}else {
|
||||
if(fwd > 0.0f){
|
||||
if(fwd > brake)
|
||||
@ -312,11 +312,11 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
|
||||
}
|
||||
|
||||
if(sq(adhesion) < sq(right) + sq(fwd)){
|
||||
if(*wheelState != WHEEL_STATE_STATIC){
|
||||
if(*wheelState != WHEEL_STATE_FIXED){
|
||||
if(bDriving && contactSpeedFwd < 0.2f)
|
||||
*wheelState = WHEEL_STATE_1;
|
||||
*wheelState = WHEEL_STATE_SPINNING;
|
||||
else
|
||||
*wheelState = WHEEL_STATE_2;
|
||||
*wheelState = WHEEL_STATE_SKIDDING;
|
||||
}
|
||||
|
||||
float l = Sqrt(sq(right) + sq(fwd));
|
||||
@ -343,10 +343,10 @@ CVehicle::ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVec
|
||||
{
|
||||
float angularVelocity;
|
||||
switch(state){
|
||||
case WHEEL_STATE_1:
|
||||
case WHEEL_STATE_SPINNING:
|
||||
angularVelocity = -1.1f; // constant speed forward
|
||||
break;
|
||||
case WHEEL_STATE_STATIC:
|
||||
case WHEEL_STATE_FIXED:
|
||||
angularVelocity = 0.0f; // not moving
|
||||
break;
|
||||
default:
|
||||
@ -377,12 +377,13 @@ CVehicle::ProcessDelayedExplosion(void)
|
||||
return;
|
||||
|
||||
int tick = CTimer::GetTimeStep()/60.0f*1000.0f;
|
||||
int16 prev = m_nBombTimer;
|
||||
if(tick > m_nBombTimer)
|
||||
m_nBombTimer = 0;
|
||||
else
|
||||
m_nBombTimer -= tick;
|
||||
|
||||
if(IsCar() && ((CAutomobile*)this)->m_bombType == CARBOMB_TIMEDACTIVE && (m_nBombTimer & 0xFE00) != 0xFE00)
|
||||
if(IsCar() && ((CAutomobile*)this)->m_bombType == CARBOMB_TIMEDACTIVE && (m_nBombTimer & 0xFE00) != (prev & 0xFE00))
|
||||
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_BOMB_TICK, 0.0f);
|
||||
|
||||
if (m_nBombTimer != 0)
|
||||
|
@ -59,6 +59,11 @@ enum
|
||||
CAR_POS_EXHAUST = 9,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
BOAT_POS_FRONTSEAT
|
||||
};
|
||||
|
||||
enum eDoors
|
||||
{
|
||||
DOOR_BONNET = 0,
|
||||
@ -119,10 +124,10 @@ enum
|
||||
|
||||
enum tWheelState
|
||||
{
|
||||
WHEEL_STATE_0 = 0,
|
||||
WHEEL_STATE_1 = 1, // constant velocity
|
||||
WHEEL_STATE_2 = 2, // normal
|
||||
WHEEL_STATE_STATIC = 3, // not moving
|
||||
WHEEL_STATE_NORMAL, // standing still or rolling normally
|
||||
WHEEL_STATE_SPINNING, // rotating but not moving
|
||||
WHEEL_STATE_SKIDDING,
|
||||
WHEEL_STATE_FIXED, // not rotating
|
||||
};
|
||||
|
||||
enum eFlightModel
|
||||
@ -176,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
|
||||
@ -186,7 +191,7 @@ public:
|
||||
uint8 m_veh_flagC10 : 1;
|
||||
uint8 m_veh_flagC20 : 1;
|
||||
uint8 bCanBeDamaged : 1; // Set to FALSE during cut scenes to avoid explosions
|
||||
uint8 m_veh_flagC80 : 1;
|
||||
uint8 bUsingSpecialColModel : 1;// Is player vehicle using special collision model, stored in player strucure
|
||||
|
||||
uint8 m_veh_flagD1 : 1;
|
||||
uint8 m_veh_flagD2 : 1;
|
||||
@ -253,7 +258,7 @@ public:
|
||||
virtual void BlowUpCar(CEntity *ent) {}
|
||||
virtual bool SetUpWheelColModel(CColModel *colModel) { return false; }
|
||||
virtual void BurstTyre(uint8 tyre) {}
|
||||
virtual bool IsRoomForPedToLeaveCar(uint32, CVector *) { return false;}
|
||||
virtual bool IsRoomForPedToLeaveCar(uint32 component, CVector *forcedDoorPos) { return false;}
|
||||
virtual float GetHeightAboveRoad(void);
|
||||
virtual void PlayCarHorn(void) {}
|
||||
|
||||
|
@ -3,11 +3,14 @@
|
||||
#include "Weapon.h"
|
||||
#include "Timer.h"
|
||||
#include "WeaponInfo.h"
|
||||
#include "Ped.h"
|
||||
#include "World.h"
|
||||
|
||||
WRAPPER bool CWeapon::Fire(CEntity*, CVector*) { EAXJMP(0x55C380); }
|
||||
WRAPPER void CWeapon::FireFromCar(CAutomobile *car, bool left) { EAXJMP(0x55C940); }
|
||||
WRAPPER void CWeapon::AddGunshell(CEntity*, CVector const&, CVector2D const&, float) { EAXJMP(0x55F770); }
|
||||
WRAPPER void CWeapon::Update(int32 audioEntity) { EAXJMP(0x563A10); }
|
||||
WRAPPER void CWeapon::DoTankDoomAiming(CEntity *playerVehicle, CEntity *playerPed, CVector *start, CVector *end) { EAXJMP(0x563200); }
|
||||
|
||||
void
|
||||
CWeapon::Initialise(eWeaponType type, int ammo)
|
||||
@ -49,7 +52,42 @@ CWeapon::IsTypeMelee(void)
|
||||
return m_eWeaponType == WEAPONTYPE_UNARMED || m_eWeaponType == WEAPONTYPE_BASEBALLBAT;
|
||||
}
|
||||
|
||||
bool
|
||||
CWeapon::HitsGround(CEntity *holder, CVector *firePos, CEntity *aimingTo)
|
||||
{
|
||||
if (!holder->IsPed() || !((CPed*)holder)->m_pSeekTarget)
|
||||
return false;
|
||||
|
||||
CWeaponInfo *ourType = CWeaponInfo::GetWeaponInfo(m_eWeaponType);
|
||||
CVector adjustedOffset = ourType->m_vecFireOffset;
|
||||
adjustedOffset.z += 0.6f;
|
||||
|
||||
CVector point1, point2;
|
||||
CEntity *foundEnt = nil;
|
||||
CColPoint foundCol;
|
||||
|
||||
if (firePos)
|
||||
point1 = *firePos;
|
||||
else
|
||||
point1 = holder->GetMatrix() * adjustedOffset;
|
||||
|
||||
CEntity *aimEntity = aimingTo ? aimingTo : ((CPed*)holder)->m_pSeekTarget;
|
||||
point2 = aimEntity->GetPosition();
|
||||
point2.z += 0.6f;
|
||||
|
||||
CWorld::ProcessLineOfSight(point1, point2, foundCol, foundEnt, true, false, false, false, false, false, false);
|
||||
if (foundEnt && foundEnt->IsBuilding()) {
|
||||
// That was supposed to be Magnitude, according to leftover code in assembly
|
||||
float diff = (foundCol.point.z - point1.z);
|
||||
if (diff < 0.0f && diff > -3.0f)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x55C330, &CWeapon::Initialise, PATCH_JUMP);
|
||||
InjectHook(0x5639D0, &CWeapon::Reload, PATCH_JUMP);
|
||||
InjectHook(0x564890, &CWeapon::HitsGround, PATCH_JUMP);
|
||||
ENDPATCHES
|
@ -70,5 +70,7 @@ public:
|
||||
void AddGunshell(CEntity*, CVector const&, CVector2D const&, float);
|
||||
bool IsTypeMelee(void);
|
||||
bool IsType2Handed(void);
|
||||
static void DoTankDoomAiming(CEntity *playerVehicle, CEntity *playerPed, CVector *start, CVector *end);
|
||||
bool HitsGround(CEntity* holder, CVector* firePos, CEntity* aimingTo);
|
||||
};
|
||||
static_assert(sizeof(CWeapon) == 0x18, "CWeapon: error");
|
||||
|
Loading…
Reference in New Issue
Block a user