jkub Posted July 23, 2010 Share Posted July 23, 2010 I have 2 scripts that handle spawns for players when they join my server. A login GUI and another GUI that lets you select your spawn location. Half the time the actual spawning works and other times not. Often when players select a spawn location and press the spawn button the player is either spawned "falling" under the middle of the map or they don't spawn at all. Then I get a infinite running script flooding my debug and it causes a tremendous FPS drop for most if not all clients. Probably bogs the server too. If I try to loop the code to make sure it spawns the player it still becomes inaffective at times and does not spawn the player and of course causes an infinite loop which will soon be aborted. If I run a simple check to see if the player is not in the middle of the map then it still dont work. Sometimes players even report black non manipulative screens function server_SpawnClient ( x, y, z, rot, skin, interior, dimension, team ) setTimer ( spawnPlayer, 1000, 1, client, x, y, z, rot, skin, interior, dimension, team ) --spawnPlayer ( client, x, y, z, rot, skin, interior, dimension, team ) setTimer ( setCameraTarget, 1000, 1, client, client ) fadeCamera ( client, false, 1.0, 0, 0, 0 ) setTimer ( fadeCamera, 2000, 1, client, true, 3.0 ) triggerClientEvent ( client, "playerSpawnedComplete", client ) local cX, cY, cZ = getElementPosition ( client ) if cX == 0 and cY == 0 and cZ == 0 then server_SpawnClient() end end EDIT: One other related problem I have is that a specific player in my server says that when he logs in, not only can he not spawn correctly, but his ping sky rockets. There are 2 main ways to spawn in my server upon joining. 1. Login_Gui (If you do not log in or register, there is a button you can click that says "play as guest" which spawns you at the LV airport) 2. Spawn GUI. This is the script that handles the spawns for any player who either logs in or registers. This is where I think the most of the problem may be coming from, however I call events from the login_gui script and the events get answered in this script. Link to comment
50p Posted July 23, 2010 Share Posted July 23, 2010 You explained what your problem is, you know what is causing it then why did you ask us here if you know everything you need to know to fix it yourself? BTW, never ever check if coords are equal to some specific number, like if x == 0 and y == 0 and z == 0 then because they will never be equal to 0. Basically, never compare float numbers. Link to comment
jkub Posted July 23, 2010 Author Share Posted July 23, 2010 Well Thanks but I explained actually where my problem might be. I just don't see whats wrong with it, other then the fact that you explained that I shouldn't compare floats. I have always had this same exact problem with any spawn script I have made. I guess I will change my float comparison thing and get back. Link to comment
50p Posted July 24, 2010 Share Posted July 24, 2010 We don't know much about your problem without more code... You just showed a little piece of code that spawns player after 1 sec., fades camera in/out and triggers client event. I even wondered why you checked if player is at 0,0,0 before he was spawned. Also, why do you set a timer? You can spawn the player and fade camera in at the same time. Besides, you don't need your arguments in your fadeCamera (line 5) apart from client and false because rest of your arguments are the same as default parameter values. Don't forget to debug your script. Link to comment
jkub Posted July 24, 2010 Author Share Posted July 24, 2010 The fade camera functions are obviously for pure aesthetic purposes because I didn't like the plain old spawn. I use a timer for spawn player because I don't want the player spawning until the screen is completely black from the fade camera function. Then when the player is spawned, the camera fades back in. My reason for checking the players position as 0, 0, 0 is my asnine way of checking if the player is spawned or not, the significance behind that is that, after I call my spawnPlayer I wanted to make sure the player still was not stuck in the middle of the map falling. I later discovered the isPedOnGround which in turn didn't really help. I even tried looking into the play script for how it spawns its players. To my discovery it uses a "repeat" loop which seems to work every time. I tried using the same exact method and it is just affective as my other methods, it even has the occasional infinite running script error to where it bogs down the server and clients in the process. Here is a shitload of code from client side. function spawnClick ( button ) if button == "left" then if source == spawnButton then local row, col = guiGridListGetSelectedItem ( spawnList ) if row == -1 then outputChatBox ( "*You have to select a location to spawn first!", 255, 0, 0 ) else if row == location1 then spawnX = 1130.0665 + math.random ( 1, 3 ) spawnY = -1488.45678 spawnZ = 22.76903 rot = 0 elseif row == location2 then spawnX = -1757.7215 + math.random ( 1, 3 ) spawnY = 957.9381 spawnZ = 24.8828 rot = 180 elseif row == location2b then spawnX = 2223.3437 spawnY = -1160.2365 spawnZ = 26 rot = 0 elseif row == location2c then spawnX = 2512.5363 spawnY = -1673.1607 spawnZ = 13.4983 rot = 74 elseif row == doherty then spawnX = -2023.8781 spawnY = 156.6600 spawnZ = 29 rot = 270 elseif row == batteryPoint then spawnX = -2631.9372 spawnY = 1381.6345 spawnZ = 7.1704 rot = 180 elseif row == location3 then spawnX = 2028.0147 spawnY = 1916.1400 + math.random ( 1, 3 ) spawnZ = 12.3284 rot = 260 elseif row == lastResort then spawnX = 2368.5908 spawnY = 1660.3601 spawnZ = 11 rot = 270 elseif row == highRoller then spawnX = 1955.9962 spawnY = 1342.9613 spawnZ = 16 rot = 270 end skin = math.random ( 0, 288 ) interior = 0 dimension = 0 team = user_Team triggerServerEvent ( "spawnWindow_SpawnPlayer", getLocalPlayer(), spawnX, spawnY, spawnZ, rot, skin, interior, dimension, team ) end elseif source == spawnList then local row, col = guiGridListGetSelectedItem ( spawnList ) if row == -1 then --no row was selected else if row == location1 then setCameraMatrix ( 1170.7250, -1481.7625, 30.4994, 1131.1616, -1495.6624, 22.7690 ) elseif row == location2 then setCameraMatrix ( -1736.7707, 959.3780, 24.8828, -1838.4617, 906.7504, 49.3268 ) elseif row == location2b then setCameraMatrix ( 2193.6376, -1108.1195, 24.8521, 2205.5949, -1138.3500, 34.2421 ) elseif row == location2c then setCameraMatrix ( 2442.3122, -1655.8826, 27.9151, 2510.4106, -1676.0703, 13.5468 ) elseif row == location3 then setCameraMatrix ( 2132.0070, 1945.4909, 10.6828, 1979.1539, 1916.1916, 95.1458 ) elseif row == doherty then setCameraMatrix ( -2015.3387, 184.3074, 27.6875, -2034.9644, 166.5152, 30.9673 ) elseif row == batteryPoint then setCameraMatrix ( -2580.9016, 1359.5323, 15.3211, -2614.8896, 1381.2315, 12.5663 ) elseif row == lastResort then setCameraMatrix ( 2397.0244, 1663.3498, 16.6667, 2367.6035, 1652.3618, 10.8203 ) elseif row == highRoller then setCameraMatrix ( 2036.9645, 1343.3657, 10.8203, 2010.3544, 1343.3742, 11.9886 ) end end end end end The idea behind all these arguments for setCameraMatrix is not only for aesthetic purposes but I also try to make the code load the area where the player wants to spawn into memory so it won't take as long, or they have less chance of falling through an LOD map. Here is my current code for server. addEvent ( "spawnWindow_SpawnPlayer", true ) function server_SpawnClient ( x, y, z, rot, skin, interior, dimension, team ) setTimer ( spawnPlayer, 1000, 1, client, x, y, z, rot, skin, interior, dimension, team ) setTimer ( setCameraTarget, 1000, 1, client, client ) fadeCamera ( client, false, 1.0, 0, 0, 0 ) setTimer ( fadeCamera, 2000, 1, client, true, 3.0 ) triggerClientEvent ( client, "playerSpawnedComplete", client ) end addEventHandler ( "spawnWindow_SpawnPlayer", getRootElement(), server_SpawnClient ) Link to comment
MaddDogg Posted July 24, 2010 Share Posted July 24, 2010 Sorry, if I missed something, but who is "client" in your serverside script? Is that supposed to be "source"? "client" is never given to the function, so I would wonder, why it would even spawn you once. But apart from that I would advise you to use tables. That would make the repeated elseif's unnecessary, since the script would get the respective data from a table using the row as index. That would definitely shorten your script to at least the half and would make it more readable and dynamic. But that's optional and just a tip Link to comment
jkub Posted July 24, 2010 Author Share Posted July 24, 2010 The serverside function is called from a client script, so thats where the client comes from. About the table thing> How would I use tables to do it? Thanks Link to comment
MaddDogg Posted July 24, 2010 Share Posted July 24, 2010 Okay, but I don't see, where you declare the 'client' variable. You don't pass on an argument called 'client' and there seems to be no global 'client' variable in existence. Do you actually mean 'source', which would be the cause of the event triggering, hence the player, who needs to be spawned? You could do it like this: locations = { {spawnX = 1000.0, spawnY = 500.0, spawnZ = 10.0, spawnRot = 90.0}, -- location 1 {spawnX = 2000.0, spawnY = -100.0, spawnZ = 18.0, spawnRot = 270.0}, -- location 2 {spawnX = -600.0, spawnY = -450.0, spawnZ = 53.0, spawnRot = 0.0}, -- location 3 -- and so on... } function spawnClick (button) -- some code... local row, col = guiGridListGetSelectedItem ( spawnList ) if row ~= -1 then -- if player selected an item triggerServerEvent ( "spawnWindow_SpawnPlayer", getLocalPlayer(), locations[row].spawnX, locations[row].spawnY, locations[row].spawnZ, locations[row].spawnRot, skin, interior, dimension, team ) end end That's just a simplified code and example, but you should get the idea. Link to comment
50p Posted July 24, 2010 Share Posted July 24, 2010 @MaddDogg Read more about addEventHandler, please. @jkub I would suggest you use table but have it in server-side script instead of client-side because if client will hack your script somehow he'll be able to change the coords to whatever value he wants therefore spawn anywhere. Then just triggerServerEvent with the "id" (row number) of the selected spawn location. I wonder why you don't know anything about tables yet. Anyway, as MaddDogg said, you could use row id to identify spawn location in a table, something like this: local spawnLocations = { { 1234.5678, 1.58, 10, 0 }, -- table 1: x, y, z, rotation { 123.5678, 14.5678, 11, 0 }, -- table 2: x, y, z, rotation { 12.5678, 134.57, 12, 0 }, -- etc. { 1.5678, 1234.568, 13, 0 }, -- etc. }; -- this table has a set of tables of spawn coords which you can use easily -- lets say selectedRow will be 2: selectedRow = 2; -- you send row id with triggerServerEvent and use it instead of the 2 -- this will take data from table #2 from the spawnLocations table above x = spawnLocations[ selectedRow ][ 1 ]; -- x of selected spawn location (123.567) y = spawnLocations[ selectedRow ][ 2 ]; -- y ... (14.5678) z = spawnLocations[ selectedRow ][ 3 ]; -- z ... (11) r = spawnLocations[ selectedRow ][ 4 ]; -- rotation ... (0) -- You can assign the values from table to a variable if you don't want your spawnPlayer function to be very long But still, I don't see any problem with your script... What is your client-side event "playerSpawnedComplete" for? May it cause any problems? Show us. Link to comment
jkub Posted July 24, 2010 Author Share Posted July 24, 2010 Thanks 50p and MaddDogg. Putting the coords in a table was a really good idea. The "playerSpawnedComplete" is for closing the GUI and hiding the cursor. It also is used to trigger a function from a seperate resource (My welcome window) which shows vital information, rules, etc... I put that in the server function instead of putting it clientside because I wanted to make sure the GUI does not close until the player is spawned, which obviously fails in several different languages. But I am wanting to keep it there for the sole purpose of triggering my welcome window. I used the table for my client side setCameraMatrices because I didn't see a problem with it and I thought as well that it would make the script cleaner and reduce repeating myself. Here is the revised part of the client script that matters addEvent ( "loginAttempt", true ) addEvent ( "closeLoginGUI", true ) addEvent ( "playerSpawnedComplete", true ) cameraCoords = { { 1170.7250, -1481.7625, 30.4994, 1131.1616, -1495.6624, 22.7690 }, --Verona Mall { 2193.6376, -1108.1195, 24.8521, 2205.5949, -1138.3500, 34.2421 }, --Jefferson Motel { 2442.3122, -1655.8826, 27.9151, 2510.4106, -1676.0703, 13.5468 }, --Grove Street { -1736.7707, 959.3780, 24.8828, -1838.4617, 906.7504, 49.3268 }, --Financial District Hotel { -2015.3387, 184.3074, 27.6875, -2034.9644, 166.5152, 30.9673 }, --Doherty Garage { -2580.9016, 1359.5323, 15.3211, -2614.8896, 1381.2315, 12.5663 }, --Jizzy's Pleasure Domes { 2132.0070, 1945.4909, 10.6828, 1979.1539, 1916.1916, 95.1458 }, --The Visage { 2397.0244, 1663.3498, 16.6667, 2367.6035, 1652.3618, 10.8203 }, --Last Resort Motel { 2036.9645, 1343.3657, 10.8203, 2010.3544, 1343.3742, 11.9886 } --The High Roller } function spawnClick ( button ) if button == "left" then if source == spawnButton then local row, col = guiGridListGetSelectedItem ( spawnList ) if row == -1 then outputChatBox ( "*You have to select a location to spawn first!", 255, 0, 0 ) else if isTransferBoxActive() == false then skin = math.random ( 0, 288 ) interior = 0 dimension = 0 team = user_Team triggerServerEvent ( "spawnWindow_SpawnPlayer", getLocalPlayer(), row, skin, interior, dimension, team ) else outputChatBox ( "*For stability/safety reasons, you need to wait for the resources to finish downloading before you spawn*", 255, 175, 0 ) end end elseif source == spawnList then local row, col = guiGridListGetSelectedItem ( spawnList ) if row == -1 then --no row was selected else x = cameraCoords[ row + 1 ][ 1 ] y = cameraCoords[ row + 1 ][ 2 ] z = cameraCoords[ row + 1 ][ 3 ] lookX = cameraCoords[ row + 1 ][ 4 ] lookY = cameraCoords[ row + 1 ][ 5 ] lookZ = cameraCoords[ row + 1 ][ 6 ] setCameraMatrix ( x, y, z, lookX, lookY, lookZ ) end end end end function openSpawnWindow ( success ) if success == true then guiSetVisible ( spawnWindow, true ) showCursor ( true ) end end function openSpawnWindowOnRegister() guiSetVisible ( spawnWindow, true ) showCursor ( true ) end function closeSpawnWindow() guiSetVisible ( spawnWindow, false ) showCursor ( false ) end addEventHandler ( "loginAttempt", getRootElement(), openSpawnWindow ) addEventHandler ( "closeLoginGUI", getRootElement(), openSpawnWindowOnRegister ) addEventHandler ( "playerSpawnedComplete", getRootElement(), closeSpawnWindow ) I had remembered from past scripts that rowIDs in a gridlist start at 0 and a table seems to start at 0. That is why I put the row + 1 in each variable. In order to sync them together< and here is the revised server side script addEvent ( "spawnWindow_SpawnPlayer", true ) local spawnLocations = { { 1130.0665, -1488.45678, 23, 0 }, --Verona Mall { 2223.3437, -1160.2365, 26, 0 }, --Jefferson Motel { 2512.5363, -1673.1607, 14, 74 }, --Grove Street { -1757.7215 , 957.9381, 25, 180 }, --Financial District Hotel { -2023.8781, 156.6600, 29, 270 }, --Doherty Garage { -2631.9372, 1381.6345, 8, 180 }, --Jizzy's Pleasure Domes { 2028.0147, 1916.1400, 13, 260 }, --The Visage { 2368.5908, 1660.3601, 11, 270 }, --Last Resort Motel { 1955.9962, 1342.9613, 16, 270 } --The High Roller } function server_SpawnClient ( rowID, skin, interior, dimension, team ) ---- x = spawnLocations[ rowID + 1 ][ 1 ] y = spawnLocations[ rowID + 1 ][ 2 ] z = spawnLocations[ rowID + 1 ][ 3 ] rot = spawnLocations[ rowID + 1 ][ 4 ] ---- setTimer ( spawnPlayer, 1000, 1, client, x, y, z, rot, skin, interior, dimension, team ) setTimer ( setCameraTarget, 1000, 1, client, client ) fadeCamera ( client, false, 1.0, 0, 0, 0 ) setTimer ( fadeCamera, 2000, 1, client, true, 3.0 ) triggerClientEvent ( client, "playerSpawnedComplete", client ) end addEventHandler ( "spawnWindow_SpawnPlayer", getRootElement(), server_SpawnClient ) 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