Burgershot
  • Home
  • Members
  • Team
  • Help
  • Search
  • Register
  • Login
  • Home
  • Members
  • Help
  • Search
Burgershot SA-MP Tutorials Make simple entrance

 
  • 0 Vote(s) - 0 Average
Make simple entrance
Tama
Offline

Burgershot Member
Posts: 42
Threads: 8
Joined: Sep 2019
Reputation: 1
Location: India
#1
2020-07-30, 10:08 AM (This post was last modified: 2020-07-30, 12:35 PM by Tama.)
Hello guys, today i want to teach you how to make a simple entrance, it's easy to make entrance.
All you need to do just follow my instruction, okay ;)

First, you need to download these includes below.
  • sscanf -> https://github.com/maddinat0r/sscanf/releases
  • streamer ->https://github.com/samp-incognito/samp-s...n/releases
  • Pawn.CMD -> https://github.com/urShadow/Pawn.CMD/releases (or you can download your own version of CMD processor)
Then you need to extract each of that include to each folder. If you found .dll file, put it on Plugins and if you found .inc file you can put on "pawno/includes"
Okay, i assuming you have extracted the include/plugins, now let's get started.

Make a base script, like this:
PHP Code:
#define FILTERSCRIPT

#include <a_samp>
#include <sscanf2>
#include <streamer>
#include <Pawn.CMD>

public OnFilterScriptInit() {
    return 1;
}

public 
OnFilterScriptExit() {
    return 1;
} 

Add MAX_ENTRANCE, enum (alias), and public variable like this:
PHP Code:
#define MAX_ENTRANCE 22 // maximum entrance "server" could handle/store temporarily

enum 
    e_ENTRANCE_DATA 
{
    bool:isExists, // checking if entrance exists
    name[24], // entrance name
    Float:pos[3], // outside position
    Float:intPos[3], // inside position
    int, // interior id
    world // world id
};
new 
EntranceData[MAX_ENTRANCE][e_ENTRANCE_DATA]; 

Next step is making a command, use your word like "entrancecreate, entranceedit, entrancedelete" or anything for the command name.
And adding "security" like IsPlayerAdmin(playerid) you can preventing people from creating a entrance.
You can do like this if you want:
PHP Code:
CMD:makeentrance(playerid, params[]) {
    if (!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, -1, "You are not administrator");
    if (!isnull(params)) return SendClientMessage(playerid, -1, "/makeentrance <name>"); // tell player if "params" is null 

Inside the cmd, you need to add this.
PHP Code:
   // getting the next slot with checking if isExists on "i" variable is false
    for (new i; i < MAX_ENTRANCE; i ++) if (!EntranceData[i][isExists]) {

        // storing useful data to server, this prevents for "false detection"
        EntranceData[i][isExists] = true;

        //you can use strcat if you want, but i prefer format
        format(EntranceData[i][name], 24, params);

       // getting player position and angle for teleport/spawning pickup
        GetPlayerPos(playerid, EntranceData[i][pos][0], EntranceData[i][pos][1], EntranceData[i][pos][2]);
        GetPlayerFacingAngle(playerid, EntranceData[i][pos][3]);
       
        
// spawning "dynamic pickup" on stored location
        EntranceData[i][text] = CreateDynamic3DTextLabel(EntranceData[i][name], -1, EntranceData[i][pos][0], EntranceData[i][pos][1], EntranceData[i][pos][2], 4.0);
        EntranceData[i][model] = CreateDynamicPickup(modelid, type, EntranceData[i][pos][0], EntranceData[i][pos][1], EntranceData[i][pos][2], 0, 0);

        // and tell player if everything done
        SendClientMessage(playerid, -1, "Successfully making a entrance");
        return 1;
    }
     // if MAX_ENTRANCE has reached, tell player
     SendClientMessage(playerid, -1, "Server cannot handle more entrance");
     return 1;
} 

That code will checking if number within "i" variable is free to use, and if is then the code will set isExists to prevent "overwriting" data/false detection.
And storing player position and angle is useful for teleporting and "spawning" pickup on that positon.

After making command for creating entrance, now you need to make another command for storing interior position, so you can enter/exit.
For example, i will make "entrancepos" instead "entranceedit" because i want to make things simpler.
PHP Code:
CMD:interiorentrance(playerid, params[]) {
    
    
// make local variable first to avoid warning/error
    new entId;
    
   
// check if player not input anything or if player input is NaN
    if (sscanf(params, "i", entId))
        return SendClientMessage(playerid, -1, "/nteriorentrance<entrance ID>"); // then tell player to do like this.
  
    
// check again if entrance is valid, using this method will avoid any warning like "Array out of bonds"
    if ((entId < 1 || entId >= MAX_ENTRANCE) && (!EntranceData[entId][isExists]))
        return SendClientMessage(playerid, -1, "Invalid entrance ID"); // if is, tell player that ID is not exists.

    // if things are clear, now we can safely store our position to Entrance Data.
    GetPlayerPos(playerid, EntranceData[entId][pos][0], EntranceData[entId][pos][1], EntranceData[entId][pos][2]);
    GetPlayerFacingAngle(playerid, EntranceData[entId][pos][3]);
 
    EntranceData
[entId][int] = GetPlayerInterior(playerid);
    EntranceData[entId][world] = GetPlayerVirtualWorld(playerid);
    
    
// tell player if script successfully storing data.
    SendClientMessage(playerid, -1, "Successfully editing Entrance Interior");
    return 1;
} 

We're finish making those command, now the last but not least.. Making a delete command.
PHP Code:
CMD:deleteentrance(playerid, params[]) {
    // make local variable first to avoid warning/error
    new entId;
    
   
// check if player not input anything or if player input is NaN
    if (sscanf(params, "i", entId))
        return SendClientMessage(playerid, -1, "/deleteentrance <entrance ID>"); // then tell player to do like this.
  
    
// check again if entrance is valid, using this method will avoid any warning like "Array out of bonds"
    if ((entId < 1 || entId >= MAX_ENTRANCE) && (!EntranceData[entId][isExists]))
        return SendClientMessage(playerid, -1, "Invalid entrance ID"); // if is, tell player that ID is not exists.

    // okay first, we gonna kick people if they are inside of what we want to destroy/delete.
    for (new i, j = GetPlayerPoolSize(); i < j; i ++) if (PlayerInEntrance[i] == entId) {

        SetPlayerPos(playerid, EntranceData[entId][pos][0], EntranceData[entId][pos][1], EntranceData[entId][pos][2]);
        SetPlayerFacingAngle(playerid, EntranceData[entId][pos][3]);
 
        SetPlayerInterior
(playerid, 0);
        SetPlayerVirtualWorld(playerid, 0);

        PlayerInEntrance[playerid] = -1;
    }

    // and let's destroy entrance pickup and text.
    if (IsValidDynamic3DTextLabel(EntranceData[entId][text]))
        DestroyDynamic3DTextLabel(EntranceData[entId][text]);

    if (IsValidDynamicPickup(EntranceData[entId][model]))
        DestroyDynamicPickup(EntranceData[entId][model]);

    // if things are clear, now we can safely reset Entrance Data.
    new tmpReset[e_ENTRANCE_DATA];
    EntranceData[entId] = tmpReset;
    EntranceData[entId][isExists] = false;
    return 1;
} 

Now we're done with command, lets go to the next step.
Okay, we need to make a code so people can enter a entrance with "F" or whatever key you'll use.
Lets say i want to make "F" for enter/exit the entrance.
PHP Code:
public OnPlayerKeyStatechange(playerid, newkeys, oldkeys) {

    // this code is detecting if player pressed KEY_FIRE (F/Enter/LMB/TAB)
    if ((newkeys & KEY_FIRE) && !(oldkeys & KEY_FIRE)) {

        //making local variabel for storing entrance ID
        new entId;

        // we need to make a function which detects if player is nearing any
        // entrance within radius 2.5, if does then script returning a entrance ID.
        if ((entId = GetNearestEntrance(playerid, 2.5)) != -1) {

            // after that, teleport player to inside of nearest entrance
            SetPlayerPos(playerid, EntranceData[entId][intPos][0], EntranceData[entId][intPos][1], EntranceData[entId][intPos][2]);
            SetPlayerFacingAngle(playerid, EntranceData[entId][intPos][3]);
 
            SetPlayerInterior
(playerid, EntranceData[entId][int]);
            SetPlayerVirtualWorld(playerid, EntranceData[entId][world]);

            // storing entrance ID to player variable, so we can use that later.
            PlayerInEntrance[playerid] = entId;
        } 

        
// this code checking player if they pressed "F"/KEY_FIRE and player in near exit + player inside a entrance.
        if ((entId = PlayerInEntrance[playerid] != -1) && IsPlayerInRangeOfPoint(playerid, 2.5, EntranceData[entId][intPos][0], EntranceData[entId][intPos][1], EntranceData[entId][intPos][2])) {
            // after that, teleport player to outside of nearest entrance
            SetPlayerPos(playerid, EntranceData[entId][pos][0], EntranceData[entId][pos][1], EntranceData[entId][pos][2]);
            SetPlayerFacingAngle(playerid, EntranceData[entId][pos][3]);
 
            SetPlayerInterior
(playerid, 0);
            SetPlayerVirtualWorld(playerid, 0);

            // change player variable to -1 to avoid false detection.
            PlayerInEntrance[playerid] = -1;
        }
    }
    return 1;
} 

Last but not least, we're gonna make "function" to check is player near any entrance 
and returning entrance ID if that entrance is closest to player than any entrance.

PHP Code:
GetNearestEntrance(playerid, Float:radius = 4.0) {
    for (new i; i < MAX_ENTRANCE; i ++) if (IsPlayerInRangeOfPoint(playerid, 2.5, EntranceData[entId][pos][0], EntranceData[entId][pos][1], EntranceData[entId][pos][2])) {
        return i;    
    
}
    return -1;
} 

Yaay, we finish making Entrance System, if you don't understand please reply so i/other people can give you proper way to make you understand.
Sorry if my bad english hehe ~

Oh yeah, btw here is the full code:
PHP Code:
#define FILTERSCRIPT

#include <a_samp>
#include <sscanf2>
#include <streamer>
#include <Pawn.CMD>

public OnFilterScriptInit() {
    return 1;
}

public 
OnFilterScriptExit() {
    return 1;
}

CMD:makeentrance(playerid, params[]) {
    if (!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, -1, "You are not administrator");
    if (!isnull(params)) return SendClientMessage(playerid, -1, "/makeentrance <name>"); // tell player if "params" is null

   // getting the next slot with checking if isExists on "i" variable is false
    for (new i; i < MAX_ENTRANCE; i ++) if (!EntranceData[i][isExists]) {

        // storing useful data to server, this prevents for "false detection"
        EntranceData[i][isExists] = true;

        //you can use strcat if you want, but i prefer format
        format(EntranceData[i][name], 24, params);

       // getting player position and angle for teleport/spawning pickup
        GetPlayerPos(playerid, EntranceData[i][pos][0], EntranceData[i][pos][1], EntranceData[i][pos][2]);
        GetPlayerFacingAngle(playerid, EntranceData[i][pos][3]);
       
        
// spawning "dynamic pickup" on stored location
        EntranceData[i][text] = CreateDynamic3DTextLabel(EntranceData[i][name], -1, EntranceData[i][pos][0], EntranceData[i][pos][1], EntranceData[i][pos][2], 4.0);
        EntranceData[i][model] = CreateDynamicPickup(modelid, type, EntranceData[i][pos][0], EntranceData[i][pos][1], EntranceData[i][pos][2], 0, 0);

        // and tell player if everything done
        SendClientMessage(playerid, -1, "Successfully making a entrance");
        return 1;
    }
     // if MAX_ENTRANCE has reached, tell player
     SendClientMessage(playerid, -1, "Server cannot handle more entrance");
     return 1;
}

CMD:interiorentrance(playerid, params[]) {
    
    
// make local variable first to avoid warning/error
    new entId;
    
   
// check if player not input anything or if player input is NaN
    if (sscanf(params, "i", entId))
        return SendClientMessage(playerid, -1, "/nteriorentrance<entrance ID>"); // then tell player to do like this.
  
    
// check again if entrance is valid, using this method will avoid any warning like "Array out of bonds"
    if ((entId < 1 || entId >= MAX_ENTRANCE) && (!EntranceData[entId][isExists]))
        return SendClientMessage(playerid, -1, "Invalid entrance ID"); // if is, tell player that ID is not exists.

    // if things are clear, now we can safely store our position to Entrance Data.
    GetPlayerPos(playerid, EntranceData[entId][pos][0], EntranceData[entId][pos][1], EntranceData[entId][pos][2]);
    GetPlayerFacingAngle(playerid, EntranceData[entId][pos][3]);
 
    EntranceData
[entId][int] = GetPlayerInterior(playerid);
    EntranceData[entId][world] = GetPlayerVirtualWorld(playerid);
    
    
// tell player if script successfully storing data.
    SendClientMessage(playerid, -1, "Successfully editing Entrance Interior");
    return 1;
}

CMD:deleteentrance(playerid, params[]) {
    // make local variable first to avoid warning/error
    new entId;
    
   
// check if player not input anything or if player input is NaN
    if (sscanf(params, "i", entId))
        return SendClientMessage(playerid, -1, "/deleteentrance <entrance ID>"); // then tell player to do like this.
  
    
// check again if entrance is valid, using this method will avoid any warning like "Array out of bonds"
    if ((entId < 1 || entId >= MAX_ENTRANCE) && (!EntranceData[entId][isExists]))
        return SendClientMessage(playerid, -1, "Invalid entrance ID"); // if is, tell player that ID is not exists.

    // okay first, we gonna kick people if they are inside of what we want to destroy/delete.
    for (new i, j = GetPlayerPoolSize(); i < j; i ++) if (PlayerInEntrance[i] == entId) {

        SetPlayerPos(playerid, EntranceData[entId][pos][0], EntranceData[entId][pos][1], EntranceData[entId][pos][2]);
        SetPlayerFacingAngle(playerid, EntranceData[entId][pos][3]);
 
        SetPlayerInterior
(playerid, 0);
        SetPlayerVirtualWorld(playerid, 0);

        PlayerInEntrance[playerid] = -1;
    }

    // and let's destroy entrance pickup and text.
    if (IsValidDynamic3DTextLabel(EntranceData[entId][text]))
        DestroyDynamic3DTextLabel(EntranceData[entId][text]);

    if (IsValidDynamicPickup(EntranceData[entId][model]))
        DestroyDynamicPickup(EntranceData[entId][model]);

    // if things are clear, now we can safely reset Entrance Data.
    new tmpReset[e_ENTRANCE_DATA];
    EntranceData[entId] = tmpReset;
    EntranceData[entId][isExists] = false;
    return 1;
}

public 
OnPlayerKeyStatechange(playerid, newkeys, oldkeys) {

    // this code is detecting if player pressed KEY_FIRE (F/Enter/LMB/TAB)
    if ((newkeys & KEY_FIRE) && !(oldkeys & KEY_FIRE)) {

        //making local variabel for storing entrance ID
        new entId;

        // we need to make a function which detects if player is nearing any
        // entrance within radius 2.5, if does then script returning a entrance ID.
        if ((entId = GetNearestEntrance(playerid, 2.5)) != -1) {

            // after that, teleport player to inside of nearest entrance
            SetPlayerPos(playerid, EntranceData[entId][intPos][0], EntranceData[entId][intPos][1], EntranceData[entId][intPos][2]);
            SetPlayerFacingAngle(playerid, EntranceData[entId][intPos][3]);
 
            SetPlayerInterior
(playerid, EntranceData[entId][int]);
            SetPlayerVirtualWorld(playerid, EntranceData[entId][world]);

            // storing entrance ID to player variable, so we can use that later.
            PlayerInEntrance[playerid] = entId;
        } 

        
// this code checking player if they pressed "F"/KEY_FIRE and player in near exit + player inside a entrance.
        if ((entId = PlayerInEntrance[playerid] != -1) && IsPlayerInRangeOfPoint(playerid, 2.5, EntranceData[entId][intPos][0], EntranceData[entId][intPos][1], EntranceData[entId][intPos][2])) {
            // after that, teleport player to outside of nearest entrance
            SetPlayerPos(playerid, EntranceData[entId][pos][0], EntranceData[entId][pos][1], EntranceData[entId][pos][2]);
            SetPlayerFacingAngle(playerid, EntranceData[entId][pos][3]);
 
            SetPlayerInterior
(playerid, 0);
            SetPlayerVirtualWorld(playerid, 0);

            // change player variable to -1 to avoid false detection.
            PlayerInEntrance[playerid] = -1;
        }
    }
    return 1;
}

GetNearestEntrance(playerid, Float:radius = 4.0) {
    for (new i; i < MAX_ENTRANCE; i ++) if (IsPlayerInRangeOfPoint(playerid, 2.5, EntranceData[entId][pos][0], EntranceData[entId][pos][1], EntranceData[entId][pos][2])) {
        return i;    
    
}
    return -1;
} 
आपको अपने पापों पर पश्चाताप करना चाहिए, वे आपको नष्ट कर देंगे। आप कोई मौका नहीं खड़े हो रहे हैं। तुम उसके हाथ पर मर जाओगे। पछताना


Pinch
Offline

Burgershot Member
Posts: 391
Threads: 19
Joined: Apr 2019
Reputation: 22
Location: Belgrade, Serbia
#2
2020-07-30, 10:04 PM
I recommend usage of Streamer_UpdateEx(...) if there is heavy usage of streamer plugin on your server.

Great tutorial tho!
Using Pawn.CMD?
If you're doing so, this is the very first sign that you absolutely shouldn't utilize your all powerful P-Code knowledge in any of the scripting discussion topics.
Tama
Offline

Burgershot Member
Posts: 42
Threads: 8
Joined: Sep 2019
Reputation: 1
Location: India
#3
2020-07-31, 02:09 PM
(2020-07-30, 10:04 PM)Pinch Wrote: I recommend usage of Streamer_UpdateEx(...) if there is heavy usage of streamer plugin on your server.
Yeah, and also you can use Streamer_ToggleIdleUpdate(...) if you want to make object appear without moving first.

(2020-07-30, 10:04 PM)Pinch Wrote: Great tutorial tho!
Thanks
आपको अपने पापों पर पश्चाताप करना चाहिए, वे आपको नष्ट कर देंगे। आप कोई मौका नहीं खड़े हो रहे हैं। तुम उसके हाथ पर मर जाओगे। पछताना


« Next Oldest | Next Newest »



  • View a Printable Version
  • Subscribe to this thread
Forum Jump:

© Burgershot - Powered by our Community and MyBB Original Theme by Emerald

Linear Mode
Threaded Mode