Merge branch 'master' into master
This commit is contained in:
commit
6909fa283a
@ -8,7 +8,6 @@
|
|||||||
cDMAudio &DMAudio = *(cDMAudio*)0x95CDBE;
|
cDMAudio &DMAudio = *(cDMAudio*)0x95CDBE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cDMAudio::Initialise(void)
|
cDMAudio::Initialise(void)
|
||||||
{
|
{
|
||||||
|
5
src/control/AutoPilot.cpp
Normal file
5
src/control/AutoPilot.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "AutoPilot.h"
|
||||||
|
|
||||||
|
WRAPPER void CAutoPilot::ModifySpeed(float) { EAXJMP(0x4137B0); }
|
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Timer.h"
|
||||||
|
|
||||||
class CVehicle;
|
class CVehicle;
|
||||||
|
|
||||||
@ -62,26 +63,26 @@ public:
|
|||||||
uint32 m_nCurrentRouteNode;
|
uint32 m_nCurrentRouteNode;
|
||||||
uint32 m_nNextRouteNode;
|
uint32 m_nNextRouteNode;
|
||||||
uint32 m_nPrevRouteNode;
|
uint32 m_nPrevRouteNode;
|
||||||
uint32 m_nTotalSpeedScaleFactor;
|
uint32 m_nTimeEnteredCurve;
|
||||||
uint32 m_nSpeedScaleFactor;
|
uint32 m_nTimeToSpendOnCurrentCurve;
|
||||||
uint32 m_nCurrentPathNodeInfo;
|
uint32 m_nCurrentPathNodeInfo;
|
||||||
uint32 m_nNextPathNodeInfo;
|
uint32 m_nNextPathNodeInfo;
|
||||||
uint32 m_nPreviousPathNodeInfo;
|
uint32 m_nPreviousPathNodeInfo;
|
||||||
uint32 m_nTimeToStartMission;
|
uint32 m_nTimeToStartMission;
|
||||||
uint32 m_nTimeSwitchedToRealPhysics;
|
uint32 m_nAntiReverseTimer;
|
||||||
int8 m_nPreviousDirection;
|
int8 m_nPreviousDirection;
|
||||||
int8 m_nCurrentDirecton;
|
int8 m_nCurrentDirection;
|
||||||
int8 m_nNextDirection;
|
int8 m_nNextDirection;
|
||||||
int8 m_nPreviousLane;
|
|
||||||
int8 m_nCurrentLane;
|
int8 m_nCurrentLane;
|
||||||
|
int8 m_nNextLane;
|
||||||
eCarDrivingStyle m_nDrivingStyle;
|
eCarDrivingStyle m_nDrivingStyle;
|
||||||
eCarMission m_nCarMission;
|
eCarMission m_nCarMission;
|
||||||
eCarTempAction m_nAnimationId;
|
eCarTempAction m_nTempAction;
|
||||||
uint8 m_nAnimationTime;
|
uint32 m_nTimeTempAction;
|
||||||
float m_fMaxTrafficSpeed;
|
float m_fMaxTrafficSpeed;
|
||||||
uint8 m_nCruiseSpeed;
|
uint8 m_nCruiseSpeed;
|
||||||
uint8 m_flag1 : 1;
|
uint8 m_flag1 : 1;
|
||||||
uint8 m_flag2 : 1;
|
uint8 m_bSlowedDownBecauseOfPeds : 1;
|
||||||
uint8 m_flag4 : 1;
|
uint8 m_flag4 : 1;
|
||||||
uint8 m_flag8 : 1;
|
uint8 m_flag8 : 1;
|
||||||
uint8 m_flag10 : 1;
|
uint8 m_flag10 : 1;
|
||||||
@ -94,26 +95,28 @@ public:
|
|||||||
m_nPrevRouteNode = 0;
|
m_nPrevRouteNode = 0;
|
||||||
m_nNextRouteNode = m_nPrevRouteNode;
|
m_nNextRouteNode = m_nPrevRouteNode;
|
||||||
m_nCurrentRouteNode = m_nNextRouteNode;
|
m_nCurrentRouteNode = m_nNextRouteNode;
|
||||||
m_nTotalSpeedScaleFactor = 0;
|
m_nTimeEnteredCurve = 0;
|
||||||
m_nSpeedScaleFactor = 1000;
|
m_nTimeToSpendOnCurrentCurve = 1000;
|
||||||
m_nPreviousPathNodeInfo = 0;
|
m_nPreviousPathNodeInfo = 0;
|
||||||
m_nNextPathNodeInfo = m_nPreviousPathNodeInfo;
|
m_nNextPathNodeInfo = m_nPreviousPathNodeInfo;
|
||||||
m_nCurrentPathNodeInfo = m_nNextPathNodeInfo;
|
m_nCurrentPathNodeInfo = m_nNextPathNodeInfo;
|
||||||
m_nNextDirection = 1;
|
m_nNextDirection = 1;
|
||||||
m_nCurrentDirecton = m_nNextDirection;
|
m_nCurrentDirection = m_nNextDirection;
|
||||||
m_nPreviousLane = m_nCurrentLane = 0;
|
m_nCurrentLane = m_nNextLane = 0;
|
||||||
m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
|
m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
|
||||||
m_nCarMission = MISSION_NONE;
|
m_nCarMission = MISSION_NONE;
|
||||||
m_nAnimationId = TEMPACT_NONE;
|
m_nTempAction = TEMPACT_NONE;
|
||||||
m_nCruiseSpeed = 10;
|
m_nCruiseSpeed = 10;
|
||||||
m_fMaxTrafficSpeed = 10.0f;
|
m_fMaxTrafficSpeed = 10.0f;
|
||||||
m_flag2 = false;
|
m_bSlowedDownBecauseOfPeds = false;
|
||||||
m_flag1 = false;
|
m_flag1 = false;
|
||||||
m_nPathFindNodesCount = 0;
|
m_nPathFindNodesCount = 0;
|
||||||
m_pTargetCar = 0;
|
m_pTargetCar = 0;
|
||||||
m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
|
m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
|
||||||
m_nTimeSwitchedToRealPhysics = m_nTimeToStartMission;
|
m_nAntiReverseTimer = m_nTimeToStartMission;
|
||||||
m_flag8 = false;
|
m_flag8 = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModifySpeed(float);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CAutoPilot) == 0x70, "CAutoPilot: error");
|
static_assert(sizeof(CAutoPilot) == 0x70, "CAutoPilot: error");
|
||||||
|
@ -2,5 +2,21 @@
|
|||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "CarAI.h"
|
#include "CarAI.h"
|
||||||
|
|
||||||
|
#include "AutoPilot.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
#include "Vehicle.h"
|
||||||
|
|
||||||
WRAPPER void CCarAI::UpdateCarAI(CVehicle*) { EAXJMP(0x413E50); }
|
WRAPPER void CCarAI::UpdateCarAI(CVehicle*) { EAXJMP(0x413E50); }
|
||||||
WRAPPER void CCarAI::MakeWayForCarWithSiren(CVehicle *veh) { EAXJMP(0x416280); }
|
WRAPPER void CCarAI::MakeWayForCarWithSiren(CVehicle *veh) { EAXJMP(0x416280); }
|
||||||
|
WRAPPER eCarMission CCarAI::FindPoliceCarMissionForWantedLevel() { EAXJMP(0x415E30); }
|
||||||
|
WRAPPER int32 CCarAI::FindPoliceCarSpeedForWantedLevel(CVehicle*) { EAXJMP(0x415EB0); }
|
||||||
|
WRAPPER void CCarAI::AddPoliceOccupants(CVehicle*) { EAXJMP(0x415C60); }
|
||||||
|
|
||||||
|
void CCarAI::CarHasReasonToStop(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
STARTPATCHES
|
||||||
|
InjectHook(0x415B00, &CCarAI::CarHasReasonToStop, PATCH_JUMP);
|
||||||
|
ENDPATCHES
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "AutoPilot.h"
|
||||||
|
|
||||||
class CVehicle;
|
class CVehicle;
|
||||||
|
|
||||||
class CCarAI
|
class CCarAI
|
||||||
@ -7,4 +9,8 @@ class CCarAI
|
|||||||
public:
|
public:
|
||||||
static void UpdateCarAI(CVehicle*);
|
static void UpdateCarAI(CVehicle*);
|
||||||
static void MakeWayForCarWithSiren(CVehicle *veh);
|
static void MakeWayForCarWithSiren(CVehicle *veh);
|
||||||
|
static int32 FindPoliceCarSpeedForWantedLevel(CVehicle*);
|
||||||
|
static eCarMission FindPoliceCarMissionForWantedLevel();
|
||||||
|
static void AddPoliceOccupants(CVehicle*);
|
||||||
|
static void CarHasReasonToStop(CVehicle*);
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,38 @@
|
|||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "CarCtrl.h"
|
#include "CarCtrl.h"
|
||||||
|
|
||||||
|
#include "Automobile.h"
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "CarAI.h"
|
||||||
|
#include "CarGen.h"
|
||||||
|
#include "Cranes.h"
|
||||||
|
#include "Curves.h"
|
||||||
|
#include "CutsceneMgr.h"
|
||||||
|
#include "Gangs.h"
|
||||||
|
#include "Garages.h"
|
||||||
|
#include "General.h"
|
||||||
|
#include "IniFile.h"
|
||||||
|
#include "ModelIndices.h"
|
||||||
|
#include "PathFind.h"
|
||||||
|
#include "Ped.h"
|
||||||
|
#include "PlayerInfo.h"
|
||||||
|
#include "PlayerPed.h"
|
||||||
|
#include "Pools.h"
|
||||||
|
#include "Renderer.h"
|
||||||
|
#include "RoadBlocks.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
#include "TrafficLights.h"
|
||||||
|
#include "Streaming.h"
|
||||||
|
#include "VisibilityPlugins.h"
|
||||||
|
#include "Vehicle.h"
|
||||||
|
#include "Wanted.h"
|
||||||
|
#include "World.h"
|
||||||
|
#include "Zones.h"
|
||||||
|
|
||||||
|
#define DISTANCE_TO_SPAWN_ROADBLOCK_PEDS 51.0f
|
||||||
|
#define DISTANCE_TO_SCAN_FOR_DANGER 11.0f
|
||||||
|
#define INFINITE_Z 1000000000.0f
|
||||||
|
|
||||||
int &CCarCtrl::NumLawEnforcerCars = *(int*)0x8F1B38;
|
int &CCarCtrl::NumLawEnforcerCars = *(int*)0x8F1B38;
|
||||||
int &CCarCtrl::NumAmbulancesOnDuty = *(int*)0x885BB0;
|
int &CCarCtrl::NumAmbulancesOnDuty = *(int*)0x885BB0;
|
||||||
int &CCarCtrl::NumFiretrucksOnDuty = *(int*)0x9411F0;
|
int &CCarCtrl::NumFiretrucksOnDuty = *(int*)0x9411F0;
|
||||||
@ -10,17 +42,833 @@ float& CCarCtrl::CarDensityMultiplier = *(float*)0x5EC8B4;
|
|||||||
int32 &CCarCtrl::NumMissionCars = *(int32*)0x8F1B54;
|
int32 &CCarCtrl::NumMissionCars = *(int32*)0x8F1B54;
|
||||||
int32 &CCarCtrl::NumRandomCars = *(int32*)0x943118;
|
int32 &CCarCtrl::NumRandomCars = *(int32*)0x943118;
|
||||||
int32 &CCarCtrl::NumParkedCars = *(int32*)0x8F29E0;
|
int32 &CCarCtrl::NumParkedCars = *(int32*)0x8F29E0;
|
||||||
|
int8 &CCarCtrl::CountDownToCarsAtStart = *(int8*)0x95CD63;
|
||||||
|
int32 &CCarCtrl::MaxNumberOfCarsInUse = *(int32*)0x5EC8B8;
|
||||||
|
uint32 &CCarCtrl::LastTimeLawEnforcerCreated = *(uint32*)0x8F5FF0;
|
||||||
|
int32 (&CCarCtrl::TotalNumOfCarsOfRating)[7] = *(int32(*)[7])*(uintptr*)0x8F1A60;
|
||||||
|
int32 (&CCarCtrl::NextCarOfRating)[7] = *(int32(*)[7])*(uintptr*)0x9412AC;
|
||||||
|
int32 (&CCarCtrl::CarArrays)[7][MAX_CAR_MODELS_IN_ARRAY] = *(int32(*)[7][MAX_CAR_MODELS_IN_ARRAY])*(uintptr*)0x6EB860;
|
||||||
|
CVehicle* (&apCarsToKeep)[MAX_CARS_TO_KEEP] = *(CVehicle*(*)[MAX_CARS_TO_KEEP])*(uintptr*)0x70D830;
|
||||||
|
|
||||||
WRAPPER void CCarCtrl::SwitchVehicleToRealPhysics(CVehicle*) { EAXJMP(0x41F7F0); }
|
WRAPPER void CCarCtrl::SwitchVehicleToRealPhysics(CVehicle*) { EAXJMP(0x41F7F0); }
|
||||||
WRAPPER void CCarCtrl::AddToCarArray(int32 id, int32 vehclass) { EAXJMP(0x4182F0); }
|
|
||||||
WRAPPER void CCarCtrl::UpdateCarCount(CVehicle*, bool) { EAXJMP(0x4202E0); }
|
WRAPPER void CCarCtrl::UpdateCarCount(CVehicle*, bool) { EAXJMP(0x4202E0); }
|
||||||
WRAPPER int32 CCarCtrl::ChooseCarModel(int32 vehclass) { EAXJMP(0x418110); }
|
|
||||||
WRAPPER bool CCarCtrl::JoinCarWithRoadSystemGotoCoors(CVehicle*, CVector, bool) { EAXJMP(0x41FA00); }
|
WRAPPER bool CCarCtrl::JoinCarWithRoadSystemGotoCoors(CVehicle*, CVector, bool) { EAXJMP(0x41FA00); }
|
||||||
WRAPPER void CCarCtrl::JoinCarWithRoadSystem(CVehicle*) { EAXJMP(0x41F820); }
|
WRAPPER void CCarCtrl::JoinCarWithRoadSystem(CVehicle*) { EAXJMP(0x41F820); }
|
||||||
WRAPPER void CCarCtrl::SteerAICarWithPhysics(CVehicle*) { EAXJMP(0x41DA60); }
|
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); }
|
WRAPPER void CCarCtrl::RemoveFromInterestingVehicleList(CVehicle* v) { EAXJMP(0x41F7A0); }
|
||||||
|
WRAPPER void CCarCtrl::GenerateEmergencyServicesCar(void) { EAXJMP(0x41FC50); }
|
||||||
|
WRAPPER void CCarCtrl::PickNextNodeAccordingStrategy(CVehicle*) { EAXJMP(0x41BA50); }
|
||||||
|
WRAPPER void CCarCtrl::DragCarToPoint(CVehicle*, CVector*) { EAXJMP(0x41D450); }
|
||||||
|
WRAPPER void CCarCtrl::SlowCarDownForCarsSectorList(CPtrList&, CVehicle*, float, float, float, float, float*, float) { EAXJMP(0x419B40); }
|
||||||
|
WRAPPER void CCarCtrl::SlowCarDownForPedsSectorList(CPtrList&, CVehicle*, float, float, float, float, float*, float) { EAXJMP(0x419300); }
|
||||||
|
|
||||||
|
void
|
||||||
|
CCarCtrl::GenerateRandomCars()
|
||||||
|
{
|
||||||
|
if (CCutsceneMgr::IsCutsceneProcessing())
|
||||||
|
return;
|
||||||
|
if (NumRandomCars < 30){
|
||||||
|
if (CountDownToCarsAtStart == 0){
|
||||||
|
GenerateOneRandomCar();
|
||||||
|
}
|
||||||
|
else if (--CountDownToCarsAtStart == 0) {
|
||||||
|
for (int i = 0; i < 50; i++)
|
||||||
|
GenerateOneRandomCar();
|
||||||
|
CTheCarGenerators::GenerateEvenIfPlayerIsCloseCounter = 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Approximately once per 4 seconds. */
|
||||||
|
if ((CTimer::GetTimeInMilliseconds() & 0xFFFFF000) != (CTimer::GetPreviousTimeInMilliseconds() & 0xFFFFF000))
|
||||||
|
GenerateEmergencyServicesCar();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CCarCtrl::GenerateOneRandomCar()
|
||||||
|
{
|
||||||
|
static int32 unk = 0;
|
||||||
|
CPlayerInfo* pPlayer = &CWorld::Players[CWorld::PlayerInFocus];
|
||||||
|
CVector vecTargetPos = FindPlayerCentreOfWorld(CWorld::PlayerInFocus);
|
||||||
|
CVector2D vecPlayerSpeed = FindPlayerSpeed();
|
||||||
|
CZoneInfo zone;
|
||||||
|
CTheZones::GetZoneInfoForTimeOfDay(&vecTargetPos, &zone);
|
||||||
|
pPlayer->m_nTrafficMultiplier = pPlayer->m_fRoadDensity * zone.carDensity;
|
||||||
|
if (NumRandomCars >= pPlayer->m_nTrafficMultiplier * CarDensityMultiplier * CIniFile::CarNumberMultiplier)
|
||||||
|
return;
|
||||||
|
if (NumFiretrucksOnDuty + NumAmbulancesOnDuty + NumParkedCars + NumMissionCars + NumLawEnforcerCars + NumRandomCars >= MaxNumberOfCarsInUse)
|
||||||
|
return;
|
||||||
|
CWanted* pWanted = pPlayer->m_pPed->m_pWanted;
|
||||||
|
int carClass;
|
||||||
|
int carModel;
|
||||||
|
if (pWanted->m_nWantedLevel > 1 && NumLawEnforcerCars < pWanted->m_MaximumLawEnforcerVehicles &&
|
||||||
|
pWanted->m_CurrentCops < pWanted->m_MaxCops && (
|
||||||
|
pWanted->m_nWantedLevel > 3 ||
|
||||||
|
pWanted->m_nWantedLevel > 2 && CTimer::GetTimeInMilliseconds() > LastTimeLawEnforcerCreated + 5000 ||
|
||||||
|
pWanted->m_nWantedLevel > 1 && CTimer::GetTimeInMilliseconds() > LastTimeLawEnforcerCreated + 8000)) {
|
||||||
|
/* Last pWanted->m_nWantedLevel > 1 is unnecessary but I added it for better readability. */
|
||||||
|
/* Wouldn't be surprised it was there originally but was optimized out. */
|
||||||
|
carClass = COPS;
|
||||||
|
carModel = ChoosePoliceCarModel();
|
||||||
|
}else{
|
||||||
|
carModel = ChooseModel(&zone, &vecTargetPos, &carClass);
|
||||||
|
if (carClass == COPS && pWanted->m_nWantedLevel >= 1)
|
||||||
|
/* All cop spawns with wanted level are handled by condition above. */
|
||||||
|
/* In particular it means that cop cars never spawn if player has wanted level of 1. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
float frontX, frontY;
|
||||||
|
float preferredDistance, angleLimit;
|
||||||
|
bool invertAngleLimitTest;
|
||||||
|
CVector spawnPosition;
|
||||||
|
int32 curNodeId, nextNodeId;
|
||||||
|
float positionBetweenNodes;
|
||||||
|
bool testForCollision;
|
||||||
|
CVehicle* pPlayerVehicle = FindPlayerVehicle();
|
||||||
|
CVector2D vecPlayerVehicleSpeed;
|
||||||
|
float fPlayerVehicleSpeed;
|
||||||
|
if (pPlayerVehicle) {
|
||||||
|
vecPlayerVehicleSpeed = FindPlayerVehicle()->GetMoveSpeed();
|
||||||
|
fPlayerVehicleSpeed = vecPlayerVehicleSpeed.Magnitude();
|
||||||
|
}
|
||||||
|
if (TheCamera.GetForward().z < -0.9f){
|
||||||
|
/* Player uses topdown camera. */
|
||||||
|
/* Spawn essentially anywhere. */
|
||||||
|
frontX = frontY = 0.707f; /* 45 degrees */
|
||||||
|
angleLimit = -1.0f;
|
||||||
|
invertAngleLimitTest = true;
|
||||||
|
preferredDistance = 40.0f;
|
||||||
|
/* BUG: testForCollision not initialized in original game. */
|
||||||
|
testForCollision = false;
|
||||||
|
}else if (!pPlayerVehicle){
|
||||||
|
/* Player is not in vehicle. */
|
||||||
|
testForCollision = true;
|
||||||
|
frontX = TheCamera.CamFrontXNorm;
|
||||||
|
frontY = TheCamera.CamFrontYNorm;
|
||||||
|
switch (CTimer::GetFrameCounter() & 1) {
|
||||||
|
case 0:
|
||||||
|
/* Spawn a vehicle relatively far away from player. */
|
||||||
|
/* Forward to his current direction (camera direction). */
|
||||||
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
|
invertAngleLimitTest = true;
|
||||||
|
preferredDistance = 120.0f * TheCamera.GenerationDistMultiplier;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* Spawn a vehicle close to player to his side. */
|
||||||
|
/* Kinda not within camera angle. */
|
||||||
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
|
invertAngleLimitTest = false;
|
||||||
|
preferredDistance = 40.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}else if (fPlayerVehicleSpeed > 0.4f){ /* 72 km/h */
|
||||||
|
/* Player is moving fast in vehicle */
|
||||||
|
/* Prefer spawning vehicles very far away from him. */
|
||||||
|
frontX = vecPlayerVehicleSpeed.x / fPlayerVehicleSpeed;
|
||||||
|
frontY = vecPlayerVehicleSpeed.y / fPlayerVehicleSpeed;
|
||||||
|
testForCollision = false;
|
||||||
|
switch (CTimer::GetFrameCounter() & 3) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
/* Spawn a vehicle in a very narrow gap in front of a player */
|
||||||
|
angleLimit = 0.85f; /* approx 30 degrees */
|
||||||
|
invertAngleLimitTest = true;
|
||||||
|
preferredDistance = 120.0f * TheCamera.GenerationDistMultiplier;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/* Spawn a vehicle relatively far away from player. */
|
||||||
|
/* Forward to his current direction (camera direction). */
|
||||||
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
|
invertAngleLimitTest = true;
|
||||||
|
preferredDistance = 120.0f * TheCamera.GenerationDistMultiplier;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
/* Spawn a vehicle close to player to his side. */
|
||||||
|
/* Kinda not within camera angle. */
|
||||||
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
|
invertAngleLimitTest = false;
|
||||||
|
preferredDistance = 40.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}else if (fPlayerVehicleSpeed > 0.1f){ /* 18 km/h */
|
||||||
|
/* Player is moving moderately fast in vehicle */
|
||||||
|
/* Spawn more vehicles to player's side. */
|
||||||
|
frontX = vecPlayerVehicleSpeed.x / fPlayerVehicleSpeed;
|
||||||
|
frontY = vecPlayerVehicleSpeed.y / fPlayerVehicleSpeed;
|
||||||
|
testForCollision = false;
|
||||||
|
switch (CTimer::GetFrameCounter() & 3) {
|
||||||
|
case 0:
|
||||||
|
/* Spawn a vehicle in a very narrow gap in front of a player */
|
||||||
|
angleLimit = 0.85f; /* approx 30 degrees */
|
||||||
|
invertAngleLimitTest = true;
|
||||||
|
preferredDistance = 120.0f * TheCamera.GenerationDistMultiplier;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* Spawn a vehicle relatively far away from player. */
|
||||||
|
/* Forward to his current direction (camera direction). */
|
||||||
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
|
invertAngleLimitTest = true;
|
||||||
|
preferredDistance = 120.0f * TheCamera.GenerationDistMultiplier;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
/* Spawn a vehicle close to player to his side. */
|
||||||
|
/* Kinda not within camera angle. */
|
||||||
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
|
invertAngleLimitTest = false;
|
||||||
|
preferredDistance = 40.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
/* Player is in vehicle but moving very slow. */
|
||||||
|
/* Then use camera direction instead of vehicle direction. */
|
||||||
|
testForCollision = true;
|
||||||
|
frontX = TheCamera.CamFrontXNorm;
|
||||||
|
frontY = TheCamera.CamFrontYNorm;
|
||||||
|
switch (CTimer::GetFrameCounter() & 1) {
|
||||||
|
case 0:
|
||||||
|
/* Spawn a vehicle relatively far away from player. */
|
||||||
|
/* Forward to his current direction (camera direction). */
|
||||||
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
|
invertAngleLimitTest = true;
|
||||||
|
preferredDistance = 120.0f * TheCamera.GenerationDistMultiplier;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* Spawn a vehicle close to player to his side. */
|
||||||
|
/* Kinda not within camera angle. */
|
||||||
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
|
invertAngleLimitTest = false;
|
||||||
|
preferredDistance = 40.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ThePaths.NewGenerateCarCreationCoors(vecTargetPos.x, vecTargetPos.y, frontX, frontY,
|
||||||
|
preferredDistance, angleLimit, invertAngleLimitTest, &spawnPosition, &curNodeId, &nextNodeId,
|
||||||
|
&positionBetweenNodes, carClass == COPS && pWanted->m_nWantedLevel >= 1))
|
||||||
|
return;
|
||||||
|
int16 colliding;
|
||||||
|
CWorld::FindObjectsKindaColliding(spawnPosition, 10.0f, true, &colliding, 2, nil, false, true, true, false, false);
|
||||||
|
if (colliding)
|
||||||
|
/* If something is already present in spawn position, do not create vehicle*/
|
||||||
|
return;
|
||||||
|
if (!ThePaths.TestCoorsCloseness(vecTargetPos, false, spawnPosition))
|
||||||
|
/* Testing if spawn position can reach target position via valid path. */
|
||||||
|
return;
|
||||||
|
int16 idInNode = 0;
|
||||||
|
CPathNode* pCurNode = &ThePaths.m_pathNodes[curNodeId];
|
||||||
|
CPathNode* pNextNode = &ThePaths.m_pathNodes[nextNodeId];
|
||||||
|
while (idInNode < pCurNode->numLinks &&
|
||||||
|
ThePaths.m_connections[idInNode + pCurNode->firstLink] != nextNodeId)
|
||||||
|
idInNode++;
|
||||||
|
int16 connectionId = ThePaths.m_carPathConnections[idInNode + pCurNode->firstLink];
|
||||||
|
CCarPathLink* pPathLink = &ThePaths.m_carPathLinks[connectionId];
|
||||||
|
int16 lanesOnCurrentRoad = pPathLink->pathNodeIndex == nextNodeId ? pPathLink->numLeftLanes : pPathLink->numRightLanes;
|
||||||
|
CVehicleModelInfo* pModelInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(carModel);
|
||||||
|
if (lanesOnCurrentRoad == 0 || pModelInfo->m_vehicleType == VEHICLE_TYPE_BIKE)
|
||||||
|
/* Not spawning vehicle if road is one way and intended direction is opposide to that way. */
|
||||||
|
/* Also not spawning bikes but they don't exist in final game. */
|
||||||
|
return;
|
||||||
|
CAutomobile* pCar = new CAutomobile(carModel, RANDOM_VEHICLE);
|
||||||
|
pCar->AutoPilot.m_nPrevRouteNode = 0;
|
||||||
|
pCar->AutoPilot.m_nCurrentRouteNode = curNodeId;
|
||||||
|
pCar->AutoPilot.m_nNextRouteNode = nextNodeId;
|
||||||
|
switch (carClass) {
|
||||||
|
case POOR:
|
||||||
|
case RICH:
|
||||||
|
case EXEC:
|
||||||
|
case WORKER:
|
||||||
|
case SPECIAL:
|
||||||
|
case BIG:
|
||||||
|
case TAXI:
|
||||||
|
case MAFIA:
|
||||||
|
case TRIAD:
|
||||||
|
case DIABLO:
|
||||||
|
case YAKUZA:
|
||||||
|
case YARDIE:
|
||||||
|
case COLOMB:
|
||||||
|
case NINES:
|
||||||
|
case GANG8:
|
||||||
|
case GANG9:
|
||||||
|
{
|
||||||
|
pCar->AutoPilot.m_nCruiseSpeed = CGeneral::GetRandomNumberInRange(9, 14);
|
||||||
|
if (carClass == EXEC)
|
||||||
|
pCar->AutoPilot.m_nCruiseSpeed = CGeneral::GetRandomNumberInRange(12, 18);
|
||||||
|
else if (carClass == POOR || carClass == SPECIAL)
|
||||||
|
pCar->AutoPilot.m_nCruiseSpeed = CGeneral::GetRandomNumberInRange(7, 10);
|
||||||
|
CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(pCar->GetModelIndex());
|
||||||
|
if (pVehicleInfo->GetColModel()->boundingBox.max.y - pVehicleInfo->GetColModel()->boundingBox.min.y > 10.0f || carClass == BIG) {
|
||||||
|
pCar->AutoPilot.m_nCruiseSpeed *= 3;
|
||||||
|
pCar->AutoPilot.m_nCruiseSpeed /= 4;
|
||||||
|
}
|
||||||
|
pCar->AutoPilot.m_fMaxTrafficSpeed = pCar->AutoPilot.m_nCruiseSpeed;
|
||||||
|
pCar->AutoPilot.m_nCarMission = MISSION_CRUISE;
|
||||||
|
pCar->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||||
|
pCar->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case COPS:
|
||||||
|
pCar->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||||
|
if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel != 0){
|
||||||
|
pCar->AutoPilot.m_nCruiseSpeed = CCarAI::FindPoliceCarSpeedForWantedLevel(pCar);
|
||||||
|
pCar->AutoPilot.m_fMaxTrafficSpeed = pCar->AutoPilot.m_nCruiseSpeed / 2;
|
||||||
|
pCar->AutoPilot.m_nCarMission = CCarAI::FindPoliceCarMissionForWantedLevel();
|
||||||
|
pCar->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
|
||||||
|
}else{
|
||||||
|
pCar->AutoPilot.m_nCruiseSpeed = CGeneral::GetRandomNumberInRange(12, 16);
|
||||||
|
pCar->AutoPilot.m_fMaxTrafficSpeed = pCar->AutoPilot.m_nCruiseSpeed;
|
||||||
|
pCar->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
|
||||||
|
pCar->AutoPilot.m_nCarMission = MISSION_CRUISE;
|
||||||
|
}
|
||||||
|
if (carModel == MI_FBICAR){
|
||||||
|
pCar->m_currentColour1 = 0;
|
||||||
|
pCar->m_currentColour2 = 0;
|
||||||
|
/* FBI cars are gray in carcols, but we want them black if they going after player. */
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pCar && pCar->GetModelIndex() == MI_MRWHOOP)
|
||||||
|
pCar->m_bSirenOrAlarm = true;
|
||||||
|
pCar->AutoPilot.m_nNextPathNodeInfo = connectionId;
|
||||||
|
pCar->AutoPilot.m_nNextLane = pCar->AutoPilot.m_nCurrentLane = CGeneral::GetRandomNumber() % lanesOnCurrentRoad;
|
||||||
|
CColBox* boundingBox = &CModelInfo::GetModelInfo(pCar->GetModelIndex())->GetColModel()->boundingBox;
|
||||||
|
float carLength = 1.0f + (boundingBox->max.y - boundingBox->min.y) / 2;
|
||||||
|
float distanceBetweenNodes = (pCurNode->pos - pNextNode->pos).Magnitude2D();
|
||||||
|
/* If car is so long that it doesn't fit between two car nodes, place it directly in the middle. */
|
||||||
|
/* Otherwise put it at least in a way that full vehicle length fits between two nodes. */
|
||||||
|
if (distanceBetweenNodes / 2 < carLength)
|
||||||
|
positionBetweenNodes = 0.5f;
|
||||||
|
else
|
||||||
|
positionBetweenNodes = min(1.0f - carLength / distanceBetweenNodes, max(carLength / distanceBetweenNodes, positionBetweenNodes));
|
||||||
|
pCar->AutoPilot.m_nNextDirection = (curNodeId >= nextNodeId) ? 1 : -1;
|
||||||
|
if (pCurNode->numLinks == 1){
|
||||||
|
/* Do not create vehicle if there is nowhere to go. */
|
||||||
|
delete pCar;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int16 nextConnection = pCar->AutoPilot.m_nNextPathNodeInfo;
|
||||||
|
int16 newLink;
|
||||||
|
while (nextConnection == pCar->AutoPilot.m_nNextPathNodeInfo){
|
||||||
|
newLink = CGeneral::GetRandomNumber() % pCurNode->numLinks;
|
||||||
|
nextConnection = ThePaths.m_carPathConnections[newLink + pCurNode->firstLink];
|
||||||
|
}
|
||||||
|
pCar->AutoPilot.m_nCurrentPathNodeInfo = nextConnection;
|
||||||
|
pCar->AutoPilot.m_nCurrentDirection = (ThePaths.m_connections[newLink + pCurNode->firstLink] >= curNodeId) ? 1 : -1;
|
||||||
|
CVector2D vecBetweenNodes = pNextNode->pos - pCurNode->pos;
|
||||||
|
float forwardX, forwardY;
|
||||||
|
float distBetweenNodes = vecBetweenNodes.Magnitude();
|
||||||
|
if (distanceBetweenNodes == 0.0f){
|
||||||
|
forwardX = 1.0f;
|
||||||
|
forwardY = 0.0f;
|
||||||
|
}else{
|
||||||
|
forwardX = vecBetweenNodes.x / distBetweenNodes;
|
||||||
|
forwardY = vecBetweenNodes.y / distBetweenNodes;
|
||||||
|
}
|
||||||
|
/* I think the following might be some form of SetRotateZOnly. */
|
||||||
|
/* Setting up direction between two car nodes. */
|
||||||
|
pCar->GetForward() = CVector(forwardX, forwardY, 0.0f);
|
||||||
|
pCar->GetRight() = CVector(forwardY, -forwardX, 0.0f);
|
||||||
|
pCar->GetUp() = CVector(0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
float currentPathLinkForwardX = pCar->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nCurrentPathNodeInfo].dirX;
|
||||||
|
float currentPathLinkForwardY = pCar->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nCurrentPathNodeInfo].dirY;
|
||||||
|
float nextPathLinkForwardX = pCar->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nNextPathNodeInfo].dirX;
|
||||||
|
float nextPathLinkForwardY = pCar->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nNextPathNodeInfo].dirY;
|
||||||
|
|
||||||
|
CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[pCar->AutoPilot.m_nCurrentPathNodeInfo];
|
||||||
|
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[pCar->AutoPilot.m_nNextPathNodeInfo];
|
||||||
|
CVector positionOnCurrentLinkIncludingLane(
|
||||||
|
pCurrentLink->posX + GetOffsetOfLaneFromCenterOfRoad(pCar->AutoPilot.m_nCurrentLane, pCurrentLink) * currentPathLinkForwardY,
|
||||||
|
pCurrentLink->posY - GetOffsetOfLaneFromCenterOfRoad(pCar->AutoPilot.m_nCurrentLane, pCurrentLink) * currentPathLinkForwardX,
|
||||||
|
0.0f);
|
||||||
|
CVector positionOnNextLinkIncludingLane(
|
||||||
|
pNextLink->posX + GetOffsetOfLaneFromCenterOfRoad(pCar->AutoPilot.m_nNextLane, pNextLink) * nextPathLinkForwardY,
|
||||||
|
pNextLink->posY - GetOffsetOfLaneFromCenterOfRoad(pCar->AutoPilot.m_nNextLane, pNextLink) * nextPathLinkForwardX,
|
||||||
|
0.0f);
|
||||||
|
float directionCurrentLinkX = pCurrentLink->dirX * pCar->AutoPilot.m_nCurrentDirection;
|
||||||
|
float directionCurrentLinkY = pCurrentLink->dirY * pCar->AutoPilot.m_nCurrentDirection;
|
||||||
|
float directionNextLinkX = pNextLink->dirX * pCar->AutoPilot.m_nNextDirection;
|
||||||
|
float directionNextLinkY = pNextLink->dirY * pCar->AutoPilot.m_nNextDirection;
|
||||||
|
/* We want to make a path between two links that may not have the same forward directions a curve. */
|
||||||
|
pCar->AutoPilot.m_nTimeToSpendOnCurrentCurve = CCurves::CalcSpeedScaleFactor(
|
||||||
|
&positionOnCurrentLinkIncludingLane,
|
||||||
|
&positionOnNextLinkIncludingLane,
|
||||||
|
directionCurrentLinkX, directionCurrentLinkY,
|
||||||
|
directionNextLinkX, directionNextLinkY
|
||||||
|
) * (1000.0f / pCar->AutoPilot.m_fMaxTrafficSpeed);
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
/* Casting timer to float is very unwanted. In this case it's not awful */
|
||||||
|
/* but in CAutoPilot::ModifySpeed it can even cause crashes (see SilentPatch). */
|
||||||
|
pCar->AutoPilot.m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() -
|
||||||
|
(uint32)((0.5f + positionBetweenNodes) * pCar->AutoPilot.m_nTimeToSpendOnCurrentCurve);
|
||||||
|
#else
|
||||||
|
pCar->AutoPilot.m_nTotalSpeedScaleFactor = CTimer::GetTimeInMilliseconds() -
|
||||||
|
(0.5f + positionBetweenNodes) * pCar->AutoPilot.m_nSpeedScaleFactor;
|
||||||
|
#endif
|
||||||
|
CVector directionCurrentLink(directionCurrentLinkX, directionCurrentLinkY, 0.0f);
|
||||||
|
CVector directionNextLink(directionNextLinkX, directionNextLinkY, 0.0f);
|
||||||
|
CVector positionIncludingCurve;
|
||||||
|
CVector directionIncludingCurve;
|
||||||
|
CCurves::CalcCurvePoint(
|
||||||
|
&positionOnCurrentLinkIncludingLane,
|
||||||
|
&positionOnNextLinkIncludingLane,
|
||||||
|
&directionCurrentLink,
|
||||||
|
&directionNextLink,
|
||||||
|
GetPositionAlongCurrentCurve(pCar),
|
||||||
|
pCar->AutoPilot.m_nTimeToSpendOnCurrentCurve,
|
||||||
|
&positionIncludingCurve,
|
||||||
|
&directionIncludingCurve
|
||||||
|
);
|
||||||
|
CVector vectorBetweenNodes = pCurNode->pos - pNextNode->pos;
|
||||||
|
CVector finalPosition = positionIncludingCurve + vectorBetweenNodes * 2.0f / vectorBetweenNodes.Magnitude();
|
||||||
|
finalPosition.z = positionBetweenNodes * pNextNode->pos.z +
|
||||||
|
(1.0f - positionBetweenNodes) * pCurNode->pos.z;
|
||||||
|
float groundZ = INFINITE_Z;
|
||||||
|
CColPoint colPoint;
|
||||||
|
CEntity* pEntity;
|
||||||
|
if (CWorld::ProcessVerticalLine(finalPosition, 1000.0f, colPoint, pEntity, true, false, false, false, true, false, nil))
|
||||||
|
groundZ = colPoint.point.z;
|
||||||
|
if (CWorld::ProcessVerticalLine(finalPosition, -1000.0f, colPoint, pEntity, true, false, false, false, true, false, nil)){
|
||||||
|
if (ABS(colPoint.point.z - finalPosition.z) < ABS(groundZ - finalPosition.z))
|
||||||
|
groundZ = colPoint.point.z;
|
||||||
|
}
|
||||||
|
if (groundZ == INFINITE_Z || ABS(groundZ - finalPosition.z) > 7.0f) {
|
||||||
|
/* Failed to find ground or too far from expected position. */
|
||||||
|
delete pCar;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
finalPosition.z = groundZ + pCar->GetHeightAboveRoad();
|
||||||
|
pCar->GetPosition() = finalPosition;
|
||||||
|
pCar->SetMoveSpeed(directionIncludingCurve / 60.0f);
|
||||||
|
CVector2D speedDifferenceWithTarget = (CVector2D)pCar->GetMoveSpeed() - vecPlayerSpeed;
|
||||||
|
CVector2D distanceToTarget = positionIncludingCurve - vecTargetPos;
|
||||||
|
switch (carClass) {
|
||||||
|
case POOR:
|
||||||
|
case RICH:
|
||||||
|
case EXEC:
|
||||||
|
case WORKER:
|
||||||
|
case SPECIAL:
|
||||||
|
case BIG:
|
||||||
|
case TAXI:
|
||||||
|
case MAFIA:
|
||||||
|
case TRIAD:
|
||||||
|
case DIABLO:
|
||||||
|
case YAKUZA:
|
||||||
|
case YARDIE:
|
||||||
|
case COLOMB:
|
||||||
|
case NINES:
|
||||||
|
case GANG8:
|
||||||
|
case GANG9:
|
||||||
|
pCar->m_status = STATUS_SIMPLE;
|
||||||
|
break;
|
||||||
|
case COPS:
|
||||||
|
pCar->m_status = (pCar->AutoPilot.m_nCarMission == MISSION_CRUISE) ? STATUS_SIMPLE : STATUS_PHYSICS;
|
||||||
|
pCar->ChangeLawEnforcerState(1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
CVisibilityPlugins::SetClumpAlpha(pCar->GetClump(), 0);
|
||||||
|
if (!pCar->GetIsOnScreen()){
|
||||||
|
if ((vecTargetPos - pCar->GetPosition()).Magnitude2D() > 50.0f) {
|
||||||
|
/* Too far away cars that are not visible aren't needed. */
|
||||||
|
delete pCar;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}else if((vecTargetPos - pCar->GetPosition()).Magnitude2D() > TheCamera.GenerationDistMultiplier * 130.0f ||
|
||||||
|
(vecTargetPos - pCar->GetPosition()).Magnitude2D() < TheCamera.GenerationDistMultiplier * 110.0f){
|
||||||
|
delete pCar;
|
||||||
|
return;
|
||||||
|
}else if((TheCamera.GetPosition() - pCar->GetPosition()).Magnitude2D() < 90.0f * TheCamera.GenerationDistMultiplier){
|
||||||
|
delete pCar;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CVehicleModelInfo* pVehicleModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(pCar->GetModelIndex());
|
||||||
|
float radiusToTest = pVehicleModel->GetColModel()->boundingSphere.radius;
|
||||||
|
if (testForCollision){
|
||||||
|
CWorld::FindObjectsKindaColliding(pCar->GetPosition(), radiusToTest + 20.0f, true, &colliding, 2, nil, false, true, false, false, false);
|
||||||
|
if (colliding){
|
||||||
|
delete pCar;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CWorld::FindObjectsKindaColliding(pCar->GetPosition(), radiusToTest, true, &colliding, 2, nil, false, true, false, false, false);
|
||||||
|
if (colliding){
|
||||||
|
delete pCar;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (speedDifferenceWithTarget.x * distanceToTarget.x +
|
||||||
|
speedDifferenceWithTarget.y * distanceToTarget.y >= 0.0f){
|
||||||
|
delete pCar;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pVehicleModel->AvoidSameVehicleColour(&pCar->m_currentColour1, &pCar->m_currentColour2);
|
||||||
|
CWorld::Add(pCar);
|
||||||
|
if (carClass == COPS)
|
||||||
|
CCarAI::AddPoliceOccupants(pCar);
|
||||||
|
else
|
||||||
|
pCar->SetUpDriver();
|
||||||
|
if ((CGeneral::GetRandomNumber() & 0x3F) == 0){ /* 1/64 probability */
|
||||||
|
pCar->m_status = STATUS_PHYSICS;
|
||||||
|
pCar->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
|
||||||
|
pCar->AutoPilot.m_nCruiseSpeed += 10;
|
||||||
|
}
|
||||||
|
if (carClass == COPS)
|
||||||
|
LastTimeLawEnforcerCreated = CTimer::GetTimeInMilliseconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
CCarCtrl::ChooseModel(CZoneInfo* pZone, CVector* pPos, int* pClass) {
|
||||||
|
int32 model = -1;;
|
||||||
|
while (model == -1 || !CStreaming::HasModelLoaded(model)){
|
||||||
|
int rnd = CGeneral::GetRandomNumberInRange(0, 1000);
|
||||||
|
if (rnd < pZone->carThreshold[0])
|
||||||
|
model = CCarCtrl::ChooseCarModel((*pClass = POOR));
|
||||||
|
else if (rnd < pZone->carThreshold[1])
|
||||||
|
model = CCarCtrl::ChooseCarModel((*pClass = RICH));
|
||||||
|
else if (rnd < pZone->carThreshold[2])
|
||||||
|
model = CCarCtrl::ChooseCarModel((*pClass = EXEC));
|
||||||
|
else if (rnd < pZone->carThreshold[3])
|
||||||
|
model = CCarCtrl::ChooseCarModel((*pClass = WORKER));
|
||||||
|
else if (rnd < pZone->carThreshold[4])
|
||||||
|
model = CCarCtrl::ChooseCarModel((*pClass = SPECIAL));
|
||||||
|
else if (rnd < pZone->carThreshold[5])
|
||||||
|
model = CCarCtrl::ChooseCarModel((*pClass = BIG));
|
||||||
|
else if (rnd < pZone->copThreshold)
|
||||||
|
*pClass = COPS, model = CCarCtrl::ChoosePoliceCarModel();
|
||||||
|
else if (rnd < pZone->gangThreshold[0])
|
||||||
|
model = CCarCtrl::ChooseGangCarModel((*pClass = MAFIA) - MAFIA);
|
||||||
|
else if (rnd < pZone->gangThreshold[1])
|
||||||
|
model = CCarCtrl::ChooseGangCarModel((*pClass = TRIAD) - MAFIA);
|
||||||
|
else if (rnd < pZone->gangThreshold[2])
|
||||||
|
model = CCarCtrl::ChooseGangCarModel((*pClass = DIABLO) - MAFIA);
|
||||||
|
else if (rnd < pZone->gangThreshold[3])
|
||||||
|
model = CCarCtrl::ChooseGangCarModel((*pClass = YAKUZA) - MAFIA);
|
||||||
|
else if (rnd < pZone->gangThreshold[4])
|
||||||
|
model = CCarCtrl::ChooseGangCarModel((*pClass = YARDIE) - MAFIA);
|
||||||
|
else if (rnd < pZone->gangThreshold[5])
|
||||||
|
model = CCarCtrl::ChooseGangCarModel((*pClass = COLOMB) - MAFIA);
|
||||||
|
else if (rnd < pZone->gangThreshold[6])
|
||||||
|
model = CCarCtrl::ChooseGangCarModel((*pClass = NINES) - MAFIA);
|
||||||
|
else if (rnd < pZone->gangThreshold[7])
|
||||||
|
model = CCarCtrl::ChooseGangCarModel((*pClass = GANG8) - MAFIA);
|
||||||
|
else if (rnd < pZone->gangThreshold[8])
|
||||||
|
model = CCarCtrl::ChooseGangCarModel((*pClass = GANG9) - MAFIA);
|
||||||
|
else
|
||||||
|
model = CCarCtrl::ChooseCarModel((*pClass = TAXI));
|
||||||
|
}
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
CCarCtrl::ChooseCarModel(int32 vehclass)
|
||||||
|
{
|
||||||
|
int32 model = -1;
|
||||||
|
switch (vehclass) {
|
||||||
|
case POOR:
|
||||||
|
case RICH:
|
||||||
|
case EXEC:
|
||||||
|
case WORKER:
|
||||||
|
case SPECIAL:
|
||||||
|
case BIG:
|
||||||
|
case TAXI:
|
||||||
|
{
|
||||||
|
if (TotalNumOfCarsOfRating[vehclass] == 0)
|
||||||
|
debug("ChooseCarModel : No cars of type %d have been declared\n");
|
||||||
|
model = CarArrays[vehclass][NextCarOfRating[vehclass]];
|
||||||
|
int32 total = TotalNumOfCarsOfRating[vehclass];
|
||||||
|
NextCarOfRating[vehclass] += 1 + CGeneral::GetRandomNumberInRange(0, total - 1);
|
||||||
|
while (NextCarOfRating[vehclass] >= total)
|
||||||
|
NextCarOfRating[vehclass] -= total;
|
||||||
|
//NextCarOfRating[vehclass] %= total;
|
||||||
|
TotalNumOfCarsOfRating[vehclass] = total; /* why... */
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
CCarCtrl::ChoosePoliceCarModel(void)
|
||||||
|
{
|
||||||
|
if (FindPlayerPed()->m_pWanted->AreSwatRequired() &&
|
||||||
|
CStreaming::HasModelLoaded(MI_ENFORCER) &&
|
||||||
|
CStreaming::HasModelLoaded(MI_POLICE))
|
||||||
|
return ((CGeneral::GetRandomNumber() & 0xF) == 0) ? MI_ENFORCER : MI_POLICE;
|
||||||
|
if (FindPlayerPed()->m_pWanted->AreFbiRequired() &&
|
||||||
|
CStreaming::HasModelLoaded(MI_FBICAR) &&
|
||||||
|
CStreaming::HasModelLoaded(MI_FBI))
|
||||||
|
return MI_FBICAR;
|
||||||
|
if (FindPlayerPed()->m_pWanted->AreArmyRequired() &&
|
||||||
|
CStreaming::HasModelLoaded(MI_RHINO) &&
|
||||||
|
CStreaming::HasModelLoaded(MI_BARRACKS) &&
|
||||||
|
CStreaming::HasModelLoaded(MI_RHINO))
|
||||||
|
return CGeneral::GetRandomTrueFalse() ? MI_BARRACKS : MI_RHINO;
|
||||||
|
return MI_POLICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
CCarCtrl::ChooseGangCarModel(int32 gang)
|
||||||
|
{
|
||||||
|
if (CStreaming::HasModelLoaded(MI_GANG01 + 2 * gang) &&
|
||||||
|
CStreaming::HasModelLoaded(MI_GANG02 + 2 * gang))
|
||||||
|
return CGangs::GetGangVehicleModel(gang);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CCarCtrl::AddToCarArray(int32 id, int32 vehclass)
|
||||||
|
{
|
||||||
|
CarArrays[vehclass][TotalNumOfCarsOfRating[vehclass]++] = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CCarCtrl::RemoveDistantCars()
|
||||||
|
{
|
||||||
|
uint32 i = CPools::GetVehiclePool()->GetSize();
|
||||||
|
while (--i){
|
||||||
|
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
|
||||||
|
if (!pVehicle)
|
||||||
|
continue;
|
||||||
|
PossiblyRemoveVehicle(pVehicle);
|
||||||
|
if (pVehicle->bCreateRoadBlockPeds){
|
||||||
|
if ((pVehicle->GetPosition() - FindPlayerCentreOfWorld(CWorld::PlayerInFocus)).Magnitude2D() < DISTANCE_TO_SPAWN_ROADBLOCK_PEDS) {
|
||||||
|
CRoadBlocks::GenerateRoadBlockCopsForCar(pVehicle, pVehicle->m_nRoadblockType, pVehicle->m_nRoadblockNode);
|
||||||
|
pVehicle->bCreateRoadBlockPeds = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
CVector vecPlayerPos = FindPlayerCentreOfWorld(CWorld::PlayerInFocus);
|
||||||
|
/* BUG: this variable is initialized only in if-block below but can be used outside of it. */
|
||||||
|
if (!IsThisVehicleInteresting(pVehicle) && !pVehicle->bIsLocked &&
|
||||||
|
pVehicle->CanBeDeleted() && !CCranes::IsThisCarBeingTargettedByAnyCrane(pVehicle)){
|
||||||
|
if (pVehicle->bFadeOut && CVisibilityPlugins::GetClumpAlpha(pVehicle->GetClump()) == 0){
|
||||||
|
CWorld::Remove(pVehicle);
|
||||||
|
delete pVehicle;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
float distanceToPlayer = (pVehicle->GetPosition() - vecPlayerPos).Magnitude2D();
|
||||||
|
float threshold = 50.0f;
|
||||||
|
if (pVehicle->GetIsOnScreen() ||
|
||||||
|
TheCamera.Cams[TheCamera.ActiveCam].LookingLeft ||
|
||||||
|
TheCamera.Cams[TheCamera.ActiveCam].LookingRight ||
|
||||||
|
TheCamera.Cams[TheCamera.ActiveCam].LookingBehind ||
|
||||||
|
TheCamera.GetLookDirection() == 0 ||
|
||||||
|
pVehicle->VehicleCreatedBy == PARKED_VEHICLE ||
|
||||||
|
pVehicle->GetModelIndex() == MI_AMBULAN ||
|
||||||
|
pVehicle->GetModelIndex() == MI_FIRETRUCK ||
|
||||||
|
pVehicle->bIsLawEnforcer ||
|
||||||
|
pVehicle->bIsCarParkVehicle
|
||||||
|
){
|
||||||
|
threshold = 130.0f * TheCamera.GenerationDistMultiplier;
|
||||||
|
}
|
||||||
|
if (pVehicle->bExtendedRange)
|
||||||
|
threshold *= 1.5f;
|
||||||
|
if (distanceToPlayer > threshold && !CGarages::IsPointWithinHideOutGarage(&pVehicle->GetPosition())){
|
||||||
|
if (pVehicle->GetIsOnScreen() && CRenderer::IsEntityCullZoneVisible(pVehicle)){
|
||||||
|
pVehicle->bFadeOut = true;
|
||||||
|
}else{
|
||||||
|
CWorld::Remove(pVehicle);
|
||||||
|
delete pVehicle;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((pVehicle->m_status == STATUS_SIMPLE || pVehicle->m_status == STATUS_PHYSICS && pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_STOP_FOR_CARS) &&
|
||||||
|
CTimer::GetTimeInMilliseconds() - pVehicle->AutoPilot.m_nTimeToStartMission > 5000 &&
|
||||||
|
!pVehicle->GetIsOnScreen() &&
|
||||||
|
(pVehicle->GetPosition() - vecPlayerPos).Magnitude2D() > 25.0f &&
|
||||||
|
!IsThisVehicleInteresting(pVehicle) &&
|
||||||
|
!pVehicle->bIsLocked &&
|
||||||
|
!CTrafficLights::ShouldCarStopForLight(pVehicle, true) &&
|
||||||
|
!CTrafficLights::ShouldCarStopForBridge(pVehicle) &&
|
||||||
|
!CGarages::IsPointWithinHideOutGarage(&pVehicle->GetPosition())){
|
||||||
|
CWorld::Remove(pVehicle);
|
||||||
|
delete pVehicle;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pVehicle->m_status != STATUS_WRECKED || pVehicle->m_nTimeOfDeath == 0)
|
||||||
|
return;
|
||||||
|
if (CTimer::GetTimeInMilliseconds() > pVehicle->m_nTimeOfDeath + 60000 &&
|
||||||
|
(!pVehicle->GetIsOnScreen() || !CRenderer::IsEntityCullZoneVisible(pVehicle))){
|
||||||
|
if ((pVehicle->GetPosition() - vecPlayerPos).MagnitudeSqr() > SQR(7.5f)){
|
||||||
|
if (!CGarages::IsPointWithinHideOutGarage(&pVehicle->GetPosition())){
|
||||||
|
CWorld::Remove(pVehicle);
|
||||||
|
delete pVehicle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
CCarCtrl::CountCarsOfType(int32 mi)
|
||||||
|
{
|
||||||
|
int32 total = 0;
|
||||||
|
uint32 i = CPools::GetVehiclePool()->GetSize();
|
||||||
|
while (i--){
|
||||||
|
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
|
||||||
|
if (!pVehicle)
|
||||||
|
continue;
|
||||||
|
if (pVehicle->GetModelIndex() == mi)
|
||||||
|
total++;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CCarCtrl::IsThisVehicleInteresting(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_CARS_TO_KEEP; i++) {
|
||||||
|
if (apCarsToKeep[i] == pVehicle)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CCarCtrl::UpdateCarOnRails(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
if (pVehicle->AutoPilot.m_nTempAction == TEMPACT_WAIT){
|
||||||
|
pVehicle->SetMoveSpeed(0.0f, 0.0f, 0.0f);
|
||||||
|
pVehicle->AutoPilot.ModifySpeed(0.0f);
|
||||||
|
if (CTimer::GetTimeInMilliseconds() > pVehicle->AutoPilot.m_nTempAction){
|
||||||
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||||
|
pVehicle->AutoPilot.m_nAntiReverseTimer = 0;
|
||||||
|
pVehicle->AutoPilot.m_nTimeToStartMission = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SlowCarOnRailsDownForTrafficAndLights(pVehicle);
|
||||||
|
if (pVehicle->AutoPilot.m_nTimeEnteredCurve + pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve <= CTimer::GetTimeInMilliseconds())
|
||||||
|
PickNextNodeAccordingStrategy(pVehicle);
|
||||||
|
if (pVehicle->m_status == STATUS_PHYSICS)
|
||||||
|
return;
|
||||||
|
CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo];
|
||||||
|
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
|
||||||
|
float currentPathLinkForwardX = pCurrentLink->dirX * pVehicle->AutoPilot.m_nCurrentDirection;
|
||||||
|
float currentPathLinkForwardY = pCurrentLink->dirY * pVehicle->AutoPilot.m_nCurrentDirection;
|
||||||
|
float nextPathLinkForwardX = pNextLink->dirX * pVehicle->AutoPilot.m_nNextDirection;
|
||||||
|
float nextPathLinkForwardY = pNextLink->dirY * pVehicle->AutoPilot.m_nNextDirection;
|
||||||
|
CVector positionOnCurrentLinkIncludingLane(
|
||||||
|
pCurrentLink->posX + GetOffsetOfLaneFromCenterOfRoad(pVehicle->AutoPilot.m_nCurrentLane, pCurrentLink) * currentPathLinkForwardY,
|
||||||
|
pCurrentLink->posY - GetOffsetOfLaneFromCenterOfRoad(pVehicle->AutoPilot.m_nCurrentLane, pCurrentLink) * currentPathLinkForwardX,
|
||||||
|
0.0f);
|
||||||
|
CVector positionOnNextLinkIncludingLane(
|
||||||
|
pNextLink->posX + GetOffsetOfLaneFromCenterOfRoad(pVehicle->AutoPilot.m_nNextLane, pNextLink) * nextPathLinkForwardY,
|
||||||
|
pNextLink->posY - GetOffsetOfLaneFromCenterOfRoad(pVehicle->AutoPilot.m_nNextLane, pNextLink) * nextPathLinkForwardX,
|
||||||
|
0.0f);
|
||||||
|
CVector directionCurrentLink(currentPathLinkForwardX, currentPathLinkForwardY, 0.0f);
|
||||||
|
CVector directionNextLink(nextPathLinkForwardX, nextPathLinkForwardY, 0.0f);
|
||||||
|
CVector positionIncludingCurve;
|
||||||
|
CVector directionIncludingCurve;
|
||||||
|
CCurves::CalcCurvePoint(
|
||||||
|
&positionOnCurrentLinkIncludingLane,
|
||||||
|
&positionOnNextLinkIncludingLane,
|
||||||
|
&directionCurrentLink,
|
||||||
|
&directionNextLink,
|
||||||
|
GetPositionAlongCurrentCurve(pVehicle),
|
||||||
|
pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve,
|
||||||
|
&positionIncludingCurve,
|
||||||
|
&directionIncludingCurve
|
||||||
|
);
|
||||||
|
positionIncludingCurve.z = 15.0f;
|
||||||
|
DragCarToPoint(pVehicle, &positionIncludingCurve);
|
||||||
|
pVehicle->SetMoveSpeed(directionIncludingCurve / 60.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
CCarCtrl::FindMaximumSpeedForThisCarInTraffic(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
if (pVehicle->AutoPilot.m_nDrivingStyle == MISSION_RAMPLAYER_FARAWAY ||
|
||||||
|
pVehicle->AutoPilot.m_nDrivingStyle == MISSION_RAMPLAYER_CLOSE)
|
||||||
|
return pVehicle->AutoPilot.m_nCruiseSpeed;
|
||||||
|
float left = pVehicle->GetPosition().x - DISTANCE_TO_SCAN_FOR_DANGER;
|
||||||
|
float right = pVehicle->GetPosition().x + DISTANCE_TO_SCAN_FOR_DANGER;
|
||||||
|
float top = pVehicle->GetPosition().y - DISTANCE_TO_SCAN_FOR_DANGER;
|
||||||
|
float bottom = pVehicle->GetPosition().y + DISTANCE_TO_SCAN_FOR_DANGER;
|
||||||
|
int xstart = max(0, CWorld::GetSectorIndexX(left));
|
||||||
|
int xend = min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right));
|
||||||
|
int ystart = max(0, CWorld::GetSectorIndexY(top));
|
||||||
|
int yend = min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom));
|
||||||
|
assert(xstart <= xend);
|
||||||
|
assert(ystart <= yend);
|
||||||
|
|
||||||
|
float maxSpeed = pVehicle->AutoPilot.m_nCruiseSpeed;
|
||||||
|
|
||||||
|
CWorld::AdvanceCurrentScanCode();
|
||||||
|
|
||||||
|
for (int y = ystart; y <= yend; y++){
|
||||||
|
for (int x = xstart; x <= xend; x++){
|
||||||
|
CSector* s = CWorld::GetSector(x, y);
|
||||||
|
SlowCarDownForCarsSectorList(s->m_lists[ENTITYLIST_VEHICLES], pVehicle, left, top, right, bottom, &maxSpeed, pVehicle->AutoPilot.m_nCruiseSpeed);
|
||||||
|
SlowCarDownForCarsSectorList(s->m_lists[ENTITYLIST_VEHICLES_OVERLAP], pVehicle, left, top, right, bottom, &maxSpeed, pVehicle->AutoPilot.m_nCruiseSpeed);
|
||||||
|
SlowCarDownForPedsSectorList(s->m_lists[ENTITYLIST_PEDS], pVehicle, left, top, right, bottom, &maxSpeed, pVehicle->AutoPilot.m_nCruiseSpeed);
|
||||||
|
SlowCarDownForPedsSectorList(s->m_lists[ENTITYLIST_PEDS_OVERLAP], pVehicle, left, top, right, bottom, &maxSpeed, pVehicle->AutoPilot.m_nCruiseSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pVehicle->bWarnedPeds = true;
|
||||||
|
if (pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_STOP_FOR_CARS)
|
||||||
|
return maxSpeed;
|
||||||
|
return (maxSpeed + pVehicle->AutoPilot.m_nDrivingStyle) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CCarCtrl::ScanForPedDanger(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
bool storedSlowDownFlag = pVehicle->AutoPilot.m_bSlowedDownBecauseOfPeds;
|
||||||
|
float left = pVehicle->GetPosition().x - DISTANCE_TO_SCAN_FOR_DANGER;
|
||||||
|
float right = pVehicle->GetPosition().x + DISTANCE_TO_SCAN_FOR_DANGER;
|
||||||
|
float top = pVehicle->GetPosition().y - DISTANCE_TO_SCAN_FOR_DANGER;
|
||||||
|
float bottom = pVehicle->GetPosition().y + DISTANCE_TO_SCAN_FOR_DANGER;
|
||||||
|
int xstart = max(0, CWorld::GetSectorIndexX(left));
|
||||||
|
int xend = min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right));
|
||||||
|
int ystart = max(0, CWorld::GetSectorIndexY(top));
|
||||||
|
int yend = min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(bottom));
|
||||||
|
assert(xstart <= xend);
|
||||||
|
assert(ystart <= yend);
|
||||||
|
|
||||||
|
float maxSpeed = pVehicle->AutoPilot.m_nCruiseSpeed;
|
||||||
|
|
||||||
|
CWorld::AdvanceCurrentScanCode();
|
||||||
|
|
||||||
|
for (int y = ystart; y <= yend; y++) {
|
||||||
|
for (int x = xstart; x <= xend; x++) {
|
||||||
|
CSector* s = CWorld::GetSector(x, y);
|
||||||
|
SlowCarDownForPedsSectorList(s->m_lists[ENTITYLIST_PEDS], pVehicle, left, top, right, bottom, &maxSpeed, pVehicle->AutoPilot.m_nCruiseSpeed);
|
||||||
|
SlowCarDownForPedsSectorList(s->m_lists[ENTITYLIST_PEDS_OVERLAP], pVehicle, left, top, right, bottom, &maxSpeed, pVehicle->AutoPilot.m_nCruiseSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pVehicle->bWarnedPeds = true;
|
||||||
|
pVehicle->AutoPilot.m_bSlowedDownBecauseOfPeds = storedSlowDownFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CCarCtrl::SlowCarOnRailsDownForTrafficAndLights(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
float maxSpeed;
|
||||||
|
if (CTrafficLights::ShouldCarStopForLight(pVehicle, false) || CTrafficLights::ShouldCarStopForBridge(pVehicle)){
|
||||||
|
CCarAI::CarHasReasonToStop(pVehicle);
|
||||||
|
maxSpeed = 0.0f;
|
||||||
|
}else{
|
||||||
|
maxSpeed = FindMaximumSpeedForThisCarInTraffic(pVehicle);
|
||||||
|
}
|
||||||
|
float curSpeed = pVehicle->AutoPilot.m_fMaxTrafficSpeed;
|
||||||
|
if (maxSpeed >= curSpeed){
|
||||||
|
if (maxSpeed > curSpeed)
|
||||||
|
pVehicle->AutoPilot.ModifySpeed(min(maxSpeed, curSpeed + 0.05f * CTimer::GetTimeStep()));
|
||||||
|
}else{
|
||||||
|
if (curSpeed == 0.0f)
|
||||||
|
return;
|
||||||
|
if (curSpeed >= 0.1f)
|
||||||
|
pVehicle->AutoPilot.ModifySpeed(max(maxSpeed, curSpeed - 0.5f * CTimer::GetTimeStep()));
|
||||||
|
else if (curSpeed != 0.0f) /* no need to check */
|
||||||
|
pVehicle->AutoPilot.ModifySpeed(0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CCarCtrl::MapCouldMoveInThisArea(float x, float y)
|
CCarCtrl::MapCouldMoveInThisArea(float x, float y)
|
||||||
@ -29,3 +877,11 @@ CCarCtrl::MapCouldMoveInThisArea(float x, float y)
|
|||||||
return x > -342.0f && x < -219.0f &&
|
return x > -342.0f && x < -219.0f &&
|
||||||
y > -677.0f && y < -580.0f;
|
y > -677.0f && y < -580.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STARTPATCHES
|
||||||
|
InjectHook(0x416580, &CCarCtrl::GenerateRandomCars, PATCH_JUMP);
|
||||||
|
InjectHook(0x417EC0, &CCarCtrl::ChooseModel, PATCH_JUMP);
|
||||||
|
InjectHook(0x418320, &CCarCtrl::RemoveDistantCars, PATCH_JUMP);
|
||||||
|
InjectHook(0x418430, &CCarCtrl::PossiblyRemoveVehicle, PATCH_JUMP);
|
||||||
|
InjectHook(0x418C10, &CCarCtrl::FindMaximumSpeedForThisCarInTraffic, PATCH_JUMP);
|
||||||
|
ENDPATCHES
|
||||||
|
@ -1,9 +1,38 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "PathFind.h"
|
||||||
|
#include "Vehicle.h"
|
||||||
|
|
||||||
class CVehicle;
|
class CZoneInfo;
|
||||||
|
|
||||||
|
enum{
|
||||||
|
MAX_CARS_TO_KEEP = 2,
|
||||||
|
MAX_CAR_MODELS_IN_ARRAY = 256,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LANE_WIDTH 5.0f
|
||||||
|
|
||||||
class CCarCtrl
|
class CCarCtrl
|
||||||
{
|
{
|
||||||
|
enum eCarClass {
|
||||||
|
POOR = 0,
|
||||||
|
RICH,
|
||||||
|
EXEC,
|
||||||
|
WORKER,
|
||||||
|
SPECIAL,
|
||||||
|
BIG,
|
||||||
|
TAXI,
|
||||||
|
CLASS7,
|
||||||
|
MAFIA,
|
||||||
|
TRIAD,
|
||||||
|
DIABLO,
|
||||||
|
YAKUZA,
|
||||||
|
YARDIE,
|
||||||
|
COLOMB,
|
||||||
|
NINES,
|
||||||
|
GANG8,
|
||||||
|
GANG9,
|
||||||
|
COPS
|
||||||
|
};
|
||||||
public:
|
public:
|
||||||
static void SwitchVehicleToRealPhysics(CVehicle*);
|
static void SwitchVehicleToRealPhysics(CVehicle*);
|
||||||
static void AddToCarArray(int32 id, int32 vehclass);
|
static void AddToCarArray(int32 id, int32 vehclass);
|
||||||
@ -16,6 +45,35 @@ public:
|
|||||||
static bool MapCouldMoveInThisArea(float x, float y);
|
static bool MapCouldMoveInThisArea(float x, float y);
|
||||||
static void ScanForPedDanger(CVehicle *veh);
|
static void ScanForPedDanger(CVehicle *veh);
|
||||||
static void RemoveFromInterestingVehicleList(CVehicle*);
|
static void RemoveFromInterestingVehicleList(CVehicle*);
|
||||||
|
static void GenerateRandomCars(void);
|
||||||
|
static void GenerateOneRandomCar(void);
|
||||||
|
static void GenerateEmergencyServicesCar(void);
|
||||||
|
static int32 ChooseModel(CZoneInfo*, CVector*, int*);
|
||||||
|
static int32 ChoosePoliceCarModel(void);
|
||||||
|
static int32 ChooseGangCarModel(int32 gang);
|
||||||
|
static void RemoveDistantCars(void);
|
||||||
|
static void PossiblyRemoveVehicle(CVehicle*);
|
||||||
|
static bool IsThisVehicleInteresting(CVehicle*);
|
||||||
|
static int32 CountCarsOfType(int32 mi);
|
||||||
|
static void SlowCarOnRailsDownForTrafficAndLights(CVehicle*);
|
||||||
|
static void PickNextNodeAccordingStrategy(CVehicle*);
|
||||||
|
static void DragCarToPoint(CVehicle*, CVector*);
|
||||||
|
static float FindMaximumSpeedForThisCarInTraffic(CVehicle*);
|
||||||
|
static void SlowCarDownForCarsSectorList(CPtrList&, CVehicle*, float, float, float, float, float*, float);
|
||||||
|
static void SlowCarDownForPedsSectorList(CPtrList&, CVehicle*, float, float, float, float, float*, float);
|
||||||
|
|
||||||
|
|
||||||
|
static float GetOffsetOfLaneFromCenterOfRoad(int8 lane, CCarPathLink* pLink)
|
||||||
|
{
|
||||||
|
return (lane + ((pLink->numLeftLanes == 0) ? (0.5f - 0.5f * pLink->numRightLanes) :
|
||||||
|
((pLink->numRightLanes == 0) ? (0.5f - 0.5f * pLink->numLeftLanes) : 0.5f))) * LANE_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float GetPositionAlongCurrentCurve(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
uint32 timeInCurve = CTimer::GetTimeInMilliseconds() - pVehicle->AutoPilot.m_nTimeEnteredCurve;
|
||||||
|
return (float)timeInCurve / pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve;
|
||||||
|
}
|
||||||
|
|
||||||
static int32 &NumLawEnforcerCars;
|
static int32 &NumLawEnforcerCars;
|
||||||
static int32 &NumAmbulancesOnDuty;
|
static int32 &NumAmbulancesOnDuty;
|
||||||
@ -25,4 +83,12 @@ public:
|
|||||||
static int32 &NumParkedCars;
|
static int32 &NumParkedCars;
|
||||||
static bool &bCarsGeneratedAroundCamera;
|
static bool &bCarsGeneratedAroundCamera;
|
||||||
static float &CarDensityMultiplier;
|
static float &CarDensityMultiplier;
|
||||||
|
static int8 &CountDownToCarsAtStart;
|
||||||
|
static int32 &MaxNumberOfCarsInUse;
|
||||||
|
static uint32 &LastTimeLawEnforcerCreated;
|
||||||
|
static int32 (&TotalNumOfCarsOfRating)[7];
|
||||||
|
static int32 (&NextCarOfRating)[7];
|
||||||
|
static int32 (&CarArrays)[7][MAX_CAR_MODELS_IN_ARRAY];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern CVehicle* (&apCarsToKeep)[MAX_CARS_TO_KEEP];
|
5
src/control/Cranes.cpp
Normal file
5
src/control/Cranes.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "Cranes.h"
|
||||||
|
|
||||||
|
WRAPPER bool CCranes::IsThisCarBeingTargettedByAnyCrane(CVehicle*) { EAXJMP(0x5451E0); }
|
10
src/control/Cranes.h
Normal file
10
src/control/Cranes.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
class CVehicle;
|
||||||
|
|
||||||
|
class CCranes
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool IsThisCarBeingTargettedByAnyCrane(CVehicle*);
|
||||||
|
};
|
6
src/control/Curves.cpp
Normal file
6
src/control/Curves.cpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "Curves.h"
|
||||||
|
|
||||||
|
WRAPPER float CCurves::CalcSpeedScaleFactor(CVector*, CVector*, float, float, float, float) { EAXJMP(0x420410); }
|
||||||
|
WRAPPER void CCurves::CalcCurvePoint(CVector*, CVector*, CVector*, CVector*, float, int32, CVector*, CVector*) { EAXJMP(0x4204D0); }
|
9
src/control/Curves.h
Normal file
9
src/control/Curves.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
class CVector;
|
||||||
|
|
||||||
|
class CCurves
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static float CalcSpeedScaleFactor(CVector*, CVector*, float, float, float, float);
|
||||||
|
static void CalcCurvePoint(CVector*, CVector*, CVector*, CVector*, float, int32, CVector*, CVector*);
|
||||||
|
};
|
@ -25,7 +25,7 @@ void CGangs::Initialize(void)
|
|||||||
Gang[GANG_8].m_nVehicleMI = -1;
|
Gang[GANG_8].m_nVehicleMI = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGangs::SetGangVehicleModel(int16 gang, int model)
|
void CGangs::SetGangVehicleModel(int16 gang, int32 model)
|
||||||
{
|
{
|
||||||
GetGangInfo(gang)->m_nVehicleMI = model;
|
GetGangInfo(gang)->m_nVehicleMI = model;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,8 @@ class CGangs
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void Initialize(void);
|
static void Initialize(void);
|
||||||
static void SetGangVehicleModel(int16, int);
|
static void SetGangVehicleModel(int16, int32);
|
||||||
|
static int32 GetGangVehicleModel(int16 gang) { return Gang[gang].m_nVehicleMI; }
|
||||||
static void SetGangWeapons(int16, eWeaponType, eWeaponType);
|
static void SetGangWeapons(int16, eWeaponType, eWeaponType);
|
||||||
static void SetGangPedModelOverride(int16, int8);
|
static void SetGangPedModelOverride(int16, int8);
|
||||||
static int8 GetGangPedModelOverride(int16);
|
static int8 GetGangPedModelOverride(int16);
|
||||||
|
@ -69,6 +69,7 @@ bool CGarages::HasCarBeenCrushed(int32 handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
WRAPPER void CGarages::TriggerMessage(char *text, int16, uint16 time, int16) { EAXJMP(0x426B20); }
|
WRAPPER void CGarages::TriggerMessage(char *text, int16, uint16 time, int16) { EAXJMP(0x426B20); }
|
||||||
|
WRAPPER bool CGarages::IsPointWithinHideOutGarage(CVector*) { EAXJMP(0x428260); }
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
WRAPPER void CGarages::PrintMessages(void) { EAXJMP(0x426310); }
|
WRAPPER void CGarages::PrintMessages(void) { EAXJMP(0x426310); }
|
||||||
|
@ -25,4 +25,5 @@ public:
|
|||||||
static void TriggerMessage(char *text, int16, uint16 time, int16);
|
static void TriggerMessage(char *text, int16, uint16 time, int16);
|
||||||
static void PrintMessages(void);
|
static void PrintMessages(void);
|
||||||
static bool HasCarBeenCrushed(int32);
|
static bool HasCarBeenCrushed(int32);
|
||||||
|
static bool IsPointWithinHideOutGarage(CVector*);
|
||||||
};
|
};
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,24 +2,37 @@
|
|||||||
|
|
||||||
#include "Treadable.h"
|
#include "Treadable.h"
|
||||||
|
|
||||||
|
class CVehicle;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PATH_CAR = 0,
|
||||||
|
PATH_PED = 1,
|
||||||
|
};
|
||||||
|
|
||||||
struct CPathNode
|
struct CPathNode
|
||||||
{
|
{
|
||||||
CVector pos;
|
CVector pos;
|
||||||
CPathNode *prev; //?
|
CPathNode *prev;
|
||||||
CPathNode *next;
|
CPathNode *next;
|
||||||
int16 unknown;
|
int16 distance; // in path search
|
||||||
int16 objectIndex;
|
int16 objectIndex;
|
||||||
int16 firstLink;
|
int16 firstLink;
|
||||||
uint8 numLinks;
|
uint8 numLinks;
|
||||||
uint8 flags;
|
|
||||||
|
uint8 unkBits : 2;
|
||||||
|
uint8 bDeadEnd : 1;
|
||||||
|
uint8 bDisabled : 1;
|
||||||
|
uint8 bBetweenLevels : 1;
|
||||||
|
|
||||||
uint8 group;
|
uint8 group;
|
||||||
/* VC:
|
/* For reference VC:
|
||||||
int16 unk1;
|
int16 prevIndex;
|
||||||
int16 nextIndex;
|
int16 nextIndex;
|
||||||
int16 x;
|
int16 x;
|
||||||
int16 y;
|
int16 y;
|
||||||
int16 z;
|
int16 z;
|
||||||
int16 unknown;
|
int16 distance;
|
||||||
int16 firstLink;
|
int16 firstLink;
|
||||||
int8 width;
|
int8 width;
|
||||||
int8 group;
|
int8 group;
|
||||||
@ -40,6 +53,15 @@ struct CPathNode
|
|||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union CConnectionFlags
|
||||||
|
{
|
||||||
|
uint8 flags;
|
||||||
|
struct {
|
||||||
|
uint8 bCrossesRoad : 1;
|
||||||
|
uint8 bTrafficLight : 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
struct CCarPathLink
|
struct CCarPathLink
|
||||||
{
|
{
|
||||||
float posX;
|
float posX;
|
||||||
@ -50,10 +72,9 @@ struct CCarPathLink
|
|||||||
int8 numLeftLanes;
|
int8 numLeftLanes;
|
||||||
int8 numRightLanes;
|
int8 numRightLanes;
|
||||||
int8 trafficLightType;
|
int8 trafficLightType;
|
||||||
int8 field15;
|
|
||||||
// probably only padding
|
uint8 bBridgeLights : 1;
|
||||||
int8 field16;
|
// more?
|
||||||
int8 field17;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CPathInfoForObject
|
struct CPathInfoForObject
|
||||||
@ -80,8 +101,6 @@ struct CTempNode
|
|||||||
int8 numLeftLanes;
|
int8 numLeftLanes;
|
||||||
int8 numRightLanes;
|
int8 numRightLanes;
|
||||||
int8 linkState;
|
int8 linkState;
|
||||||
// probably padding
|
|
||||||
int8 field1B;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CTempDetachedNode // unused
|
struct CTempDetachedNode // unused
|
||||||
@ -102,39 +121,65 @@ public:
|
|||||||
uint8 m_distances[20400];
|
uint8 m_distances[20400];
|
||||||
int16 m_carPathConnections[20400];
|
int16 m_carPathConnections[20400];
|
||||||
*/
|
*/
|
||||||
CPathNode m_pathNodes[4930];
|
CPathNode m_pathNodes[NUM_PATHNODES];
|
||||||
CCarPathLink m_carPathLinks[2076];
|
CCarPathLink m_carPathLinks[NUM_CARPATHLINKS];
|
||||||
CTreadable *m_mapObjects[1250];
|
CTreadable *m_mapObjects[NUM_MAPOBJECTS];
|
||||||
uint8 m_objectFlags[1250];
|
uint8 m_objectFlags[NUM_MAPOBJECTS];
|
||||||
int16 m_connections[10260];
|
int16 m_connections[NUM_PATHCONNECTIONS];
|
||||||
int16 m_distances[10260];
|
int16 m_distances[NUM_PATHCONNECTIONS];
|
||||||
uint8 m_connectionFlags[10260];
|
CConnectionFlags m_connectionFlags[NUM_PATHCONNECTIONS];
|
||||||
int16 m_carPathConnections[10260];
|
int16 m_carPathConnections[NUM_PATHCONNECTIONS];
|
||||||
int32 m_numPathNodes;
|
int32 m_numPathNodes;
|
||||||
int32 m_numCarPathNodes;
|
int32 m_numCarPathNodes;
|
||||||
int32 m_numPedPathNodes;
|
int32 m_numPedPathNodes;
|
||||||
int16 m_numMapObjects;
|
int16 m_numMapObjects;
|
||||||
int16 m_numConnections;
|
int16 m_numConnections;
|
||||||
int32 m_numCarPathLinks;
|
int32 m_numCarPathLinks;
|
||||||
int32 h;
|
int32 unk;
|
||||||
uint8 m_numGroups[2];
|
uint8 m_numGroups[2];
|
||||||
CPathNode m_aExtraPaths[872];
|
CPathNode m_searchNodes[512];
|
||||||
|
|
||||||
|
void Init(void);
|
||||||
|
void AllocatePathFindInfoMem(int16 numPathGroups);
|
||||||
|
void RegisterMapObject(CTreadable *mapObject);
|
||||||
|
void StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, bool crossing);
|
||||||
|
void StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, int8 numLeft, int8 numRight);
|
||||||
|
void CalcNodeCoors(int16 x, int16 y, int16 z, int32 id, CVector *out);
|
||||||
|
bool LoadPathFindData(void);
|
||||||
void PreparePathData(void);
|
void PreparePathData(void);
|
||||||
void CountFloodFillGroups(uint8 type);
|
void CountFloodFillGroups(uint8 type);
|
||||||
void PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoForObject *objectpathinfo,
|
void PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoForObject *objectpathinfo,
|
||||||
float unk, CTempDetachedNode *detachednodes, int unused);
|
float unk, CTempDetachedNode *detachednodes, int unused);
|
||||||
void CalcNodeCoors(int16 x, int16 y, int16 z, int32 id, CVector *out);
|
|
||||||
void StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, bool crossing);
|
|
||||||
void StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, int8 numLeft, int8 numRight);
|
|
||||||
void RegisterMapObject(CTreadable *mapObject);
|
|
||||||
int32 FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool disabled, bool betweenLevels);
|
|
||||||
CPathNode** FindNextNodeWandering(uint8, CVector, CPathNode**, CPathNode**, uint8, uint8*);
|
|
||||||
|
|
||||||
bool IsPathObject(int id) { return id < PATHNODESIZE && (InfoForTileCars[id*12].type != 0 || InfoForTilePeds[id*12].type != 0); }
|
bool IsPathObject(int id) { return id < PATHNODESIZE && (InfoForTileCars[id*12].type != 0 || InfoForTilePeds[id*12].type != 0); }
|
||||||
|
|
||||||
|
float CalcRoadDensity(float x, float y);
|
||||||
|
bool TestForPedTrafficLight(CPathNode *n1, CPathNode *n2);
|
||||||
|
bool TestCrossesRoad(CPathNode *n1, CPathNode *n2);
|
||||||
|
void AddNodeToList(CPathNode *node, int32 listId);
|
||||||
|
void RemoveNodeFromList(CPathNode *node);
|
||||||
|
void RemoveBadStartNode(CVector pos, CPathNode **nodes, int16 *n);
|
||||||
void SetLinksBridgeLights(float, float, float, float, bool);
|
void SetLinksBridgeLights(float, float, float, float, bool);
|
||||||
|
void SwitchOffNodeAndNeighbours(int32 nodeId, bool disable);
|
||||||
|
void SwitchRoadsOffInArea(float x1, float x2, float y1, float y2, float z1, float z2, bool disable);
|
||||||
|
void SwitchPedRoadsOffInArea(float x1, float x2, float y1, float y2, float z1, float z2, bool disable);
|
||||||
|
void SwitchRoadsInAngledArea(float x1, float y1, float z1, float x2, float y2, float z2, float length, uint8 type, uint8 enable);
|
||||||
|
void MarkRoadsBetweenLevelsNodeAndNeighbours(int32 nodeId);
|
||||||
|
void MarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2);
|
||||||
|
void MarkPedRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2);
|
||||||
|
int32 FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled = false, bool ignoreBetweenLevels = false);
|
||||||
|
int32 FindNodeClosestToCoorsFavourDirection(CVector coors, uint8 type, float dirX, float dirY);
|
||||||
|
float FindNodeOrientationForCarPlacement(int32 nodeId);
|
||||||
|
float FindNodeOrientationForCarPlacementFacingDestination(int32 nodeId, float x, float y, bool towards);
|
||||||
|
bool NewGenerateCarCreationCoors(float x, float y, float dirX, float dirY, float spawnDist, float angleLimit, bool forward, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, bool ignoreDisabled = false);
|
||||||
|
bool GeneratePedCreationCoors(float x, float y, float minDist, float maxDist, float minDistOffScreen, float maxDistOffScreen, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, CMatrix *camMatrix);
|
||||||
|
CTreadable *FindRoadObjectClosestToCoors(CVector coors, uint8 type);
|
||||||
|
void FindNextNodeWandering(uint8, CVector, CPathNode**, CPathNode**, uint8, uint8*);
|
||||||
|
void DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector target, CPathNode **nodes, int16 *numNodes, int16 maxNumNodes, CVehicle *vehicle, float *dist, float distLimit, int32 forcedTargetNode);
|
||||||
|
bool TestCoorsCloseness(CVector target, uint8 type, CVector start);
|
||||||
|
void Save(uint8 *buffer, uint32 *length);
|
||||||
|
void Load(uint8 *buffer, uint32 length);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CPathFind) == 0x4c8f4, "CPathFind: error");
|
static_assert(sizeof(CPathFind) == 0x49bf4, "CPathFind: error");
|
||||||
|
|
||||||
extern CPathFind &ThePaths;
|
extern CPathFind &ThePaths;
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
CPickup(&CPickups::aPickUps)[NUMPICKUPS] = *(CPickup(*)[NUMPICKUPS])*(uintptr*)0x878C98;
|
CPickup(&CPickups::aPickUps)[NUMPICKUPS] = *(CPickup(*)[NUMPICKUPS])*(uintptr*)0x878C98;
|
||||||
|
|
||||||
// 20 ?! Some Miami leftover? (Originally at 0x5ED8D4)
|
// 20 ?! Some Miami leftover? (Originally at 0x5ED8D4)
|
||||||
uint16 CPickups::ms_maxAmmosForWeapons[20] = { 0, 1, 45, 125, 25, 150, 300, 25, 5, 250, 5, 5, 0, 500, 0, 100, 0, 0, 0, 0 };
|
uint16 AmmoForWeapon[20] = { 0, 1, 45, 125, 25, 150, 300, 25, 5, 250, 5, 5, 0, 500, 0, 100, 0, 0, 0, 0 };
|
||||||
|
uint16 AmmoForWeapon_OnStreet[20] = { 0, 1, 9, 25, 5, 30, 60, 5, 1, 50, 1, 1, 0, 200, 0, 100, 0, 0, 0, 0 };
|
||||||
|
|
||||||
WRAPPER void CPickups::RenderPickUpText(void) { EAXJMP(0x432440); }
|
WRAPPER void CPickups::RenderPickUpText(void) { EAXJMP(0x432440); }
|
||||||
WRAPPER void CPickups::DoCollectableEffects(CEntity *ent) { EAXJMP(0x431C30); }
|
WRAPPER void CPickups::DoCollectableEffects(CEntity *ent) { EAXJMP(0x431C30); }
|
||||||
|
@ -47,9 +47,11 @@ public:
|
|||||||
static int32 GenerateNewOne_WeaponType(CVector, eWeaponType, uint8, uint32);
|
static int32 GenerateNewOne_WeaponType(CVector, eWeaponType, uint8, uint32);
|
||||||
|
|
||||||
static CPickup (&aPickUps)[NUMPICKUPS];
|
static CPickup (&aPickUps)[NUMPICKUPS];
|
||||||
static uint16 ms_maxAmmosForWeapons[20];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern uint16 AmmoForWeapon[20];
|
||||||
|
extern uint16 AmmoForWeapon_OnStreet[20];
|
||||||
|
|
||||||
class CPacManPickups
|
class CPacManPickups
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -8,6 +8,7 @@ bool &CPopulation::ms_bGivePedsWeapons = *(bool*)0x95CCF6;
|
|||||||
int32 &CPopulation::m_AllRandomPedsThisType = *(int32*)0x5FA570;
|
int32 &CPopulation::m_AllRandomPedsThisType = *(int32*)0x5FA570;
|
||||||
float &CPopulation::PedDensityMultiplier = *(float*)0x5FA56C;
|
float &CPopulation::PedDensityMultiplier = *(float*)0x5FA56C;
|
||||||
uint32 &CPopulation::ms_nTotalMissionPeds = *(uint32*)0x8F5F70;
|
uint32 &CPopulation::ms_nTotalMissionPeds = *(uint32*)0x8F5F70;
|
||||||
|
int32 &CPopulation::MaxNumberOfPedsInUse = *(int32*)0x5FA574;
|
||||||
|
|
||||||
WRAPPER void CPopulation::UpdatePedCount(uint32, bool) { EAXJMP(0x4F5A60); }
|
WRAPPER void CPopulation::UpdatePedCount(uint32, bool) { EAXJMP(0x4F5A60); }
|
||||||
WRAPPER void CPopulation::DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool) { EAXJMP(0x4F6200); }
|
WRAPPER void CPopulation::DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool) { EAXJMP(0x4F6200); }
|
||||||
|
@ -17,6 +17,7 @@ public:
|
|||||||
static int32 &m_AllRandomPedsThisType;
|
static int32 &m_AllRandomPedsThisType;
|
||||||
static float &PedDensityMultiplier;
|
static float &PedDensityMultiplier;
|
||||||
static uint32 &ms_nTotalMissionPeds;
|
static uint32 &ms_nTotalMissionPeds;
|
||||||
|
static int32 &MaxNumberOfPedsInUse;
|
||||||
|
|
||||||
static void UpdatePedCount(uint32, bool);
|
static void UpdatePedCount(uint32, bool);
|
||||||
static void DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool);
|
static void DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool);
|
||||||
|
7
src/control/Restart.cpp
Normal file
7
src/control/Restart.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "Restart.h"
|
||||||
|
|
||||||
|
WRAPPER void CRestart::AddHospitalRestartPoint(const CVector&, float) { EAXJMP(0x436100); }
|
||||||
|
WRAPPER void CRestart::AddPoliceRestartPoint(const CVector&, float) { EAXJMP(0x436150); }
|
||||||
|
WRAPPER void CRestart::OverrideNextRestart(const CVector&, float) { EAXJMP(0x4366C0); }
|
9
src/control/Restart.h
Normal file
9
src/control/Restart.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class CRestart
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void AddPoliceRestartPoint(const CVector&, float);
|
||||||
|
static void AddHospitalRestartPoint(const CVector&, float);
|
||||||
|
static void OverrideNextRestart(const CVector&, float);
|
||||||
|
};
|
5
src/control/RoadBlocks.cpp
Normal file
5
src/control/RoadBlocks.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "RoadBlocks.h"
|
||||||
|
|
||||||
|
WRAPPER void CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle*, int32, int16) { EAXJMP(0x4376A0); }
|
10
src/control/RoadBlocks.h
Normal file
10
src/control/RoadBlocks.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
class CVehicle;
|
||||||
|
|
||||||
|
class CRoadBlocks
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void GenerateRoadBlockCopsForCar(CVehicle*, int32, int16);
|
||||||
|
};
|
@ -27,7 +27,9 @@
|
|||||||
#include "Pools.h"
|
#include "Pools.h"
|
||||||
#include "Population.h"
|
#include "Population.h"
|
||||||
#include "Remote.h"
|
#include "Remote.h"
|
||||||
|
#include "Restart.h"
|
||||||
#include "Replay.h"
|
#include "Replay.h"
|
||||||
|
#include "Shadows.h"
|
||||||
#include "Streaming.h"
|
#include "Streaming.h"
|
||||||
#include "Text.h"
|
#include "Text.h"
|
||||||
#include "User.h"
|
#include "User.h"
|
||||||
@ -1384,20 +1386,20 @@ void CRunningScript::UpdateCompareFlag(bool flag)
|
|||||||
{
|
{
|
||||||
if (m_bNotFlag)
|
if (m_bNotFlag)
|
||||||
flag = !flag;
|
flag = !flag;
|
||||||
if (m_nAndOrState == 0){
|
if (m_nAndOrState == ANDOR_NONE){
|
||||||
m_bCondResult = flag;
|
m_bCondResult = flag;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_nAndOrState >= 1 && m_nAndOrState <= 8) { /* Maybe enums?*/
|
if (m_nAndOrState >= ANDS_1 && m_nAndOrState <= ANDS_8){
|
||||||
m_bCondResult &= flag;
|
m_bCondResult &= flag;
|
||||||
if (m_nAndOrState == 1){
|
if (m_nAndOrState == ANDS_1){
|
||||||
m_nAndOrState = 0;
|
m_nAndOrState = ANDOR_NONE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}else if (m_nAndOrState >= 21 && m_nAndOrState <= 28){
|
}else if (m_nAndOrState >= ORS_1 && m_nAndOrState <= ORS_8){
|
||||||
m_bCondResult |= flag;
|
m_bCondResult |= flag;
|
||||||
if (m_nAndOrState == 21) {
|
if (m_nAndOrState == ORS_1) {
|
||||||
m_nAndOrState = 0;
|
m_nAndOrState = ANDOR_NONE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@ -1922,7 +1924,7 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
|
|||||||
boat->m_status = STATUS_ABANDONED;
|
boat->m_status = STATUS_ABANDONED;
|
||||||
boat->bIsLocked = true;
|
boat->bIsLocked = true;
|
||||||
boat->AutoPilot.m_nCarMission = MISSION_NONE;
|
boat->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
boat->AutoPilot.m_nAnimationId = TEMPACT_NONE; /* Animation ID? */
|
boat->AutoPilot.m_nTempAction = TEMPACT_NONE; /* Animation ID? */
|
||||||
boat->AutoPilot.m_nCruiseSpeed = boat->AutoPilot.m_fMaxTrafficSpeed = 20.0f;
|
boat->AutoPilot.m_nCruiseSpeed = boat->AutoPilot.m_fMaxTrafficSpeed = 20.0f;
|
||||||
CWorld::Add(boat);
|
CWorld::Add(boat);
|
||||||
handle = CPools::GetVehiclePool()->GetIndex(boat);
|
handle = CPools::GetVehiclePool()->GetIndex(boat);
|
||||||
@ -1941,10 +1943,10 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
|
|||||||
car->bIsLocked = true;
|
car->bIsLocked = true;
|
||||||
CCarCtrl::JoinCarWithRoadSystem(car);
|
CCarCtrl::JoinCarWithRoadSystem(car);
|
||||||
car->AutoPilot.m_nCarMission = MISSION_NONE;
|
car->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
car->AutoPilot.m_nAnimationId = TEMPACT_NONE; /* Animation ID? */
|
car->AutoPilot.m_nTempAction = TEMPACT_NONE; /* Animation ID? */
|
||||||
car->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
|
car->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
|
||||||
car->AutoPilot.m_nCruiseSpeed = car->AutoPilot.m_fMaxTrafficSpeed = 9.0f;
|
car->AutoPilot.m_nCruiseSpeed = car->AutoPilot.m_fMaxTrafficSpeed = 9.0f;
|
||||||
car->AutoPilot.m_nPreviousLane = car->AutoPilot.m_nCurrentLane = 0;
|
car->AutoPilot.m_nCurrentLane = car->AutoPilot.m_nNextLane = 0;
|
||||||
car->bEngineOn = false;
|
car->bEngineOn = false;
|
||||||
car->m_level = CTheZones::GetLevelFromPosition(pos);
|
car->m_level = CTheZones::GetLevelFromPosition(pos);
|
||||||
car->bHasBeenOwnedByPlayer = true;
|
car->bHasBeenOwnedByPlayer = true;
|
||||||
@ -2803,7 +2805,7 @@ int8 CRunningScript::ProcessCommandsFrom200To299(int32 command)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
WRAPPER int8 CRunningScript::ProcessCommandsFrom300To399(int32 command) { EAXJMP(0x43ED30); }
|
WRAPPER int8 CRunningScript::ProcessCommandsFrom300To399(int32 command) { EAXJMP(0x43ED30); }
|
||||||
#else
|
#else
|
||||||
int8 CRunningScript::ProcessCommandsFrom300To399(int32 command)
|
int8 CRunningScript::ProcessCommandsFrom300To399(int32 command)
|
||||||
@ -2846,6 +2848,7 @@ int8 CRunningScript::ProcessCommandsFrom300To399(int32 command)
|
|||||||
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
|
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
|
||||||
assert(pVehicle);
|
assert(pVehicle);
|
||||||
UpdateCompareFlag(pVehicle->GetModelIndex() == ScriptParams[1]);
|
UpdateCompareFlag(pVehicle->GetModelIndex() == ScriptParams[1]);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
/* Not implemented.
|
/* Not implemented.
|
||||||
case COMMAND_IS_CAR_REMAP:
|
case COMMAND_IS_CAR_REMAP:
|
||||||
@ -3010,67 +3013,526 @@ int8 CRunningScript::ProcessCommandsFrom300To399(int32 command)
|
|||||||
{
|
{
|
||||||
char label[12];
|
char label[12];
|
||||||
CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
|
CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
|
||||||
|
int16 zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
|
||||||
m_nIp += 8;
|
m_nIp += 8;
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
if (zone < 0) {
|
||||||
|
debug("Couldn't find zone - %s\n", label);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
CTheZones::SetCarDensity(zone, ScriptParams[0], ScriptParams[1]);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
case COMMAND_SET_PED_DENSITY:
|
case COMMAND_SET_PED_DENSITY:
|
||||||
|
{
|
||||||
|
char label[12];
|
||||||
|
CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
|
||||||
|
int16 zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
|
||||||
|
m_nIp += 8;
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
if (zone < 0) {
|
||||||
|
debug("Couldn't find zone - %s\n", label);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
CTheZones::SetPedDensity(zone, ScriptParams[0], ScriptParams[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_POINT_CAMERA_AT_PLAYER:
|
case COMMAND_POINT_CAMERA_AT_PLAYER:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 3);
|
||||||
|
// ScriptParams[0] is unused.
|
||||||
|
TheCamera.TakeControl(nil, ScriptParams[1], ScriptParams[2], 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_POINT_CAMERA_AT_CAR:
|
case COMMAND_POINT_CAMERA_AT_CAR:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 3);
|
||||||
|
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pVehicle);
|
||||||
|
TheCamera.TakeControl(pVehicle, ScriptParams[1], ScriptParams[2], 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_POINT_CAMERA_AT_CHAR:
|
case COMMAND_POINT_CAMERA_AT_CHAR:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 3);
|
||||||
|
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pPed);
|
||||||
|
TheCamera.TakeControl(pPed, ScriptParams[1], ScriptParams[2], 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_RESTORE_CAMERA:
|
case COMMAND_RESTORE_CAMERA:
|
||||||
|
TheCamera.Restore();
|
||||||
|
return 0;
|
||||||
case COMMAND_SHAKE_PAD:
|
case COMMAND_SHAKE_PAD:
|
||||||
|
CPad::GetPad(ScriptParams[0])->StartShake(ScriptParams[1], ScriptParams[2]);
|
||||||
|
return 0;
|
||||||
case COMMAND_SET_ZONE_PED_INFO:
|
case COMMAND_SET_ZONE_PED_INFO:
|
||||||
|
{
|
||||||
|
char label[12];
|
||||||
|
CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
|
||||||
|
m_nIp += 8;
|
||||||
|
CollectParameters(&m_nIp, 10);
|
||||||
|
int16 zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
|
||||||
|
if (zone < 0) {
|
||||||
|
debug("Couldn't find zone - %s\n", label);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
CTheZones::SetZonePedInfo(zone, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3],
|
||||||
|
ScriptParams[4], ScriptParams[5], ScriptParams[6], ScriptParams[7], ScriptParams[8], 0, 0, ScriptParams[9]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_SET_TIME_SCALE:
|
case COMMAND_SET_TIME_SCALE:
|
||||||
|
CollectParameters(&m_nIp, 1);
|
||||||
|
CTimer::SetTimeScale(*(float*)&ScriptParams[0]);
|
||||||
|
return 0;
|
||||||
case COMMAND_IS_CAR_IN_AIR:
|
case COMMAND_IS_CAR_IN_AIR:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 1);
|
||||||
|
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pVehicle && pVehicle->IsCar());
|
||||||
|
CAutomobile* pCar = (CAutomobile*)pVehicle;
|
||||||
|
UpdateCompareFlag(pCar->GetAllWheelsOffGround());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_SET_FIXED_CAMERA_POSITION:
|
case COMMAND_SET_FIXED_CAMERA_POSITION:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 6);
|
||||||
|
TheCamera.SetCamPositionForFixedMode(
|
||||||
|
CVector(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2]),
|
||||||
|
CVector(*(float*)&ScriptParams[3], *(float*)&ScriptParams[4], *(float*)&ScriptParams[5]));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_POINT_CAMERA_AT_POINT:
|
case COMMAND_POINT_CAMERA_AT_POINT:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 4);
|
||||||
|
CVector pos = *(CVector*)&ScriptParams[0];
|
||||||
|
if (pos.z <= -100.0f)
|
||||||
|
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
|
||||||
|
TheCamera.TakeControlNoEntity(pos, ScriptParams[3], 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_ADD_BLIP_FOR_CAR_OLD:
|
case COMMAND_ADD_BLIP_FOR_CAR_OLD:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 3);
|
||||||
|
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pVehicle);
|
||||||
|
// Useless call.
|
||||||
|
CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
|
||||||
|
ScriptParams[0] = CRadar::SetEntityBlip(BLIP_CAR, ScriptParams[0], ScriptParams[1], (eBlipDisplay)ScriptParams[2]);
|
||||||
|
StoreParameters(&m_nIp, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_ADD_BLIP_FOR_CHAR_OLD:
|
case COMMAND_ADD_BLIP_FOR_CHAR_OLD:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 3);
|
||||||
|
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pPed);
|
||||||
|
// Useless call.
|
||||||
|
CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
|
||||||
|
ScriptParams[0] = CRadar::SetEntityBlip(BLIP_CHAR, ScriptParams[0], ScriptParams[1], (eBlipDisplay)ScriptParams[2]);
|
||||||
|
StoreParameters(&m_nIp, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_ADD_BLIP_FOR_OBJECT_OLD:
|
case COMMAND_ADD_BLIP_FOR_OBJECT_OLD:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 3);
|
||||||
|
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pObject);
|
||||||
|
// Useless call.
|
||||||
|
CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
|
||||||
|
ScriptParams[0] = CRadar::SetEntityBlip(BLIP_OBJECT, ScriptParams[0], ScriptParams[1], (eBlipDisplay)ScriptParams[2]);
|
||||||
|
StoreParameters(&m_nIp, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_REMOVE_BLIP:
|
case COMMAND_REMOVE_BLIP:
|
||||||
|
CollectParameters(&m_nIp, 1);
|
||||||
|
CRadar::ClearBlip(ScriptParams[0]);
|
||||||
|
return 0;
|
||||||
case COMMAND_CHANGE_BLIP_COLOUR:
|
case COMMAND_CHANGE_BLIP_COLOUR:
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
CRadar::ChangeBlipColour(ScriptParams[0], ScriptParams[1]);
|
||||||
|
return 0;
|
||||||
case COMMAND_DIM_BLIP:
|
case COMMAND_DIM_BLIP:
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
CRadar::ChangeBlipBrightness(ScriptParams[0], ScriptParams[1]);
|
||||||
|
return 0;
|
||||||
case COMMAND_ADD_BLIP_FOR_COORD_OLD:
|
case COMMAND_ADD_BLIP_FOR_COORD_OLD:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 5);
|
||||||
|
CVector pos = *(CVector*)&ScriptParams[0];
|
||||||
|
if (pos.z <= -100.0f)
|
||||||
|
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
|
||||||
|
// Useless call
|
||||||
|
CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
|
||||||
|
ScriptParams[0] = CRadar::SetCoordBlip(BLIP_COORD, pos, ScriptParams[3], (eBlipDisplay)ScriptParams[4]);
|
||||||
|
StoreParameters(&m_nIp, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_CHANGE_BLIP_SCALE:
|
case COMMAND_CHANGE_BLIP_SCALE:
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
CRadar::ChangeBlipScale(ScriptParams[0], ScriptParams[1]);
|
||||||
|
return 0;
|
||||||
case COMMAND_SET_FADING_COLOUR:
|
case COMMAND_SET_FADING_COLOUR:
|
||||||
|
CollectParameters(&m_nIp, 3);
|
||||||
|
TheCamera.SetFadeColour(ScriptParams[0], ScriptParams[1], ScriptParams[2]);
|
||||||
|
return 0;
|
||||||
case COMMAND_DO_FADE:
|
case COMMAND_DO_FADE:
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
TheCamera.Fade(ScriptParams[0] / 1000.0f, ScriptParams[1]);
|
||||||
|
return 0;
|
||||||
case COMMAND_GET_FADING_STATUS:
|
case COMMAND_GET_FADING_STATUS:
|
||||||
|
UpdateCompareFlag(TheCamera.GetFading());
|
||||||
|
return 0;
|
||||||
case COMMAND_ADD_HOSPITAL_RESTART:
|
case COMMAND_ADD_HOSPITAL_RESTART:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 4);
|
||||||
|
CVector pos = *(CVector*)&ScriptParams[0];
|
||||||
|
float angle = *(float*)&ScriptParams[3];
|
||||||
|
if (pos.z <= -100.0f)
|
||||||
|
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
|
||||||
|
CRestart::AddHospitalRestartPoint(pos, angle);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_ADD_POLICE_RESTART:
|
case COMMAND_ADD_POLICE_RESTART:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 4);
|
||||||
|
CVector pos = *(CVector*)&ScriptParams[0];
|
||||||
|
float angle = *(float*)&ScriptParams[3];
|
||||||
|
if (pos.z <= -100.0f)
|
||||||
|
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
|
||||||
|
CRestart::AddPoliceRestartPoint(pos, angle);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_OVERRIDE_NEXT_RESTART:
|
case COMMAND_OVERRIDE_NEXT_RESTART:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 4);
|
||||||
|
CVector pos = *(CVector*)&ScriptParams[0];
|
||||||
|
float angle = *(float*)&ScriptParams[3];
|
||||||
|
if (pos.z <= -100.0f)
|
||||||
|
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
|
||||||
|
CRestart::OverrideNextRestart(pos, angle);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_DRAW_SHADOW:
|
case COMMAND_DRAW_SHADOW:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 10);
|
||||||
|
CVector pos = *(CVector*)&ScriptParams[1];
|
||||||
|
float angle = *(float*)&ScriptParams[4];
|
||||||
|
float length = *(float*)&ScriptParams[5];
|
||||||
|
float x, y;
|
||||||
|
if (angle != 0.0f){
|
||||||
|
y = cos(angle) * length;
|
||||||
|
x = sin(angle) * length;
|
||||||
|
}else{
|
||||||
|
y = length;
|
||||||
|
x = 0.0f;
|
||||||
|
}
|
||||||
|
float frontX = -x;
|
||||||
|
float frontY = y;
|
||||||
|
float sideX = y;
|
||||||
|
float sideY = x;
|
||||||
|
/* Not very nicely named intermediate variables. */
|
||||||
|
CShadows::StoreShadowToBeRendered(ScriptParams[0], &pos, frontX, frontY, sideX, sideY,
|
||||||
|
ScriptParams[6], ScriptParams[7], ScriptParams[8], ScriptParams[9]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_GET_PLAYER_HEADING:
|
case COMMAND_GET_PLAYER_HEADING:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 1);
|
||||||
|
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
|
||||||
|
float angle = pPed->bInVehicle ? pPed->m_pMyVehicle->GetForward().Heading() : pPed->GetForward().Heading();
|
||||||
|
*(float*)&ScriptParams[0] = CGeneral::LimitAngle(RADTODEG(angle));
|
||||||
|
StoreParameters(&m_nIp, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_SET_PLAYER_HEADING:
|
case COMMAND_SET_PLAYER_HEADING:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
|
||||||
|
if (pPed->bInVehicle){
|
||||||
|
// Is assertion required?
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pPed->m_fRotationDest = pPed->m_fRotationCur = DEGTORAD(*(float*)&ScriptParams[1]);
|
||||||
|
pPed->SetHeading(DEGTORAD(*(float*)&ScriptParams[1]));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_GET_CHAR_HEADING:
|
case COMMAND_GET_CHAR_HEADING:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 1);
|
||||||
|
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pPed);
|
||||||
|
float angle = pPed->bInVehicle ? pPed->m_pMyVehicle->GetForward().Heading() : pPed->GetForward().Heading();
|
||||||
|
*(float*)&ScriptParams[0] = CGeneral::LimitAngle(RADTODEG(angle));
|
||||||
|
StoreParameters(&m_nIp, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_SET_CHAR_HEADING:
|
case COMMAND_SET_CHAR_HEADING:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pPed);
|
||||||
|
if (pPed->bInVehicle) {
|
||||||
|
// Is assertion required?
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pPed->m_fRotationDest = pPed->m_fRotationCur = DEGTORAD(*(float*)&ScriptParams[1]);
|
||||||
|
pPed->SetHeading(DEGTORAD(*(float*)&ScriptParams[1]));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_GET_CAR_HEADING:
|
case COMMAND_GET_CAR_HEADING:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 1);
|
||||||
|
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pVehicle);
|
||||||
|
float angle = pVehicle->GetForward().Heading();
|
||||||
|
*(float*)&ScriptParams[0] = CGeneral::LimitAngle(RADTODEG(angle));
|
||||||
|
StoreParameters(&m_nIp, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_SET_CAR_HEADING:
|
case COMMAND_SET_CAR_HEADING:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pVehicle);
|
||||||
|
pVehicle->SetHeading(DEGTORAD(*(float*)&ScriptParams[1]));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_GET_OBJECT_HEADING:
|
case COMMAND_GET_OBJECT_HEADING:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 1);
|
||||||
|
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pObject);
|
||||||
|
float angle = pObject->GetForward().Heading();
|
||||||
|
*(float*)&ScriptParams[0] = CGeneral::LimitAngle(RADTODEG(angle));
|
||||||
|
StoreParameters(&m_nIp, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_SET_OBJECT_HEADING:
|
case COMMAND_SET_OBJECT_HEADING:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pObject);
|
||||||
|
CWorld::Remove(pObject);
|
||||||
|
pObject->SetHeading(DEGTORAD(*(float*)&ScriptParams[1]));
|
||||||
|
pObject->GetMatrix().UpdateRW();
|
||||||
|
pObject->UpdateRwFrame();
|
||||||
|
CWorld::Add(pObject);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_IS_PLAYER_TOUCHING_OBJECT:
|
case COMMAND_IS_PLAYER_TOUCHING_OBJECT:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
|
||||||
|
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
|
||||||
|
assert(pObject);
|
||||||
|
CPhysical* pEntityToTest = pPed->bInVehicle ? (CPhysical*)pPed->m_pMyVehicle : pPed;
|
||||||
|
UpdateCompareFlag(pEntityToTest->GetHasCollidedWith(pObject));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_IS_CHAR_TOUCHING_OBJECT:
|
case COMMAND_IS_CHAR_TOUCHING_OBJECT:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pPed);
|
||||||
|
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
|
||||||
|
assert(pObject);
|
||||||
|
CPhysical* pEntityToTest = pPed->bInVehicle ? (CPhysical*)pPed->m_pMyVehicle : pPed;
|
||||||
|
UpdateCompareFlag(pEntityToTest->GetHasCollidedWith(pObject));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_SET_PLAYER_AMMO:
|
case COMMAND_SET_PLAYER_AMMO:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 3);
|
||||||
|
CWorld::Players[0].m_pPed->SetAmmo((eWeaponType)ScriptParams[1], ScriptParams[2]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_SET_CHAR_AMMO:
|
case COMMAND_SET_CHAR_AMMO:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 3);
|
||||||
|
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
|
||||||
|
pPed->SetAmmo((eWeaponType)ScriptParams[1], ScriptParams[2]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Not implemented.
|
||||||
case COMMAND_SET_CAR_AMMO:
|
case COMMAND_SET_CAR_AMMO:
|
||||||
case COMMAND_LOAD_CAMERA_SPLINE:
|
case COMMAND_LOAD_CAMERA_SPLINE:
|
||||||
case COMMAND_MOVE_CAMERA_ALONG_SPLINE:
|
case COMMAND_MOVE_CAMERA_ALONG_SPLINE:
|
||||||
case COMMAND_GET_CAMERA_POSITION_ALONG_SPLINE:
|
case COMMAND_GET_CAMERA_POSITION_ALONG_SPLINE:
|
||||||
|
*/
|
||||||
case COMMAND_DECLARE_MISSION_FLAG:
|
case COMMAND_DECLARE_MISSION_FLAG:
|
||||||
|
CTheScripts::OnAMissionFlag = CTheScripts::Read2BytesFromScript(&++m_nIp);
|
||||||
|
return 0;
|
||||||
case COMMAND_DECLARE_MISSION_FLAG_FOR_CONTACT:
|
case COMMAND_DECLARE_MISSION_FLAG_FOR_CONTACT:
|
||||||
|
CollectParameters(&m_nIp, 1);
|
||||||
|
CTheScripts::OnAMissionForContactFlag[ScriptParams[0]] = CTheScripts::Read2BytesFromScript(&++m_nIp);
|
||||||
|
return 0;
|
||||||
case COMMAND_DECLARE_BASE_BRIEF_ID_FOR_CONTACT:
|
case COMMAND_DECLARE_BASE_BRIEF_ID_FOR_CONTACT:
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
CTheScripts::BaseBriefIdForContact[ScriptParams[0]] = ScriptParams[1];
|
||||||
|
return 0;
|
||||||
case COMMAND_IS_PLAYER_HEALTH_GREATER:
|
case COMMAND_IS_PLAYER_HEALTH_GREATER:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
|
||||||
|
UpdateCompareFlag(pPed->m_fHealth > ScriptParams[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_IS_CHAR_HEALTH_GREATER:
|
case COMMAND_IS_CHAR_HEALTH_GREATER:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pPed);
|
||||||
|
UpdateCompareFlag(pPed->m_fHealth > ScriptParams[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_IS_CAR_HEALTH_GREATER:
|
case COMMAND_IS_CAR_HEALTH_GREATER:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pVehicle);
|
||||||
|
UpdateCompareFlag(pVehicle->m_fHealth > ScriptParams[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_ADD_BLIP_FOR_CAR:
|
case COMMAND_ADD_BLIP_FOR_CAR:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 1);
|
||||||
|
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pVehicle);
|
||||||
|
// Useless call.
|
||||||
|
CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
|
||||||
|
int handle = CRadar::SetEntityBlip(BLIP_CAR, ScriptParams[0], 0, BLIP_DISPLAY_BOTH);
|
||||||
|
CRadar::ChangeBlipScale(handle, 3);
|
||||||
|
ScriptParams[0] = handle;
|
||||||
|
StoreParameters(&m_nIp, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_ADD_BLIP_FOR_CHAR:
|
case COMMAND_ADD_BLIP_FOR_CHAR:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 1);
|
||||||
|
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pPed);
|
||||||
|
// Useless call.
|
||||||
|
CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
|
||||||
|
int handle = CRadar::SetEntityBlip(BLIP_CHAR, ScriptParams[0], 0, BLIP_DISPLAY_BOTH);
|
||||||
|
CRadar::ChangeBlipScale(handle, 3);
|
||||||
|
ScriptParams[0] = handle;
|
||||||
|
StoreParameters(&m_nIp, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_ADD_BLIP_FOR_OBJECT:
|
case COMMAND_ADD_BLIP_FOR_OBJECT:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 1);
|
||||||
|
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pObject);
|
||||||
|
// Useless call.
|
||||||
|
CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
|
||||||
|
int handle = CRadar::SetEntityBlip(BLIP_OBJECT, ScriptParams[0], 0, BLIP_DISPLAY_BOTH);
|
||||||
|
CRadar::ChangeBlipScale(handle, 3);
|
||||||
|
ScriptParams[0] = handle;
|
||||||
|
StoreParameters(&m_nIp, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_ADD_BLIP_FOR_CONTACT_POINT:
|
case COMMAND_ADD_BLIP_FOR_CONTACT_POINT:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 3);
|
||||||
|
CVector pos = *(CVector*)&ScriptParams[0];
|
||||||
|
if (pos.z <= -100.0f)
|
||||||
|
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
|
||||||
|
// Useless call
|
||||||
|
CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
|
||||||
|
int handle = CRadar::SetCoordBlip(BLIP_COORD, pos, 2, BLIP_DISPLAY_BOTH);
|
||||||
|
CRadar::ChangeBlipScale(handle, 3);
|
||||||
|
ScriptParams[0] = handle;
|
||||||
|
StoreParameters(&m_nIp, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_ADD_BLIP_FOR_COORD:
|
case COMMAND_ADD_BLIP_FOR_COORD:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 3);
|
||||||
|
CVector pos = *(CVector*)&ScriptParams[0];
|
||||||
|
if (pos.z <= -100.0f)
|
||||||
|
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
|
||||||
|
// Useless call
|
||||||
|
CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
|
||||||
|
int handle = CRadar::SetCoordBlip(BLIP_COORD, pos, 5, BLIP_DISPLAY_BOTH);
|
||||||
|
CRadar::ChangeBlipScale(handle, 3);
|
||||||
|
ScriptParams[0] = handle;
|
||||||
|
StoreParameters(&m_nIp, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_CHANGE_BLIP_DISPLAY:
|
case COMMAND_CHANGE_BLIP_DISPLAY:
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
CRadar::ChangeBlipDisplay(ScriptParams[0], (eBlipDisplay)ScriptParams[1]);
|
||||||
|
return 0;
|
||||||
case COMMAND_ADD_ONE_OFF_SOUND:
|
case COMMAND_ADD_ONE_OFF_SOUND:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 4);
|
||||||
|
switch (ScriptParams[3]) {
|
||||||
|
case SCRIPT_SOUND_EVIDENCE_PICKUP:
|
||||||
|
DMAudio.PlayFrontEndSound(SOUND_EVIDENCE_PICKUP, 0);
|
||||||
|
return 0;
|
||||||
|
case SCRIPT_SOUND_UNLOAD_GOLD:
|
||||||
|
DMAudio.PlayFrontEndSound(SOUND_UNLOAD_GOLD, 0);
|
||||||
|
return 0;
|
||||||
|
case SCRIPT_SOUND_PART_MISSION_COMPLETE:
|
||||||
|
DMAudio.PlayFrontEndSound(SOUND_PART_MISSION_COMPLETE, 0);
|
||||||
|
return 0;
|
||||||
|
case SCRIPT_SOUND_RACE_START_3:
|
||||||
|
DMAudio.PlayFrontEndSound(SOUND_RACE_START_3, 0);
|
||||||
|
return 0;
|
||||||
|
case SCRIPT_SOUND_RACE_START_2:
|
||||||
|
DMAudio.PlayFrontEndSound(SOUND_RACE_START_2, 0);
|
||||||
|
return 0;
|
||||||
|
case SCRIPT_SOUND_RACE_START_1:
|
||||||
|
DMAudio.PlayFrontEndSound(SOUND_RACE_START_1, 0);
|
||||||
|
return 0;
|
||||||
|
case SCRIPT_SOUND_RACE_START_GO:
|
||||||
|
DMAudio.PlayFrontEndSound(SOUND_RACE_START_GO, 0);
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cAudioScriptObject* obj = new cAudioScriptObject();
|
||||||
|
obj->m_vecPos = *(CVector*)&ScriptParams[0];
|
||||||
|
obj->m_wSound = ScriptParams[3];
|
||||||
|
obj->m_nAudioEntityId = -5;
|
||||||
|
/* BUG: if audio is not initialized, this object will not be freed. */
|
||||||
|
/* Issue needs to be addressed in CreateOneShotScriptObject. */
|
||||||
|
DMAudio.CreateOneShotScriptObject(obj);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_ADD_CONTINUOUS_SOUND:
|
case COMMAND_ADD_CONTINUOUS_SOUND:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 4);
|
||||||
|
cAudioScriptObject* obj = new cAudioScriptObject();
|
||||||
|
obj->m_vecPos = *(CVector*)&ScriptParams[0];
|
||||||
|
obj->m_wSound = ScriptParams[3];
|
||||||
|
obj->m_nAudioEntityId = DMAudio.CreateLoopingScriptObject(obj);
|
||||||
|
ScriptParams[0] = CPools::GetAudioScriptObjectPool()->GetIndex(obj);
|
||||||
|
StoreParameters(&m_nIp, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_REMOVE_SOUND:
|
case COMMAND_REMOVE_SOUND:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 1);
|
||||||
|
cAudioScriptObject* obj = CPools::GetAudioScriptObjectPool()->GetAt(ScriptParams[0]);
|
||||||
|
if (!obj){
|
||||||
|
debug("REMOVE_SOUND - Sound doesn't exist\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DMAudio.DestroyLoopingScriptObject(obj->m_nAudioEntityId);
|
||||||
|
delete obj;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_IS_CAR_STUCK_ON_ROOF:
|
case COMMAND_IS_CAR_STUCK_ON_ROOF:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 1);
|
||||||
|
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pVehicle);
|
||||||
|
UpdateCompareFlag(CTheScripts::UpsideDownCars.HasCarBeenUpsideDownForAWhile(ScriptParams[0]));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,22 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "TrafficLights.h"
|
#include "TrafficLights.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
#include "Vehicle.h"
|
||||||
|
|
||||||
WRAPPER void CTrafficLights::DisplayActualLight(CEntity *ent) { EAXJMP(0x455800); }
|
WRAPPER void CTrafficLights::DisplayActualLight(CEntity *ent) { EAXJMP(0x455800); }
|
||||||
|
WRAPPER bool CTrafficLights::ShouldCarStopForLight(CVehicle*, bool) { EAXJMP(0x455350); }
|
||||||
|
WRAPPER bool CTrafficLights::ShouldCarStopForBridge(CVehicle*) { EAXJMP(0x456460); }
|
||||||
|
|
||||||
|
uint8
|
||||||
|
CTrafficLights::LightForPeds(void)
|
||||||
|
{
|
||||||
|
uint32 period = CTimer::GetTimeInMilliseconds() & 0x3FFF; // Equals to % 16384
|
||||||
|
|
||||||
|
if (period >= 15384)
|
||||||
|
return PED_LIGHTS_WALK_BLINK;
|
||||||
|
else if (period >= 12000)
|
||||||
|
return PED_LIGHTS_WALK;
|
||||||
|
else
|
||||||
|
return PED_LIGHTS_DONT_WALK;
|
||||||
|
}
|
@ -1,9 +1,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class CEntity;
|
class CEntity;
|
||||||
|
class CVehicle;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PED_LIGHTS_WALK,
|
||||||
|
PED_LIGHTS_WALK_BLINK,
|
||||||
|
PED_LIGHTS_DONT_WALK,
|
||||||
|
};
|
||||||
|
|
||||||
class CTrafficLights
|
class CTrafficLights
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void DisplayActualLight(CEntity *ent);
|
static void DisplayActualLight(CEntity *ent);
|
||||||
|
static uint8 LightForPeds(void);
|
||||||
|
static bool ShouldCarStopForLight(CVehicle*, bool);
|
||||||
|
static bool ShouldCarStopForBridge(CVehicle*);
|
||||||
};
|
};
|
||||||
|
@ -24,6 +24,16 @@ WRAPPER void CCamera::CalculateDerivedValues(void) { EAXJMP(0x46EEA0); }
|
|||||||
WRAPPER void CCamera::Restore(void) { EAXJMP(0x46F990); }
|
WRAPPER void CCamera::Restore(void) { EAXJMP(0x46F990); }
|
||||||
WRAPPER void CCamera::SetWidescreenOff(void) { EAXJMP(0x46FF10); }
|
WRAPPER void CCamera::SetWidescreenOff(void) { EAXJMP(0x46FF10); }
|
||||||
WRAPPER void CamShakeNoPos(CCamera*, float) { EAXJMP(0x46B100); }
|
WRAPPER void CamShakeNoPos(CCamera*, float) { EAXJMP(0x46B100); }
|
||||||
|
WRAPPER void CCamera::TakeControl(CEntity*, int16, int16, int32) { EAXJMP(0x471500); }
|
||||||
|
WRAPPER void CCamera::TakeControlNoEntity(const CVector&, int16, int32) { EAXJMP(0x4715B0); }
|
||||||
|
WRAPPER void CCamera::SetCamPositionForFixedMode(const CVector&, const CVector&) { EAXJMP(0x46FCC0); }
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
CCamera::GetFading()
|
||||||
|
{
|
||||||
|
return m_bFading;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CCamera::IsSphereVisible(const CVector ¢er, float radius, const CMatrix *mat)
|
CCamera::IsSphereVisible(const CVector ¢er, float radius, const CMatrix *mat)
|
||||||
|
@ -471,6 +471,11 @@ int m_iModeObbeCamIsInForCar;
|
|||||||
|
|
||||||
float Find3rdPersonQuickAimPitch(void);
|
float Find3rdPersonQuickAimPitch(void);
|
||||||
|
|
||||||
|
void TakeControl(CEntity*, int16, int16, int32);
|
||||||
|
void TakeControlNoEntity(const CVector&, int16, int32);
|
||||||
|
void SetCamPositionForFixedMode(const CVector&, const CVector&);
|
||||||
|
bool GetFading();
|
||||||
|
|
||||||
void dtor(void) { this->CCamera::~CCamera(); }
|
void dtor(void) { this->CCamera::~CCamera(); }
|
||||||
};
|
};
|
||||||
static_assert(offsetof(CCamera, m_WideScreenOn) == 0x70, "CCamera: error");
|
static_assert(offsetof(CCamera, m_WideScreenOn) == 0x70, "CCamera: error");
|
||||||
|
@ -144,7 +144,7 @@ CCollision::LoadCollisionWhenINeedIt(bool forceChange)
|
|||||||
if(veh && veh->IsTrain()){
|
if(veh && veh->IsTrain()){
|
||||||
if(((CTrain*)veh)->m_nDoorState != TRAIN_DOOR_OPEN)
|
if(((CTrain*)veh)->m_nDoorState != TRAIN_DOOR_OPEN)
|
||||||
return;
|
return;
|
||||||
}else if(playerCoors.z < 4.0f && !CCullZones::DoINeedToLoadCollision())
|
}else if(playerCoors.z < -4.0f && !CCullZones::DoINeedToLoadCollision())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Figure out whose level's collisions we're most likely to be interested in
|
// Figure out whose level's collisions we're most likely to be interested in
|
||||||
|
@ -74,6 +74,7 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns an angle such that x2/y2 looks at x1/y1 with its forward vector if rotated by that angle
|
||||||
static float GetRadianAngleBetweenPoints(float x1, float y1, float x2, float y2)
|
static float GetRadianAngleBetweenPoints(float x1, float y1, float x2, float y2)
|
||||||
{
|
{
|
||||||
float x = x2 - x1;
|
float x = x2 - x1;
|
||||||
@ -95,9 +96,26 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// should return direction in 0-8 range. fits perfectly to peds' path directions.
|
||||||
|
static int CGeneral::GetNodeHeadingFromVector(float x, float y)
|
||||||
|
{
|
||||||
|
float angle = CGeneral::GetRadianAngleBetweenPoints(x, y, 0.0f, 0.0f);
|
||||||
|
if (angle < 0.0f)
|
||||||
|
angle += TWOPI;
|
||||||
|
|
||||||
|
angle = DEGTORAD(22.5f) + TWOPI - angle;
|
||||||
|
|
||||||
|
if (angle >= TWOPI)
|
||||||
|
angle -= TWOPI;
|
||||||
|
|
||||||
|
return (int)floorf(angle / DEGTORAD(45.0f));
|
||||||
|
}
|
||||||
|
|
||||||
// not too sure about all these...
|
// not too sure about all these...
|
||||||
static uint16 GetRandomNumber(void)
|
static uint16 GetRandomNumber(void)
|
||||||
{ return myrand() & MYRAND_MAX; }
|
{ return myrand() & MYRAND_MAX; }
|
||||||
|
static bool GetRandomTrueFalse(void)
|
||||||
|
{ return GetRandomNumber() < MYRAND_MAX / 2; }
|
||||||
// Probably don't want to ever reach high
|
// Probably don't want to ever reach high
|
||||||
static float GetRandomNumberInRange(float low, float high)
|
static float GetRandomNumberInRange(float low, float high)
|
||||||
{ return low + (high - low)*(GetRandomNumber()/float(MYRAND_MAX + 1)); }
|
{ return low + (high - low)*(GetRandomNumber()/float(MYRAND_MAX + 1)); }
|
||||||
|
28
src/core/IniFile.cpp
Normal file
28
src/core/IniFile.cpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "IniFile.h"
|
||||||
|
|
||||||
|
#include "CarCtrl.h"
|
||||||
|
#include "FileMgr.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "Population.h"
|
||||||
|
|
||||||
|
float &CIniFile::PedNumberMultiplier = *(float*)0x6182F4;
|
||||||
|
float &CIniFile::CarNumberMultiplier = *(float*)0x6182F8;
|
||||||
|
|
||||||
|
void CIniFile::LoadIniFile()
|
||||||
|
{
|
||||||
|
CFileMgr::SetDir("");
|
||||||
|
int f = CFileMgr::OpenFile("gta3.ini", "r");
|
||||||
|
if (f){
|
||||||
|
CFileMgr::ReadLine(f, gString, 200);
|
||||||
|
sscanf(gString, "%f", &PedNumberMultiplier);
|
||||||
|
PedNumberMultiplier = min(3.0f, max(0.5f, PedNumberMultiplier));
|
||||||
|
CFileMgr::ReadLine(f, gString, 200);
|
||||||
|
sscanf(gString, "%f", &CarNumberMultiplier);
|
||||||
|
CarNumberMultiplier = min(3.0f, max(0.5f, CarNumberMultiplier));
|
||||||
|
CFileMgr::CloseFile(f);
|
||||||
|
}
|
||||||
|
CPopulation::MaxNumberOfPedsInUse = 25.0f * PedNumberMultiplier;
|
||||||
|
CCarCtrl::MaxNumberOfCarsInUse = 12.0f * CarNumberMultiplier;
|
||||||
|
}
|
10
src/core/IniFile.h
Normal file
10
src/core/IniFile.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class CIniFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void LoadIniFile();
|
||||||
|
|
||||||
|
static float& PedNumberMultiplier;
|
||||||
|
static float& CarNumberMultiplier;
|
||||||
|
};
|
@ -100,9 +100,9 @@ void CRadar::ChangeBlipBrightness(int32 i, int32 bright)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
WRAPPER void CRadar::ChangeBlipColour(int32) { EAXJMP(0x4A5770); }
|
WRAPPER void CRadar::ChangeBlipColour(int32, int32) { EAXJMP(0x4A5770); }
|
||||||
#else
|
#else
|
||||||
void CRadar::ChangeBlipColour(int32 i)
|
void CRadar::ChangeBlipColour(int32 i, int32)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -571,9 +571,9 @@ void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
WRAPPER int32 CRadar::GetActualBlipArray(int32) { EAXJMP(0x4A41C0); }
|
WRAPPER int32 CRadar::GetActualBlipArrayIndex(int32) { EAXJMP(0x4A41C0); }
|
||||||
#else
|
#else
|
||||||
int32 CRadar::GetActualBlipArray(int32 i)
|
int32 CRadar::GetActualBlipArrayIndex(int32 i)
|
||||||
{
|
{
|
||||||
return int32();
|
return int32();
|
||||||
}
|
}
|
||||||
@ -737,18 +737,18 @@ void CRadar::SetBlipSprite(int32 i, int32 icon)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
WRAPPER int CRadar::SetCoordBlip(int32, CVector, int32) { EAXJMP(0x4A5590); }
|
WRAPPER int32 CRadar::SetCoordBlip(eBlipType, CVector, int32, eBlipDisplay) { EAXJMP(0x4A5590); }
|
||||||
#else
|
#else
|
||||||
int CRadar::SetCoordBlip(int32 type, CVector pos, int32 flag)
|
int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 flag, eBlipDisplay)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
WRAPPER int CRadar::SetEntityBlip(int32 type, CVector pos, int32 color, int32 flag) { EAXJMP(0x4A5640); }
|
WRAPPER int CRadar::SetEntityBlip(eBlipType type, int32, int32, eBlipDisplay) { EAXJMP(0x4A5640); }
|
||||||
#else
|
#else
|
||||||
int CRadar::SetEntityBlip(int32 type, CVector pos, int32 color, int32 flag)
|
int CRadar::SetEntityBlip(eBlipType type, int32, int32, eBlipDisplay)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
static int CalculateBlipAlpha(float dist);
|
static int CalculateBlipAlpha(float dist);
|
||||||
static void ChangeBlipBrightness(int32 i, int32 bright);
|
static void ChangeBlipBrightness(int32 i, int32 bright);
|
||||||
static void ChangeBlipColour(int32 i);
|
static void ChangeBlipColour(int32 i, int32);
|
||||||
static void ChangeBlipDisplay(int32 i, int16 flag);
|
static void ChangeBlipDisplay(int32 i, int16 flag);
|
||||||
static void ChangeBlipScale(int32 i, int16 scale);
|
static void ChangeBlipScale(int32 i, int16 scale);
|
||||||
static void ClearBlip(int32 i);
|
static void ClearBlip(int32 i);
|
||||||
@ -113,7 +113,7 @@ public:
|
|||||||
static void DrawRadarSection(int32 x, int32 y);
|
static void DrawRadarSection(int32 x, int32 y);
|
||||||
static void DrawRadarSprite(int32 sprite, float x, float y, int32 alpha);
|
static void DrawRadarSprite(int32 sprite, float x, float y, int32 alpha);
|
||||||
static void DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha);
|
static void DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha);
|
||||||
static int32 GetActualBlipArray(int32 i);
|
static int32 GetActualBlipArrayIndex(int32 i);
|
||||||
static int32 GetNewUniqueBlipIndex(int32 i);
|
static int32 GetNewUniqueBlipIndex(int32 i);
|
||||||
static int32 GetRadarTraceColour(int32 color, bool bright);
|
static int32 GetRadarTraceColour(int32 color, bool bright);
|
||||||
static void Initialise();
|
static void Initialise();
|
||||||
@ -125,8 +125,8 @@ public:
|
|||||||
static void RequestMapSection(int32 x, int32 y);
|
static void RequestMapSection(int32 x, int32 y);
|
||||||
static void SaveAllRadarBlips(int32);
|
static void SaveAllRadarBlips(int32);
|
||||||
static void SetBlipSprite(int32 i, int32 icon);
|
static void SetBlipSprite(int32 i, int32 icon);
|
||||||
static int SetCoordBlip(int32 type, CVector pos, int32 flag);
|
static int32 SetCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay flag);
|
||||||
static int SetEntityBlip(int32 type, CVector pos, int32 color, int32 flag);
|
static int32 SetEntityBlip(eBlipType type, int32, int32, eBlipDisplay);
|
||||||
static void SetRadarMarkerState(int32 i, int32 flag);
|
static void SetRadarMarkerState(int32 i, int32 flag);
|
||||||
static void ShowRadarMarker(CVector pos, int16 color, float radius);
|
static void ShowRadarMarker(CVector pos, int16 color, float radius);
|
||||||
static void ShowRadarTrace(float x, float y, uint32 size, uint32 red, uint32 green, uint32 blue, uint32 alpha);
|
static void ShowRadarTrace(float x, float y, uint32 size, uint32 red, uint32 green, uint32 blue, uint32 alpha);
|
||||||
|
@ -7,6 +7,8 @@ bool& CStats::CommercialPassed = *(bool*)0x8F4334;
|
|||||||
bool& CStats::IndustrialPassed = *(bool*)0x8E2A68;
|
bool& CStats::IndustrialPassed = *(bool*)0x8E2A68;
|
||||||
int32 &CStats::NumberKillFrenziesPassed = *(int32*)0x8E287C;
|
int32 &CStats::NumberKillFrenziesPassed = *(int32*)0x8E287C;
|
||||||
int32 &CStats::PeopleKilledByOthers = *(int32*)0x8E2C50;
|
int32 &CStats::PeopleKilledByOthers = *(int32*)0x8E2C50;
|
||||||
|
int32 &CStats::HelisDestroyed = *(int32*)0x8E2A64;
|
||||||
|
int32 *CStats::PedsKilledOfThisType = (int32*)0x880DBC;
|
||||||
|
|
||||||
void CStats::AnotherKillFrenzyPassed()
|
void CStats::AnotherKillFrenzyPassed()
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,8 @@ public:
|
|||||||
static bool& IndustrialPassed;
|
static bool& IndustrialPassed;
|
||||||
static int32 &NumberKillFrenziesPassed;
|
static int32 &NumberKillFrenziesPassed;
|
||||||
static int32 &PeopleKilledByOthers;
|
static int32 &PeopleKilledByOthers;
|
||||||
|
static int32 &HelisDestroyed;
|
||||||
|
static int32 *PedsKilledOfThisType; //[NUM_PEDTYPES]
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void AnotherKillFrenzyPassed();
|
static void AnotherKillFrenzyPassed();
|
||||||
|
@ -77,6 +77,8 @@ public:
|
|||||||
void ReportCrimeNow(eCrimeType type, const CVector &coors, bool policeDoesntCare);
|
void ReportCrimeNow(eCrimeType type, const CVector &coors, bool policeDoesntCare);
|
||||||
void UpdateWantedLevel();
|
void UpdateWantedLevel();
|
||||||
|
|
||||||
|
bool IsIgnored(void) { return m_bIgnoredByCops || m_bIgnoredByEveryone; }
|
||||||
|
|
||||||
static int32 WorkOutPolicePresence(CVector posn, float radius);
|
static int32 WorkOutPolicePresence(CVector posn, float radius);
|
||||||
static void SetMaximumWantedLevel(int32 level);
|
static void SetMaximumWantedLevel(int32 level);
|
||||||
};
|
};
|
||||||
|
@ -646,7 +646,7 @@ CWorld::FindObjectsInRange(CVector ¢re, float distance, bool ignoreZ, short
|
|||||||
}
|
}
|
||||||
|
|
||||||
CEntity*
|
CEntity*
|
||||||
CWorld::TestSphereAgainstWorld(CVector centre, float distance, CEntity* entityToIgnore, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSomeObjects)
|
CWorld::TestSphereAgainstWorld(CVector centre, float distance, CEntity *entityToIgnore, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSomeObjects)
|
||||||
{
|
{
|
||||||
CEntity* foundE = nil;
|
CEntity* foundE = nil;
|
||||||
|
|
||||||
|
@ -95,8 +95,8 @@ public:
|
|||||||
static bool GetIsLineOfSightSectorClear(CSector §or, const CColLine &line, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
|
static bool GetIsLineOfSightSectorClear(CSector §or, const CColLine &line, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
|
||||||
static bool GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
|
static bool GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
|
||||||
|
|
||||||
static CEntity* TestSphereAgainstWorld(CVector, float, CEntity*, bool, bool, bool, bool, bool, bool);
|
static CEntity *TestSphereAgainstWorld(CVector centre, float distance, CEntity *entityToIgnore, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSomeObjects);
|
||||||
static CEntity* TestSphereAgainstSectorList(CPtrList&, CVector, float, CEntity*, bool);
|
static CEntity *TestSphereAgainstSectorList(CPtrList&, CVector, float, CEntity*, bool);
|
||||||
static void FindObjectsInRangeSectorList(CPtrList&, CVector&, float, bool, short*, short, CEntity**);
|
static void FindObjectsInRangeSectorList(CPtrList&, CVector&, float, bool, short*, short, CEntity**);
|
||||||
static void FindObjectsInRange(CVector&, float, bool, short*, short, CEntity**, bool, bool, bool, bool, bool);
|
static void FindObjectsInRange(CVector&, float, bool, short*, short, CEntity**, bool, bool, bool, bool, bool);
|
||||||
static float FindGroundZForCoord(float x, float y);
|
static float FindGroundZForCoord(float x, float y);
|
||||||
|
@ -197,7 +197,7 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con
|
|||||||
|
|
||||||
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
#define ABS(a) (((a) < 0) ? (-a) : (a))
|
#define ABS(a) (((a) < 0) ? (-(a)) : (a))
|
||||||
#define norm(value, min, max) (((value) < (min)) ? 0 : (((value) > (max)) ? 1 : (((value) - (min)) / ((max) - (min)))))
|
#define norm(value, min, max) (((value) < (min)) ? 0 : (((value) > (max)) ? 1 : (((value) - (min)) / ((max) - (min)))))
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,6 +33,12 @@ enum Config {
|
|||||||
|
|
||||||
NUMTEMPOBJECTS = 30,
|
NUMTEMPOBJECTS = 30,
|
||||||
|
|
||||||
|
// Path data
|
||||||
|
NUM_PATHNODES = 4930,
|
||||||
|
NUM_CARPATHLINKS = 2076,
|
||||||
|
NUM_MAPOBJECTS = 1250,
|
||||||
|
NUM_PATHCONNECTIONS = 10260,
|
||||||
|
|
||||||
// Link list lengths
|
// Link list lengths
|
||||||
// TODO: alpha list
|
// TODO: alpha list
|
||||||
NUMCOLCACHELINKS = 200,
|
NUMCOLCACHELINKS = 200,
|
||||||
|
@ -14,7 +14,9 @@
|
|||||||
#include "Streaming.h"
|
#include "Streaming.h"
|
||||||
#include "PathFind.h"
|
#include "PathFind.h"
|
||||||
#include "Boat.h"
|
#include "Boat.h"
|
||||||
|
#include "Heli.h"
|
||||||
#include "Automobile.h"
|
#include "Automobile.h"
|
||||||
|
#include "Ped.h"
|
||||||
#include "debugmenu_public.h"
|
#include "debugmenu_public.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -137,6 +139,20 @@ SpawnCar(int id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
LetThemFollowYou(void) {
|
||||||
|
CPed* player = (CPed*) FindPlayerPed();
|
||||||
|
for (int i = 0; i < player->m_numNearPeds; i++) {
|
||||||
|
|
||||||
|
CPed* nearPed = player->m_nearPeds[i];
|
||||||
|
if (nearPed && !nearPed->IsPlayer()) {
|
||||||
|
nearPed->SetObjective(OBJECTIVE_FOLLOW_PED_IN_FORMATION, (void*)player);
|
||||||
|
nearPed->m_pedFormation = rand() & 7;
|
||||||
|
nearPed->bScriptObjectiveCompleted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
FixCar(void)
|
FixCar(void)
|
||||||
{
|
{
|
||||||
@ -318,6 +334,12 @@ DebugMenuPopulate(void)
|
|||||||
DebugMenuAddCmd("Debug", "Toggle Comedy Controls", ToggleComedy);
|
DebugMenuAddCmd("Debug", "Toggle Comedy Controls", ToggleComedy);
|
||||||
DebugMenuAddCmd("Debug", "Place Car on Road", PlaceOnRoad);
|
DebugMenuAddCmd("Debug", "Place Car on Road", PlaceOnRoad);
|
||||||
|
|
||||||
|
DebugMenuAddVarBool8("Debug", "Catalina Heli On", (int8*)&CHeli::CatalinaHeliOn, nil);
|
||||||
|
DebugMenuAddCmd("Debug", "Catalina Fly By", CHeli::StartCatalinaFlyBy);
|
||||||
|
DebugMenuAddCmd("Debug", "Catalina Take Off", CHeli::CatalinaTakeOff);
|
||||||
|
DebugMenuAddCmd("Debug", "Catalina Fly Away", CHeli::MakeCatalinaHeliFlyAway);
|
||||||
|
DebugMenuAddVarBool8("Debug", "Script Heli On", (int8*)0x95CD43, nil);
|
||||||
|
|
||||||
DebugMenuAddVarBool8("Debug", "Show Ped Road Groups", (int8*)&gbShowPedRoadGroups, nil);
|
DebugMenuAddVarBool8("Debug", "Show Ped Road Groups", (int8*)&gbShowPedRoadGroups, nil);
|
||||||
DebugMenuAddVarBool8("Debug", "Show Car Road Groups", (int8*)&gbShowCarRoadGroups, nil);
|
DebugMenuAddVarBool8("Debug", "Show Car Road Groups", (int8*)&gbShowCarRoadGroups, nil);
|
||||||
DebugMenuAddVarBool8("Debug", "Show Collision Lines", (int8*)&gbShowCollisionLines, nil);
|
DebugMenuAddVarBool8("Debug", "Show Collision Lines", (int8*)&gbShowCollisionLines, nil);
|
||||||
@ -328,6 +350,11 @@ DebugMenuPopulate(void)
|
|||||||
DebugMenuAddVarBool8("Debug", "Don't render Vehicles", (int8*)&gbDontRenderVehicles, nil);
|
DebugMenuAddVarBool8("Debug", "Don't render Vehicles", (int8*)&gbDontRenderVehicles, nil);
|
||||||
DebugMenuAddVarBool8("Debug", "Don't render Objects", (int8*)&gbDontRenderObjects, nil);
|
DebugMenuAddVarBool8("Debug", "Don't render Objects", (int8*)&gbDontRenderObjects, nil);
|
||||||
|
|
||||||
|
DebugMenuAddCmd("Debug", "Make peds around you follow you", LetThemFollowYou);
|
||||||
|
#ifndef FINAL
|
||||||
|
DebugMenuAddVarBool8("Debug", "Toggle unused fight feature", (int8*)&CPed::bUnusedFightThingOnPlayer, nil);
|
||||||
|
#endif
|
||||||
|
|
||||||
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);
|
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);
|
||||||
DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop);
|
DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop);
|
||||||
|
|
||||||
@ -347,29 +374,6 @@ delayedPatches10(int a, int b)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void __declspec(naked) HeadlightsFix()
|
|
||||||
{
|
|
||||||
static const float fMinusOne = -1.0f;
|
|
||||||
_asm
|
|
||||||
{
|
|
||||||
fld [esp+708h-690h]
|
|
||||||
fcomp fMinusOne
|
|
||||||
fnstsw ax
|
|
||||||
and ah, 5
|
|
||||||
cmp ah, 1
|
|
||||||
jnz HeadlightsFix_DontLimit
|
|
||||||
fld fMinusOne
|
|
||||||
fstp [esp+708h-690h]
|
|
||||||
|
|
||||||
HeadlightsFix_DontLimit:
|
|
||||||
fld [esp+708h-690h]
|
|
||||||
fabs
|
|
||||||
fld st
|
|
||||||
push 0x5382F2
|
|
||||||
retn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const int re3_buffsize = 1024;
|
const int re3_buffsize = 1024;
|
||||||
static char re3_buff[re3_buffsize];
|
static char re3_buff[re3_buffsize];
|
||||||
|
|
||||||
@ -454,10 +458,6 @@ patch()
|
|||||||
InjectHook(0x475E00, printf, PATCH_JUMP); // _Error
|
InjectHook(0x475E00, printf, PATCH_JUMP); // _Error
|
||||||
|
|
||||||
|
|
||||||
// stolen from silentpatch (sorry)
|
|
||||||
Patch<WORD>(0x5382BF, 0x0EEB);
|
|
||||||
InjectHook(0x5382EC, HeadlightsFix, PATCH_JUMP);
|
|
||||||
|
|
||||||
// InterceptCall(&open_script_orig, open_script, 0x438869);
|
// InterceptCall(&open_script_orig, open_script, 0x438869);
|
||||||
|
|
||||||
// InterceptCall(&RsEventHandler_orig, delayedPatches10, 0x58275E);
|
// InterceptCall(&RsEventHandler_orig, delayedPatches10, 0x58275E);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "ParticleObject.h"
|
#include "ParticleObject.h"
|
||||||
#include "Particle.h"
|
#include "Particle.h"
|
||||||
#include "SurfaceTable.h"
|
#include "SurfaceTable.h"
|
||||||
|
#include "PathFind.h"
|
||||||
#include "CarCtrl.h"
|
#include "CarCtrl.h"
|
||||||
#include "DMAudio.h"
|
#include "DMAudio.h"
|
||||||
#include "Automobile.h"
|
#include "Automobile.h"
|
||||||
@ -56,13 +57,13 @@ CPhysical::CPhysical(void)
|
|||||||
m_phy_flagA80 = false;
|
m_phy_flagA80 = false;
|
||||||
|
|
||||||
m_fDistanceTravelled = 0.0f;
|
m_fDistanceTravelled = 0.0f;
|
||||||
m_pedTreadable = nil;
|
m_treadable[PATH_CAR] = nil;
|
||||||
m_carTreadable = nil;
|
m_treadable[PATH_PED] = nil;
|
||||||
|
|
||||||
m_phy_flagA10 = false;
|
m_phy_flagA10 = false;
|
||||||
m_phy_flagA20 = false;
|
m_phy_flagA20 = false;
|
||||||
|
|
||||||
m_nSurfaceTouched = SURFACE_DEFAULT;
|
m_nZoneLevel = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPhysical::~CPhysical(void)
|
CPhysical::~CPhysical(void)
|
||||||
@ -267,16 +268,16 @@ CPhysical::AddCollisionRecord_Treadable(CEntity *ent)
|
|||||||
{
|
{
|
||||||
if(ent->IsBuilding() && ((CBuilding*)ent)->GetIsATreadable()){
|
if(ent->IsBuilding() && ((CBuilding*)ent)->GetIsATreadable()){
|
||||||
CTreadable *t = (CTreadable*)ent;
|
CTreadable *t = (CTreadable*)ent;
|
||||||
if(t->m_nodeIndicesPeds[0] >= 0 ||
|
if(t->m_nodeIndices[PATH_PED][0] >= 0 ||
|
||||||
t->m_nodeIndicesPeds[1] >= 0 ||
|
t->m_nodeIndices[PATH_PED][1] >= 0 ||
|
||||||
t->m_nodeIndicesPeds[2] >= 0 ||
|
t->m_nodeIndices[PATH_PED][2] >= 0 ||
|
||||||
t->m_nodeIndicesPeds[3] >= 0)
|
t->m_nodeIndices[PATH_PED][3] >= 0)
|
||||||
m_pedTreadable = t;
|
m_treadable[PATH_PED] = t;
|
||||||
if(t->m_nodeIndicesCars[0] >= 0 ||
|
if(t->m_nodeIndices[PATH_CAR][0] >= 0 ||
|
||||||
t->m_nodeIndicesCars[1] >= 0 ||
|
t->m_nodeIndices[PATH_CAR][1] >= 0 ||
|
||||||
t->m_nodeIndicesCars[2] >= 0 ||
|
t->m_nodeIndices[PATH_CAR][2] >= 0 ||
|
||||||
t->m_nodeIndicesCars[3] >= 0)
|
t->m_nodeIndices[PATH_CAR][3] >= 0)
|
||||||
m_carTreadable = t;
|
m_treadable[PATH_CAR] = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,8 +19,7 @@ public:
|
|||||||
|
|
||||||
int32 m_audioEntityId;
|
int32 m_audioEntityId;
|
||||||
float unk1;
|
float unk1;
|
||||||
CTreadable *m_carTreadable;
|
CTreadable *m_treadable[2]; // car and ped
|
||||||
CTreadable *m_pedTreadable;
|
|
||||||
uint32 m_nLastTimeCollided;
|
uint32 m_nLastTimeCollided;
|
||||||
CVector m_vecMoveSpeed; // velocity
|
CVector m_vecMoveSpeed; // velocity
|
||||||
CVector m_vecTurnSpeed; // angular velocity
|
CVector m_vecTurnSpeed; // angular velocity
|
||||||
@ -115,6 +114,9 @@ public:
|
|||||||
m_vecMoveSpeed.y = y;
|
m_vecMoveSpeed.y = y;
|
||||||
m_vecMoveSpeed.z = z;
|
m_vecMoveSpeed.z = z;
|
||||||
}
|
}
|
||||||
|
void SetMoveSpeed(const CVector& speed) {
|
||||||
|
m_vecMoveSpeed = speed;
|
||||||
|
}
|
||||||
const CVector &GetTurnSpeed() { return m_vecTurnSpeed; }
|
const CVector &GetTurnSpeed() { return m_vecTurnSpeed; }
|
||||||
void SetTurnSpeed(float x, float y, float z) {
|
void SetTurnSpeed(float x, float y, float z) {
|
||||||
m_vecTurnSpeed.x = x;
|
m_vecTurnSpeed.x = x;
|
||||||
|
@ -8,8 +8,7 @@ public:
|
|||||||
static void *operator new(size_t);
|
static void *operator new(size_t);
|
||||||
static void operator delete(void*, size_t);
|
static void operator delete(void*, size_t);
|
||||||
|
|
||||||
int16 m_nodeIndicesCars[12];
|
int16 m_nodeIndices[2][12]; // first car, then ped
|
||||||
int16 m_nodeIndicesPeds[12];
|
|
||||||
|
|
||||||
bool GetIsATreadable(void) { return true; }
|
bool GetIsATreadable(void) { return true; }
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,30 @@ public:
|
|||||||
x *= invsqrt;
|
x *= invsqrt;
|
||||||
y *= invsqrt;
|
y *= invsqrt;
|
||||||
}else
|
}else
|
||||||
x = 0.0f;
|
x = 1.0f;
|
||||||
|
}
|
||||||
|
const CVector2D &operator+=(CVector2D const &right) {
|
||||||
|
x += right.x;
|
||||||
|
y += right.y;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CVector2D &operator-=(CVector2D const &right) {
|
||||||
|
x -= right.x;
|
||||||
|
y -= right.y;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CVector2D &operator*=(float right) {
|
||||||
|
x *= right;
|
||||||
|
y *= right;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CVector2D &operator/=(float right) {
|
||||||
|
x /= right;
|
||||||
|
y /= right;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
CVector2D operator-(const CVector2D &rhs) const {
|
CVector2D operator-(const CVector2D &rhs) const {
|
||||||
return CVector2D(x-rhs.x, y-rhs.y);
|
return CVector2D(x-rhs.x, y-rhs.y);
|
||||||
@ -29,6 +52,9 @@ public:
|
|||||||
CVector2D operator*(float t) const {
|
CVector2D operator*(float t) const {
|
||||||
return CVector2D(x*t, y*t);
|
return CVector2D(x*t, y*t);
|
||||||
}
|
}
|
||||||
|
CVector2D operator/(float t) const {
|
||||||
|
return CVector2D(x/t, y/t);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline float
|
inline float
|
||||||
@ -42,3 +68,26 @@ CrossProduct2D(const CVector2D &v1, const CVector2D &v2)
|
|||||||
{
|
{
|
||||||
return v1.x*v2.y - v1.y*v2.x;
|
return v1.x*v2.y - v1.y*v2.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline float
|
||||||
|
Distance2D(const CVector2D &v, float x, float y)
|
||||||
|
{
|
||||||
|
return Sqrt((v.x-x)*(v.x-x) + (v.y-y)*(v.y-y));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float
|
||||||
|
DistanceSqr2D(const CVector2D &v, float x, float y)
|
||||||
|
{
|
||||||
|
return (v.x-x)*(v.x-x) + (v.y-y)*(v.y-y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
NormalizeXY(float &x, float &y)
|
||||||
|
{
|
||||||
|
float l = Sqrt(x*x + y*y);
|
||||||
|
if(l != 0.0f){
|
||||||
|
x /= l;
|
||||||
|
y /= l;
|
||||||
|
}else
|
||||||
|
x = 1.0f;
|
||||||
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "Automobile.h"
|
#include "Automobile.h"
|
||||||
#include "Train.h"
|
#include "Train.h"
|
||||||
#include "Plane.h"
|
#include "Plane.h"
|
||||||
|
#include "Heli.h"
|
||||||
#include "ModelIndices.h"
|
#include "ModelIndices.h"
|
||||||
#include "ModelInfo.h"
|
#include "ModelInfo.h"
|
||||||
|
|
||||||
@ -98,13 +99,13 @@ RwObjectNameIdAssocation trainIds[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
RwObjectNameIdAssocation heliIds[] = {
|
RwObjectNameIdAssocation heliIds[] = {
|
||||||
{ "chassis_dummy", 1, VEHICLE_FLAG_COLLAPSE },
|
{ "chassis_dummy", HELI_CHASSIS, VEHICLE_FLAG_COLLAPSE },
|
||||||
{ "toprotor", 2, 0 },
|
{ "toprotor", HELI_TOPROTOR, 0 },
|
||||||
{ "backrotor", 3, 0 },
|
{ "backrotor", HELI_BACKROTOR, 0 },
|
||||||
{ "tail", 4, 0 },
|
{ "tail", HELI_TAIL, 0 },
|
||||||
{ "topknot", 5, 0 },
|
{ "topknot", HELI_TOPKNOT, 0 },
|
||||||
{ "skid_left", 6, 0 },
|
{ "skid_left", HELI_SKID_LEFT, 0 },
|
||||||
{ "skid_right", 7, 0 },
|
{ "skid_right", HELI_SKID_RIGHT, 0 },
|
||||||
{ nil, 0, 0 }
|
{ nil, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
2260
src/peds/Ped.cpp
2260
src/peds/Ped.cpp
File diff suppressed because it is too large
Load Diff
@ -22,6 +22,20 @@ struct CPedAudioData
|
|||||||
int m_nMaxRandomDelayTime;
|
int m_nMaxRandomDelayTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ENDFIGHT_NORMAL,
|
||||||
|
ENDFIGHT_WITH_A_STEP,
|
||||||
|
ENDFIGHT_FAST
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PedRouteType
|
||||||
|
{
|
||||||
|
PEDROUTE_STOP_WHEN_DONE = 1,
|
||||||
|
PEDROUTE_GO_BACKWARD_WHEN_DONE,
|
||||||
|
PEDROUTE_GO_TO_START_WHEN_DONE
|
||||||
|
};
|
||||||
|
|
||||||
struct FightMove
|
struct FightMove
|
||||||
{
|
{
|
||||||
AnimationId animId;
|
AnimationId animId;
|
||||||
@ -152,7 +166,7 @@ enum PedLineUpPhase {
|
|||||||
|
|
||||||
enum PedOnGroundState {
|
enum PedOnGroundState {
|
||||||
NO_PED,
|
NO_PED,
|
||||||
PED_BELOW_PLAYER,
|
PED_IN_FRONT_OF_ATTACKER,
|
||||||
PED_ON_THE_FLOOR,
|
PED_ON_THE_FLOOR,
|
||||||
PED_DEAD_ON_THE_FLOOR
|
PED_DEAD_ON_THE_FLOOR
|
||||||
};
|
};
|
||||||
@ -241,7 +255,7 @@ public:
|
|||||||
// cf. https://github.com/DK22Pac/plugin-sdk/blob/master/plugin_sa/game_sa/CPed.h from R*
|
// cf. https://github.com/DK22Pac/plugin-sdk/blob/master/plugin_sa/game_sa/CPed.h from R*
|
||||||
uint8 bIsStanding : 1;
|
uint8 bIsStanding : 1;
|
||||||
uint8 m_ped_flagA2 : 1;
|
uint8 m_ped_flagA2 : 1;
|
||||||
uint8 m_ped_flagA4 : 1; // stores (CTimer::GetTimeInMilliseconds() < m_lastHitTime)
|
uint8 bIsAttacking : 1; // doesn't reset after fist fight, also stores (CTimer::GetTimeInMilliseconds() < m_lastHitTime)
|
||||||
uint8 bIsPointingGunAt : 1;
|
uint8 bIsPointingGunAt : 1;
|
||||||
uint8 bIsLooking : 1;
|
uint8 bIsLooking : 1;
|
||||||
uint8 m_ped_flagA20 : 1; // "look" method? - probably missing in SA
|
uint8 m_ped_flagA20 : 1; // "look" method? - probably missing in SA
|
||||||
@ -253,7 +267,7 @@ public:
|
|||||||
uint8 bIsTalking : 1;
|
uint8 bIsTalking : 1;
|
||||||
uint8 bIsInTheAir : 1;
|
uint8 bIsInTheAir : 1;
|
||||||
uint8 bIsLanding : 1;
|
uint8 bIsLanding : 1;
|
||||||
uint8 m_ped_flagB20 : 1;
|
uint8 bIsRunning : 1; // not fleeing
|
||||||
uint8 m_ped_flagB40 : 1;
|
uint8 m_ped_flagB40 : 1;
|
||||||
uint8 m_ped_flagB80 : 1;
|
uint8 m_ped_flagB80 : 1;
|
||||||
|
|
||||||
@ -296,7 +310,7 @@ public:
|
|||||||
uint8 m_ped_flagG1 : 1;
|
uint8 m_ped_flagG1 : 1;
|
||||||
uint8 m_ped_flagG2 : 1;
|
uint8 m_ped_flagG2 : 1;
|
||||||
uint8 m_ped_flagG4 : 1;
|
uint8 m_ped_flagG4 : 1;
|
||||||
uint8 m_ped_flagG8 : 1;
|
uint8 m_ped_flagG8 : 1; // ped starts to go somewhere when set
|
||||||
uint8 m_ped_flagG10 : 1;
|
uint8 m_ped_flagG10 : 1;
|
||||||
uint8 m_ped_flagG20 : 1;
|
uint8 m_ped_flagG20 : 1;
|
||||||
uint8 m_ped_flagG40 : 1;
|
uint8 m_ped_flagG40 : 1;
|
||||||
@ -328,9 +342,7 @@ public:
|
|||||||
eObjective m_prevObjective;
|
eObjective m_prevObjective;
|
||||||
CPed *m_pedInObjective;
|
CPed *m_pedInObjective;
|
||||||
CVehicle *m_carInObjective;
|
CVehicle *m_carInObjective;
|
||||||
uint32 field_174;
|
CVector m_nextRoutePointPos;
|
||||||
uint32 field_178;
|
|
||||||
uint32 field_17C;
|
|
||||||
CPed *m_leader;
|
CPed *m_leader;
|
||||||
uint32 m_pedFormation;
|
uint32 m_pedFormation;
|
||||||
uint32 m_fearFlags;
|
uint32 m_fearFlags;
|
||||||
@ -363,15 +375,15 @@ public:
|
|||||||
private:
|
private:
|
||||||
int8 _pad2B5[3];
|
int8 _pad2B5[3];
|
||||||
public:
|
public:
|
||||||
CPathNode *m_pNextPathNode;
|
|
||||||
CPathNode *m_pLastPathNode;
|
CPathNode *m_pLastPathNode;
|
||||||
|
CPathNode *m_pNextPathNode;
|
||||||
float m_fHealth;
|
float m_fHealth;
|
||||||
float m_fArmour;
|
float m_fArmour;
|
||||||
int16 m_routeLastPoint;
|
int16 m_routeLastPoint;
|
||||||
uint16 m_routePoints;
|
uint16 m_routeStartPoint;
|
||||||
int16 m_routePos;
|
int16 m_routePointsPassed;
|
||||||
int16 m_routeType;
|
int16 m_routeType;
|
||||||
int16 m_routeCurDir;
|
int16 m_routePointsBeingPassed;
|
||||||
uint16 field_2D2;
|
uint16 field_2D2;
|
||||||
CVector2D m_moved;
|
CVector2D m_moved;
|
||||||
float m_fRotationCur;
|
float m_fRotationCur;
|
||||||
@ -382,12 +394,12 @@ public:
|
|||||||
CEntity *m_pCurrentPhysSurface;
|
CEntity *m_pCurrentPhysSurface;
|
||||||
CVector m_vecOffsetFromPhysSurface;
|
CVector m_vecOffsetFromPhysSurface;
|
||||||
CEntity *m_pCurSurface;
|
CEntity *m_pCurSurface;
|
||||||
CVector m_vecSeekVehicle;
|
CVector m_vecSeekPos;
|
||||||
CEntity *m_pSeekTarget;
|
CEntity *m_pSeekTarget;
|
||||||
CVehicle *m_pMyVehicle;
|
CVehicle *m_pMyVehicle;
|
||||||
bool bInVehicle;
|
bool bInVehicle;
|
||||||
uint8 pad_315[3];
|
uint8 pad_315[3];
|
||||||
float field_318;
|
float m_distanceToCountSeekDone;
|
||||||
bool bRunningToPhone;
|
bool bRunningToPhone;
|
||||||
uint8 field_31D;
|
uint8 field_31D;
|
||||||
int16 m_phoneId;
|
int16 m_phoneId;
|
||||||
@ -400,8 +412,8 @@ public:
|
|||||||
float m_fleeFromPosY;
|
float m_fleeFromPosY;
|
||||||
CEntity *m_fleeFrom;
|
CEntity *m_fleeFrom;
|
||||||
uint32 m_fleeTimer;
|
uint32 m_fleeTimer;
|
||||||
uint32 field_344;
|
CEntity* m_collidingEntityWhileFleeing;
|
||||||
uint32 m_lastThreatTimer;
|
uint32 m_collidingThingTimer;
|
||||||
CEntity *m_pCollidingEntity;
|
CEntity *m_pCollidingEntity;
|
||||||
uint8 m_stateUnused;
|
uint8 m_stateUnused;
|
||||||
uint8 pad_351[3];
|
uint8 pad_351[3];
|
||||||
@ -418,7 +430,7 @@ public:
|
|||||||
PedFightMoves m_lastFightMove;
|
PedFightMoves m_lastFightMove;
|
||||||
uint8 m_fightButtonPressure;
|
uint8 m_fightButtonPressure;
|
||||||
int8 m_fightUnk2; // TODO
|
int8 m_fightUnk2; // TODO
|
||||||
uint8 m_fightUnk1; // TODO
|
bool m_takeAStepAfterAttack;
|
||||||
uint8 pad_4B3;
|
uint8 pad_4B3;
|
||||||
CFire *m_pFire;
|
CFire *m_pFire;
|
||||||
CEntity *m_pLookTarget;
|
CEntity *m_pLookTarget;
|
||||||
@ -429,7 +441,7 @@ public:
|
|||||||
uint32 m_lookTimer;
|
uint32 m_lookTimer;
|
||||||
uint32 m_standardTimer;
|
uint32 m_standardTimer;
|
||||||
uint32 m_attackTimer;
|
uint32 m_attackTimer;
|
||||||
uint32 m_lastHitTime;
|
uint32 m_lastHitTime; // obviously not correct
|
||||||
uint32 m_hitRecoverTimer;
|
uint32 m_hitRecoverTimer;
|
||||||
uint32 m_objectiveTimer;
|
uint32 m_objectiveTimer;
|
||||||
uint32 m_duckTimer;
|
uint32 m_duckTimer;
|
||||||
@ -560,7 +572,6 @@ public:
|
|||||||
void SetEvasiveDive(CPhysical*, uint8);
|
void SetEvasiveDive(CPhysical*, uint8);
|
||||||
void SetAttack(CEntity*);
|
void SetAttack(CEntity*);
|
||||||
void StartFightAttack(uint8);
|
void StartFightAttack(uint8);
|
||||||
void LoadFightData(void);
|
|
||||||
void SetWaitState(eWaitState, void*);
|
void SetWaitState(eWaitState, void*);
|
||||||
bool FightStrike(CVector&);
|
bool FightStrike(CVector&);
|
||||||
int GetLocalDirection(CVector2D&);
|
int GetLocalDirection(CVector2D&);
|
||||||
@ -583,11 +594,38 @@ public:
|
|||||||
void MakeTyresMuddySectorList(CPtrList&);
|
void MakeTyresMuddySectorList(CPtrList&);
|
||||||
uint8 DoesLOSBulletHitPed(CColPoint &point);
|
uint8 DoesLOSBulletHitPed(CColPoint &point);
|
||||||
bool DuckAndCover(void);
|
bool DuckAndCover(void);
|
||||||
|
void EndFight(uint8);
|
||||||
|
void EnterCar(void);
|
||||||
|
uint8 GetNearestTrainPedPosition(CVehicle*, CVector&);
|
||||||
|
uint8 GetNearestTrainDoor(CVehicle*, CVector&);
|
||||||
|
void LineUpPedWithTrain(void);
|
||||||
|
void ExitCar(void);
|
||||||
|
void Fight(void);
|
||||||
|
bool FindBestCoordsFromNodes(CVector unused, CVector* a6);
|
||||||
|
void Wait(void);
|
||||||
|
void ProcessObjective(void);
|
||||||
|
bool SeekFollowingPath(CVector*);
|
||||||
|
void Flee(void);
|
||||||
|
void FollowPath(void);
|
||||||
|
CVector GetFormationPosition(void);
|
||||||
|
void GetNearestDoor(CVehicle*, CVector&);
|
||||||
|
bool GetNearestPassengerDoor(CVehicle*, CVector&);
|
||||||
|
int GetNextPointOnRoute(void);
|
||||||
|
uint8 GetPedRadioCategory(uint32);
|
||||||
|
int GetWeaponSlot(eWeaponType);
|
||||||
|
void GoToNearestDoor(CVehicle*);
|
||||||
|
bool HaveReachedNextPointOnRoute(float a2);
|
||||||
|
void Idle(void);
|
||||||
|
void InTheAir(void);
|
||||||
|
void SetLanding(void);
|
||||||
|
|
||||||
// Static methods
|
// Static methods
|
||||||
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset);
|
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, float seatPosMult);
|
||||||
static CVector GetPositionToOpenCarDoor(CVehicle* veh, uint32 component);
|
static CVector GetPositionToOpenCarDoor(CVehicle* veh, uint32 component);
|
||||||
|
static void Initialise(void);
|
||||||
|
static void SetAnimOffsetForEnterOrExitVehicle(void);
|
||||||
|
static void LoadFightData(void);
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
static RwObject *SetPedAtomicVisibilityCB(RwObject *object, void *data);
|
static RwObject *SetPedAtomicVisibilityCB(RwObject *object, void *data);
|
||||||
@ -640,6 +678,9 @@ public:
|
|||||||
void SetPedStats(ePedStats);
|
void SetPedStats(ePedStats);
|
||||||
bool IsGangMember(void);
|
bool IsGangMember(void);
|
||||||
void Die(void);
|
void Die(void);
|
||||||
|
void EnterTrain(void);
|
||||||
|
void ExitTrain(void);
|
||||||
|
void Fall(void);
|
||||||
|
|
||||||
bool HasWeapon(uint8 weaponType) { return m_weapons[weaponType].m_eWeaponType == weaponType; }
|
bool HasWeapon(uint8 weaponType) { return m_weapons[weaponType].m_eWeaponType == weaponType; }
|
||||||
CWeapon &GetWeapon(uint8 weaponType) { return m_weapons[weaponType]; }
|
CWeapon &GetWeapon(uint8 weaponType) { return m_weapons[weaponType]; }
|
||||||
@ -649,18 +690,17 @@ public:
|
|||||||
void SetPedState(PedState state) { m_nPedState = state; }
|
void SetPedState(PedState state) { m_nPedState = state; }
|
||||||
|
|
||||||
// set by 0482:set_threat_reaction_range_multiplier opcode
|
// set by 0482:set_threat_reaction_range_multiplier opcode
|
||||||
static uint16 &distanceMultToCountPedNear;
|
static uint16 &nThreatReactionRangeMultiplier;
|
||||||
|
|
||||||
static CVector &offsetToOpenRegularCarDoor;
|
|
||||||
static CVector &offsetToOpenLowCarDoor;
|
|
||||||
static CVector &offsetToOpenVanDoor;
|
|
||||||
static bool &bNastyLimbsCheat;
|
static bool &bNastyLimbsCheat;
|
||||||
static bool &bPedCheat2;
|
static bool &bPedCheat2;
|
||||||
static bool &bPedCheat3;
|
static bool &bPedCheat3;
|
||||||
static CColPoint &ms_tempColPoint;
|
static CVector2D &ms_vec2DFleePosition;
|
||||||
static uint16 &unknownFightThing; // TODO
|
static CPedAudioData (&CommentWaitTime)[38];
|
||||||
static FightMove (&ms_fightMoves)[24];
|
|
||||||
static CPedAudioData (&PedAudioData)[38];
|
#ifndef FINAL
|
||||||
|
static bool bUnusedFightThingOnPlayer;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void FinishFuckUCB(CAnimBlendAssociation *assoc, void *arg);
|
void FinishFuckUCB(CAnimBlendAssociation *assoc, void *arg);
|
||||||
|
6
src/peds/PedRoutes.cpp
Normal file
6
src/peds/PedRoutes.cpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "PedRoutes.h"
|
||||||
|
|
||||||
|
WRAPPER int16 CRouteNode::GetRouteThisPointIsOn(int16) { EAXJMP(0x4EE7A0); }
|
7
src/peds/PedRoutes.h
Normal file
7
src/peds/PedRoutes.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class CRouteNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static int16 GetRouteThisPointIsOn(int16 point);
|
||||||
|
};
|
@ -200,9 +200,9 @@ CRenderer::RenderRoads(void)
|
|||||||
if(gbShowCarRoadGroups || gbShowPedRoadGroups){
|
if(gbShowCarRoadGroups || gbShowPedRoadGroups){
|
||||||
int ind = 0;
|
int ind = 0;
|
||||||
if(gbShowCarRoadGroups)
|
if(gbShowCarRoadGroups)
|
||||||
ind += ThePaths.m_pathNodes[t->m_nodeIndicesCars[0]].group;
|
ind += ThePaths.m_pathNodes[t->m_nodeIndices[PATH_CAR][0]].group;
|
||||||
if(gbShowPedRoadGroups)
|
if(gbShowPedRoadGroups)
|
||||||
ind += ThePaths.m_pathNodes[t->m_nodeIndicesPeds[0]].group;
|
ind += ThePaths.m_pathNodes[t->m_nodeIndices[PATH_PED][0]].group;
|
||||||
SetAmbientColoursToIndicateRoadGroup(ind);
|
SetAmbientColoursToIndicateRoadGroup(ind);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -312,7 +312,7 @@ CAutomobile::ProcessControl(void)
|
|||||||
CVisibilityPlugins::SetClumpAlpha((RpClump*)m_rwObject, clumpAlpha);
|
CVisibilityPlugins::SetClumpAlpha((RpClump*)m_rwObject, clumpAlpha);
|
||||||
|
|
||||||
AutoPilot.m_flag1 = false;
|
AutoPilot.m_flag1 = false;
|
||||||
AutoPilot.m_flag2 = false;
|
AutoPilot.m_bSlowedDownBecauseOfPeds = false;
|
||||||
|
|
||||||
// Set Center of Mass to make car more stable
|
// Set Center of Mass to make car more stable
|
||||||
if(strongGrip1 || bCheat3)
|
if(strongGrip1 || bCheat3)
|
||||||
@ -3930,7 +3930,7 @@ CAutomobile::PlayCarHorn(void)
|
|||||||
void
|
void
|
||||||
CAutomobile::PlayHornIfNecessary(void)
|
CAutomobile::PlayHornIfNecessary(void)
|
||||||
{
|
{
|
||||||
if(AutoPilot.m_flag2 ||
|
if(AutoPilot.m_bSlowedDownBecauseOfPeds ||
|
||||||
AutoPilot.m_flag1)
|
AutoPilot.m_flag1)
|
||||||
if(!HasCarStoppedBecauseOfLight())
|
if(!HasCarStoppedBecauseOfLight())
|
||||||
PlayCarHorn();
|
PlayCarHorn();
|
||||||
|
@ -58,6 +58,14 @@ enum eBombType
|
|||||||
CARBOMB_ONIGNITIONACTIVE,
|
CARBOMB_ONIGNITIONACTIVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CAR_DOOR_FLAG_UNKNOWN = 0x0,
|
||||||
|
CAR_DOOR_FLAG_LF = 0x1,
|
||||||
|
CAR_DOOR_FLAG_LR = 0x2,
|
||||||
|
CAR_DOOR_FLAG_RF = 0x4,
|
||||||
|
CAR_DOOR_FLAG_RR = 0x8
|
||||||
|
};
|
||||||
|
|
||||||
class CAutomobile : public CVehicle
|
class CAutomobile : public CVehicle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -189,14 +197,14 @@ static_assert(sizeof(CAutomobile) == 0x5A8, "CAutomobile: error");
|
|||||||
inline uint8 GetCarDoorFlag(int32 carnode) {
|
inline uint8 GetCarDoorFlag(int32 carnode) {
|
||||||
switch (carnode) {
|
switch (carnode) {
|
||||||
case CAR_DOOR_LF:
|
case CAR_DOOR_LF:
|
||||||
return 1;
|
return CAR_DOOR_FLAG_LF;
|
||||||
case CAR_DOOR_LR:
|
case CAR_DOOR_LR:
|
||||||
return 2;
|
return CAR_DOOR_FLAG_LR;
|
||||||
case CAR_DOOR_RF:
|
case CAR_DOOR_RF:
|
||||||
return 4;
|
return CAR_DOOR_FLAG_RF;
|
||||||
case CAR_DOOR_RR:
|
case CAR_DOOR_RR:
|
||||||
return 8;
|
return CAR_DOOR_FLAG_RR;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return CAR_DOOR_FLAG_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,15 +2,98 @@
|
|||||||
|
|
||||||
#include "Vehicle.h"
|
#include "Vehicle.h"
|
||||||
|
|
||||||
|
class CObject;
|
||||||
|
|
||||||
|
enum eHeliNodes
|
||||||
|
{
|
||||||
|
HELI_CHASSIS = 1,
|
||||||
|
HELI_TOPROTOR,
|
||||||
|
HELI_BACKROTOR,
|
||||||
|
HELI_TAIL,
|
||||||
|
HELI_TOPKNOT,
|
||||||
|
HELI_SKID_LEFT,
|
||||||
|
HELI_SKID_RIGHT,
|
||||||
|
NUM_HELI_NODES
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
HELI_RANDOM0,
|
||||||
|
HELI_RANDOM1,
|
||||||
|
HELI_SCRIPT,
|
||||||
|
HELI_CATALINA,
|
||||||
|
NUM_HELIS
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
HELI_TYPE_RANDOM,
|
||||||
|
HELI_TYPE_SCRIPT,
|
||||||
|
HELI_TYPE_CATALINA,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class CHeli : public CVehicle
|
class CHeli : public CVehicle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// 0x288
|
// 0x288
|
||||||
uint8 stuff[180];
|
RwFrame *m_aHeliNodes[NUM_HELI_NODES];
|
||||||
|
int8 m_heliStatus;
|
||||||
|
float m_fSearchLightX;
|
||||||
|
float m_fSearchLightY;
|
||||||
|
uint32 m_nExplosionTimer;
|
||||||
|
float m_fRotation;
|
||||||
|
float m_fAngularSpeed;
|
||||||
|
float m_fTargetZ;
|
||||||
|
float m_fSearchLightIntensity;
|
||||||
|
int8 m_nHeliId;
|
||||||
|
int8 m_heliType;
|
||||||
|
int8 m_pathState;
|
||||||
|
float m_aSearchLightHistoryX[6];
|
||||||
|
float m_aSearchLightHistoryY[6];
|
||||||
|
uint32 m_nSearchLightTimer;
|
||||||
|
uint32 m_nShootTimer;
|
||||||
|
uint32 m_nLastShotTime;
|
||||||
|
uint32 m_nBulletDamage;
|
||||||
|
float m_fRotorRotation;
|
||||||
|
float m_fHeliDustZ[8];
|
||||||
|
uint32 m_nPoliceShoutTimer;
|
||||||
|
float m_fTargetOffset;
|
||||||
|
bool m_bTestRight;
|
||||||
|
|
||||||
CHeli(int, uint8);
|
static CHeli **pHelis; //[NUM_HELIS]
|
||||||
|
static int16 &NumRandomHelis;
|
||||||
|
static uint32 &TestForNewRandomHelisTimer;
|
||||||
|
static int16 NumScriptHelis; // unused
|
||||||
|
static bool &CatalinaHeliOn;
|
||||||
|
static bool &CatalinaHasBeenShotDown;
|
||||||
|
static bool &ScriptHeliOn;
|
||||||
|
|
||||||
|
CHeli(int32 id, uint8 CreatedBy);
|
||||||
CHeli* ctor(int, uint8);
|
CHeli* ctor(int, uint8);
|
||||||
|
|
||||||
|
// from CEntity
|
||||||
|
void SetModelIndex(uint32 id);
|
||||||
|
void ProcessControl(void);
|
||||||
|
void PreRender(void);
|
||||||
|
void Render(void);
|
||||||
|
|
||||||
|
void PreRenderAlways(void);
|
||||||
|
CObject *SpawnFlyingComponent(int32 component);
|
||||||
|
|
||||||
|
static void InitHelis(void);
|
||||||
|
static void UpdateHelis(void);
|
||||||
static void SpecialHeliPreRender(void);
|
static void SpecialHeliPreRender(void);
|
||||||
|
static bool TestRocketCollision(CVector *coors);
|
||||||
|
static bool TestBulletCollision(CVector *line0, CVector *line1, CVector *bulletPos, int32 damage);
|
||||||
|
|
||||||
|
static void StartCatalinaFlyBy(void);
|
||||||
|
static void RemoveCatalinaHeli(void);
|
||||||
|
static CHeli *FindPointerToCatalinasHeli(void);
|
||||||
|
static void CatalinaTakeOff(void);
|
||||||
|
static void MakeCatalinaHeliFlyAway(void);
|
||||||
|
static bool HasCatalinaBeenShotDown(void);
|
||||||
|
|
||||||
|
static void ActivateHeli(bool activate);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CHeli) == 0x33C, "CHeli: error");
|
static_assert(sizeof(CHeli) == 0x33C, "CHeli: error");
|
||||||
|
@ -137,15 +137,16 @@ CPlane::ProcessControl(void)
|
|||||||
colors[6] = CRGBA(0, 0, 0, 255);
|
colors[6] = CRGBA(0, 0, 0, 255);
|
||||||
colors[7] = CRGBA(224, 230, 238, 255);
|
colors[7] = CRGBA(224, 230, 238, 255);
|
||||||
|
|
||||||
|
CVector dir;
|
||||||
for(i = 0; i < 40; i++){
|
for(i = 0; i < 40; i++){
|
||||||
int rotSpeed = CGeneral::GetRandomNumberInRange(30.0f, 20.0f);
|
dir.x = CGeneral::GetRandomNumberInRange(-2.0f, 2.0f);
|
||||||
|
dir.y = CGeneral::GetRandomNumberInRange(-2.0f, 2.0f);
|
||||||
|
dir.z = CGeneral::GetRandomNumberInRange(0.0f, 2.0f);
|
||||||
|
int rotSpeed = CGeneral::GetRandomNumberInRange(10, 30);
|
||||||
if(CGeneral::GetRandomNumber() & 1)
|
if(CGeneral::GetRandomNumber() & 1)
|
||||||
rotSpeed = -rotSpeed;
|
rotSpeed = -rotSpeed;
|
||||||
int f = ++nFrameGen & 3;
|
int f = ++nFrameGen & 3;
|
||||||
CParticle::AddParticle(PARTICLE_HELI_DEBRIS, GetMatrix() * CVector(0.0f, 0.0f, 0.0f),
|
CParticle::AddParticle(PARTICLE_HELI_DEBRIS, GetMatrix() * CVector(0.0f, 0.0f, 0.0f), dir,
|
||||||
CVector(CGeneral::GetRandomNumberInRange(-2.0f, 2.0f),
|
|
||||||
CGeneral::GetRandomNumberInRange(-2.0f, 2.0f),
|
|
||||||
CGeneral::GetRandomNumberInRange(0.0f, 2.0f)),
|
|
||||||
nil, CGeneral::GetRandomNumberInRange(0.1f, 1.0f),
|
nil, CGeneral::GetRandomNumberInRange(0.1f, 1.0f),
|
||||||
colors[nFrameGen], rotSpeed, 0, f, 0);
|
colors[nFrameGen], rotSpeed, 0, f, 0);
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ CTrain::SetModelIndex(uint32 id)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
CVehicle::SetModelIndex(id);
|
CVehicle::SetModelIndex(id);
|
||||||
for(i = 0; i < 3; i++)
|
for(i = 0; i < NUM_TRAIN_NODES; i++)
|
||||||
m_aTrainNodes[i] = nil;
|
m_aTrainNodes[i] = nil;
|
||||||
CClumpModelInfo::FillFrameArray(GetClump(), m_aTrainNodes);
|
CClumpModelInfo::FillFrameArray(GetClump(), m_aTrainNodes);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,8 @@ enum
|
|||||||
enum eTrainNodes
|
enum eTrainNodes
|
||||||
{
|
{
|
||||||
TRAIN_DOOR_LHS = 1,
|
TRAIN_DOOR_LHS = 1,
|
||||||
TRAIN_DOOR_RHS
|
TRAIN_DOOR_RHS,
|
||||||
|
NUM_TRAIN_NODES
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eTrainPositions
|
enum eTrainPositions
|
||||||
@ -66,7 +67,7 @@ public:
|
|||||||
uint32 m_nDoorTimer;
|
uint32 m_nDoorTimer;
|
||||||
int16 m_nDoorState;
|
int16 m_nDoorState;
|
||||||
CTrainDoor Doors[2];
|
CTrainDoor Doors[2];
|
||||||
RwFrame *m_aTrainNodes[3];
|
RwFrame *m_aTrainNodes[NUM_TRAIN_NODES];
|
||||||
|
|
||||||
// unused
|
// unused
|
||||||
static CVector aStationCoors[3];
|
static CVector aStationCoors[3];
|
||||||
|
@ -30,6 +30,10 @@ void *CVehicle::operator new(size_t sz, int handle) { return CPools::GetVehicleP
|
|||||||
void CVehicle::operator delete(void *p, size_t sz) { CPools::GetVehiclePool()->Delete((CVehicle*)p); }
|
void CVehicle::operator delete(void *p, size_t sz) { CPools::GetVehiclePool()->Delete((CVehicle*)p); }
|
||||||
void CVehicle::operator delete(void *p, int handle) { CPools::GetVehiclePool()->Delete((CVehicle*)p); }
|
void CVehicle::operator delete(void *p, int handle) { CPools::GetVehiclePool()->Delete((CVehicle*)p); }
|
||||||
|
|
||||||
|
WRAPPER bool CVehicle::ShufflePassengersToMakeSpace(void) { EAXJMP(0x5528A0); }
|
||||||
|
// or Weapon.cpp?
|
||||||
|
WRAPPER void FireOneInstantHitRound(CVector *shotSource, CVector *shotTarget, int32 damage) { EAXJMP(0x563B00); }
|
||||||
|
|
||||||
CVehicle::CVehicle(uint8 CreatedBy)
|
CVehicle::CVehicle(uint8 CreatedBy)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -57,7 +61,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
|
|||||||
pPassengers[i] = nil;
|
pPassengers[i] = nil;
|
||||||
m_nBombTimer = 0;
|
m_nBombTimer = 0;
|
||||||
m_pBlowUpEntity = nil;
|
m_pBlowUpEntity = nil;
|
||||||
field_1FB = 0;
|
m_nPacManPickupsCarried = 0;
|
||||||
bComedyControls = false;
|
bComedyControls = false;
|
||||||
bCraneMessageDone = false;
|
bCraneMessageDone = false;
|
||||||
bExtendedRange = false;
|
bExtendedRange = false;
|
||||||
@ -68,7 +72,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
|
|||||||
m_nTimeOfDeath = 0;
|
m_nTimeOfDeath = 0;
|
||||||
m_pCarFire = nil;
|
m_pCarFire = nil;
|
||||||
bHasBeenOwnedByPlayer = false;
|
bHasBeenOwnedByPlayer = false;
|
||||||
m_veh_flagC20 = false;
|
bCreateRoadBlockPeds = false;
|
||||||
bCanBeDamaged = true;
|
bCanBeDamaged = true;
|
||||||
bUsingSpecialColModel = false;
|
bUsingSpecialColModel = false;
|
||||||
m_veh_flagD1 = false;
|
m_veh_flagD1 = false;
|
||||||
@ -99,7 +103,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
|
|||||||
m_aCollPolys[0].valid = false;
|
m_aCollPolys[0].valid = false;
|
||||||
m_aCollPolys[1].valid = false;
|
m_aCollPolys[1].valid = false;
|
||||||
AutoPilot.m_nCarMission = MISSION_NONE;
|
AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
AutoPilot.m_nAnimationId = TEMPACT_NONE;
|
AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||||
AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
|
AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
|
||||||
AutoPilot.m_flag4 = false;
|
AutoPilot.m_flag4 = false;
|
||||||
AutoPilot.m_flag10 = false;
|
AutoPilot.m_flag10 = false;
|
||||||
|
@ -106,6 +106,9 @@ enum eFlightModel
|
|||||||
FLIGHT_MODEL_SEAPLANE
|
FLIGHT_MODEL_SEAPLANE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Or Weapon.h?
|
||||||
|
void FireOneInstantHitRound(CVector *shotSource, CVector *shotTarget, int32 damage);
|
||||||
|
|
||||||
class CVehicle : public CPhysical
|
class CVehicle : public CPhysical
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -156,7 +159,7 @@ public:
|
|||||||
uint8 bHasBeenOwnedByPlayer : 1;// To work out whether stealing it is a crime
|
uint8 bHasBeenOwnedByPlayer : 1;// To work out whether stealing it is a crime
|
||||||
uint8 bFadeOut : 1; // Fade vehicle out
|
uint8 bFadeOut : 1; // Fade vehicle out
|
||||||
uint8 m_veh_flagC10 : 1;
|
uint8 m_veh_flagC10 : 1;
|
||||||
uint8 m_veh_flagC20 : 1;
|
uint8 bCreateRoadBlockPeds : 1; // If this vehicle gets close enough we will create peds (coppers or gang members) round it
|
||||||
uint8 bCanBeDamaged : 1; // Set to FALSE during cut scenes to avoid explosions
|
uint8 bCanBeDamaged : 1; // Set to FALSE during cut scenes to avoid explosions
|
||||||
uint8 bUsingSpecialColModel : 1;// Is player vehicle using special collision model, stored in player strucure
|
uint8 bUsingSpecialColModel : 1;// Is player vehicle using special collision model, stored in player strucure
|
||||||
|
|
||||||
@ -171,8 +174,9 @@ public:
|
|||||||
|
|
||||||
int8 m_numPedsUseItAsCover;
|
int8 m_numPedsUseItAsCover;
|
||||||
uint8 m_nAmmoInClip; // Used to make the guns on boat do a reload (20 by default)
|
uint8 m_nAmmoInClip; // Used to make the guns on boat do a reload (20 by default)
|
||||||
int8 field_1FB;
|
int8 m_nPacManPickupsCarried;
|
||||||
int8 field_1FC[4];
|
uint8 m_nRoadblockType;
|
||||||
|
int16 m_nRoadblockNode;
|
||||||
float m_fHealth; // 1000.0f = full health. 250.0f = fire. 0 -> explode
|
float m_fHealth; // 1000.0f = full health. 250.0f = fire. 0 -> explode
|
||||||
uint8 m_nCurrentGear;
|
uint8 m_nCurrentGear;
|
||||||
int8 field_205[3];
|
int8 field_205[3];
|
||||||
@ -262,6 +266,7 @@ public:
|
|||||||
void RemoveDriver(void);
|
void RemoveDriver(void);
|
||||||
void ProcessCarAlarm(void);
|
void ProcessCarAlarm(void);
|
||||||
bool IsSphereTouchingVehicle(float sx, float sy, float sz, float radius);
|
bool IsSphereTouchingVehicle(float sx, float sy, float sz, float radius);
|
||||||
|
bool ShufflePassengersToMakeSpace(void);
|
||||||
|
|
||||||
bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1; }
|
bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1; }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user