[Tutorial] SuperS82's House System
#1

Introduction

Ok so you wanna make a really good house system that works, works well, looks great, and most of all has alot of great features? Well tonights your lucky night! I'll share my house system that I think should be used in every RP server that exists! Oh yeah and most of all, the icons are created/deleted on command execution. So if your used to restarting the server to see changes, be prepared to drool in amazement! Ok, or just be like, "wow, thats nice!".

Preparation

First thing we gotta do is create our empty files to be used. To do this, open up your handy notepad.exe or any other text editor. Open a blank document and enter the following information. Also, make sure to untick word wrap.
pawn Код:
0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,Owner,Description,0,0,0,0,0,0,0,0,0,0,0,0
//This will be our line 0 and represents our houseinfo template
now save it and name it as "houseinfo.cfg" in your serverfiles folder.

Scripting

Creating the enum to store all the houseinfo.cfg variables
pawn Код:
enum hInfo
{
    Float:hEntranceX,
    Float:hEntranceY,
    Float:hEntranceZ,
    Float:hEntranceA,
    Float:hExitX,
    Float:hExitY,
    Float:hExitZ,
    Float:hExitA,
    hOwner[MAX_PLAYER_NAME],
    hDescription[MAX_PLAYER_NAME],
    hValue,
    hRevenue,
    hHel,
    hArm,
    hInt,
    hWorld,
    hLock,
    hOwned,
    hRooms,
    hRent,
    hRentable,
    hPickup,
};
new HouseInfo[1000][hInfo];
Creating Load/Save Stocks for the houseinfo.cfg file

A. stock LoadHouse()

The code does the following:
- looks for the file houseinfo.cfg and reads its contents starting at line 1 HouseInfo[1][hInfo]
- splits the current array into seperate variables
- if the variable hOwned has no value it creates a green property pickup at the variables for hEntranceX,hEntranceY,hEntranceZ
- if the variable hOwned has a value it creates a "?" pickup at the variables for hEntranceX,hEntranceY,hEntranceZ
- checks the string length of hOwner and if it has none stores the string "Los Santos" as hOwner
- loops threw every line of houseinfo.cfg until it reaches the end
- once the loops is finished it prints the final information to the server console
- closes houseinfo.cfg
pawn Код:
stock LoadHouse()
{
    new arrCoords[22][64];
    new strFromFile2[128];
    new File: file = fopen("houseinfo.cfg", io_read);
    if (file)
    {
        new idx;
        while (idx < sizeof(HouseInfo))
        {
            fread(file, strFromFile2);
            split(strFromFile2, arrCoords, ',');
            HouseInfo[idx][hEntranceX] = floatstr(arrCoords[0]);
            HouseInfo[idx][hEntranceY] = floatstr(arrCoords[1]);
            HouseInfo[idx][hEntranceZ] = floatstr(arrCoords[2]);
            HouseInfo[idx][hEntranceA] = floatstr(arrCoords[3]);
            HouseInfo[idx][hExitX] = floatstr(arrCoords[4]);
            HouseInfo[idx][hExitY] = floatstr(arrCoords[5]);
            HouseInfo[idx][hExitZ] = floatstr(arrCoords[6]);
            HouseInfo[idx][hExitA] = floatstr(arrCoords[7]);
            strmid(HouseInfo[idx][hOwner], arrCoords[8], 0, strlen(arrCoords[8]), 255);
            strmid(HouseInfo[idx][hDescription], arrCoords[9], 0, strlen(arrCoords[9]), 255);
            HouseInfo[idx][hValue] = strval(arrCoords[10]);
            HouseInfo[idx][hRevenue] = strval(arrCoords[11]);
            HouseInfo[idx][hHel] = strval(arrCoords[12]);
            HouseInfo[idx][hArm] = strval(arrCoords[13]);
            HouseInfo[idx][hInt] = strval(arrCoords[14]);
            HouseInfo[idx][hWorld] = strval(arrCoords[15]);
            HouseInfo[idx][hLock] = strval(arrCoords[16]);
            HouseInfo[idx][hOwned] = strval(arrCoords[17]);
            HouseInfo[idx][hRooms] = strval(arrCoords[18]);
            HouseInfo[idx][hRent] = strval(arrCoords[19]);
            HouseInfo[idx][hRentable] = strval(arrCoords[20]);
            HouseInfo[idx][hPickup] = strval(arrCoords[21]);
            if(HouseInfo[idx][hOwned] == 0)
            {
                HouseInfo[idx][hPickup] = CreatePickup(1273,1,HouseInfo[idx][hEntranceX],HouseInfo[idx][hEntranceY],HouseInfo[idx][hEntranceZ],0);
            }
            if(HouseInfo[idx][hOwned] == 1)
            {
                HouseInfo[idx][hPickup] = CreatePickup(1239,1,HouseInfo[idx][hEntranceX],HouseInfo[idx][hEntranceY],HouseInfo[idx][hEntranceZ],0);
            }
            if(!strlen(HouseInfo[idx][hOwner]))
            {
                strmid(HouseInfo[idx][hOwner],"Los Santos",0,10,255);
            }
            idx++;
        }
        print(" ");
        print("Dynamic Houses");
        print("---------------");
        printf("  Loaded %d dynamic houses.\n",sizeof(HouseInfo));
        fclose(file);
    }
    return 1;
}
b. Create stock SaveHouse()

The code does the following:
- opens the file houseinfo.cfg
- creates a new string using all the stored variables of HouseInfo[1][hInfo]
- writes the new string to the housinfo.cfg file starting at line 1
- loops until all HouseInfo arrays are stored to the file
- closes the file
pawn Код:
stock SaveHouse()
{
    new idx;
    new File: file2;
    while (idx < sizeof(HouseInfo))
    {
        new coordsstring[128];
        format(coordsstring, sizeof(coordsstring), "%f,%f,%f,%f,%f,%f,%f,%f,%s,%s,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
        HouseInfo[idx][hEntranceX],
        HouseInfo[idx][hEntranceY],
        HouseInfo[idx][hEntranceZ],
        HouseInfo[idx][hEntranceA],
        HouseInfo[idx][hExitX],
        HouseInfo[idx][hExitY],
        HouseInfo[idx][hExitZ],
        HouseInfo[idx][hExitA],
        HouseInfo[idx][hOwner],
        HouseInfo[idx][hDescription],
        HouseInfo[idx][hValue],
        HouseInfo[idx][hRevenue],
        HouseInfo[idx][hHel],
        HouseInfo[idx][hArm],
        HouseInfo[idx][hInt],
        HouseInfo[idx][hWorld],
        HouseInfo[idx][hLock],
        HouseInfo[idx][hOwned],
        HouseInfo[idx][hRooms],
        HouseInfo[idx][hRent],
        HouseInfo[idx][hRentable],
        HouseInfo[idx][hPickup]);
        if(idx == 0)
        {
            file2 = fopen("houseinfo.cfg", io_write);
        }
        else
        {
            file2 = fopen("houseinfo.cfg", io_append);
        }
        fwrite(file2, coordsstring);
        idx++;
        fclose(file2);
    }
    return 1;
}
3. Load Houses in OnGameModeInit()
pawn Код:
public OnGameModeInit()
{
    // Place this before everything else
    LoadHouse();
Making Commands to Set House Enter/Exits

1. Making Entrances and Deleting/Creating Icons

The code does the following:
- checks if admin level is lower than 1337
- if it is sends a message saying your not authorized to use this and ends command
- if it is not moves on to check if a string value is also entered
- if no string value is entered the code sends a message with the command syntax and ends command
- once a string value is entered the code creates variable X,Y,Z,A
- Gets the players position and stores it as X,Y,Z
- Gets the players facing angle and stores it as A
- saves the hEntranceX,hEntranceY,and hEntranceZ variables as X,Y,Z
- saves the variable hEntranceA as the players facing angle
- deletes the pickup id of the string value entered
- checks if the house is owned
- if unowned creates the green property pickup at the players X,Y,Z and stores it as the string value of the pickup id
- if owned creates the "?" pickup at the players X,Y,Z and stores it as the string value of the pickup id
- calls the function SaveHouse()
pawn Код:
if(strcmp(cmd, "/houseenter", true) == 0)
        {
            if(PlayerInfo[playerid][pAdmin] < 1337)
            {
                SendClientMessage(playerid,COLOR_LIGHTRED,"You are not authorized to use this!");
                return 1;
            }
            tmp = strtok(cmdtext, idx);
            if(!strlen(tmp))
            {
                SendClientMessage(playerid,COLOR_LIGHTBLUE,"USAGE: /houseenter [id]");
                return 1;
            }
            new id;
            id = strval(tmp);
            if(id < 1 || id > sizeof(HouseInfo))
            {
                SendClientMessage(playerid,COLOR_LIGHTBLUE,"USAGE: /houseenter [id]");
                return 1;
            }
            new Float:X,Float:Y,Float:Z,Float:A;
            GetPlayerPos(playerid,X,Y,Z);
            GetPlayerFacingAngle(playerid,A);
            HouseInfo[id][hEntranceX] = X;
            HouseInfo[id][hEntranceY] = Y;
            HouseInfo[id][hEntranceZ] = Z;
            HouseInfo[id][hEntranceA] = A;
            DestroyPickup(HouseInfo[id][hPickup]);
            if(HouseInfo[id][hOwned] == 0)
            {
                HouseInfo[id][hPickup] = CreatePickup(1273,1,X,Y,Z,0);
            }
            else
            {
                HouseInfo[id][hPickup] = CreatePickup(1239,1,X,Y,Z,0);
            }
            SaveHouse();
            format(string,sizeof(string),"House: %d's Entrance has been set!",id);
            SendClientMessage(playerid,COLOR_LIGHTBLUE,string);
        }
2. Making Exits and Storing the Interiors

The code does the following:
- checks if the admin level is lower than 1337
- if it is send the message you are not authorized to use this and ends the command
- if it is not the code continues to check if a string value is also entered
- if no string value is entered it sends a message with the command syntax and ends the command
- once a string value is entered it checks if the string value is less than or greater than the files total amount of arrays
- if it is less or greater than the total arrays it again sends the command syntax and ends the command
- once a valid string value is entered the code creates the variable X,Y,Z,A
- Gets the players position and stores the coordinates in X,Y,Z
- Gets the players facing angle and stores it as A
- stores the variables hExitX,hExitY,and hExitZ as the values of X,Y,Z
- stores the variable hExitA as the value of A
- Gets the players current interior and stores it as pInt
- calls the function SaveHouse()
pawn Код:
if(strcmp(cmd, "/houseexit", true) == 0)
        {
            if(PlayerInfo[playerid][pAdmin] < 1337)
            {
                SendClientMessage(playerid,COLOR_LIGHTRED,"You are not authorized to use this!");
                return 1;
            }
            tmp = strtok(cmdtext, idx);
            if(!strlen(tmp))
            {
                SendClientMessage(playerid,COLOR_LIGHTBLUE,"USAGE: /houseexit [id]");
                return 1;
            }
            new id;
            id = strval(tmp);
            if(id < 0 || id > sizeof(HouseInfo))
            {
                SendClientMessage(playerid,COLOR_LIGHTBLUE,"USAGE: /houseexit [id]");
                return 1;
            }
            new Float:X,Float:Y,Float:Z,Float:A;
            GetPlayerPos(playerid,X,Y,Z);
            GetPlayerFacingAngle(playerid,A);
            HouseInfo[id][hExitX] = X;
            HouseInfo[id][hExitY] = Y;
            HouseInfo[id][hExitZ] = Z;
            HouseInfo[id][hExitA] = A;
            HouseInfo[id][hInt] = GetPlayerInterior(playerid);
            SaveHouse();
            format(string,sizeof(string),"House: %d's Exit has been set!",id);
            SendClientMessage(playerid,COLOR_LIGHTBLUE,string);
        }
Conclusion

This is just a little touch on the capabilities of this system. It can be modified to hold more variables/features to your liking. I just think everyone who has a pickup based system needs to implement the ability to delete/create the pickups ingame rather than restarting to move the pickup locations. Currently this is the only way I have found works to store the pickups into variables that can be deleted/recreated seperately. And there is many more things you can do with this system, add drugs into house system, weapons, etc.

Hope it helped some of you out and if there is a more optimal way to do this I will be glad to hear any feedback.
Reply
#2

I'm sorry, but this tutorial sucks. You don't explain what the code you posted does, that's just a copy and paste script, people won't learn from that. Read ******'s 'How to create a tutorial' tutorial
Reply
#3

Ok thanks for your input. I will explain each part as it progresses.
Reply
#4

This look a bit "Copied - Pasted" to me.
Reply
#5

Ok updated the original post wow that took long... Hopefully its simple to follow now and makes sense to you newbz. And no its not copy/pasted... It is similiar to GF house system but I added alot of tweaks and explained them the best I could as I went hopefully making this a good tutorial. This is my first one so thanks for the input.
Reply
#6

IN here can only enter a admin not a legural player
Reply
#7

this still kinda fails alot.
Reply
#8

Not to burst your bubble mate, this looks exactly like the GF, loose the split and the format, please !

Anyway, it works- but not very good if there's alot of houses, this could take nearly 10 seconds to load with about 50 houses, I bet !
Reply
#9

There is no enter and exit commands... Those are admin commands to create the entrances and exits... Anyone can make a /enter and /exit command so I never included them.

And Joe it takes about 5 seconds to load 1000.
Reply
#10

This look a litle like Raven's roleplay house system... A litle diferent but i think it do the something...

But, Good work, only make a better toturial coz i am alried start scripter and i want to use it on my deveployement GM...
[EDIT]
And you should include ALL Cmds! Not all people know make it and like i said On Raven's you have the /enter and /exit cmd to Houses, bizzes and stuff but i don't have sure if this is raven's one or not! The cmds script is the some type too... But Raven's one is better, you have 5 types of houses.... Appartement, smal house, normal house, medium house, big house (like this)

WhatEver...
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)