Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,45 @@ static void Init()
return retval;
}));


fx::ScriptEngine::RegisterNativeHandler("NETWORK_SET_FIRST_ENTITY_OWNER", makeEntityFunction([](fx::ScriptContext& context, const fx::sync::SyncEntityPtr& entity)
{
auto resourceManager = fx::ResourceManager::GetCurrent();
auto instance = resourceManager->GetComponent<fx::ServerInstanceBaseRef>()->Get();
auto clientRegistry = instance->GetComponent<fx::ClientRegistry>();

auto playerSrc = context.GetArgument<const char*>(1);

int playerNetId = atoi(playerSrc);
if (playerNetId == 0)
{
throw std::runtime_error(va("NETWORK_SET_FIRST_ENTITY_OWNER: invalid player: %s", playerSrc));
}

bool firstOwnerExists = !!entity->GetFirstOwner();
bool hasClient = !!entity->GetClient();

// We only allow this to be set whenever we don't have an initial owner and the entity isn't already sync'd to clients
if (firstOwnerExists || hasClient)
{
fx::scripting::Warningf("net", "Tried to set the first owner for entity: %u but it already had an owner or client, hasFirstOwner: %d, hasClient: %d", context.GetArgument<uint32_t>(0), firstOwnerExists, hasClient);
return false;
}

auto client = clientRegistry->GetClientByNetID(playerNetId);
if (!client)
{
return false;
}

// set all of the owner fields that are expected, this is safe since this shouldn't be broadcasted yet if we just created the entity.
entity->GetFirstOwnerUnsafe() = client;
entity->GetLastOwnerUnsafe() = client;
entity->GetClientUnsafe() = client;

return true;
}));

fx::ScriptEngine::RegisterNativeHandler("SET_ENTITY_ORPHAN_MODE", [](fx::ScriptContext& context)
{
// get the current resource manager
Expand Down
37 changes: 37 additions & 0 deletions ext/native-decls/NetworkSetFirstEntityOwner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
ns: CFX
apiset: server
---
## NETWORK_SET_FIRST_ENTITY_OWNER

```c
void NETWORK_SET_FIRST_ENTITY_OWNER(Entity entity, char* playerSrc);
```

**WARNING**: This native is not planned to be ported to Enhanced. You should make sure this native exists before calling it.

In Lua you can do this by doing `if NetworkSetFirstEntityOwner then` in JS you can do this by checking that `typeof globalThis.NetworkGetFirstEntityOwner === "function"`.

If you fail to do this when enhanced is released, it is likely that native will error and you will be expected to fix it.

**NOTE**: This only works for server created entities, and only work in the same tick that the server-created entity was made, trying to call this after an owner has been assigned will do nothing.

This native sets the first entity owner for server-created entitys in order to reduce the migration the server might do with the entity.

## Parameters
* **entity**: The entity to set the first owner for.
* **playerSrc**: The player to set as the owner

## Examples
```lua
-- for this example we just get the first player
local player = GetPlayers()[1]

-- create the helicopter
local heli = CreateVehicleServerSetter(`seasparrow`, 'heli', GetEntityCoords(GetPlayerPed(player)) + vector3(0, 0, 15), 0.0)

-- and set the first entity owner to the player
if NetworkSetFirstEntityOwner then
NetworkSetFirstEntityOwner(heli, player)
end
```
Loading