Jump to content

Make Client-side Object Visible Server-side


Recommended Posts

Hello guys!

I have a question (again) and now i want to know, how to make this script server-sided so the object "helm" can be seen by every player. At the moment this obect can only be seen by the client because the "helm" is created and moved in a client-sided script.

I hope anybody is able to help!

helm = nil 
helmart = nil 
zahl = 0 
  
function stahlhelm() 
    if (zahl ~= nil or zahl ~= 0) then 
    rz = getPedRotation (getLocalPlayer()) 
    px, py, pz = getPedBonePosition(getLocalPlayer(), 8) 
    px = px+( ( math.cos ( math.rad ( rz ) ) ) * 0.02 ) - math.sin ( math.rad ( rz ) ) * 0.007 
    py = py+( ( math.sin ( math.rad ( rz ) ) ) * 0.02 ) + math.cos ( math.rad ( rz ) ) * 0.007 
            if (zahl == 1) then 
        if (helmart == 1) or (helmart == 2) then 
                setElementPosition (helm, px, py, pz+0.1 ) 
                setElementRotation (helm, 0,0,(rz-180) ) 
        else 
        setElementPosition (helm, px, py, pz+0.112 ) 
                setElementRotation (helm, 0,0,(rz-180) ) 
        end 
        end 
    end 
end 
addEventHandler ( "onClientPreRender", getRootElement(), stahlhelm ) 
  
  
function helmi(player, helmart) 
helmart = tonumber(helmart) 
if (helmart == "" or helmart == nil) then 
    outputChatBox ( "Valid numbers are 0,1,2 and 3." ) 
end 
  
if (helmart == 0) then 
    destroyElement(helm) 
    zahl = 0 
end 
  
    if (helmart == 1) then 
    if (zahl == 0) then 
outputChatBox ( "Stahlhelm 1" ) 
        helm = createObject (2052, px, py, pz+0.11, 0, 0, rz ) -- tommy 
    setObjectScale(helm, 0.85) 
    setElementDoubleSided ( helm, true ) 
        zahl = 1 
    setElementData ( getLocalPlayer(), "helmeted", true ) 
    end 
end 
  
    if (helmart == 2) then 
    if (zahl == 0) then  
outputChatBox ( "Stahlhelm 2" ) 
        helm = createObject (2053, px, py, pz+0.11, 0, 0, rz ) -- jerry 
    setObjectScale(helm, 0.85) 
    setElementDoubleSided ( helm, true ) 
        zahl = 1 
    setElementData ( getLocalPlayer(), "helmeted", true ) 
    end 
end 
  
    if (helmart == 3) then 
    if (zahl == 0) then 
outputChatBox ( "Offiziersmütze" ) 
        helm = createObject (2054, px, py, pz+0.11, 0, 0, rz ) -- officer 
    setObjectScale(helm, 0.85) 
    setElementDoubleSided ( helm, true ) 
        zahl = 1 
    setElementData ( getLocalPlayer(), "helmeted", true ) 
    end 
end 
  
    if (helmart > 3) then 
        outputChatBox ( "Valid numbers are 0,1,2 and 3." ) 
    end 
end 
addCommandHandler("stahl", helmi) 
  
function res() 
    outputChatBox("Stahlhelm by Einheit-101 loaded", 245,0,0) 
end 
addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), res) 
  

I also want to say, that i DO NOT WANT that this script is published by anyone. Thanks a lot.

Edited by Guest
Link to comment

You can create the object server-side and set its position client-side for every player. Though I don't know if that will work in 1.1 as dynamic objects are synced. If position of static objects is synced too, then MTA may override the position which is set by the script.

Link to comment

Hey i have tried to create the object server side and control it client side. But hey, thats breaking my brain :o

Server

  
helmart = nil 
  
addEvent "onPlayerHeadshot" 
addEventHandler("onPlayerDamage", getRootElement(), 
    function (attacker, weapon, bodypart, loss) 
        if bodypart == 9 then 
            local helmet = getElementData( source, "helmeted" ) 
            if (helmet == false) then 
            local result = triggerEvent("onPlayerHeadshot", source, attacker, weapon, loss) 
            if result == true then 
            killPed(source, attacker, weapon, bodypart) 
            end 
        end 
    end 
end 
) 
  
function helmi(sourcePlayer, cmd, helmart) 
helmart = tonumber(helmart) 
if (helmart == "" or helmart == nil) then 
    outputChatBox ( "Valid numbers are 0,1 and 2.", sourcePlayer ) 
end 
  
if (helmart == 0) then 
    destroyElement(helm) 
    setElementData ( sourcePlayer, "helmeted", false ) 
    triggerClientEvent("zahlnull", getRootElement(), helm) 
end 
  
    if (helmart == 1) then 
    setElementData ( sourcePlayer, "helmeted", true ) 
        helm = createObject (2052, 1, 0, 1 ) -- tommy 
    outputChatBox ( "Tommy helmet" ) 
    -- setObjectScale(helm, 0.85) 
    setElementDoubleSided ( helm, true ) 
    triggerClientEvent( "movehelm", getRootElement(), helm) 
end 
  
    if (helmart == 2) then 
    setElementData ( sourcePlayer, "helmeted", true ) 
        helm = createObject (2053, 1, 0, 1 ) -- jerry 
    outputChatBox ( "Jerry helmet" ) 
    -- setObjectScale(helm, 0.85) 
    setElementDoubleSided ( helm, true ) 
    triggerClientEvent( "movehelm", getRootElement(), helm) 
end 
    if (helmart > 2) then 
        outputChatBox ( "Valid numbers are 0,1 and 2." ) 
    end 
end 
addCommandHandler("stahl", helmi) 
  

Client

  
 helmet = nil 
zahl = 0 
player = getLocalPlayer() 
  
addEvent("movehelm", true) 
function lolmao(helm) 
helmet = helm 
zahl = 1 
end 
addEventHandler("movehelm", getRootElement(), lolmao) 
  
function stahlhelm(helmet) 
    if (zahl ~= 0) then 
if (getElementData(player, "helmeted") == true) then 
    rz = getPedRotation (player) 
    px, py, pz = getPedBonePosition(player, 8) 
    px = px+( ( math.cos ( math.rad ( rz ) ) ) * 0.02 ) - math.sin ( math.rad ( rz ) ) * 0.007 
    py = py+( ( math.sin ( math.rad ( rz ) ) ) * 0.02 ) + math.cos ( math.rad ( rz ) ) * 0.007 
            if (zahl == 1) then 
                setElementPosition (helmet, px, py, pz+0.1 ) 
                setElementRotation (helmet, 0,0,(rz-180) ) 
        end 
    end 
    end 
end 
addEventHandler ( "onClientPreRender", getRootElement(), stahlhelm ) 
  
addEvent("zahlnull", true) 
function nulll(helm) 
zahl = 0 
end 
addEventHandler("zahlnull", getRootElement(), nulll) 
  
function res() 
    outputChatBox("Stahlhelm by Einheit-101 loaded", 245,0,0) 
end 
addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), res) 
  

I really hope that someguy knows whats wrong, however, it seems that the client "function stahlhelm(helm)" does not know the object helm because i get a "bad argument @ setElementPosition" and "setElementRotation".... :redhotevil:

Edited by Guest
Link to comment

helm is a local variable of lolmao function, so stahlhelm isn't aware of it. If you stored helmet element into zahl variable, you could use this variable to set element position. Also, it is unknown what player variable in stahlhelm function is. You could use setElementData on helmet to store player element and getElementData to get the value client-side.

Link to comment

Okay I have changed some things like this:

  
function lolmao(helm) 
helmet = helm 
zahl = 1 
end 
addEventHandler("movehelm", getRootElement(), lolmao) 
... 
  

  
function stahlhelm(helmet) 
    if (zahl ~= 0) then 
if (getElementData(player, "helmeted") == true) then 
    rz = getPedRotation (player) 
... 
  

EDIT #1:::: You can watch the changed code a few posts above, ive edited it::::

EDIT #2:::: I still get lots of bad arguments @

stahlhelm.lua:20: Bad argument @ 'setElementPosition'

stahlhelm.lua:21: Bad argument @ 'setElementRotation'

::::

Link to comment

Hm okay but why does THAT not work? Thats my last question^^

  
 if (helmart == 1) then 
    setElementData ( sourcePlayer, "helmeted", true ) 
        helm = createObject (2052, 1, 0, 1 ) -- tommy 
    outputChatBox ( "Tommy helmet" ) 
    setObjectScale(helm, 0.85)  -- SET OBECT SCALE DOES NOT WORK 
    setElementDoubleSided ( helm, true ) -- ATTEMPT TO CALL GLOBEL BLABLA, NIL VALUE... 
    triggerClientEvent( "movehelm", getRootElement(), helm) 
  

Link to comment

Very Special Thanks to CrystalMV.

EDIT:::

Ive tried the final code, and the Object was visible For all players. But it moved client side, that means, if the script starts the Object spawns and does not move. Only the local player can see his own object moving, the others dont move and stay at their spawn.

I tried to avoid this by making the movement server-side, but now the Objects LAG LIKE HELL :redhotevil:

this is the newest code:

Clinet

helmet = nil 
zahl = 0 
player = getLocalPlayer() 
  
addEvent("movehelm", true) 
function lolmao(helm) 
helmet = helm 
zahl = 1 
end 
addEventHandler("movehelm", getRootElement(), lolmao) 
  
function stahlhelm() 
    if (zahl ~= 0) then 
if (getElementData(player, "helmeted") == true) then 
    rz = getPedRotation (player) 
    px, py, pz = getPedBonePosition(player, 8) 
    px = px+( ( math.cos ( math.rad ( rz ) ) ) * 0.02 ) - math.sin ( math.rad ( rz ) ) * 0.007 
    py = py+( ( math.sin ( math.rad ( rz ) ) ) * 0.02 ) + math.cos ( math.rad ( rz ) ) * 0.007 
            if (zahl == 1) then 
        setObjectScale(helmet, 0.85) 
        triggerServerEvent ( "movethehelm", getLocalPlayer(), px, py, pz, rz, helmet )  
        end 
    end 
    end 
end 
addEventHandler ( "onClientPreRender", getRootElement(), stahlhelm ) 
  
addEvent("zahlnull", true) 
function nulll(helm) 
zahl = 0 
end 
addEventHandler("zahlnull", getRootElement(), nulll) 
  
function res() 
    outputChatBox("Stahlhelm by Einheit-101 loaded", 245,0,0) 
end 
addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), res) 

Server

helmart = nil 
helm = nil 
  
addEvent "onPlayerHeadshot" 
addEventHandler("onPlayerDamage", getRootElement(), 
    function (attacker, weapon, bodypart, loss) 
        if bodypart == 9 then 
            local helmet = getElementData( source, "helmeted" ) 
            if (helmet == false) then 
            local result = triggerEvent("onPlayerHeadshot", source, attacker, weapon, loss) 
            if result == true then 
            killPed(source, attacker, weapon, bodypart) 
            end 
        end 
    end 
end 
) 
  
addEvent("movethehelm", true) 
function setPos(px, py, pz, rz, helmet) 
    setElementPosition (helmet, px, py, pz+0.1 ) 
    setElementRotation (helmet, 0,0,(rz-180) ) 
end 
addEventHandler("movethehelm", getRootElement(), setPos) 
  
function helmi(sourcePlayer, cmd, helmart) 
helmart = tonumber(helmart) 
if (helmart == "" or helmart == nil) then 
    outputChatBox ( "Valid numbers are 0,1 and 2.", sourcePlayer ) 
end 
  
if (helmart == 0) then 
    destroyElement(helm) 
    setElementData ( sourcePlayer, "helmeted", false ) 
    triggerClientEvent("zahlnull", getRootElement(), helm) 
end 
  
    if (helmart == 1) then 
    setElementData ( sourcePlayer, "helmeted", true ) 
        helm = createObject (2052, 1, 0, 1 ) -- tommy 
    outputChatBox ( "Tommy helmet" ) 
    setElementDoubleSided ( helm, true ) 
    triggerClientEvent( "movehelm", getRootElement(), helm) 
end 
  
    if (helmart == 2) then 
    setElementData ( sourcePlayer, "helmeted", true ) 
        helm = createObject (2053, 1, 0, 1 ) -- jerry 
    outputChatBox ( "Jerry helmet" ) 
    setElementDoubleSided ( helm, true ) 
    triggerClientEvent( "movehelm", getRootElement(), helm) 
end 
    if (helmart > 2) then 
        outputChatBox ( "Valid numbers are 0,1 and 2." ) 
    end 
end 
addCommandHandler("stahl", helmi) 

Link to comment
  • Moderators

I have only 1 question:

Why you don't create the ID 2053 for each players and make a setElementVisibleTo ?

Exemple:

if (helmart == 1) then 
    setElementData ( sourcePlayer, "helmeted", true ) 
    helm = createObject (2052, 1, 0, 1 ) -- tommy 
    setElementData( sourcePlayer, "helmobject", helm ) 
    setElementVisibleTo ( helm , getRootElement(), false ) -- hide for all 
    setElementVisibleTo ( helm , sourcePlayer, true ) -- show for sourcePlayer 
    outputChatBox ( "Tommy helmet" ) 

Then you just have to make a

local helm = getElementData( thePlayer, "helmobject" ) 

for retrieve the object and move it:

setElementPosition( helm, x, y, z ) 

But maybe it's not that you want ?

Link to comment
  • Moderators

Lol I make this for my food system like the singleplayer. It's works very well but it makes a triggerServerEvent in an onClientRender so you have to buy a good Server ^^

I explain this system:

The server make a triggerClientEvent and it's add an addEventHandler( "onClientRender", getLocalPlayer(), myFunction )

Then myFunction get the Bone position x, y, z and send thePlayer, x, y, z to the server with this: triggerServertEvent( "myOtherFunction", getLocalPlayer(),getLocalPlayer(), x, y, z )

Then myOtherFunction retreive the object ( getElementData( thePlayer, "object" ) ) and set the position to the x, y, z coordinates

It's easy but if you are 15 players who have 100 FPS, your function in the server will be called 1500 times per second :o

So make your choice :mrgreen:

Link to comment

Man, i make this already with my code, but my local host is totally ownd by just 4 players (My Home-PC is my Server, DSL 6000 xDDD)

so i need a rlly good server and my Playerlimit is 16 anyway and most of the players got just 30 FPS... :mrgreen::mrgreen:

:arrow: Suggestion:

developing "attachElementToBone" function or sth. like that :!:

PS: Citicen, congrats to your "101st" post, i like this number^^ 8)

Link to comment

I don't like whot you people are doing in here ;)

keep it simple and 99% clientside

helm should be a table clientside indexed by players

when player enter a comand - client send information to serwer (event on loacl player), then the server should send the information back to all players (event on root element), and create a helmet clientside and store it in a table helm

function starthelm should be for all players

players = geteEementsByType("player") 
for i,p in pairs(players) do 
if helm[p] then 
... 
end 
end 

Link to comment
  • Moderators

Oh I like this system but how do you call this function ?

Because in server side, there are no onServerRender or something like that and a timer of 50 ms is not enough fast for update the position of the object

PS: Citicen, congrats to your "101st" post, i like this number^^

lol and it's Citizen xD

Link to comment

you doing it clientside (read my post)

you using the server to retrive the data frome one client (player who enter the command), and send the data back to all clients (basic MP stuff) player is pased as source in handler function, and you may pass command arguments as arguments in the event

Link to comment
  • Moderators

I understood but we don't want that only one update from one client, but we want an update every frames and this update start when a player tape a command.

So each client update his table of position x, y, z in a onClientRender ( it's ok )

Then we want that the server get the table of position from all client every... hum I don't know but we want less than 50 milliseconds

So how do you make that unless a lot of triggerBlablaEvent per seconds ?

Link to comment

Impossible, my opinion. Client side only no problem, but the object has to be visible for all players (server side).

Contacting the server to create and move the object every "PreRender" needs too much resource and too much time.

So the object will lag and not move smoothly.

Link to comment

If you want object movement made client-side be visible for all players, then do it for all players. MTA doesn't need to have a function for attaching elements to bones. You can already make it yourself. Actually, it would be better to create such attaching system and then use it for helmet. Attaching system could be done in this way:

Attachments would be set by changing element data. Something like:

setElementData(object,"attached_player",player) 
setElementData(object,"attached_boneid",boneid) 

This could be done server-side. Then in client side onClientRender you could loop through all objects, check attachment data and if it exists, get the position of player bone and put an object there.

And after creating attachments system, you could use it for helmets. What's more, you could use it for other stuff without the need to rewrite the code.

Link to comment

try this, i did not test it with other players, there probably sgould be some garbage colecting on player quit

server

addEvent("onHelmCommand", true) 
addEvent("onFileDownload",true) 
helmlist = {} 
addEventHandler("onHelmCommand",getRootElement(),function(helmart) 
    helmlist[source] = helmart 
    triggerClientEvent(getRootElement(),"onHelmSyncedCommand",source,helmart) 
end) 
addEventHandler("onFileDownload",getRootElement(),function() 
    for i,h in pairs(helmlist) do 
    if isElement(i) then 
        triggerClientEvent(source,"onHelmSyncedCommand",i,h) 
    end 
    end 
end) 

client

addEvent("onHelmSyncedCommand",true) 
helm = {} 
helmart = {} 
  
function stahlhelm() 
players = getElementsByType("player") 
for i,p in pairs(players) do 
if isElement(p) and isElement(helm[p]) then 
rz = getPedRotation (p) 
 px, py, pz = getPedBonePosition(p,8)  
px = px+( ( math.cos ( math.rad ( rz ) ) ) * 0.02 ) - math.sin ( math.rad ( rz ) ) * 0.007 
  py = py+( ( math.sin ( math.rad ( rz ) ) ) * 0.02 ) + math.cos ( math.rad ( rz ) ) * 0.007 
       
      if (helmart[p] == 1) or (helmart[p] == 2) then 
               setElementPosition (helm[p], px, py, pz+0.1 ) 
                setElementRotation (helm[p], 0,0,(rz-180) ) 
        else 
       setElementPosition (helm[p], px, py, pz+0.112 ) 
               setElementRotation (helm[p], 0,0,(rz-180) ) 
        end 
        
     end 
     end 
  end 
 addEventHandler ( "onClientPreRender", getRootElement(), stahlhelm ) 
   
   
  addEventHandler("onHelmSyncedCommand", getRootElement(),function(helmart_) 
   helmart[source] = helmart_   
   if isElement (helm[source]) then 
     destroyElement(helm[source]) 
     end 
  if (helmart_ == 1) then 
      
   outputChatBox ( "Stahlhelm 1" ) 
          helm[source] = createObject (2052, 0,0,0 ) -- tommy 
    setObjectScale(helm[source], 0.85) 
     setElementDoubleSided ( helm[source], true ) 
          
     setElementData ( getLocalPlayer(), "helmeted", true ) 
    
   elseif (helmart_ == 2) then 
      
   outputChatBox ( "Stahlhelm 2" ) 
          helm[source] = createObject (2053, 0,0,0 ) -- jerry 
    setObjectScale(helm[source], 0.85) 
    setElementDoubleSided ( helm[source], true ) 
        
     setElementData ( getLocalPlayer(), "helmeted", true ) 
     
 elseif (helmart_ == 3) then 
     
 outputChatBox ( "Offiziersmütze" ) 
         helm[source] = createObject (2054, 0,0,0 ) -- officer 
    setObjectScale(helm[source], 0.85) 
     setElementDoubleSided ( helm[source], true ) 
         
   setElementData ( getLocalPlayer(), "helmeted", true ) 
    
    end 
 end) 
  
 addCommandHandler("stahl", function(com, helmart_) 
    outputChatBox ( "?" ) 
    if tonumber(helmart_) == 0 or tonumber(helmart_) == 1 or tonumber(helmart_) == 2 or tonumber(helmart_) == 3 then 
        triggerServerEvent("onHelmCommand", getLocalPlayer(),tonumber(helmart_)) 
    else 
        outputChatBox ( "Valid numbers are 0,1,2 and 3." ) 
    end 
 end) 
  
outputChatBox("Stahlhelm by Einheit-101 loaded", 245,0,0) 
triggerServerEvent("onFileDownload", getLocalPlayer()) 
  
  

btw: "Make Client-side Object Visible Server-side" thinking is wrong imo

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...