diff options
author | aap <aap@papnet.eu> | 2019-07-09 23:49:44 +0200 |
---|---|---|
committer | aap <aap@papnet.eu> | 2019-07-09 23:49:44 +0200 |
commit | 702cd0076506dad26abc3c5239a2cfddfa7deb00 (patch) | |
tree | a8f19ccb0e3972f516abeebe85addb4f11ddc601 /src/vehicles | |
parent | yet more CAutomobile (diff) | |
download | re3-702cd0076506dad26abc3c5239a2cfddfa7deb00.tar re3-702cd0076506dad26abc3c5239a2cfddfa7deb00.tar.gz re3-702cd0076506dad26abc3c5239a2cfddfa7deb00.tar.bz2 re3-702cd0076506dad26abc3c5239a2cfddfa7deb00.tar.lz re3-702cd0076506dad26abc3c5239a2cfddfa7deb00.tar.xz re3-702cd0076506dad26abc3c5239a2cfddfa7deb00.tar.zst re3-702cd0076506dad26abc3c5239a2cfddfa7deb00.zip |
Diffstat (limited to 'src/vehicles')
-rw-r--r-- | src/vehicles/Automobile.cpp | 25 | ||||
-rw-r--r-- | src/vehicles/Automobile.h | 7 | ||||
-rw-r--r-- | src/vehicles/Vehicle.cpp | 195 | ||||
-rw-r--r-- | src/vehicles/Vehicle.h | 28 |
4 files changed, 233 insertions, 22 deletions
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 54557dc2..7d3f8ee3 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -24,9 +24,9 @@ bool &CAutomobile::m_sAllTaxiLights = *(bool*)0x95CD21; WRAPPER CAutomobile* CAutomobile::ctor(int, uint8) { EAXJMP(0x52C6B0); } -CAutomobile::CAutomobile(int mi, uint8 owner) +CAutomobile::CAutomobile(int mi, uint8 CreatedBy) { - ctor(mi, owner); + ctor(mi, CreatedBy); } @@ -397,9 +397,7 @@ CAutomobile::BlowUpCar(CEntity *culprit) m_fHealth = 0.0f; m_nBombTimer = 0; - m_auto_flagA1 = false; - m_auto_flagA2 = false; - m_auto_flagA4 = false; + m_auto_flagA7 = 0; TheCamera.CamShake(0.7f, GetPosition().x, GetPosition().y, GetPosition().z); @@ -535,9 +533,8 @@ CAutomobile::PlayCarHorn(void) void CAutomobile::PlayHornIfNecessary(void) { - // TODO: flags - if(m_autoPilot.m_nCarCtrlFlags & 2 || - m_autoPilot.m_nCarCtrlFlags & 1) + if(m_autoPilot.m_flag2 || + m_autoPilot.m_flag1) if(!HasCarStoppedBecauseOfLight()) PlayCarHorn(); } @@ -637,20 +634,20 @@ CAutomobile::HasCarStoppedBecauseOfLight(void) if(m_status != STATUS_SIMPLE && m_status != STATUS_PHYSICS) return false; - if(m_autoPilot.m_currentAddress && m_autoPilot.m_startingRouteNode){ - CPathNode *curnode = &ThePaths.m_pathNodes[m_autoPilot.m_currentAddress]; + if(m_autoPilot.m_nCurrentRouteNode && m_autoPilot.m_nNextRouteNode){ + CPathNode *curnode = &ThePaths.m_pathNodes[m_autoPilot.m_nCurrentRouteNode]; for(i = 0; i < curnode->numLinks; i++) - if(ThePaths.m_connections[curnode->firstLink + i] == m_autoPilot.m_startingRouteNode) + if(ThePaths.m_connections[curnode->firstLink + i] == m_autoPilot.m_nNextRouteNode) break; if(i < curnode->numLinks && ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3) // TODO return true; } - if(m_autoPilot.m_currentAddress && m_autoPilot.m_PreviousRouteNode){ - CPathNode *curnode = &ThePaths.m_pathNodes[m_autoPilot.m_currentAddress]; + if(m_autoPilot.m_nCurrentRouteNode && m_autoPilot.m_nPrevRouteNode){ + CPathNode *curnode = &ThePaths.m_pathNodes[m_autoPilot.m_nCurrentRouteNode]; for(i = 0; i < curnode->numLinks; i++) - if(ThePaths.m_connections[curnode->firstLink + i] == m_autoPilot.m_PreviousRouteNode) + if(ThePaths.m_connections[curnode->firstLink + i] == m_autoPilot.m_nPrevRouteNode) break; if(i < curnode->numLinks && ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3) // TODO diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index 0e9bd945..60e08d0a 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -24,9 +24,7 @@ public: float m_aWheelPosition[4]; float m_aWheelSpeed[4]; uint8 field_4D8; - uint8 m_auto_flagA1 : 1; - uint8 m_auto_flagA2 : 1; - uint8 m_auto_flagA4 : 1; + uint8 m_auto_flagA7 : 1; uint8 bTaxiLight : 1; uint8 m_auto_flagA10 : 1; uint8 m_auto_flagA20 : 1; @@ -39,7 +37,8 @@ public: float m_aSuspensionLineLength[4]; float m_fHeightAboveRoad; float m_fImprovedHandling; - uint8 stuff6[32]; + uint8 stuff6[28]; + float field_530; CPhysical *m_aGroundPhysical[4]; // physicals touching wheels CVector m_aGroundOffset[4]; // from ground object to colpoint CEntity *m_pBlowUpEntity; diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 6ea0e61e..c541bae5 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -1,7 +1,9 @@ #include "common.h" #include "main.h" #include "patcher.h" +#include "General.h" #include "Timer.h" +#include "Pad.h" #include "Vehicle.h" #include "Pools.h" #include "HandlingMgr.h" @@ -13,6 +15,7 @@ #include "PointLights.h" #include "Renderer.h" #include "DMAudio.h" +#include "MusicManager.h" #include "Radar.h" bool &CVehicle::bWheelsOnlyCheat = *(bool *)0x95CD78; @@ -27,6 +30,79 @@ 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, int handle) { CPools::GetVehiclePool()->Delete((CVehicle*)p); } +CVehicle::CVehicle(uint8 CreatedBy) +{ + int i; + + m_nCurrentGear = 0; + field_208 = 0; + m_fSteerRatio = 0.0f; + m_type = ENTITY_TYPE_VEHICLE; + VehicleCreatedBy = CreatedBy; + bIsLocked = false; + bIsLawEnforcer = false; + bIsAmbulanceOnDuty = false; + bIsFireTruckOnDuty = false; + CCarCtrl::UpdateCarCount(this, false); + m_fHealth = 1000.0f; + bEngineOn = true; + bFreebies = true; + pDriver = nil; + m_nNumPassengers = 0; + m_nNumGettingIn = 0; + m_nGettingInFlags = 0; + m_nGettingOutFlags = 0; + m_nNumMaxPassengers = 8; + for(i = 0; i < m_nNumMaxPassengers; i++) + pPassengers[i] = nil; + m_nBombTimer = 0; + m_pWhoSetMeOnFire = nil; + field_1FB = 0; + m_veh_flagB10 = false; + m_veh_flagB40 = false; + m_veh_flagB80 = false; + m_veh_flagC1 = false; + bIsDamaged = false; + m_veh_flagC8 = false; + m_veh_flagC10 = false; + m_veh_flagC4 = false; + m_veh_flagC20 = false; + bCanBeDamaged = true; + m_veh_flagC80 = false; + m_veh_flagD1 = false; + m_veh_flagD2 = false; + m_nGunFiringTime = 0; + field_214 = 0; + bLightsOn = false; + bVehicleColProcessed = false; + field_1F9 = 0; + bIsCarParkVehicle = false; + bHasAlreadyBeenRecorded = false; + m_bSirenOrAlarm = 0; + m_nCarHornTimer = 0; + field_22D = 0; + m_nAlarmState = 0; + m_nDoorLock = CARLOCK_UNLOCKED; + m_nLastWeaponDamage = -1; + field_220 = 0.0; + field_21C = field_220; + m_audioEntityId = DMAudio.CreateEntity(0, this); + if(m_audioEntityId) + DMAudio.SetEntityStatus(m_audioEntityId, true); + m_nRadioStation = CGeneral::GetRandomNumber() % USERTRACK; + m_pCurGroundEntity = nil; + field_22A = 0; + field_22B = 0; + field_22F = 0; + m_aCollPolys[0].valid = false; + m_aCollPolys[1].valid = false; + m_autoPilot.m_nCarMission = MISSION_NONE; + m_autoPilot.m_nAnimationId = TEMPACT_NONE; + m_autoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds(); + m_autoPilot.m_flag4 = false; + m_autoPilot.m_flag10 = false; +} + CVehicle::~CVehicle() { m_nAlarmState = 0; @@ -55,6 +131,67 @@ CVehicle::~CVehicle() } void +CVehicle::FlyingControl(eFlightModel flightModel) +{ + switch(flightModel){ + case FLIGHT_MODEL_DODO: + { + // This seems pretty magic + + // Move Left/Right + float moveSpeed = m_vecMoveSpeed.Magnitude(); + float sideSpeed = DotProduct(m_vecMoveSpeed, GetRight()); + float sideImpulse = -1.0f * sideSpeed / moveSpeed; + float fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward()); + float magic = m_vecMoveSpeed.MagnitudeSqr() * sq(fwdSpeed); + float turnImpulse = (sideImpulse*0.003f + m_fSteerAngle*0.001f) * + magic*m_fTurnMass*CTimer::GetTimeStep(); + ApplyTurnForce(turnImpulse*GetRight(), -4.0f*GetForward()); + + float impulse = sideImpulse*0.2f * + magic*m_fMass*CTimer::GetTimeStep(); + ApplyMoveForce(impulse*GetRight()); + ApplyTurnForce(impulse*GetRight(), 2.0f*GetUp()); + + + // Move Up/Down + moveSpeed = m_vecMoveSpeed.Magnitude(); + float upSpeed = DotProduct(m_vecMoveSpeed, GetUp()); + float upImpulse = -1.0f * upSpeed / moveSpeed; + turnImpulse = (upImpulse*0.002f + -CPad::GetPad(0)->GetSteeringUpDown()/128.0f*0.001f) * + magic*m_fTurnMass*CTimer::GetTimeStep(); + ApplyTurnForce(turnImpulse*GetUp(), -4.0f*GetForward()); + + impulse = (upImpulse*3.5f + 0.5f)*0.05f * + magic*m_fMass*CTimer::GetTimeStep(); + if(GRAVITY*m_fMass*CTimer::GetTimeStep() < impulse && + GetPosition().z > 100.0f) + impulse = 0.9f*GRAVITY*m_fMass*CTimer::GetTimeStep(); + CVector com = Multiply3x3(GetMatrix(), m_vecCentreOfMass); + ApplyMoveForce(impulse*GetUp()); + ApplyTurnForce(impulse*GetUp(), 2.0f*GetUp() + com); + + + m_vecTurnSpeed.y *= powf(0.9f, CTimer::GetTimeStep()); + moveSpeed = m_vecMoveSpeed.MagnitudeSqr(); + if(moveSpeed > 2.25f) + m_vecMoveSpeed *= 1.5f/sqrt(moveSpeed); + + float turnSpeed = m_vecTurnSpeed.MagnitudeSqr(); + if(turnSpeed > 0.04f) + m_vecTurnSpeed *= 0.2f/sqrt(turnSpeed); + } + break; + + case FLIGHT_MODEL_RCPLANE: + case FLIGHT_MODEL_SEAPLANE: + assert(0 && "Plane flight model not implemented"); + case FLIGHT_MODEL_HELI: + assert(0 && "Heli flight model not implemented"); + } +} + +void CVehicle::SetModelIndex(uint32 id) { CEntity::SetModelIndex(id); @@ -96,6 +233,60 @@ CVehicle::GetHeightAboveRoad(void) } +void +CVehicle::ExtinguishCarFire(void) +{ + m_fHealth = max(m_fHealth, 300.0f); + if(m_pCarFire) + m_pCarFire->Extinguish(); + if(IsCar()){ + CAutomobile *car = (CAutomobile*)this; + if(car->Damage.GetEngineStatus() >= 225) + car->Damage.SetEngineStatus(215); + car->field_530 = 0.0f; + } +} + +void +CVehicle::ProcessDelayedExplosion(void) +{ + if(m_nBombTimer == 0) + return; + + if(m_nBombTimer == 0){ + int tick = CTimer::GetTimeStep()/60.0f*1000.0f; + if(tick > m_nBombTimer) + m_nBombTimer = 0; + else + m_nBombTimer -= tick; + + if(IsCar() && ((CAutomobile*)this)->m_auto_flagA7 == 4 && (m_nBombTimer & 0xFE00) != 0xFE00) + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_BOMB_TICK, 0.0f); + + if(FindPlayerVehicle() != this && m_pWhoSetMeOnFire == FindPlayerPed()) + CWorld::Players[CWorld::PlayerInFocus].AwardMoneyForExplosion(this); + BlowUpCar(m_pWhoSetMeOnFire); + } +} + +float +CVehicle::ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVector &speed, float radius) +{ + float angularVelocity; + switch(state){ + case WHEEL_STATE_1: + angularVelocity = -1.1f; // constant speed forward + break; + case WHEEL_STATE_3: + angularVelocity = 0.0f; // not moving + break; + default: + angularVelocity = -DotProduct(fwd, speed) / radius; // forward speed + break; + } + return angularVelocity * CTimer::GetTimeStep(); +} + bool CVehicle::IsLawEnforcementVehicle(void) { @@ -477,6 +668,10 @@ STARTPATCHES InjectHook(0x4A7E60, &CVehicle_::RemoveLighting_, PATCH_JUMP); InjectHook(0x417E60, &CVehicle_::GetHeightAboveRoad_, PATCH_JUMP); + InjectHook(0x552BB0, &CVehicle::FlyingControl, PATCH_JUMP); + InjectHook(0x552AF0, &CVehicle::ExtinguishCarFire, PATCH_JUMP); + InjectHook(0x551C90, &CVehicle::ProcessDelayedExplosion, PATCH_JUMP); + InjectHook(0x551280, &CVehicle::ProcessWheelRotation, PATCH_JUMP); InjectHook(0x552880, &CVehicle::IsLawEnforcementVehicle, PATCH_JUMP); InjectHook(0x552820, &CVehicle::ChangeLawEnforcerState, PATCH_JUMP); InjectHook(0x552200, &CVehicle::UsesSiren, PATCH_JUMP); diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index cd877da5..76ea76cb 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -104,6 +104,21 @@ enum CAR_PIECE_WHEEL_RR, }; +enum tWheelState +{ + WHEEL_STATE_1 = 1, // constant velocity + WHEEL_STATE_3 = 3, // not moving +}; + +enum eFlightModel +{ + FLIGHT_MODEL_DODO, + // not used in III + FLIGHT_MODEL_RCPLANE, + FLIGHT_MODEL_HELI, + FLIGHT_MODEL_SEAPLANE +}; + class CVehicle : public CPhysical { public: @@ -179,7 +194,7 @@ public: uint32 m_nTimeOfDeath; int16 field_214; int16 m_nBombTimer; // goes down with each frame - CPed *m_pWhoDetonatedMe; + CPed *m_pWhoSetMeOnFire; float field_21C; float field_220; eCarLock m_nDoorLock; @@ -191,9 +206,7 @@ public: int8 field_22D; bool m_bSirenOrAlarm; int8 field_22F; - // TODO: this is an array - CStoredCollPoly m_frontCollPoly; // poly which is under front part of car - CStoredCollPoly m_rearCollPoly; // poly which is under rear part of car + CStoredCollPoly m_aCollPolys[2]; // poly which is under front/rear part of car float m_fSteerRatio; eVehicleType m_vehType; @@ -202,6 +215,8 @@ public: static void operator delete(void*, size_t); static void operator delete(void*, int); + CVehicle(void) {} // FAKE + CVehicle(uint8 CreatedBy); ~CVehicle(void); // from CEntity void SetModelIndex(uint32 id); @@ -232,6 +247,11 @@ public: bool IsTrain(void) { return m_vehType == VEHICLE_TYPE_TRAIN; } bool IsHeli(void) { return m_vehType == VEHICLE_TYPE_HELI; } bool IsPlane(void) { return m_vehType == VEHICLE_TYPE_PLANE; } + + void FlyingControl(eFlightModel flightModel); + void ExtinguishCarFire(void); + void ProcessDelayedExplosion(void); + float ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVector &speed, float radius); bool IsLawEnforcementVehicle(void); void ChangeLawEnforcerState(uint8 enable); bool UsesSiren(uint32 id); |