Skip to content

Commit 5328ddb

Browse files
committed
Add turnlights feature
1 parent ce89892 commit 5328ddb

4 files changed

Lines changed: 127 additions & 0 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,4 @@ build/obj/Win32/Debug/handlebar.obj
251251
build/obj/Win32/Debug/remap.obj
252252
build/obj/Win32/Release/handlebar.obj
253253
build/obj/Win32/Release/remap.obj
254+
build/obj/Win32/Debug/turnlights.obj

src/dllmain.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "features/vehicle/gear.h"
66
#include "features/vehicle/plate.h"
77
#include "features/vehicle/handlebar.h"
8+
#include "features/vehicle/turnlights.h"
89
#include "features/weapon/bodystate.h"
910
#include "features/weapon/bloodremap.h"
1011
#include "features/common/randomizer.h"
@@ -16,6 +17,7 @@ static ThiscallEvent <AddressList<0x5343B2, H_CALL>, PRIORITY_BEFORE, ArgPickN<C
1617
static void InitFeatures() {
1718
Remap.Initialize();
1819
Randomizer.Initialize();
20+
TurnLights.Initialize();
1921
}
2022

2123
static void ProcessNodesRecursive(RwFrame * frame, void* pEntity, eModelEntityType type) {
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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+
}

src/features/vehicle/turnlights.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
#include "plugin.h"
3+
#include "../../interface/ifeature.hpp"
4+
5+
enum class eLightsStatus {
6+
Off,
7+
Left,
8+
Right,
9+
Both
10+
};
11+
12+
class TurnLightsFeature : public IFeature {
13+
protected:
14+
struct VehData {
15+
eLightsStatus lightsStatus;
16+
17+
VehData(CVehicle *) : lightsStatus(eLightsStatus::Off) {}
18+
};
19+
20+
VehicleExtendedData<VehData> vehData;
21+
22+
public:
23+
void Initialize();
24+
};
25+
26+
extern TurnLightsFeature TurnLights;

0 commit comments

Comments
 (0)