Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(es_extended/server/classes/vehicle): add vehicle class #1555

Merged
merged 23 commits into from
Jan 14, 2025

Conversation

Kenshiin13
Copy link
Contributor

@Kenshiin13 Kenshiin13 commented Dec 20, 2024

Description

This PR introduces a robust vehicle class to the ESX framework, offering developers a standardized way to manage owned vehicle entities in FiveM.


Motivation

The primary motivation for this addition is to address the challenges of managing owned vehicles reliably in a multiplayer environment. Specifically, this class enables developers to:

  • Determine if an owned vehicle is spawned or not: With this class, it's straightforward to check whether a specific vehicle is currently active in the world or has been despawned.

  • Ensure vehicle validity: By leveraging entity statebags, the system ensures that each tracked vehicle is indeed the one that was created, avoiding issues caused by network ID reassignment (a common occurrence when entities are deleted and new ones are created).


Implementation Details

  1. Entity Statebags
    Each vehicle is assigned the owner's identifier and plate in its statebag at the time of creation. This ensures that, regardless of entity lifecycle events, the vehicle can still be uniquely and reliably identified. The plate stored in the statebag acts as an additional tool for validation, as it is a crucial identifier for vehicles. Using the statebag for the plate, instead of relying on fetching the vehicle plate through natives, avoids potential race conditions. Native RPCs take time to propagate changes to the entity, so if a script were to perform an operation on a vehicle class object immediately after creation, there could be a mismatch between the plate the class expects and the plate set on the entity in the game. This mismatch could cause the class to invalidate the entity incorrectly. Storing the plate in the statebag ensures consistency and immediate access to the correct data.

  2. Automatic Validation
    The isValid function plays a critical role in maintaining the integrity of the vehicle object. It checks the existence and validity of the associated entity in the world. The class automatically invokes isValid on every action (e.g., getting the netId, setting the vehicle properties, or getting the entity handle). This guarantees that actions are always performed on up-to-date and valid entities.


Usage Example

AddEventHandler("esx:createdExtendedVehicle", function(xVehicle)
    print("[esx:createdExtendedVehicle] VEHICLE NET ID", xVehicle:getNetId())         -- Output: <netId>
    print("[esx:createdExtendedVehicle] VEHICLE ENTITY", xVehicle:getEntity())        -- Output: <entityHandle>
    print("[esx:createdExtendedVehicle] VEHICLE PLATE", xVehicle:getPlate())          -- Output: "ESX"
    print("[esx:createdExtendedVehicle] VEHICLE MODEL HASH", xVehicle:getModelHash()) -- Output: <modelHash>
    print("[esx:createdExtendedVehicle] VEHICLE OWNER", xVehicle:getOwner())
end)

AddEventHandler("esx:deletedExtendedVehicle", function(xVehicle)
    print("[esx:deletedExtendedVehicle] VEHICLE NET ID", xVehicle:getNetId())         -- Output: <netId>
    print("[esx:deletedExtendedVehicle] VEHICLE ENTITY", xVehicle:getEntity())        -- Output: <entityHandle>
    print("[esx:deletedExtendedVehicle] VEHICLE PLATE", xVehicle:getPlate())          -- Output: "NEWPLATE"
    print("[esx:deletedExtendedVehicle] VEHICLE MODEL HASH", xVehicle:getModelHash()) -- Output: <modelHash>
    print("[esx:deletedExtendedVehicle] VEHICLE OWNER", xVehicle:getOwner())          -- Output: "char1:12754a0705e35cda21ced87c7daf329730135087"
end)

AddEventHandler("esx:changedExtendedVehiclePlate", function(newPlate, oldPlate)
    if xVehicle.plate == oldPlate then
        xVehicle.plate = newPlate
    end
end)

xVehicle = ESX.CreateExtendedVehicle("char1:12754a0705e35cda21ced87c7daf329730135087", "ESX", vector4(-204.5230, -1703.2838, 33.4497, 91.1210))
if not xVehicle then
    return
end

print("VEHICLE NET ID", xVehicle:getNetId())         -- Output: <netId>
print("VEHICLE ENTITY", xVehicle:getEntity())        -- Output: <entityHandle>
print("VEHICLE PLATE", xVehicle:getPlate())          -- Output: "ESX"
print("VEHICLE MODEL HASH", xVehicle:getModelHash()) -- Output: <modelHash>
print("VEHICLE OWNER", xVehicle:getOwner())          -- Output: "char1:12754a0705e35cda21ced87c7daf329730135087"

local success = xVehicle:setPlate("NEWPLATE")
if not success then
    print("Vehicle has been invalidated")
    return
end
print("VEHICLE PLATE", xVehicle:getPlate()) -- Output: "NEWPLATE"

local xVehicle2 = ESX.GetExtendedVehicleFromPlate("NEWPLATE")
if not xVehicle2 then
    print("Vehicle not found")
    return
end
print("SECOND VEHICLE PLATE", xVehicle2:getPlate()) -- Output: "NEWPLATE"

local xVehicle3 = ESX.CreateExtendedVehicle("char1:12754a0705e35cda21ced87c7daf329730135087", "NEWPLATE", vector4(-204.5230, -1703.2838, 33.4497, 91.1210))
if not xVehicle3 then
    return
end
print("THIRD VEHICLE PLATE", xVehicle3:getPlate()) -- Output: "NEWPLATE"

xVehicle:delete()
print("[AFTER DELETION] VEHICLE NET ID", xVehicle:getNetId() or "nil")  -- Output: "nil"
print("[AFTER DELETION] SECOND VEHICLE NET ID", xVehicle2:getNetId() or "nil") -- Output: "nil" (points to the same entity as xVehicle)
print("[AFTER DELETION] THIRD VEHICLE NET ID", xVehicle3:getNetId() or "nil") -- Output: "nil" (points to the same entity as xVehicle)

PR Checklist

  • My commit messages and PR title follow the Conventional Commits standard.
  • My changes have been tested locally and function as expected.
  • My PR does not introduce any breaking changes.
  • I have provided a clear explanation of what my PR does, including the reasoning behind the changes and any relevant context.

@Kenshiin13 Kenshiin13 self-assigned this Dec 21, 2024
@Kenshiin13 Kenshiin13 marked this pull request as ready for review December 21, 2024 13:27
@Kenshiin13 Kenshiin13 mentioned this pull request Dec 23, 2024
@Arctos2win Arctos2win merged commit e855be0 into esx-framework:dev Jan 14, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Ready for Next Update
Development

Successfully merging this pull request may close these issues.

3 participants