• math.random always returning 1
    25 replies, posted
[lua] hook.Add( "PlayerSpawn", "Playerspawnarena", function( ply ) local randomspawn = math.random (1,3) if randomspawn == 1 then if (ply:getDarkRPVar("job") == "Deathmatch Red") then timer.Simple( 0, function() ply:SetPos(Vector(-5328.645508, -2802.839600, 432.031250)) end ) end if (ply:getDarkRPVar("job") == "Deathmatch Blue") then timer.Simple( 0, function() ply:SetPos(Vector(-5342.098145, -4546.042969, 432.031250)) end ) end end if randomspawn == 2 then if (ply:getDarkRPVar("job") == "Deathmatch Red") then timer.Simple( 0, function() ply:SetPos(Vector(-5972.556152, -3636.981445, 465.201019)) end ) end if (ply:getDarkRPVar("job") == "Deathmatch Blue") then timer.Simple( 0, function() ply:SetPos(Vector(-4344.031250, -3616.388428, 432.031250)) end ) end end if randomspawn == 3 then if (ply:getDarkRPVar("job") == "Deathmatch Red") then timer.Simple( 0, function() ply:SetPos(Vector(-6279.968750, -2685.031250, 432.031250)) end ) end if (ply:getDarkRPVar("job") == "Deathmatch Blue") then timer.Simple( 0, function() ply:SetPos(Vector(-4710.122559, -3631.762939, 432.031250)) end ) end end end) [/lua] Trying to force a random spawn between 3 locations but i seem to spawn in the same position every time (1) does math.random only return values between 1-3 (so only 2? ) that wouldnt make since bc this is always spawning me at 1 I know this is really messy. (could have put all of this under one timer... XD)
Try adding the following before your call to retrieve a random number. [code]math.randomseed(os.time())[/code]
[code] for i = 1, 20 do print(math.random(1,3)) end [/code] [code] 3 2 3 3 3 1 2 3 1 2 2 2 2 2 3 3 2 3 1 2 [/code]
[QUOTE=Exho;46851974][code] for i = 1, 20 do print(math.random(1,3)) end [/code][/QUOTE] Unless you seed the math.random function you will always get "random" numbers in that exact order.
Why does this have a space? [quote]math.random (1,3)[/quote]
[QUOTE=Nookyava;46852083]Why does this have a space?[/QUOTE] would the space effect the number?
Nope. It's possible you have an addon that sets the seed to a static value every time a player spawns (or maybe just on server start). Make sure you test spawning more than once in a session in case of the latter. By default the randomseed is set to os.time() when the server/client has loaded a level.
ok NEVER had to use randomseed but it seems to have worked.
Let me recommend a change to your script.. Correcting tabs, shortening code, using table.Random instead... [code]local TeamSpawnPoints = { // I'd recommend using TEAM_RED, TEAM_BLUE in these, but you have the job name so I'll leave it as is.. // Also, no need to be super-precise with spawn-points. Can round them / truncate decimals; makes it look nicer. [ "Deathmatch Red" ] = { { pos = Vector( -5329, -2803, 433 ), ang = angle_zero }; { pos = Vector( -5973, -3637, 466 ), ang = angle_zero }; { pos = Vector( -6280, -2686, 433 ), ang = angle_zero }; }; [ "Deathmatch Blue" ] = { { pos = Vector( -5343, -4547, 433 ), ang = angle_zero }; { pos = Vector( -4345, -3617, 433 ), ang = angle_zero }; { pos = Vector( -4711, -3632, 433 ), ang = angle_zero }; }; }; hook.Add( "PlayerSpawn", "Playerspawnarena", function( ply ) // Grab the table which corresponds with the team, could use TeamSpawnPoints[ ply:Team( ) ] if you use [ TEAM_RED ] etc above... local _tab = TeamSpawnPoints[ ply:getDarkRPVar( "job" ) ]; // Run this next frame timer.Simple( 0, function( ) // Grab a random element from the above table local _spawn = table.Random( _tab ); // We stored sub pos and sub ang in each, set the positions... ply:SetPos( _spawn.pos ); ply:SetEyeAngles( _spawn.ang ); end ); end ); [/code] Although, instead of using a timer ( which fails in current builds ), the proper way to setup spawns in Lua is this: [url]https://dl.dropboxusercontent.com/u/26074909/tutoring/_systems/playerselectspawn_system.lua.html[/url] PlayerSelectSpawn; it returns a point-entity which is moved to the position the player should spawn in.
unforchanatly if i changed to that i would never be able to edit it due to having no idea how that bit of code works i tried (with many MANY fails) to use a table for the vectors but kept getting errors the _tab thing (underscore) always confuses me. why is _ there and what does it accomplish
[QUOTE=kulcris;46852716]the _tab thing (underscore) always confuses me. why is _ there and what does it accomplish[/QUOTE] Underscores have no effect on the actual code. Variables and the like can be prefixed with it if the user chooses, meaning [B]_Variable[/B] and [B]Variable[/B] are equally valid (and unique) variable names. It is simply Acecool's convention of naming various things. Whether or not it is a good convention is a different matter.
ok thank you for clearing that up. for some reason this still has a chance of not doing anything at all. (just leaves you at the normal spawn) would someone standing on the spawn cause it to not tp someone there? or if someone spawns at the same time as you? *EDIT* just tested the blocked spawn and it seems if someone is on it you just spawn above them standing on their head
The issue is because you're using a timer to control spawning and currently timers aren't good. If you follow the link, it shows how to set up a spawning system. What part of the code I rewrote don't you understand? The _ is my coding standards ( I tried keeping everything as original as possible, must've missed that one by habit ). Here's the same code with comments: [code]// This is a local, to this file, table which contains spawn-points... local TeamSpawnPoints = { // I'd recommend using TEAM_RED, TEAM_BLUE in these, but you have the job name so I'll leave it as is.. // Also, no need to be super-precise with spawn-points. Can round them / truncate decimals; makes it look nicer. // To access this we use: TeamSpawnPoints[ "Deathmatch Red" ] [ "Deathmatch Red" ] = { // To access each of these ( imagine you used table.insert for each line, we'd have [1], [2] and [3] from the above: TeamSpawnPoints[ "Deathmatch Red" ][ 1 ], TeamSpawnPoints[ "Deathmatch Red" ][ 2 ], TeamSpawnPoints[ "Deathmatch Red" ][ 3 ] to access each line. { pos = Vector( -5329, -2803, 433 ), ang = angle_zero }; -- [ 1 ] { pos = Vector( -5973, -3637, 466 ), ang = angle_zero }; -- [ 2 ] { pos = Vector( -6280, -2686, 433 ), ang = angle_zero }; -- [ 3 ] }; [ "Deathmatch Blue" ] = { { pos = Vector( -5343, -4547, 433 ), ang = angle_zero }; { pos = Vector( -4345, -3617, 433 ), ang = angle_zero }; { pos = Vector( -4711, -3632, 433 ), ang = angle_zero }; }; }; // We add the hook into PlayerSpawn hook.Add( "PlayerSpawn", "Playerspawnarena", function( ply ) // Grab the table which corresponds with the team, could use TeamSpawnPoints[ ply:Team( ) ] if you use [ TEAM_RED ] etc above... // This grabs TeamSpawnPoints[ "Deathmatch Red" ]; this points to a table containing 3 elements ( the 3 rows, each is a table with a pos key and ang key ). local _tab = TeamSpawnPoints[ ply:getDarkRPVar( "job" ) ]; // Run this next frame timer.Simple( 0, function( ) // Grab a random element from the above table -- This accesses a random line [ 1 ], [ 2 ], or [ 3 ] -- You can have as many or as few as 1 elements in the table following the pattern and this won't need to be changed local _spawn = table.Random( _tab ); // We stored sub pos and sub ang in each, set the positions... So from [ 1 ], [ 2 ], or [ 3 ] we can access them like so: TeamSpawnPoints[ "Deathmatch Red" ][ 1 ].pos, TeamSpawnPoints[ "Deathmatch Red" ][ 1 ].ang, changing the number gives us a different spawn point ply:SetPos( _spawn.pos ); ply:SetEyeAngles( _spawn.ang ); end ); end ); [/code] The above code gives us the ability to modify the table ( following the pattern of { pos = Vector( x, y, z ), ang = Angle( p, y, r ) }; per line as a new spawn point within the team.. For proper spawn procedure you'd need an entity called a Point Entity. It is a basic entity and can be made with 1 line of code: [url]https://dl.dropboxusercontent.com/u/26074909/tutoring/__projects/acecooldev_base/entities/entities/info_mobile_spawn.lua[/url] With the PlayerSelectSpawn, we move the point entity to the position where we want the player to spawn and we return the entity. The rest is behind the scenes. The spawn system: [url]https://dl.dropboxusercontent.com/u/26074909/tutoring/_systems/playerselectspawn_system.lua.html[/url] doesn't need as much code as I have there but you will need one entity ( keep a reference to it because you can move it around and continue using it ). Some of the code makes sure you can spawn before returning the value ( and it actually goes through recursion if you can't spawn which means it'll keep calling itself until you can spawn or a stack overflow occurs ).. If we keep all code the same, we'd only need to change one part: [code] // Select random spawn point from either a table, or existing entity spawn points on the map -- [/code] This is where we'd set the position and angle for spawning. For your system to be copy/pasted into that, we'd copy the table from the above code outside of the function and we'd replace: [code] // Select random spawn point from either a table, or existing entity spawn points on the map -- [/code] with: [code] local _tab = TeamSpawnPoints[ _p:getDarkRPVar( "job" ) ]; local _spawn = table.Random( _tab ); _pos = _spawn.pos; _ang = _spawn.ang;[/code] And that would be it ( as long as you copy the point entity into your entities/entities/ folder, copy the table with the spawn points to the top of the file, and put the file data into a server-file or into addons/acecool/lua/autorun/server/blah.lua... Here's a few things which may help: [url]https://dl.dropboxusercontent.com/u/26074909/tutoring/tables/quick_intro_to_tables.lua.html[/url] [url]https://dl.dropboxusercontent.com/u/26074909/tutoring/strings/string_concatenation.lua.html[/url] [url]https://dl.dropboxusercontent.com/u/26074909/tutoring/logic/ternary_operations.lua.html[/url]
From what i am seeing of that code there are no team checks. i understand how it works now (after going to sleep and looking at it with fresh eyes) but i cant seem to find how i would put the table in that or how i would make sure only those two teams spawned there [editline]4th January 2015[/editline] wait.. ok so if function GM:PlayerSelectSpawn( _p ) _p is the player. what happens if the job does not match what is in the table?
You'd need to copy the table I created: [code]// This is a local, to this file, table which contains spawn-points... local TeamSpawnPoints = { // I'd recommend using TEAM_RED, TEAM_BLUE in these, but you have the job name so I'll leave it as is.. // Also, no need to be super-precise with spawn-points. Can round them / truncate decimals; makes it look nicer. // To access this we use: TeamSpawnPoints[ "Deathmatch Red" ] [ "Deathmatch Red" ] = { // To access each of these ( imagine you used table.insert for each line, we'd have [1], [2] and [3] from the above: TeamSpawnPoints[ "Deathmatch Red" ][ 1 ], TeamSpawnPoints[ "Deathmatch Red" ][ 2 ], TeamSpawnPoints[ "Deathmatch Red" ][ 3 ] to access each line. { pos = Vector( -5329, -2803, 433 ), ang = angle_zero }; -- [ 1 ] { pos = Vector( -5973, -3637, 466 ), ang = angle_zero }; -- [ 2 ] { pos = Vector( -6280, -2686, 433 ), ang = angle_zero }; -- [ 3 ] }; [ "Deathmatch Blue" ] = { { pos = Vector( -5343, -4547, 433 ), ang = angle_zero }; { pos = Vector( -4345, -3617, 433 ), ang = angle_zero }; { pos = Vector( -4711, -3632, 433 ), ang = angle_zero }; }; }; [/code] To the top of the PlayerSelectSpawn file ( outside of the functions ). Then you'd use this code to grab the random position from the table above: [code] local _tab = TeamSpawnPoints[ _p:getDarkRPVar( "job" ) ]; local _spawn = table.Random( _tab ); _pos = _spawn.pos; _ang = _spawn.ang; [/code] From my code that'd be all that would need to be changed in order to use the PlayerSelectSpawn system; however DarkRP may already have a system in place. I suggested that instead of storing the team-names as strings in the table ( as you're currently doing ) to store them as the team identifier ( When you set up a team in DarkRP there is a residual CONST typically there... TEAM_X = DarkRP.createTeam....; use [ TEAM_X ] = { ... }; instead of [ "Deathmatch Red" ] = { ... }; is what I meant by using team ids instead of strings ). The reason there are no "team checks" ie if ( team == x ) then ... elseif then .... etc... end is because we can access that index in the table directly and there is no reason to create all of the if/elseifs for the random because we stored the data in such a way that after targeting the table sub team we're at the spawn-locations and only need to pluck a random row in order to spawn the player.
lua/autorun/server/playerselectspawn_system.lua:52: attempt to index global 'GM' (a nil value) 1. unknown - lua/autorun/server/playerselectspawn_system.lua:52
I can't recall if addons load before or after game-mode but seeing as GM isn't valid, it must load after... Change: function GM:PlayerSelectSpawn( _p ) to: function ( GM || GAMEMODE ):PlayerSelectSpawn( _p ) Or use hook.Add( "PlayerSelectSpawn", "CustomSpawnpoints", function( _p ) ... end );
06:46:27 [ERROR] lua/autorun/server/playerselectspawn_system.lua:53: attempt to call method 'Unassigned' (a nil value) 1. fn - lua/autorun/server/playerselectspawn_system.lua:53 2. unknown - addons/ulib/lua/ulib/shared/hook.lua:184 3. Spawn - [C]:-1 4. unknown - gamemodes/base/gamemode/player.lua:110 Would i even need that line of code? XD if ( _p:Unassigned( ) ) then return; end
Nah, get rid of it; It was just to prevent the spawn system from getting called if the player was in TEAM_SPECTATOR or TEAM_UNASSIGNED ( I need to add the meta function to the file but it isn't necessary ).
hopefully one last error XD [ERROR] lua/includes/extensions/table.lua:161: bad argument #1 to 'pairs' (table expected, got nil) 1. pairs - [C]:-1 2. Count - lua/includes/extensions/table.lua:161 3. Random - lua/includes/extensions/table.lua:173 4. PlayerSelectSpawn - lua/autorun/server/playerselectspawn_system.lua:38 5. fn - lua/autorun/server/playerselectspawn_system.lua:69 6. unknown - addons/ulib/lua/ulib/shared/hook.lua:184 [lua] local PlayerHullSize = { mins = Vector( -16, -16, 0 ), maxs = Vector( 16, 16, 72 ) }; local function PlayerSelectSpawn( _p ) local _pos = vector_origin; local _ang = angle_zero; local _bSpawnPointBlocked = false; // Select random spawn point from either a table, or existing entity spawn points on the map -- local TeamSpawnPoints = { [ "Deathmatch Red" ] = { { pos = Vector( -5329, -2803, 433 ), ang = angle_zero }; { pos = Vector( -5973, -3637, 433 ), ang = angle_zero }; { pos = Vector( -6280, -2686, 433 ), ang = angle_zero }; }; [ "Deathmatch Blue" ] = { { pos = Vector( -5343, -4547, 433 ), ang = angle_zero }; { pos = Vector( -4345, -3617, 433 ), ang = angle_zero }; { pos = Vector( -4711, -3632, 433 ), ang = angle_zero }; }; }; local _tab = TeamSpawnPoints[ _p:getDarkRPVar( "job" ) ]; local _spawn = table.Random( _tab ); _pos = _spawn.pos; _ang = _spawn.ang; local _ents = ents.FindInBox( _pos + PlayerHullSize.mins, _pos + PlayerHullSize.maxs ) || { }; if ( #_ents > 0 ) then _bSpawnPointBlocked = true; end if ( _bSpawnPointBlocked ) then _pos, _ang = PlayerSelectSpawn( _p ) end return _pos, _ang; end [/lua] line 38 local _spawn = table.Random( _tab ); i have a feeling it is the position of the table in the code
(tldr, just saw the last post) It's because [CODE] _p:getDarkRPVar("job") [/CODE] Doesn't return either "Deathmatch Blue" or "Deathmatch Red". Try printing it and see what the value is.
actually sorry it looks like that is on first spawn (before the job is assigned) only issue is its not actually spawning me in those positions... [editline]4th January 2015[/editline] looking at the checks on making a job i found this PlayerSelectSpawn = function(ply, spawn) end, looks like im going to have to do all of this in that..?
Move the table outside of the function. Next, right under: local _tab = TeamSpawnPoints[ _p:getDarkRPVar( "job" ) ]; Add: if ( !_tab ) then return; end By returning nothing the original DarkRP hook will be called. Once they set a team then it'll work.
ok .. .no error still not spawning. i think the darkrp spawn is overriding this one
If you also have ULX, it rewrites the hook system so it may be changing the order and letting DarkRP one through. Check in darkrpmodification addon to see if there is a file you can overwrite for the spawn system.
the only thing i can find is when making a new job there is a playerspawn option [url]http://wiki.darkrp.com/index.php/DarkRP:CustomJobFields[/url] PlayerSelectSpawn = function(ply, spawn) end, [editline]4th January 2015[/editline] PlayerSelectSpawn Called when a spawn is selected for this player. Arguments: Player ply, Entity spawn [editline]4th January 2015[/editline] nothing i do seems to work with this. guess im going to have to go back to the timer system. the darkrp /setspawn {job} doesnt work. not sure what is breaking this... [editline]4th January 2015[/editline] GM.Config.customspawns swear i looked for this before and couldnt find an option for it. anyways this should work Acecool Thank you so much for teaching me so much about tables. i am such an if whore that i was giving up on tables all together. thanks.
Sorry, you need to Log In to post a reply to this thread.