1+ #include " pch.h"
2+ #include " turnlights.h"
3+ #include < CCoronas.h>
4+ #include < CGeneral.h>
5+
6+ #define TURN_ON_OFF_DELAY 500
7+ #define MAX_RADIUS 200 .0f
8+
9+ TurnLightsFeature TurnLights;
10+
11+ static CVector2D GetCarPathLinkPosition (CCarPathLinkAddress &address) {
12+ if (address.m_nAreaId != -1 && address.m_nCarPathLinkId != -1 && ThePaths.m_pPathNodes [address.m_nAreaId ]) {
13+ return CVector2D (static_cast <float >(ThePaths.m_pNaviNodes [address.m_nAreaId ][address.m_nCarPathLinkId ].m_vecPosn .x ) / 8 .0f ,
14+ static_cast <float >(ThePaths.m_pNaviNodes [address.m_nAreaId ][address.m_nCarPathLinkId ].m_vecPosn .y ) / 8 .0f );
15+ }
16+ return CVector2D (0 .0f , 0 .0f );
17+ }
18+
19+ static void DrawTurnlight (CVehicle *vehicle, unsigned int dummyId, bool leftSide) {
20+ CVector posn =
21+ reinterpret_cast <CVehicleModelInfo *>(CModelInfo::ms_modelInfoPtrs[vehicle->m_nModelIndex ])->m_pVehicleStruct ->m_avDummyPos [dummyId];
22+ if (posn.x == 0 .0f ) posn.x = 0 .15f ;
23+ if (leftSide) posn.x *= -1 .0f ;
24+ CCoronas::RegisterCorona (reinterpret_cast <unsigned int >(vehicle) + 50 + dummyId + (leftSide ? 0 : 2 ), vehicle, 255 , 128 , 0 , 255 , posn,
25+ 0 .3f , 150 .0f , CORONATYPE_SHINYSTAR, eCoronaFlareType::FLARETYPE_NONE, false , false , 0 , 0 .0f , false , 0 .5f , 0 , 50 .0f , false , true );
26+ }
27+
28+ static void DrawVehicleTurnlights (CVehicle *vehicle, eLightsStatus lightsStatus) {
29+ if (lightsStatus == eLightsStatus::Both || lightsStatus == eLightsStatus::Right) {
30+ DrawTurnlight (vehicle, 0 , false );
31+ DrawTurnlight (vehicle, 1 , false );
32+ }
33+ if (lightsStatus == eLightsStatus::Both || lightsStatus == eLightsStatus::Left) {
34+ DrawTurnlight (vehicle, 0 , true );
35+ DrawTurnlight (vehicle, 1 , true );
36+ }
37+ }
38+
39+ static float GetZAngleForPoint (CVector2D const &point) {
40+ float angle = CGeneral::GetATanOfXY (point.x , point.y ) * 57 .295776f - 90 .0f ;
41+ while (angle < 0 .0f ) angle += 360 .0f ;
42+ return angle;
43+ }
44+
45+ void TurnLightsFeature::Initialize () {
46+ Events::vehicleRenderEvent.before += [this ](CVehicle *vehicle) {
47+ VehData &data = vehData.Get (vehicle);
48+ if ((vehicle->m_nVehicleSubClass == VEHICLE_AUTOMOBILE || vehicle->m_nVehicleSubClass == VEHICLE_BIKE) &&
49+ (vehicle->GetVehicleAppearance () == VEHICLE_APPEARANCE_AUTOMOBILE || vehicle->GetVehicleAppearance () == VEHICLE_APPEARANCE_BIKE) &&
50+ vehicle->m_nVehicleFlags .bEngineOn && vehicle->m_fHealth > 0 && !vehicle->m_nVehicleFlags .bIsDrowning && !vehicle->m_pAttachedTo )
51+ {
52+ eLightsStatus &lightsStatus = data.lightsStatus ;
53+ if (vehicle->m_pDriver ) {
54+ CPed *playa = FindPlayerPed ();
55+ if (playa && playa->m_pVehicle == vehicle && playa->m_nPedFlags .bInVehicle ) {
56+ if (KeyPressed (90 )) // Z
57+ lightsStatus = eLightsStatus::Left;
58+ else if (KeyPressed (88 )) // X
59+ lightsStatus = eLightsStatus::Both;
60+ else if (KeyPressed (67 )) // C
61+ lightsStatus = eLightsStatus::Right;
62+ else if (KeyPressed (VK_SHIFT))
63+ lightsStatus = eLightsStatus::Off;
64+ }
65+ else {
66+ lightsStatus = eLightsStatus::Off;
67+
68+ CVector2D prevPoint = GetCarPathLinkPosition (vehicle->m_autoPilot .m_nPreviousPathNodeInfo );
69+ CVector2D currPoint = GetCarPathLinkPosition (vehicle->m_autoPilot .m_nCurrentPathNodeInfo );
70+ CVector2D nextPoint = GetCarPathLinkPosition (vehicle->m_autoPilot .m_nNextPathNodeInfo );
71+
72+ float angle = GetZAngleForPoint (nextPoint - currPoint) - GetZAngleForPoint (currPoint - prevPoint);
73+ while (angle < 0 .0f ) angle += 360 .0f ;
74+ while (angle > 360 .0f ) angle -= 360 .0f ;
75+
76+ if (angle >= 30 .0f && angle < 180 .0f )
77+ lightsStatus = eLightsStatus::Left;
78+ else if (angle <= 330 .0f && angle > 180 .0f )
79+ lightsStatus = eLightsStatus::Right;
80+
81+ if (lightsStatus == eLightsStatus::Off) {
82+ if (vehicle->m_autoPilot .m_nCurrentLane == 0 && vehicle->m_autoPilot .m_nNextLane == 1 )
83+ lightsStatus = eLightsStatus::Right;
84+ else if (vehicle->m_autoPilot .m_nCurrentLane == 1 && vehicle->m_autoPilot .m_nNextLane == 0 )
85+ lightsStatus = eLightsStatus::Left;
86+ }
87+ }
88+ }
89+ if (CTimer::m_snTimeInMilliseconds % (TURN_ON_OFF_DELAY * 2 ) < TURN_ON_OFF_DELAY) {
90+ if (DistanceBetweenPoints (TheCamera.m_vecGameCamPos , vehicle->GetPosition ()) < MAX_RADIUS) {
91+ DrawVehicleTurnlights (vehicle, lightsStatus);
92+ if (vehicle->m_pTractor )
93+ DrawVehicleTurnlights (vehicle->m_pTractor , lightsStatus);
94+ }
95+ }
96+ }
97+ };
98+ }
0 commit comments