Need suggestions for prefered method on spawning a model into a map at round start

I am dicking around with a round based team gamemode and currently am trying to figure out how to spawn a model into a random location into the map at the beginning of the round. I have most of the code working successfully, but the problem is I’m using…

Target1 = (player.GetByID( 1 ):GetShootPos())
Target2 = (player.GetByID( 2 ):GetShootPos())

SpawnRandomModel(Target1 + (Vector(<randomized vector code here>)
SpawnRandomModel(Target2 + (Vector(<randomized vector code here>)

…which spawns the model based randomly around the first two players to join the server.

The problem with doing the above is that if one of the first two players to join the server leaves the server, the gamemode breaks.

In the situation the following situation, player 1, 2, 3 and 4 join a server. This are going well. Player 2 leaves the server and a new player joins. The GetByID’s now look like 1,3,4,5. Because of that, (I believe due to testing, I could be wrong, I’m a 2 week lua noob), I can’t use a math.random because of the missing gap, as well as the fact that I don’t want it to choose the same number twice.

I’m seeking a more elegant solution, if possible, that spawns two models randomly in the map, (I have the randomization code all set, just need the delivery). I had thought that perhaps using the map’s spawnpoints would be a better constant to use, but I couldn’t figure out how to use Team.GetSpawnPoint without quickly getting all the Steam lua error achievements because of an insane loop I had created inadvertently.

So, ideas would be to use the players or spawnpoints. I’m not sure which other direction to go into that also wouldn’t choose the same number again. That would cause model in model again that I don’t think people would be ready for.

Any ideas are extremely welcome. Thank you everyone for reading :slight_smile:


use google next time, this is code is from Entoros

Thank you for the code and suggestion. I assure you I have googled for hours before posting for suggestions, but it would seem I was googling all the wrong things.

Wouldn’t your code have the chance of giving the same number twice?

You could store the result as a variable and compare it to the second random spawn?

Thank’s for the respond and idea.

I’ve been working on this single problem since I originally posted and am still struggling with this, but it’s not for a lack of not trying! :slight_smile: Anyway, I’m thinking that I need to create a table and do the following:

For the first model deposit

  1. Create a table of all GetByID’s // THIS is the hardest part for me right now. Still trying to figure this out.
  2. Randomly choose a number within that table // Easy enough
  3. Take that chosen number out of the table // Haven’t looked into how to do it. Maybe make a new table for the second model deposit to use if it’s too complicated.
  4. Deposit the model. // Easy enough.

For the Second model deposit

  1. Randomly choose a number within the GetByID’s table // Easy enough
  2. Deposit the model. // Easy enough.
  3. Empty the table // So it’s ready for next time.

Conceptually I can visualize it, but getting it to appear in lua is not there for me just yet.

[lua]local tbl = player.GetAll()

local Target1 = table.Random(tbl)
table.RemoveByValue(tbl, Target1)

local Target2 = table.Random(tbl)
table.RemoveByValue(tbl, Target2)[/lua]

Actually, a more “proper” solution would be to find the player SPAWNS, not the players themselves and spawn the props around those. If you can show me how you spawn your players I can help with that.

Write it in pseudocode, and just slowly convert it more and more into lua

Hi, and sorry for the late response. I had to go to bed.

I’m currently using the code for Prop Hunt as my foundation and have only been coding for a couple of weeks. This is what I’m thinking is being used when someone spawns on any map, be it a gm_, ph_, cp_, anything:

// Called on gamemdoe initialization to create teams
function GM:CreateTeams()
	if !GAMEMODE.TeamBased then
	team.SetUp(TEAM_HUNTERS, "Hunters", Color(150, 205, 255, 255))
	team.SetSpawnPoint(TEAM_HUNTERS, {"info_player_counterterrorist", "info_player_combine", "info_player_deathmatch", "info_player_axis"})
	team.SetClass(TEAM_HUNTERS, {"Hunter"})

	team.SetUp(TEAM_PROPS, "Props", Color(255, 60, 10, 255))
	team.SetSpawnPoint(TEAM_PROPS, {"info_player_terrorist", "info_player_rebel", "info_player_deathmatch", "info_player_allies"})
	team.SetClass(TEAM_PROPS, {"Prop"})
	team.SetUp(TEAM_SPECTATOR, "Spectators", Color( 200, 200, 200 ))
	team.SetSpawnPoint(TEAM_SPECTATOR, {"info_player_start", "info_player_terrorist", "info_player_counterterrorist", "info_player_combine", "info_player_rebel"}) 

I’m thinking that having the model spawn from a random spawn location might be the best idea as well. I was trying to print all known vector coordinates of all the spawn points into the console, but didn’t get any errors…but didn’t get any results either. i didn’t save the code, but perhaps it was a step in the right direction. I’ll see if I can recreate it and maybe it’ll be something.

lua_run print( table.Random( team.GetSpawnPoints( TEAM_HUNTERS ) ) )
lua_run print( table.Random( team.GetSpawnPoints( TEAM_PROPS ) ) )

Doesn’t output anything, but…

] lua_run PrintTable(( team.GetSpawnPoint( TEAM_PROPS ) ) )
> PrintTable(( team.GetSpawnPoint( TEAM_PROPS ) ) )...
1	=	info_player_terrorist
2	=	info_player_rebel
3	=	info_player_deathmatch
4	=	info_player_allies

] lua_run PrintTable(( team.GetSpawnPoint( TEAM_HUNTERS ) ) )
> PrintTable(( team.GetSpawnPoint( TEAM_HUNTERS ) ) )...
1	=	info_player_counterterrorist
2	=	info_player_combine
3	=	info_player_deathmatch
4	=	info_player_axis

I guess that just lists what spawnpoints labels are valid for which team/class.

I need to find the vector of each spawnpoint within the map though. I feel I’m getting closer though.

I found the following example function at what looks like an outdated gmod wiki which looks like it might do what I’m looking for, at least some of it.

function GetSpawnpoints()
    -- First create the table we're storing the player entities in.
    local pTable = {}
    -- Then loop through every spawn point found in the map.
    for k,v in pairs(ents.FindByClass("info_player_deathmatch")) do
        -- Set the variable 'idx' to the player's entity index.
        local idx = v:EntIndex() 
        -- Using the index as the key, add the entity (val) to the table.
        pTable[idx] = v
    -- Return our filled table!
    return pTable

but when i run

lua_run PrintTable(pTable)

I just get the error:

[ERROR] lua/includes/util.lua:54: bad argument #1 to 'pairs' (table expected, got nil)
  1. pairs - [C]:-1
   2. PrintTable - lua/includes/util.lua:54
    3. unknown - lua_run:1

I’m guessing some of the functionality of that function has be replaced in a newer version of gmod and no longer works.

I think the key to this is figuring out how to use EntIndex() properly.

I went and tried something different, trying to spawn a model for every player that joins the server using the below code, but didn’t realize until just now that all it did was that for each user that is logged into the server, spawn a model at the same person. So the more people, the more models that were overlapping and clipping into each other, haha. Woops.

	for _, Target1 in pairs(player.GetAll()) do
	Target1 = (player.GetByID( ( player.GetAll()[#player.GetAll()]:EntIndex() ) ):GetShootPos())

	SpawnModel(Target1 + (Vector(100,100,10), model