Skip to content

Commit

Permalink
Add turnlights feature
Browse files Browse the repository at this point in the history
  • Loading branch information
user-grinch committed Feb 8, 2024
1 parent ce89892 commit 5328ddb
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,4 @@ build/obj/Win32/Debug/handlebar.obj
build/obj/Win32/Debug/remap.obj
build/obj/Win32/Release/handlebar.obj
build/obj/Win32/Release/remap.obj
build/obj/Win32/Debug/turnlights.obj
2 changes: 2 additions & 0 deletions src/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "features/vehicle/gear.h"
#include "features/vehicle/plate.h"
#include "features/vehicle/handlebar.h"
#include "features/vehicle/turnlights.h"
#include "features/weapon/bodystate.h"
#include "features/weapon/bloodremap.h"
#include "features/common/randomizer.h"
Expand All @@ -16,6 +17,7 @@ static ThiscallEvent <AddressList<0x5343B2, H_CALL>, PRIORITY_BEFORE, ArgPickN<C
static void InitFeatures() {
Remap.Initialize();
Randomizer.Initialize();
TurnLights.Initialize();
}

static void ProcessNodesRecursive(RwFrame * frame, void* pEntity, eModelEntityType type) {
Expand Down
98 changes: 98 additions & 0 deletions src/features/vehicle/turnlights.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#include "pch.h"
#include "turnlights.h"
#include <CCoronas.h>
#include <CGeneral.h>

#define TURN_ON_OFF_DELAY 500
#define MAX_RADIUS 200.0f

TurnLightsFeature TurnLights;

static CVector2D GetCarPathLinkPosition(CCarPathLinkAddress &address) {
if (address.m_nAreaId != -1 && address.m_nCarPathLinkId != -1 && ThePaths.m_pPathNodes[address.m_nAreaId]) {
return CVector2D(static_cast<float>(ThePaths.m_pNaviNodes[address.m_nAreaId][address.m_nCarPathLinkId].m_vecPosn.x) / 8.0f,
static_cast<float>(ThePaths.m_pNaviNodes[address.m_nAreaId][address.m_nCarPathLinkId].m_vecPosn.y) / 8.0f);
}
return CVector2D(0.0f, 0.0f);
}

static void DrawTurnlight(CVehicle *vehicle, unsigned int dummyId, bool leftSide) {
CVector posn =
reinterpret_cast<CVehicleModelInfo *>(CModelInfo::ms_modelInfoPtrs[vehicle->m_nModelIndex])->m_pVehicleStruct->m_avDummyPos[dummyId];
if (posn.x == 0.0f) posn.x = 0.15f;
if (leftSide) posn.x *= -1.0f;
CCoronas::RegisterCorona(reinterpret_cast<unsigned int>(vehicle) + 50 + dummyId + (leftSide ? 0 : 2), vehicle, 255, 128, 0, 255, posn,
0.3f, 150.0f, CORONATYPE_SHINYSTAR, eCoronaFlareType::FLARETYPE_NONE, false, false, 0, 0.0f, false, 0.5f, 0, 50.0f, false, true);
}

static void DrawVehicleTurnlights(CVehicle *vehicle, eLightsStatus lightsStatus) {
if (lightsStatus == eLightsStatus::Both || lightsStatus == eLightsStatus::Right) {
DrawTurnlight(vehicle, 0, false);
DrawTurnlight(vehicle, 1, false);
}
if (lightsStatus == eLightsStatus::Both || lightsStatus == eLightsStatus::Left) {
DrawTurnlight(vehicle, 0, true);
DrawTurnlight(vehicle, 1, true);
}
}

static float GetZAngleForPoint(CVector2D const &point) {
float angle = CGeneral::GetATanOfXY(point.x, point.y) * 57.295776f - 90.0f;
while (angle < 0.0f) angle += 360.0f;
return angle;
}

void TurnLightsFeature::Initialize() {
Events::vehicleRenderEvent.before += [this](CVehicle *vehicle) {
VehData &data = vehData.Get(vehicle);
if ((vehicle->m_nVehicleSubClass == VEHICLE_AUTOMOBILE || vehicle->m_nVehicleSubClass == VEHICLE_BIKE) &&
(vehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_AUTOMOBILE || vehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE) &&
vehicle->m_nVehicleFlags.bEngineOn && vehicle->m_fHealth > 0 && !vehicle->m_nVehicleFlags.bIsDrowning && !vehicle->m_pAttachedTo )
{
eLightsStatus &lightsStatus = data.lightsStatus;
if (vehicle->m_pDriver) {
CPed *playa = FindPlayerPed();
if (playa && playa->m_pVehicle == vehicle && playa->m_nPedFlags.bInVehicle) {
if (KeyPressed(90)) // Z
lightsStatus = eLightsStatus::Left;
else if (KeyPressed(88)) // X
lightsStatus = eLightsStatus::Both;
else if (KeyPressed(67)) // C
lightsStatus = eLightsStatus::Right;
else if (KeyPressed(VK_SHIFT))
lightsStatus = eLightsStatus::Off;
}
else {
lightsStatus = eLightsStatus::Off;

CVector2D prevPoint = GetCarPathLinkPosition(vehicle->m_autoPilot.m_nPreviousPathNodeInfo);
CVector2D currPoint = GetCarPathLinkPosition(vehicle->m_autoPilot.m_nCurrentPathNodeInfo);
CVector2D nextPoint = GetCarPathLinkPosition(vehicle->m_autoPilot.m_nNextPathNodeInfo);

float angle = GetZAngleForPoint(nextPoint - currPoint) - GetZAngleForPoint(currPoint - prevPoint);
while (angle < 0.0f) angle += 360.0f;
while (angle > 360.0f) angle -= 360.0f;

if (angle >= 30.0f && angle < 180.0f)
lightsStatus = eLightsStatus::Left;
else if (angle <= 330.0f && angle > 180.0f)
lightsStatus = eLightsStatus::Right;

if (lightsStatus == eLightsStatus::Off) {
if (vehicle->m_autoPilot.m_nCurrentLane == 0 && vehicle->m_autoPilot.m_nNextLane == 1)
lightsStatus = eLightsStatus::Right;
else if (vehicle->m_autoPilot.m_nCurrentLane == 1 && vehicle->m_autoPilot.m_nNextLane == 0)
lightsStatus = eLightsStatus::Left;
}
}
}
if (CTimer::m_snTimeInMilliseconds % (TURN_ON_OFF_DELAY * 2) < TURN_ON_OFF_DELAY) {
if (DistanceBetweenPoints(TheCamera.m_vecGameCamPos, vehicle->GetPosition()) < MAX_RADIUS) {
DrawVehicleTurnlights(vehicle, lightsStatus);
if (vehicle->m_pTractor)
DrawVehicleTurnlights(vehicle->m_pTractor, lightsStatus);
}
}
}
};
}
26 changes: 26 additions & 0 deletions src/features/vehicle/turnlights.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once
#include "plugin.h"
#include "../../interface/ifeature.hpp"

enum class eLightsStatus {
Off,
Left,
Right,
Both
};

class TurnLightsFeature : public IFeature {
protected:
struct VehData {
eLightsStatus lightsStatus;

VehData(CVehicle *) : lightsStatus(eLightsStatus::Off) {}
};

VehicleExtendedData<VehData> vehData;

public:
void Initialize();
};

extern TurnLightsFeature TurnLights;

0 comments on commit 5328ddb

Please sign in to comment.