cranes init
This commit is contained in:
parent
bd0cd13be1
commit
057b28e39b
@ -2,13 +2,238 @@
|
||||
#include "patcher.h"
|
||||
#include "Cranes.h"
|
||||
|
||||
#include "Camera.h"
|
||||
#include "DMAudio.h"
|
||||
#include "Entity.h"
|
||||
#include "ModelIndices.h"
|
||||
#include "Replay.h"
|
||||
#include "Object.h"
|
||||
#include "World.h"
|
||||
|
||||
#define MAX_DISTANCE_TO_FIND_CRANE (10.0f)
|
||||
#define CRANE_UPDATE_RADIUS (300.0f)
|
||||
#define CRANE_MOVEMENT_PROCESSING_RADIUS (150.0f)
|
||||
#define CRUSHER_Z (-0.951f)
|
||||
#define MILITARY_Z (10.7862f)
|
||||
|
||||
void CCranes::InitCranes(void)
|
||||
{
|
||||
CarsCollectedMilitaryCrane = 0;
|
||||
NumCranes = 0;
|
||||
for (int i = 0; i < NUMSECTORS_X; i++) {
|
||||
for (int j = 0; j < NUMSECTORS_Y; j++) {
|
||||
for (CPtrNode* pNode = CWorld::GetSector(i, j)->m_lists[ENTITYLIST_BUILDINGS].first; pNode; pNode = pNode->next) {
|
||||
CEntity* pEntity = (CEntity*)pNode->item;
|
||||
if (MODELID_CRANE_1 == pEntity->GetModelIndex() ||
|
||||
MODELID_CRANE_2 == pEntity->GetModelIndex() ||
|
||||
MODELID_CRANE_3 == pEntity->GetModelIndex())
|
||||
AddThisOneCrane(pEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (CPtrNode* pNode = CWorld::GetBigBuildingList(LEVEL_INDUSTRIAL).first; pNode; pNode->next) {
|
||||
CEntity* pEntity = (CEntity*)pNode->item;
|
||||
if (MODELID_CRANE_1 == pEntity->GetModelIndex() ||
|
||||
MODELID_CRANE_2 == pEntity->GetModelIndex() ||
|
||||
MODELID_CRANE_3 == pEntity->GetModelIndex())
|
||||
AddThisOneCrane(pEntity);
|
||||
}
|
||||
}
|
||||
|
||||
void CCranes::AddThisOneCrane(CEntity* pEntity)
|
||||
{
|
||||
pEntity->GetMatrix().ResetOrientation();
|
||||
if (NumCranes >= NUM_CRANES)
|
||||
return;
|
||||
CCrane* pCrane = &aCranes[NumCranes];
|
||||
pCrane->Init();
|
||||
pCrane->m_pObject = pEntity;
|
||||
pCrane->m_bCraneStatus = CCrane::NONE;
|
||||
pCrane->m_fHeight = NumCranes; // lol wtf
|
||||
while (pCrane->m_fHeight > TWOPI)
|
||||
pCrane->m_fHeight -= TWOPI;
|
||||
pCrane->m_fHookOffset = 20.0f;
|
||||
pCrane->m_fHookHeight = 20.0f;
|
||||
pCrane->m_nUpdateTimer = 0;
|
||||
pCrane->m_bCraneState = CCrane::IDLE;
|
||||
pCrane->m_bWasMilitaryCrane = 0;
|
||||
pCrane->m_nAudioEntity = DMAudio.CreateEntity(AUDIOTYPE_CRANE, &aCranes[NumCranes]);
|
||||
if (pCrane->m_nAudioEntity >= 0)
|
||||
DMAudio.SetEntityStatus(pCrane->m_nAudioEntity, 1);
|
||||
pCrane->m_bIsTop = (MODELID_CRANE_1 != pEntity->GetModelIndex());
|
||||
// W T F ? ? ?
|
||||
// Is this used to avoid military crane?
|
||||
if (pCrane->m_bIsTop || pEntity->GetPosition().y > 0.0f) {
|
||||
CObject* pMagnet = new CObject(MI_MAGNET, false);
|
||||
pMagnet->ObjectCreatedBy = MISSION_OBJECT;
|
||||
pMagnet->bUsesCollision = false;
|
||||
pMagnet->bExplosionProof = true;
|
||||
pMagnet->bAffectedByGravity = false;
|
||||
pCrane->m_pMagnet = pMagnet;
|
||||
pCrane->CalcHookCoordinates(&pCrane->m_vecHookCurPos.x, &pCrane->m_vecHookCurPos.y, &pCrane->m_vecHookCurPos.z);
|
||||
pCrane->SetHookMatrix();
|
||||
}
|
||||
else
|
||||
pCrane->m_pMagnet = nil;
|
||||
NumCranes++;
|
||||
}
|
||||
|
||||
void CCranes::ActivateCrane(float fInfX, float fSupX, float fInfY, float fSupY, float fDropOffX, float fDropOffY, float fDropOffZ, float fHeading, bool bIsCrusher, bool bIsMilitary, float fPosX, float fPosY)
|
||||
{
|
||||
float fMinDistance = 99999.9f;
|
||||
float X = fPosX, Y = fPosY;
|
||||
if (X <= -10000.0f || Y <= -10000.0f) {
|
||||
X = fDropOffX;
|
||||
Y = fDropOffY;
|
||||
}
|
||||
int index = 0;
|
||||
for (int i = 0; i < NumCranes; i++) {
|
||||
float distance = (CVector2D(X, Y) - aCranes[i].m_pObject->GetPosition()).Magnitude();
|
||||
if (distance < fMinDistance && distance < MAX_DISTANCE_TO_FIND_CRANE) {
|
||||
fMinDistance = distance;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
#ifdef FIX_BUGS // classic
|
||||
if (fMinDistance == 99999.9f)
|
||||
return;
|
||||
#endif
|
||||
CCrane* pCrane = &aCranes[NumCranes];
|
||||
pCrane->m_fPickupX1 = fInfX;
|
||||
pCrane->m_fPickupX2 = fSupX;
|
||||
pCrane->m_fPickupY1 = fInfY;
|
||||
pCrane->m_fPickupY2 = fSupY;
|
||||
pCrane->m_vecDropoffTarget.x = fDropOffX;
|
||||
pCrane->m_vecDropoffTarget.y = fDropOffY;
|
||||
pCrane->m_vecDropoffTarget.z = fDropOffZ;
|
||||
pCrane->m_bCraneStatus = CCrane::ACTIVATED;
|
||||
pCrane->m_pVehiclePickedUp = nil;
|
||||
pCrane->m_bVehiclesCollected = 0;
|
||||
pCrane->m_bIsCrusher = bIsCrusher;
|
||||
pCrane->m_bIsMilitaryCrane = bIsMilitary;
|
||||
bool military = true;
|
||||
if (!bIsMilitary && !pCrane->m_bWasMilitaryCrane)
|
||||
military = false;
|
||||
pCrane->m_bWasMilitaryCrane = military;
|
||||
pCrane->m_nUpdateTimer = 0;
|
||||
pCrane->m_bCraneState = CCrane::IDLE;
|
||||
float Z;
|
||||
if (bIsCrusher)
|
||||
Z = CRUSHER_Z;
|
||||
else if (bIsMilitary)
|
||||
Z = MILITARY_Z;
|
||||
else
|
||||
Z = CWorld::FindGroundZForCoord((fInfX + fSupY) / 2, (fInfY + fSupY) / 2);
|
||||
pCrane->FindParametersForTarget((fInfX + fSupY) / 2, (fInfY + fSupY) / 2, Z, &pCrane->m_fPickupAngle, &pCrane->m_fPickupDistance, &pCrane->m_fAngle);
|
||||
pCrane->FindParametersForTarget(fDropOffX, fDropOffY, fDropOffZ, &pCrane->m_fDropoffAngle, &pCrane->m_fDropoffDistance, &pCrane->m_fDistance);
|
||||
}
|
||||
|
||||
void CCranes::DeActivateCrane(float X, float Y)
|
||||
{
|
||||
float fMinDistance = 99999.9f;
|
||||
int index = 0;
|
||||
for (int i = 0; i < NumCranes; i++) {
|
||||
float distance = (CVector2D(X, Y) - aCranes[i].m_pObject->GetPosition()).Magnitude();
|
||||
if (distance < fMinDistance && distance < MAX_DISTANCE_TO_FIND_CRANE) {
|
||||
fMinDistance = distance;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
#ifdef FIX_BUGS // classic
|
||||
if (fMinDistance == 99999.9f)
|
||||
return;
|
||||
#endif
|
||||
aCranes[index].m_bCraneStatus = CCrane::DEACTIVATED;
|
||||
aCranes[index].m_bCraneState = CCrane::IDLE;
|
||||
}
|
||||
|
||||
bool CCranes::IsThisCarPickedUp(float X, float Y, CVehicle* pVehicle)
|
||||
{
|
||||
int index = 0;
|
||||
bool result = false;
|
||||
for (int i = 0; i < NumCranes; i++) {
|
||||
float distance = (CVector2D(X, Y) - aCranes[i].m_pObject->GetPosition()).Magnitude();
|
||||
if (distance < MAX_DISTANCE_TO_FIND_CRANE && aCranes[i].m_pVehiclePickedUp == pVehicle) {
|
||||
if (aCranes[i].m_bCraneStatus == CCrane::LIFTING_TARGET || aCranes[i].m_bCraneStatus == CCrane::ROTATING_TARGET)
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CCranes::UpdateCranes(void)
|
||||
{
|
||||
for (int i = 0; i < NumCranes; i++) {
|
||||
if (aCranes[i].m_bIsTop || aCranes[i].m_bIsCrusher ||
|
||||
(TheCamera.GetPosition().x + CRANE_UPDATE_RADIUS > aCranes[i].m_pObject->GetPosition().x &&
|
||||
TheCamera.GetPosition().x - CRANE_UPDATE_RADIUS < aCranes[i].m_pObject->GetPosition().x &&
|
||||
TheCamera.GetPosition().y + CRANE_UPDATE_RADIUS > aCranes[i].m_pObject->GetPosition().y &&
|
||||
TheCamera.GetPosition().y + CRANE_UPDATE_RADIUS < aCranes[i].m_pObject->GetPosition().y))
|
||||
aCranes[i].Update();
|
||||
}
|
||||
}
|
||||
|
||||
void CCrane::Update(void)
|
||||
{
|
||||
if (CReplay::IsPlayingBack())
|
||||
return;
|
||||
if ((m_bCraneStatus == ACTIVATED || m_bCraneStatus == DEACTIVATED) &&
|
||||
Abs(TheCamera.GetGameCamPosition().x - m_pObject->GetPosition().x) < CRANE_MOVEMENT_PROCESSING_RADIUS &&
|
||||
Abs(TheCamera.GetGameCamPosition().y - m_pObject->GetPosition().y) < CRANE_MOVEMENT_PROCESSING_RADIUS) {
|
||||
switch (m_bCraneState) {
|
||||
case IDLE:
|
||||
if (GoTowardsTarget(m_fPickupAngle, m_fPickupDistance, 4.0f + m_fAngle + m_bIsCrusher ? 4.5f : 0.0f, 1.0f) &&
|
||||
CTimer::GetTimeInMilliseconds() > m_nUpdateTimer) {
|
||||
CWorld::AdvanceCurrentScanCode();
|
||||
#ifdef FIX_BUGS
|
||||
int xstart = max(0, CWorld::GetSectorIndexX(m_fPickupX1));
|
||||
int xend = min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(m_fPickupX2));
|
||||
int ystart = max(0, CWorld::GetSectorIndexY(m_fPickupY1));
|
||||
int yend = min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(m_fPickupY2));
|
||||
#else
|
||||
int xstart = CWorld::GetSectorIndexX(m_fPickupX1);
|
||||
int xend = CWorld::GetSectorIndexX(m_fPickupX2);
|
||||
int ystart = CWorld::GetSectorIndexY(m_fPickupY1);
|
||||
int yend = CWorld::GetSectorIndexY(m_fPickupY1);
|
||||
#endif
|
||||
assert(xstart <= xend);
|
||||
assert(ystart <= yend);
|
||||
for (int i = xstart; i <= xend; i++) {
|
||||
for (int j = ystart; j <= yend; j++) {
|
||||
FindCarInSectorList(&CWorld::GetSector(i, j)->m_lists[ENTITYLIST_VEHICLES]);
|
||||
FindCarInSectorList(&CWorld::GetSector(i, j)->m_lists[ENTITYLIST_VEHICLES_OVERLAP]);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GOING_TOWARDS_TARGET:
|
||||
if (!m_pVehiclePickedUp) {
|
||||
m_bCraneState = IDLE;
|
||||
break;
|
||||
}
|
||||
if (m_pVehiclePickedUp->GetPosition().x < m_fPickupX1 ||
|
||||
m_pVehiclePickedUp->GetPosition().x > m_fPickupX2 ||
|
||||
m_pVehiclePickedUp->GetPosition().y > m_fPickupY1 ||
|
||||
m_pVehiclePickedUp->GetPosition().y > m_fPickupY2 ||
|
||||
m_pVehiclePickedUp->pDriver ||
|
||||
Abs(m_pVehiclePickedUp->GetMoveSpeed().x) > 0.01f ||
|
||||
Abs(m_pVehiclePickedUp->GetMoveSpeed().y) > 0.01f ||
|
||||
Abs(m_pVehiclePickedUp->GetMoveSpeed().z) > 0.01f ||
|
||||
FindPlayerPed()->GetPedState() == PED_ENTER_CAR &&
|
||||
FindPlayerPed()->m_pSeekTarget == m_pVehiclePickedUp) {
|
||||
m_pVehiclePickedUp = nil;
|
||||
m_bCraneState = IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WRAPPER bool CCranes::IsThisCarBeingTargettedByAnyCrane(CVehicle*) { EAXJMP(0x5451E0); }
|
||||
WRAPPER bool CCranes::IsThisCarBeingCarriedByAnyCrane(CVehicle*) { EAXJMP(0x545190); }
|
||||
WRAPPER bool CCranes::IsThisCarPickedUp(float, float, CVehicle*) { EAXJMP(0x543940); }
|
||||
WRAPPER bool CCranes::HaveAllCarsBeenCollectedByMilitaryCrane() { EAXJMP(0x544BE0); }
|
||||
WRAPPER void CCranes::ActivateCrane(float, float, float, float, float, float, float, float, bool, bool, float, float) { EAXJMP(0x543650); }
|
||||
WRAPPER void CCranes::DeActivateCrane(float, float) { EAXJMP(0x543890); }
|
||||
WRAPPER void CCranes::InitCranes(void) { EAXJMP(0x543360); }
|
||||
WRAPPER void CCranes::UpdateCranes(void) { EAXJMP(0x5439E0); }
|
||||
|
||||
|
||||
WRAPPER void CCranes::Save(uint8*, uint32*) { EAXJMP(0x545210); }
|
||||
WRAPPER void CranesLoad(uint8*, uint32) { EAXJMP(0x5454d0); }
|
||||
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
#include "common.h"
|
||||
|
||||
#include "World.h"
|
||||
|
||||
class CVehicle;
|
||||
class CEntity;
|
||||
class CObject;
|
||||
@ -8,9 +10,22 @@ class CObject;
|
||||
class CCrane
|
||||
{
|
||||
public:
|
||||
enum CraneState : uint8 {
|
||||
IDLE = 0,
|
||||
GOING_TOWARDS_TARGET = 1,
|
||||
LIFTING_TARGET = 2,
|
||||
GOING_TOWARDS_HEIGHT_TARGET = 3,
|
||||
ROTATING_TARGET = 4,
|
||||
DROPPING_TARGET = 5
|
||||
};
|
||||
enum CraneStatus : uint8 {
|
||||
NONE = 0,
|
||||
ACTIVATED = 1,
|
||||
DEACTIVATED = 2
|
||||
};
|
||||
CEntity *m_pObject;
|
||||
CObject *m_pMagnet;
|
||||
int m_nAudioEntity;
|
||||
int32 m_nAudioEntity;
|
||||
float m_fPickupX1;
|
||||
float m_fPickupX2;
|
||||
float m_fPickupY1;
|
||||
@ -31,15 +46,25 @@ public:
|
||||
float m_fHookVelocityX;
|
||||
float m_fHookVelocityY;
|
||||
CVehicle *m_pVehiclePickedUp;
|
||||
int m_nUpdateTimer;
|
||||
char m_bCraneActive;
|
||||
char m_bCraneStatus;
|
||||
char m_bVehiclesCollected;
|
||||
char m_bIsCrusher;
|
||||
char m_bIsMilitaryCrane;
|
||||
char field_125;
|
||||
char m_bNotMilitaryCrane;
|
||||
char gap_127[1];
|
||||
uint32 m_nUpdateTimer;
|
||||
CraneStatus m_bCraneStatus;
|
||||
CraneState m_bCraneState;
|
||||
uint8 m_bVehiclesCollected;
|
||||
bool m_bIsCrusher;
|
||||
bool m_bIsMilitaryCrane;
|
||||
bool m_bWasMilitaryCrane;
|
||||
bool m_bIsTop;
|
||||
|
||||
void Init(void) { memset(this, 0, sizeof(*this)); }
|
||||
void Update(void);
|
||||
bool RotateCarriedCarProperly();
|
||||
void FindCarInSectorList(CPtrList*);
|
||||
bool DoesCranePickUpThisCarType(uint32);
|
||||
bool GoTowardsTarget(float, float, float, float);
|
||||
bool GoTowardsHeightTarget(float, float);
|
||||
void FindParametersForTarget(float, float, float, float*, float*, float*);
|
||||
void CalcHookCoordinates(float*, float*, float*);
|
||||
void SetHookMatrix();
|
||||
};
|
||||
|
||||
static_assert(sizeof(CCrane) == 128, "CCrane: error");
|
||||
@ -47,15 +72,22 @@ static_assert(sizeof(CCrane) == 128, "CCrane: error");
|
||||
class CCranes
|
||||
{
|
||||
public:
|
||||
static bool IsThisCarBeingTargettedByAnyCrane(CVehicle*);
|
||||
static bool IsThisCarBeingCarriedByAnyCrane(CVehicle*);
|
||||
static bool IsThisCarPickedUp(float, float, CVehicle*);
|
||||
static bool HaveAllCarsBeenCollectedByMilitaryCrane();
|
||||
static void InitCranes(void);
|
||||
static void AddThisOneCrane(CEntity*);
|
||||
static void ActivateCrane(float, float, float, float, float, float, float, float, bool, bool, float, float);
|
||||
static void DeActivateCrane(float, float);
|
||||
static void InitCranes(void);
|
||||
static bool IsThisCarPickedUp(float, float, CVehicle*);
|
||||
static void UpdateCranes(void);
|
||||
static bool DoesMilitaryCraneHaveThisOneAlready(uint32);
|
||||
static void RegisterCarForMilitaryCrane(uint32);
|
||||
static bool HaveAllCarsBeenCollectedByMilitaryCrane();
|
||||
static bool IsThisCarBeingCarriedByAnyCrane(CVehicle*);
|
||||
static bool IsThisCarBeingTargettedByAnyCrane(CVehicle*);
|
||||
static void Save(uint8*, uint32*);
|
||||
|
||||
static int32& CarsCollectedMilitaryCrane;
|
||||
static int32& NumCranes;
|
||||
static CCrane(&aCranes)[NUM_CRANES];
|
||||
};
|
||||
|
||||
void CranesLoad(uint8*, uint32); // is this really outside CCranes?
|
||||
|
@ -118,7 +118,9 @@ enum Config {
|
||||
NUM_AUDIO_REFLECTIONS = 5,
|
||||
NUM_SCRIPT_MAX_ENTITIES = 40,
|
||||
|
||||
NUM_GARAGE_STORED_CARS = 6
|
||||
NUM_GARAGE_STORED_CARS = 6,
|
||||
|
||||
NUM_CRANES = 8
|
||||
};
|
||||
|
||||
// We'll use this once we're ready to become independent of the game
|
||||
|
@ -243,6 +243,17 @@ public:
|
||||
m_matrix.pos.y = 0.0f;
|
||||
m_matrix.pos.z = 0.0f;
|
||||
}
|
||||
void ResetOrientation(void) {
|
||||
m_matrix.right.x = 1.0f;
|
||||
m_matrix.right.y = 0.0f;
|
||||
m_matrix.right.z = 0.0f;
|
||||
m_matrix.up.x = 0.0f;
|
||||
m_matrix.up.y = 1.0f;
|
||||
m_matrix.up.z = 0.0f;
|
||||
m_matrix.at.x = 0.0f;
|
||||
m_matrix.at.y = 0.0f;
|
||||
m_matrix.at.z = 1.0f;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user