Jump to content

Client/Server sync questions


Recommended Posts

Hello community!

I have some simple questions about the usage of client sided Scripts.

Unfortunately, "onVehicleDamage" server side is very slow, I can't cancel it and it has almost no parameters. Now I have to use the client variant "onClientVehicleDamage".

I want to check the damage (loss parameter), cancel the event and reduce the loss (only 1/3 damage should be applied). This works great on my client but when I use setElementHealth on my client, will this sync with the server when the vehicle is not controlled by the localPlayer? I think I have to use triggerServerEvent but when the vehicle is on fire, it would call triggerServerEvent a thousand times...

And if two clients are on the same place, this event gets triggered twice, am I right?

Or will onClientVehicleDamage only trigger for the client that is currently syncing the vehicle? If that's the case, is it possible to use setElementHealth on the "vehicle syncing client"? Or are vehicles synced by the server itself? Questions over questions.

Greetings, the 101

Link to comment
  • MTA Team

Try this solution. It synchronizes the damage multiplier with the server and each client handles the damage themself.

CLIENT

local vehicleDamage = {} 
  
addEventHandler("onClientResourceStart", resourceRoot, 
    function () 
        local vehicles = getElementsByType("vehicle", root, true) 
        if #vehicles > 0 then 
            triggerServerEvent("onClientElementStreamIn", resourceRoot, vehicles) 
        end 
    end 
) 
  
addEventHandler("onClientElementStreamIn", root, 
    function () 
        vehicleDamage[source] = 1.0 
        triggerServerEvent("onClientElementStreamIn", resourceRoot, source) 
    end 
) 
  
addEventHandler("onClientElementStreamOut", root, 
    function () 
        vehicleDamage[source] = nil 
    end 
) 
  
addEventHandler("onClientElementDestroy", root, 
    function () 
        vehicleDamage[source] = nil 
    end 
) 
  
addEvent("onClientVehicleDamageSync", true) 
addEventHandler("onClientVehicleDamageSync", resourceRoot, 
    function (vehicle, multiplier) 
        vehicleDamage[vehicle] = multiplier 
    end 
) 
  
addEventHandler("onClientVehicleDamage", root, 
    function (_, _, loss) 
        if vehicleDamage[source] then 
            setElementHealth(source, getElementHealth(source) - (loss * vehicleDamage[source])) 
            cancelEvent() 
        end 
    end 
) 
  

SERVER

DAMAGE_MULTIPLIER = 0.30 
  
addEvent("onClientElementStreamIn", true) 
addEventHandler("onClientElementStreamIn", resourceRoot, 
    function (data) 
        if type(data) == "vehicle" then 
            for index, vehicle in pairs(data) do 
                if isElement(vehicle) then 
                    triggerClientEvent(client, "onClientVehicleDamageSync", resourceRoot, vehicle, DAMAGE_MULTIPLIER) 
                end 
            end 
        else if isElement(data) then 
            triggerClientEvent(client, "onClientVehicleDamageSync", resourceRoot, data, DAMAGE_MULTIPLIER) 
        end 
    end 
) 
  

Link to comment

My damage multiplier is always 0.3.

That means, I can use just the client side setElementHealth?

addEventHandler("onClientVehicleDamage", root, 
    function (_, _, loss) 
            setElementHealth(source, getElementHealth(source) - (loss *0.3)) 
            cancelEvent() 
    end 
) 

And the sync of the damage will be fine without issues and triggerServerEvent?

Link to comment
  • Moderators
That means, I can use just the client side setElementHealth?

Yes you can, the syncer(there is always one) will update the health for all. For the vehicles without a syncer, that might give some unexpected results. You will need to test everything properly.

About something related to your script:

But you have to keep in mind that the loss of the onClientVehicleDamage event isn't always the same as the damage that has been done.

Example:

Your vehicle has [b]1000 health[/b]. Your [b]damage is 400[/b] and then the [b]loss will be also 400[/b]. 
Your vehicle health will be set too: [b]1000-(400*0.3) = 880 hp[/b] 
  
But when your vehicle has [b]400 health[/b] and the [b]damage is 800[/b]. Then your loss will be [b]400[/b]. 
Your remaining health will be: [b]400*0.3 = 120 hp[/b] 

This isn't really a big problem because the burning starts at 250 hp. But keep it in mind that the results might not always be correct.

Link to comment

Thats no problem. Thanks a lot for the info, mate.

I will see what unexpected results there are when no player is syncing the vehicle but if there is no syncer (player), then the damaged vehicle should nowhere be streamed in and that means, no player could harm the vehicle if its not visible.

My biggest fear was, that eventually 3 or more players are calculating the damage like:

2000 health, 400 loss

3 players calculate and update the server:

3* 400 = 1200 loss for the server

But if only one player does this job, everything is fine.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...