add server-side and client-side entity spawn wrappers and shared helper#762
add server-side and client-side entity spawn wrappers and shared helper#762TGIANN wants to merge 2 commits into
Conversation
Add `lib.createObject`, `lib.createPed`, and `lib.createVehicle` for the server, plus a shared `lib.spawnEntity` helper used by both client and server wrappers. Each wrapper splits its body at module load time based on `cache.game` so that the correct CREATE_OBJECT/PED/VEHICLE native signature is used on FiveM vs RedM. Server wrappers default `orphanMode` to 2 (KeepEntity). Server `createVehicle` uses `CreateVehicleServerSetter` (with `vehicleType`) on FiveM and the CFX `CreateVehicle` native on RedM, where `vehicleType`, `properties`, and `seat` are not exposed. Existing client wrappers were refactored to delegate model loading to `lib.spawnEntity`, with a few client-side fixes folded in: - pass heading as the float arg in `SetEntityHeading` for createObject - replace undefined `netMissionEntity` with `isNetwork` in createPed - drop duplicate `isNetwork` assert in createPed - mark `isNetwork`, `netMissionEntity`, and `doorFlag` as optional in the type annotations to match runtime behavior
| 'imports/spawnEntity/server.lua', | ||
| 'imports/createObject/server.lua', | ||
| 'imports/createPed/server.lua', | ||
| 'imports/createVehicle/server.lua', |
| ---@alias SeatPosition | ||
| ---| -2 # SF_ANY | ||
| ---| -1 # SF_FrontDriverSide | ||
| ---| 0 # SF_FrontPassengerSide | ||
| ---| 1 # SF_BackDriverSide | ||
| ---| 2 # SF_BackPassengerSide | ||
| ---| 3 # SF_AltFrontDriverSide | ||
| ---| 4 # SF_AltFrontPassengerSide | ||
| ---| 5 # SF_AltBackDriverSide | ||
| ---| 6 # SF_AltBackPassengerSide |
There was a problem hiding this comment.
It would be best to have a types file or have game types like this defined as part of fivem-lls-addon.
|
My biggest issues with this are
I'd personally want to see classes used for any entity wrappers, e.g. lib.entity as a base class inherited by lib.object, lib.ped, lib.vehicle with some common methods across server and client. Networked entities from clients are also somewhat discouraged and potentially disabled on many servers, so focusing on server-created entities is more important. |
I've re edit everything. If everything is as you want and there are no issues, I can prepare the docs test script |
There was a problem hiding this comment.
This is usable but I might need to do some planning for a future implementation to ensure its fully fit for purpose. This can also work into a proposal for a custom statebag interface and would need a solid TS implementation too.
Things like resource management/cleanup, grid handling, etc. would probably be necessary for any (local) client entities too.
| ---@class Entity : OxClass | ||
| ---@field handle number Native entity handle. | ||
| ---@field script string Resource that created or wrapped this entity. | ||
| local Entity = lib.class('Entity') |
There was a problem hiding this comment.
You'll need to use lib.entity from the start. Assigning the value later results in private and protected fields giving errors. Same applies to the other classes of course.
| ---to wrap any pre-existing entity, or as the parent of `lib.object`, `lib.ped`, and | ||
| ---`lib.vehicle` for typed spawn wrappers. | ||
| ---@class Entity : OxClass | ||
| ---@field handle number Native entity handle. |
There was a problem hiding this comment.
Unfortunately there's no readonly annotation, but always good to tell people not to mess with values.
| assert(handleType == 'number' and handle ~= 0, ('expected non-zero entity handle, got %s (%s)'):format(handleType, tostring(handle))) | ||
|
|
||
| self.handle = handle | ||
| self.script = GetInvokingResource() or cache.resource |
| ---Returns the entity's state bag. | ||
| function Entity:getState() | ||
| return getEntityStateBag(self.handle).state | ||
| end |
There was a problem hiding this comment.
I'd scrap this for now, in case we do our own statebag handling (#778)
| if IS_SERVER and cache.game ~= 'redm' then | ||
| self:setOrphanMode(data.orphanMode or 2) | ||
| end |
There was a problem hiding this comment.
cache.game on the server will be 'fxserver'.
| function Entity:onAfterRespawn(data) end | ||
|
|
||
| if IS_SERVER then | ||
| local allowClientServerEntityCreation = GetConvarInt('ox:allowClientServerEntityCreation', 0) == 1 |
There was a problem hiding this comment.
For now let's just focus solely on class wrappers and not implementing RPCs.
| return CreateObject(modelHash, data.coords.x, data.coords.y, data.coords.z, | ||
| true, data.bScriptHostObj or false, data.dynamic or false, data.p7 or false, data.p8 or false) | ||
| end | ||
|
|
||
| return CreateObject(modelHash, data.coords.x, data.coords.y, data.coords.z, true, true, data.doorFlag or false) |
There was a problem hiding this comment.
CreateObject is an RPC; the server needs to use CreateObjectNoOffset.
| ---Base class wrapping a CFX entity handle. Used directly via `lib.entity:new(handle)` | ||
| ---to wrap any pre-existing entity, or as the parent of `lib.object`, `lib.ped`, and | ||
| ---`lib.vehicle` for typed spawn wrappers. | ||
| ---@class Entity : OxClass |
There was a problem hiding this comment.
This should probably be GameEntity.
Add
lib.createObject,lib.createPed, andlib.createVehiclefor the server, plus a sharedlib.spawnEntityhelper used by both client and server wrappers. Each wrapper splits its body at module load time based oncache.gameso that the correct CREATE_OBJECT/PED/VEHICLE native signature is used on FiveM vs RedM.Server wrappers default
orphanModeto 2 (KeepEntity). ServercreateVehicleusesCreateVehicleServerSetter(withvehicleType) on FiveM and the CFXCreateVehiclenative on RedM, wherevehicleType,properties, andseatare not exposed.Existing client wrappers were refactored to delegate model loading to
lib.spawnEntity, with a few client-side fixes folded in:SetEntityHeadingfor createObjectnetMissionEntitywithisNetworkin createPedisNetworkassert in createPedisNetwork,netMissionEntity, anddoorFlagas optional in the type annotations to match runtime behavior