ID:1053645
 
Map Based Player Spawning
Time to implement: 5 minutes or less

So what does the system do? Well rather than hard coding your spawn location like so:

Move(locate(1,2,3))

Instead you place an object on the map:



This only requires that you know how to make a dmi file called "Mechanics.dmi", and that you know how place objects on the map. It's really that simple. You may also have some code that sits in the same place as this code but you should be able to easily paste it above or below the code you have. Also, I'm using three separate DM files but you can put this code where you'd rather of course.

Step One

Here you implement the mechanics file. I use different mechanics but you might want to just change it to /Spawns, just remember if you make changes that the changes will need to flow on.

Mechanics
parent_type = /obj
icon = 'Mechanics.dmi'

Spawns

Player_Spawn
icon_state = "Player Spawn" // Not seen at runtime.


Here we make a new type of obj, type Mechanics. Then there's a Spawns sub category. In there our Player_Spawn object, pretty simple. You just need to make the dmi file and put an icon state in that called "Player Spawn", make it however you like or just copy my simple one above.

Step Two

// Global Variables
var
global/PLAYER_SPAWN_LOC

world
New()
Find_Player_Spawn()

proc
Find_Player_Spawn()
var/Mechanics/Spawns/Player_Spawn

for(Player_Spawn)
PLAYER_SPAWN_LOC = Player_Spawn.loc
del Player_Spawn


This is really simple. First there's a variable called PLAYER_SPAWN_LOC, it's not initialized to anything. However if you trace down, you find the world.New() process. This works the same the mob.New() if you're familiar with that one but basically this is what's run every time the world is created, before the player logs in. That's really helpful because it means we can find the Player_Spawn Mechanics object and send the player to it.

To do that we just use a simple for() loop. It will go through every Player_Spawn you place on the map and the very last one it finds will have it's location stored in PLAYER_SPAWN_LOC. So remember if you place more than one then it's going to use the last one you placed.

The del statement deletes all the Player_Spawn objects on the map. That's so it disappears when players get into the game but also for efficiency's sake because those objects are only needed at the start. This also means you will only seen the mechanics in the map file. How cool?

Step 3

Change your mob's Login() process to send it to the global variable.

mob
Login()
Move(PLAYER_SPAWN_LOC)
..()


The End

Now you've implemented your own map based spawning system for players, go into your map file and now you can look at where you're sending the player as you choose.

Thanks, feel free to ask any questions or if I could have done something better I'll correct it.
Why?
Move(locate("some-tag"))
Can a moderator please delete this post and page him the DM reference?
I don't know anybody that even uses the x, y, and z coordinates when moving a mob or obj. Not to mention you put WAY more work to this than was necessary.
In response to Super Saiyan X
Super Saiyan X wrote:
Why?

Now you can go into your map, build it and then choose where the player is going to spawn from the map.
Galactic Soldier wrote:
This is pretty bad.

Magnum2k wrote:
Can a moderator please delete this post and page him the DM reference?

What's wrong with it?
You made some interesting points and I'll work on some of that but there's a couple of things I disagree with.

The first thing is the for() loop. Assuming it's using the world.New() method it makes sense to use a loop because there might be more than one player spawn and it assures that each one is noted. It also allows a programmer to design his/her own rules for what happens if the loop finds more than one.

The second thing, you said it should be done in the New() process for the Spawn object. That works and it's functional but I want everything that happens when the world is loaded to be explicitly noted and listed together. Otherwise what happens is that you get 5 processes running when the world is created but because none of them are listed together it's difficult to tell what might be causing an error if two of them conflict.

A lot of what I've written is designed with maintainability, clarity, simplicity and customization in mind.

I see some syntactical things I can fix like making it a global variable instead of a variable with unbounded scope but I still think my method is more user friendly and more defensible against difficult runtime errors.

Robust, that's the word.
Oh do you mean?

world
New()
Find_Player_Spawn()
..()


I thought about that for a moment while I was writing it but unlike Login() it doesn't appear to need it but I could be wrong. My project runs find without from what I can tell anyway, that's all I know.

Login() doesn't need it. The only default actions in Login() are set loc to place closest to bottom left corner, and client.statobj = src.

World's is nothing.