[Tutorial] Dynamic Spawns
#1

Alright, well I've never made a tutorial before, so I hope I did good.
But something I see a-lot is creating a dynamic spawning system.
I went ahead and created one, and decided that I minus well make a tutorial on how to make one for anyone who doesn't already know.
Alright, well if you don't already have ZCMD Grab that now, as you'll need it.
Here is the link for it:
Link: ZCMD Command Processor

First, you will need to add the Zcmd include at the very top of your script.
This is so the command, written with Zcmd can be read.
pawn Code:
#include <a_samp>
#include <zcmd> // Command Processor being used.
Next, add this function below your #includes.
If you're not using a new pawn file, place this below your forward's or below a existing enum.
The reason you're making it an enum is because you're representing the entire group that has to deal with Dynamic Spawning, and it makes it a lot easier to adjust everything at once.
The X, Y, Z as listed below is the location on the map in which the player will spawn.
The D_Angle is the direction the player will be facing.
pawn Code:
enum DynamicSpawn
{
    Float:D_SpawnX,// X Float for the Dynamic Spawn
    Float:D_SpawnY,// Y Float for the Dynamic Spawn
    Float:D_SpawnZ,// Z Float for the Dynamic Spawn
    Float:D_Angle,// Facing Angle for the Dynamic Spawn
    D_Int,// Interior of the Dynamic Spawn
    D_World// Virtual World of the Dynamic Spawn
}
new D_Info[DynamicSpawn];// This will be used to represent the enum
Now, under OnGameModeInit(), or, when the server is started and the game mode is loaded, let's load the Dynamic Spawns.
the LoadDynamicSpawns function is called as-soon as the server starts.
If the spawn is not set yet, you'll probably spawn at blueberry.
pawn Code:
public OnGameModeInit()
{
    LoadDynamicSpawn();// Loads the Dynamic Spawn X, Y, Z, and Facing Angle from d_spawn.cfg
    return 1;
}
Now let's take a look at when the player actually spawns.
This may look pretty confusing to you, if you're new to pawno but it's really not.
Let's break it down.
Everything using D_Info is reading from the enum we created earlier.
Such as the players position, facing angle, interior, and virtual world.
For example, SetPlayerInterior(playerid, D_Info[D_Int]); is tell it to set that's player interior to what ever the interior ID is that's saved to the Dynamic Spawns file.
pawn Code:
public OnPlayerSpawn(playerid)
{
    SetPlayerPos(playerid, D_Info[D_SpawnX], D_Info[D_SpawnY], D_Info[D_SpawnZ]);// Sets the player position for the X,Y, Z loaded from d_spawn.cfg.
    SetPlayerFacingAngle(playerid, D_Info[D_Angle]);// Sets the Facing angle loaded from d_spawn.cfg
    SetPlayerInterior(playerid, D_Info[D_Int]);// Sets the players Interior, to what ever was loaded from d_spawn.cfg
    SetPlayerVirtualWorld(playerid, D_Info[D_World]);// Sets your Virual world to what's loaded from d_spawn.cfg
    SetCameraBehindPlayer(playerid);// Sets your Camera behind you, when you spawn.
    return 1;
}
Now it's time to create the actual command to set the Dynamic Spawn.
This command, once again is using ZCMD, so if you don't have it download it now.
The Link is at the top of this page.
pawn Code:
CMD:spawn(playerid, params[])// Sets the Dynamic Spawn.
{
    new Float:X, Float:Y, Float:Z, Float:A; // Defines that X, Y, Z are floats not just letters.
    GetPlayerPos(playerid, X, Y, Z); // This is getting your current position.
    GetPlayerFacingAngle(playerid, A); // This is getting your current Facing Angle.
    D_Info[D_SpawnX] = X;// This is setting the Dynamic Spawn's X to what ever X is for you right now.
    D_Info[D_SpawnY] = Y;// This is setting the Dynamic Spawn's Y to what ever Y is for you right now.
    D_Info[D_SpawnZ] = Z;// This is setting the Dynamic Spawn's Z to what ever Z is for you right now.
    D_Info[D_Angle] = A;// This is setting the Dynamic Spawn's Facing Angle, to what ever direction you're facing
    D_Info[D_Int] = GetPlayerInterior(playerid);// This sets the Spawning Interior, to your current interior
    D_Info[D_World] = GetPlayerVirtualWorld(playerid);// This sets the spawning Virtualworld, to your current.
    SaveDynamicSpawn();// Saves the information above.
    SendClientMessage(playerid, 0xFFFFFF, " ** The Spawn has been changed to your location !");
    return 1;
}
Add this at the bottom of your script, as it'll be used later for reading the Dynamic Spawn's file.
It's detecting where there is a " | " Separating the X, Y, Z, etc. That way it's not reading the dividers as part of the spawn chords.
pawn Code:
forward splits(const strsrc[], strdest[][], delimiter);
public splits(const strsrc[], strdest[][], delimiter)
{
    new i, li;
    new aNum;
    new len;
    while(i <= strlen(strsrc)){
        if(strsrc[i]==delimiter || i==strlen(strsrc)){
            len = strmid(strdest[aNum], strsrc, li, i, 128);
            strdest[aNum][len] = 0;
            li = i+1;
            aNum++;
        }
        i++;
    }
    return 1;
}
Alright, now that we've done all that let's save it all.
This will write all the information saved when using /spawn to a .cfg file in Scriptfiles.
The file will be called d_spawn.cfg
As you can see they're being separated by " | ". As I said above.
%f stands for Float. %d means it's a number being used, but not a float.
%f is for our X, Y, Z, and Facing Angle, %d is for our Interior, and Virtual world.
pawn Code:
SaveDynamicSpawn()
{
    new FString[256], File: flocation = fopen("d_spawn.cfg", io_write);// Location in which all Spawn information is saved.
    format(FString, sizeof(FString), "%f|%f|%f|%f|%d|%d", D_Info[D_SpawnX], D_Info[D_SpawnY], D_Info[D_SpawnZ], D_Info[D_Angle], D_Info[D_Int], D_Info[D_World]);
    fwrite(flocation, FString);
    return fclose(flocation);// Closes the file, after the information above has been Saved.
}
Now, let's load it all up.
It's pretty much the same as what's above, except only this time you're reading from d_spawn.cfg, not saving information to it.
pawn Code:
LoadDynamicSpawn()
{
    new SCoords[6][64];
    new FString2[256];
    new File: flocation = fopen("d_spawn.cfg", io_read);// Location in which all Spawn information is loaded.
    if (flocation)
    {
        fread(flocation, FString2);
        splits(FString2, SCoords, '|');// Reads the " | " From SaveDynamicSpawn
        D_Info[D_SpawnX] = floatstr(SCoords[0]); // Reads the X Float
        D_Info[D_SpawnY] = floatstr(SCoords[1]);// Reads the Y Float
        D_Info[D_SpawnZ] = floatstr(SCoords[2]);// Reads the Z Float
        D_Info[D_Angle] = floatstr(SCoords[3]);// Reads the Facing Angle
        D_Info[D_Int] = strval(SCoords[4]);// Reads the Interior set.
        D_Info[D_World] = strval(SCoords[5]);// Reads the Virtual World Set
        fclose(flocation);// Closes the file after everything is loaded.
    }
    return 1;
}
This is a video of what's listed above so you know exactly what the code's outcome will be.
Make sure to watch it in HD(720p) for the best quality.
[ame]http://www.youtube.com/watch?v=c_m-NLRpQPM[/ame]

/loc Command featured in the video.
Obtains your location, and compares it to the Dynamic Spawn location.
pawn Code:
CMD:loc(playerid, params[])
{
    new string[256];
    new Float:X, Float:Y, Float:Z, Float:A;
    GetPlayerPos(playerid, X, Y, Z);
    GetPlayerFacingAngle(playerid, A);
    format(string, sizeof(string), " {FFFFFF}D_Location: {F81414}X: {FFFFFF}%f, {F81414}Y: {FFFFFF}%f, {F81414}Z: {FFFFFF}%f, {F81414}A: {FFFFFF}%f ", D_Info[D_SpawnX], D_Info[D_SpawnY], D_Info[D_SpawnZ], D_Info[D_Angle]);
    SendClientMessage(playerid, 0xFFFFFF, string);
    format(string, sizeof(string), " {FFFFFF}M_Location: {F81414}X: {FFFFFF}%f, {F81414}Y: {FFFFFF}%f, {F81414}Z: {FFFFFF}%f, {F81414}A: {FFFFFF}%f ", X, Y, Z, A);
    SendClientMessage(playerid, 0xFFFFFF, string);
    return 1;
}
Reply
#2

Simple but well explained.
Reply
#3

Well it's directed more towards newbies who are still learning the works of pawno.
Reply
#4

Very useful for newbies, easy tho
+rep
Reply
#5

Instead of split I recommend sscanf.
Reply
#6

Quote:
Originally Posted by [CG]Milito
View Post
Very useful for newbies, easy tho
+rep
Thank you, and it was intended for newbies. If it wasn't easy, I wouldn't recommend it for newbies.

Quote:
Originally Posted by SuperViper
View Post
Instead of split I recommend sscanf.
Thank you for your input.
Reply
#7

Actually that splits() function could be really useful for some stuff as an example a map editor with multiple import methods, I know where to come if I need to steal it as a stock function

BTW - Good tutorial for the noobs but I think you should have made it work for every player which might be a good idea as follow up tutorial to expand on dynamic scripting methods.
Reply
#8

Quote:
Originally Posted by [uL]Pottus
View Post
BTW - Good tutorial for the noobs but I think you should have made it work for every player which might be a good idea as follow up tutorial to expand on dynamic scripting methods.
Not sure what you're saying.
The spawn sets for every player in the server.
Or do you mean so ever player can individually set their own spawn? Sorry for the misunderstanding.
Reply
#9

When I try to change the CMD to set the spawn from "spawn" to "setspawn" it does not work
Reply
#10

An good Tutorial, well explained for Beginners.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)