[Help] Making server sided npcs invincible for clients

Hi first of all. Sorry, I tried creating a topic in another category but I wasnt allowed to do so :(.

I am making a copchase server where you can start a event called copchase and people can join. Everything works just fine. There are shops that can be robbed etc.

At first I made a /rob command for the robber to rob a store. But I wanted to make it better by spawning in NPCs on the server side like so (which works):

local shopKeeperLocations =  {{loc = vector3(26.49102, -1345.805, 29.49702), name = "South LS Convenient store", isRobbed = false, maxCash = 5000, ped = nil, model = "mp_m_shopkeep_01", heading = 0.0}, {loc = vector3(146.6646, -1044.801, 29.37783), name = "Bank", isRobbed = false, maxCash = 10000, ped = nil, model = "s_f_y_airhostess_0", heading = 0.0},

{loc = vector3(22.53048, -1106.929, 29.79703), name = "Central LS Ammunation", isRobbed = false, maxCash = 7500, ped= nil, model = "s_m_y_ammucity_01", heading = 0.0}, {loc = vector3(130.2697, -1285.411, 29.27999), name = "Stripclub", isRobbed = false, maxCash = 35000, ped = nil, model = "s_f_y_bartender_01", heading = 0.0},

{loc = vector3(-48.60311, -1756.754, 29.42101), name = "Davis Gas station", isRobbed = false, maxCash = 5000, ped = nil, model = "mp_m_shopkeep_01", heading = 0.0}, {loc = vector3(841.8622, -1033.938, 28.19485), name = "East LS Gun shop", isRobbed = false, maxCash = 5000, ped = nil, model ="s_m_y_ammucity_01", heading = 0.0},

for index, value in ipairs(shopKeeperLocations) do

    local ped = CreatePed(1, value.model, value.loc.x, value.loc.y, value.loc.z, value.heading, true, true)

    value.ped = ped

    FreezeEntityPosition(ped, true)

end

RegisterNetEvent("CallForShopkeepers")

AddEventHandler("CallForShopkeepers", function ()

    TriggerClientEvent("GetShopKeepers", source, shopKeeperLocations)

end)

The CallForShopkeepers event will be called by clients once they join the server so they have access to the NPCs that are spawned in on the server side.

Two things dont work, or work halfway:

  1. The native FreezeEntityPosition(ped, true) seems to work sometimes. Sometimes the npcs run in place when you aim a gun on them (which is fine) but, the other time they just run away while they should have been frozen.

  2. I tried to make these npcs invincible using the native: SetEntityInvincible(value.ped, true)

This native is called once on the client for all the spawned npcs in the array shopKeeperLocations once the players spawn into the server. However when the client shoots at the npcs they still die.

Client side script:

RegisterNetEvent('GetShopKeepers')
AddEventHandler('GetShopKeepers', function(shopKeepers)
    print("Setting up shopkeepers")
    robberyLocations = shopKeepers
end)

AddEventHandler('MakeNPCInvincible', function()
    print("MakingPedsInvincible")

    for index, value in ipairs(robberyLocations) do
                SetEntityInvincible(value.ped, true)
            end
    end
    end)

MakeNPCInvincible event is called once, when the players spawn in for the first time. Also the prints are being printed so I can safely say they reach that block of code and when I tried printing the peds in the array they also seem to be there and not nil or something ^^.

Anyone have an idea why it wont work? Also sorry if it may be a bit confusing, first time trying to get help :stuck_out_tongue: .

Thanks in advance!

I always spawn my peds on the client side, not sure if it’s a real difference though.

What I always do:

SetPedCanRagDoll(value.ped, false)
SetPedFleeAttributes(value.ped, 0, 0)
SetPedAsMissionEntity(value.ped, true, true)
SetEntityInvincible(value.ped, true)
SetPedDiesWhenInjured(value.ped, false)
SetEntityProofs(value.ped, true, true, true, true, true, true, true, true)

What could be the problem is that it doesn’t know “value” and that it therefor can’t “proof” the ped

1 Like

Thanks for the reply :)!

Sorry if it may be a stupid question but what do you mean with it may not know “value”?

Also if I remembered correctly the documentation said when you use the CreatePed native on server side it automaticly made it a MissionEntity.

I tried your natives in the client side where I tried to make them invincible. Still same problem(s).
However in the same client script I have the following block of code which iterates through the same array:

 for index, value in ipairs(robberyLocations) do
              if GetEntityPlayerIsFreeAimingAt(PlayerId(), value.ped) then

which returns true when you aim on one of the spawned in npcs.
(this is to check if you are robbing a store instead of the /rob command)

I guess I should switch to spawning in the NPCs on the client side? :frowning:
I was hoping this could work. So I dont have to do the request model etc :stuck_out_tongue: (lazy hehe)

Also is there something like authority? What do I mean with authority:

The NPCs are spawned by the server so, only the server has authority over these NPCs?
Thus when a client tries to modify its behaviour for example making it invincible its not allowed because the client doesnt have authority over the NPC only the server?

I think I fixed the issue where they are sometimes unfrozen (one of the peds I tried to create had an invalid model, I guess that was part of a problem) however the invincible thingy is still a problem.

This will not save the peds in shopKeeperLocations, because value is a local value here. It should be used for reading, not writing. You should save the peds as shopKeeperLocations[index].ped = ped

Here you are sending shopKeeperLocations table to the client. You think that this also includes the ped handle but it doesn’t. This includes the SERVER’S PED HANDLE. You will need to convert it to a netID using NetworkGetNetworkIdFromEntity - FiveM Natives @ Cfx.re Docs BEFORE sending it to the client.

After you receive the netIDs from the server, you will need to convert them to client entity ids using NetToPed - FiveM Natives @ Cfx.re Docs
WARNING: Just because a ped is created on the server, that doesn’t mean all clients are aware of it. NetToPed() can fail, if the server-side ped is not in the client’s scope.

Again, you need to make sure that value.ped is the client’s ped handle, not server’s ped handle.

Check the comments above. 99% of the time, the peds will not be in player’s reach to make the invincible.

Additional comments:

  • The safest way to handle this is to first test with peds, how they spawn server-side and how pedID > netID > pedID is handled. (each client, and the server have different handle ids for the same entity)
  • When you do stuff to the ped client-side, best practice is to check if that entity exists first (DoesEntityExist - FiveM Natives @ Cfx.re Docs)
  • My suggestion is to run ‘MakeNPCInvincible’ when the player approaches the bank.
1 Like
This will not save the peds in shopKeeperLocations, because value is a local value here. It should be used for reading, not writing. You should save the peds as shopKeeperLocations[index].ped = ped

Oof I certainly should have know that one. :man_facepalming:

Wow thank you so much! I now have a waaay better understanding how to deal with peds. I have no doubt that I can fix my problems with this information.
Again thanks for the time! Really appreciated.

1 Like

All my problems are fixed with your information thanks again.

I have one more question though if you dont mind :stuck_out_tongue:

It indeed happened that NedToPed failed and the entity didnt exist on client side. Is there a way to make the client aware of the ped and respawn it for that client? Instead of creating a new ped or is that impossible?

Didnt know if I should have opened a different topic for this question as it seems to me its kinda a follow-up thingy.

The ped still exists on the server, it’s just that the client is not aware of it unless it’s in the client’s scope (so, like, near the player).

netID remains the same, so it’s safe to just try and find the client ped associated with the netID, whenever the client is in the proximity of that ped. You can run a loop until DoesEntityExist - Natives @ Cfx.re Docs returns true, but that will leave the client to a lot of while-true loops.

1 Like