[Include] mGates (Easily create automatic gates with one function!)
#1

mGates 2.1
by MP2
Introduction
This include makes it EXTREMELY easy to create automatic gates, with only one single line of code required!
I made this for my own server that I am developing, but I like to share, so here it is.
It also has an option for you to deny access for certain players based on things such as their team, so if you want to make a gate that only opens for the police, it's extremely easy.
Perhaps with this we can reduce the number of 'HELP PLS MY GATE WHY HE NO OPEN?? [REP++++]' topics.
It also makes use of a custom iterator in foreach() - so is very efficient! No big loops.

[ame]http://www.youtube.com/watch?v=PcOD5AThnFE[/ame]
Code used in video (messy long version - this should be spread over multiple lines to make it clearer to read/edit, which it will be later in the topic):
pawn Code:
CreateAutomaticGate(968, 1544.692993, -1630.822509, 13.08, 0.000000, 90.000000, 90.000000, 1544.692993, -1630.822509, 13.08+0.01, 0.000000, 10.000000, 90.000000, 1544.6627, -1627.4036, 13.1099, 20.0, 0.003);
Let's get in to it.

Usage

==================================================
FUNCTIONS
==================================================

To create an automatic gate (opens when players are near)

CreateAutomaticGate(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, Float:x2, Float:y2, Float:z2, Float:rx2, Float:ry2, Float:rz2, Float:trigx, Float:trigy, Float:trigz, Float:trig_range, Float:movespeed, condition=0);

Parameters:
modelid - The object model to use for the gate

x y z - The position of the CLOSED gate

rx ry rz - The rotation of the CLOSED gate

x2 y2 z2 - The position of the OPEN gate

rx2 ry2 rz2 - The rotation of the OPEN gate
Set ALL to -1000 or the same as rx, ry, rz to NOT change rotation

trigx trigy trigz - The trigger point. Players in range of this point will
cause the gate to open (or close if nobody in range)

trig_range - The range from the trigger point (trigx trigy trigz) at which
players will cause the gate to open (or close if not in range)

movespeed - The movement speed for the object. The differs drastically for
rotating and sliding gates. See tutorial HERE

condition - If condition is set to 1, you must return 1 in the the
OnPlayerRequestGate callback for the player to pass,
there you can check if the player meets a certain condition,
for example you may only want cops to be able to trigger the
gate to open. If set to 0 the gate will open for anyone.
Do note however, someone that is NOT a cop could still get in
after a cop triggers it to open.

This function has many parameters. Typing 'CreateAutomaticGate(' in pawno will pop-up a syntax box that will update in real-time as you specify parameters. In order for this to work you must include the .inc file and re-open pawno.

Returns:
The ID of the gate that was created (NOTE: NOT the object ID!)
-1 if the gate wasn't created (limit reached)

Example: Create a barrier at the LSPD that will have a condition (cops only):

pawn Code:
new BARRIER_LSPD;

public OnGameModeInit()
{
    // LSPD Barrier
    BARRIER_LSPD = CreateAutomaticGate(
    968, // Model
    1544.69, -1630.8739, 13.0728, // Closed Position
    0.0, 90.0, 90.0, // Closed Rotation
    1544.69, -1630.8739, 13.0728+0.001, // Open Position
    0.0, 00.0, 90.0, // Open Rotation
    1542.87, -1627.0, 13.37, // Trigger Point Position
    20.0, // Trigger Point Radius
    0.001, // Object move speed
    true // Condition? True/False
);
    return 1;
}
Setting it out in this way allows for you to easily see, understand and edit a gate quickly, as opposed to having all the parameters on one line.
You should also comment them (//) so you know which is which - as there are quite a few parameters to pass.

==================================================

To force a gate to open:

OpenGate(gateid);

Parameters:
gateid - The ID of the gate. Returned by CreateAutomaticGate().

Returns:
-1 - Gate doesn't exist
0- Gate already open(ing)
1 - Gate opening - success!

Example:

pawn Code:
public OnPlayerCommandText(playerid, cmdtext[])
{
    if(!strcmp(cmdtext, "/LSPD", true))
    {
        OpenGate(BARRIER_LSPD);
        return 1;
    }
    return 0;
}
==================================================

To force a gate to close:

CloseGate(gateid);

Parameters:
gateid - The ID of the gate. Returned by CreateAutomaticGate().

Returns:
-1 - Gate doesn't exist
0- Gate already close(ing)
1 - Gate closing - success!

pawn Code:
public OnPlayerCommandText(playerid, cmdtext[])
{
    if(!strcmp(cmdtext, "/LSPD", true))
    {
        CloseGate(BARRIER_LSPD);
        return 1;
    }
    return 0;
}
==================================================

To check the state of a gate (open/closed/opening/closing):

GateStatus(gateid);

Parameters:
gateid - The ID of the gate. Returned by CreateAutomaticGate().

Returns:
-1 - Gate doesn't exist
GATE_STATUS_CLOSED 0 - Gate is fully closed
GATE_STATUS_OPENING 1 - Gate is opening, not yet fully open
GATE_STATUS_OPEN 2 - Gate is fully open
GATE_STATUS_CLOSING 3 - Gate is closing, not yet fully closed

pawn Code:
public OnPlayerCommandText(playerid, cmdtext[])
{
    if(!strcmp(cmdtext, "/LSPD", true))
    {
        if(GateStatus(BARRIER_LSPD) == GATE_STATUS_OPEN || GateStatus(BARRIER_LSPD) == GATE_STATUS_OPENING) return SendClientMessage(playerid, COLOR_RED, "Gate is already open!");
        OpenGate(BARRIER_LSPD);
        return 1;
    }
    return 0;
}
==================================================

To remove/delete/destroy a gate:

DestroyGate(gateid);
or
DeleteGate(gateid);
or
RemoveGate(gateid);

Parameters:
gateid -
The ID of the gate to destroy/delete. Returned by CreateAutomaticGate().

Returns:
-1 - Invalid gate ID
0 - Gate doesn't exist
1 - Gate was destroyed successfully

Example:

pawn Code:
new BARRIER_LSPD;

public OnGameModeInit()
{
    BARRIER_LSPD = CreateAutomaticGate(...);
    return 1;
}

public OnPlayerCommandText(playerid, cmdtext[])
{
    if(!strcmp(cmdtext, "/LSPD", true))
    {
        DestroyGate(BARRIER_LSPD);
        return 1;
    }
    return 0;
}
==================================================
CALLBACKS
==================================================


public OnGateOpenClose(gateid, openclose, Float:gatex, Float:gatey, Float:gatez)

OnGateOpenClose is called when a gate opens or closes.
It is called 4 times per gate: when the gate starts to open, when it's fully open, when it starts to close and when it's fully closed again.

'gateid' is the ID of the gate that triggered this callback (returned by CreateAutomaticGate).

GATE_STATUS_CLOSED 0 - Gate is fully closed
GATE_STATUS_OPENING 1 - Gate is opening, not yet fully open
GATE_STATUS_OPEN 2 - Gate is fully open
GATE_STATUS_CLOSING 3 - Gate is closing, not yet fully closed

gatex, gatey, and gatez are the coordinates of the gate currently (whether opening or closing) - can be used, for example, to play a sound for players near-by


==================================================

public OnPlayerRequestGate(playerid, gateid)

The core of the 'condition' system.
Returning 0/false in this callback will deny the player access to the gate.
Is it important to note, however, if one player triggers the gate open, it opens for everyone, even those without access. This is unavoidable unless the gate objects are per-player, which would not look or work well.
See the second post below for detailed explanation of condition system.

==================================================

public OnPlayerTriggerGate(playerid, gateid)

Called when a player triggers a gate to open.
One use I had for this was playing the 'They'll give a pilots license to anybody these days' sound when players triggered the airport gates to open.
This callback may not be needed, as the code could simply be put under OnPlayerRequestGate, but this makes things easier.

==================================================

Download

http://pastebin.com/jS0mWwaL
Save as mGates.inc and place in pawno/include/ folder.

Installation

You will need to download foreach and y_hooks (YSI) to use this include. Put all the .inc files (and the YSI folder) in your \pawno\include folder.

Add '#include <mGates>' under '#include <a_samp>' in your script.
NOTE: It's mGates, not mgates.

If you're going to create more than 100 gates, re-define MAX_GATES in mGates.inc.
You can also set how often the gates are all checked. This is once a second by default.

Use it (see usage).

Changelog

See in file.

Credits
Big thanks to Y_Less for foreach and y_hooks (YSI). foreach() makes this include very efficient.
Thanks to iGetty for testing

Enjoy, and please report any bugs.
Reply
#2

Explanation of 'condition' system.


The 'condition' value in CreateAutomaticGate() determines whether a player must meet certain contitions if they are to pass through a gate, for example you may wish to create a gate that only a police officer can open. This makes it extremely easy to do so.

First, create the gate with a GLOBAL VARIABLE to store the gate's ID in:

pawn Code:
new BARRIER_LSPD;

public OnGameModeInit()
{
    BARRIER_LSPD = CreateAutomaticGate(968, 1544.692993, -1630.822509, 13.08, 0.000000, 90.000000, 90.000000, 1544.692993, -1630.822509, 13.08+0.01, 0.000000, 10.000000, 90.000000, 1544.6627, -1627.4036, 13.1099, 20.0, 0.003, 1);
    return 1;
}
Notice how the last parameter is a 1? That is the 'condition' parameter. If set to 1, players must meet conditions we set.

Now, pretend we have a variable called 'gTeam' and a team defined as TEAM_COP. If the player's gTeam is TEAM_COP, we will allow them to trigger the gate to open.

pawn Code:
#define TEAM_COP 1

new gTeam[MAX_PLAYERS];
To set permissions, we need to use the OnPlayerRequestGate callback. If we return 0 here, the gate will not open, if we return 1 it will.

pawn Code:
#define TEAM_COP 1

new gTeam[MAX_PLAYERS];

public OnPlayerRequestGate(playerid, gateid)
{
    if(gateid == BARRIER_LSPD && gTeam[playerid] != TEAM_COP) return 0;

    return 1; // Player can pass
}
If that is not obvious, allow me to break it down:

if(gateid == BARRIER_LSPD
If the gate that they requested is BARRIER_LSPD

&& gTeam[playerid] != TEAM_COP
and their gTeam is NOT TEAM_COP
return 0, denying entrance.

Extremely simple eh?
Reply
#3

Using OnGateOpenClose and OnPlayerTriggerGate

These two functions are useful for many things. In this example we will create the gates at LS airport, and add 'clang' sounds when they open/close using OnGateOpenClose. We will also play the 'This area is restricted to pilots only.' voice from single-player on OnPlayerRequestGate if entrance is denied, as we only want pilots (skin 61) to enter.

First we need to create the gate, and store its ID in a global variable to handle it later. Two gates are required at the LS airport, but we will only handle one for the sounds, but still need to provide an ID for it for the permissions:

pawn Code:
new GATE_LSAP[2];

public OnGameModeInit()
{
    // LS airport gates
    GATE_LSAP[0] = CreateAutomaticGate(988, 1958.742797, -2189.757324, 13.586877, 0.000000, 0.000000, 180.000000, 1954.142822, -2189.757324, 13.586876, -1000, -1000, -1000, 1961.5413,-2189.3660,13.5469, 15, 4, 1);
    GATE_LSAP[1] = CreateAutomaticGate(988, 1964.242919, -2189.757324, 13.586877, 0.000000, 0.000000, 180.000000, 1968.842895, -2189.757324, 13.586876, -1000, -1000, -1000, 1961.5413,-2189.3660,13.5469, 15, 4, 1);
    return 1;
}
Now, when OnGateOpenClose is called, we want to play the sound of the gate opening to players that are in range:

pawn Code:
public OnGateOpenClose(gateid, openclose, Float:gatex, Float:gatey, Float:gatez)
{
    if(gateid == GATE_LSAP[0])
    {
        if(openclose == GATE_STATUS_OPENING || openclose == GATE_STATUS_CLOSING)
        {
            foreach(new i : Player)
            {
                if(IsPlayerInRangeOfPoint(i, 30, gatex, gatey, gatez)) PlayerPlaySound(i, 1100, gatex, gatey, gatez);
            }
        }
        else
        {
            foreach(new i : Player)
            {
                if(IsPlayerInRangeOfPoint(i, 30, gatex, gatey, gatez)) PlayerPlaySound(i, 1101, gatex, gatey, gatez);
            }
        }
    }
    return 1;
}
When a player triggers the gate, we need to play the 'They'll give a pilot's license to anybody these days!' sound:

pawn Code:
public OnPlayerTriggerGate(playerid, gateid)
{
    if(gateid == GATE_LSAP[0]) SetTimerEx("pilot_speech", 321, 0, "i", playerid);
    return 1;
}

forward pilot_speech(playerid);
public pilot_speech(playerid)
{
    PlayerPlaySound(playerid, 16802+random(2), 0, 0, 0);
    return 1;
}
The reason we have to delay it is so that it does not over-ride the 'clang' sound of the game opening. ~300 miliseconds is good.

Finally we must set the conditions for players to pass, which in this case, they must be using skin ID 61 which is a pilot:

pawn Code:
new pGateTick[MAX_PLAYERS];
public OnPlayerRequestGate(playerid, gateid)
{
    if((gateid == GATE_LSAP[0] || gateid == GATE_LSAP[1]) && GetPlayerSkin(playerid) != 61)
    {
        if(gettime()-pGateTick[playerid] > 10) // If 10 seconds have passed since the last trigger (to prevent spam)
        {
            PlayerPlaySound(playerid, 16800+random(2), 0, 0, 0);
            pGateTick[playerid] = gettime();
        }
        return 0;
    }
    return 1;
}
If they are not using skin 61, entry is denied (return 0;) and the 'This area is restricted to pilots only' sound is played. The pGateTick and gettime() stuff is an 'antispam' as this function would be called once a second for a player standing in the trigger zone, so we don't want to 'spam' the sound.

Here's that code in action:

[ame]http://www.youtube.com/watch?v=PoJ4qhdoA2U[/ame]
Reply
#4

nice job but I think it's not automatic if you open it with commands?
Reply
#5

Nice work!
Reply
#6

Quote:
Originally Posted by System64
View Post
nice job but I think it's not automatic if you open it with commands?
That's just an example for the OpenGate and CloseGate function..
Reply
#7

I will try it! .
Reply
#8

Video: [ame]http://www.youtube.com/watch?v=PcOD5AThnFE[/ame]
Reply
#9

Excellent job dude, really.

Keep the releases coming, a lot of effort was involved.
Reply
#10

An example of using OpenGate() with condition=1 could be if you used this with my keypad include (see signature), you could make a blast door in Area 69 (as is in the example GM in the keypad include topic) and you could let players with the army skin through, and other players must enter the key in the keypad, then you use OpenGate().
Reply
#11

Nice Really nice
Reply
#12

Cool, this is similar to my filterscript but seems more advanced.
Reply
#13

Dude you are the best this is so cool script. How you made the gates to move smoothly ?
Reply
#14

Quote:
Originally Posted by Rg-Gaming.Info
Посмотреть сообщение
Dude you are the best this is so cool script. How you made the gates to move smoothly ?
MoveObject. And what's with that triple post documentation of a script like that? I mean seriously...
Reply
#15

Why did you triple post? there's an edit post button, you know.
Reply
#16

Nice and useful.
Reply
#17

Quote:
Originally Posted by Porsche911
Посмотреть сообщение
Why did you triple post? there's an edit post button, you know.
Stop kissing ass to king_hual.


OT: Nice gate system.
Reply
#18

Quote:
Originally Posted by king_hual
Посмотреть сообщение
what's with that triple post documentation of a script like that? I mean seriously...
Quote:
Originally Posted by Porsche911
Посмотреть сообщение
Why did you triple post? there's an edit post button, you know.
I wanted to keep them separate.
Reply
#19

One Question: Do they get saved after a server restart?
Reply
#20

You create them in your script.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)