Einheit-101 Posted March 4, 2011 Share Posted March 4, 2011 (edited) 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 March 4, 2011 by Guest Link to comment
Castillo Posted March 4, 2011 Share Posted March 4, 2011 As far as i know it's not possible, but maybe you could create it for every player. Link to comment
Einheit-101 Posted March 4, 2011 Author Share Posted March 4, 2011 HMM. That would be NOT good. But you are right. Maybe its possible to create the object for every player, but how to make that? Link to comment
DiSaMe Posted March 4, 2011 Share Posted March 4, 2011 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
Einheit-101 Posted March 5, 2011 Author Share Posted March 5, 2011 (edited) Hey i have tried to create the object server side and control it client side. But hey, thats breaking my brain 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".... Edited March 5, 2011 by Guest Link to comment
Castillo Posted March 5, 2011 Share Posted March 5, 2011 if i'am right, you can't pass the object like that, but maybe you could set a ID to the object. Link to comment
DiSaMe Posted March 5, 2011 Share Posted March 5, 2011 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
Einheit-101 Posted March 5, 2011 Author Share Posted March 5, 2011 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
DiSaMe Posted March 5, 2011 Share Posted March 5, 2011 You have an unused argument for function stahlhelm which overrides the global variable. Remove that argument. Link to comment
Einheit-101 Posted March 5, 2011 Author Share Posted March 5, 2011 Do you mean function Stahlhelm(helmet) to function Stahlhelm() ??? Link to comment
Einheit-101 Posted March 5, 2011 Author Share Posted March 5, 2011 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
DiSaMe Posted March 6, 2011 Share Posted March 6, 2011 If you are using MTA SA 1.0.4, then setObjectScale is not available server-side. You either need to set object scale client-side or switch to unstable nightly builds of MTA SA 1.1. Link to comment
Einheit-101 Posted March 6, 2011 Author Share Posted March 6, 2011 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 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 Citizen Posted March 6, 2011 Moderators Share Posted March 6, 2011 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
Einheit-101 Posted March 6, 2011 Author Share Posted March 6, 2011 No, its not ONE object, every player can create one and it should follow a specific Bone. Link to comment
Moderators Citizen Posted March 6, 2011 Moderators Share Posted March 6, 2011 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 So make your choice Link to comment
Einheit-101 Posted March 6, 2011 Author Share Posted March 6, 2011 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... Suggestion: developing "attachElementToBone" function or sth. like that PS: Citicen, congrats to your "101st" post, i like this number^^ Link to comment
Wojak Posted March 7, 2011 Share Posted March 7, 2011 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 Citizen Posted March 7, 2011 Moderators Share Posted March 7, 2011 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 Link to comment
Wojak Posted March 7, 2011 Share Posted March 7, 2011 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 Citizen Posted March 7, 2011 Moderators Share Posted March 7, 2011 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
Einheit-101 Posted March 7, 2011 Author Share Posted March 7, 2011 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
DiSaMe Posted March 7, 2011 Share Posted March 7, 2011 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
Wojak Posted March 7, 2011 Share Posted March 7, 2011 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
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now