[Tutorial] Making really long dialogs without crashing
#1

Making really long dialogs without crashing the server


I've seen a few tutorials regarding this lately, but they aren't descriptive enough of what they are doing.
First of all, this tutorial assumes that you have at least basic knowledge of PAWN and of SA-MP functions. You need to know how to create a variable and how to use dialogs in the first place. If you don't know this, please learn how to do so. Besides, if you don't know that, why would you need this tutorial in the first place?
1. Introduction
So, we'd like to show the player a really long dialog, of over 256 characters.
Keeping it all in one ShowPlayerDialog line will crash pawncc.exe if you go above that limit. Many people do not know this, ending up confused about why their gamemode will refuse to compile. To fix this problem, we need to split up the text of the dialog!
"But wait," you will say, "how do we do that? How would we split a dialog up?"
Don't take that literally! I'm not cutting the dialog into separate pieces here,
Easy! We need to know the usage of the function strcat. You won't actually be SPLITTING the text, but you will be adding each 'piece', each line of it separately.

Unlike OnPlayerText, which I covered in the last section and is a callback, strcat is just a function. Remember that. It concatenates (merges) one string with another. If you'd like to know more about concatenation itself, I advise you to check the Wikipedia page for it: http://en.wikipedia.org/wiki/Concatenation

Strcat has three parameters.
  • dest[] - Because of the [], we notice it is a string. It is actually the destination string - the string in which both strings 'mentioned' in the function are 'merged'.
  • source[] - Source is a string, as well, and it is the string that we want to merge into the string we have written instead of the first parameter, which is 'dest'.
  • maxlength- It mentions the size of the destination (i.e dest[] string). It is not necessary to mention it, but I prefer doing it.
P.S: embedded colours count as eight whole characters! If you happen to have many such colours within one string, the same problem will occur. Do not believe that colours occupy no space - that is not true!
2. Demonstrating the issue
Let's simulate such a situation! We will show a dialog with the rules of the server just when the player spawns - i.e OnPlayerSpawn - but you can do it in any callback of your choice and with any text.
pawn Код:
public OnPlayerSpawn(playerid)
{  
    return 1;
}
Now, let's create the dialog. Perhaps we want to have a rules dialog saying this:
Код:
'Hi, and welcome to my Awesome Server of Freeroaming!
Here are some rules that you should respect:
1. You are not allowed to spam.
2. You are not allowed to advertise.
3. You are not allowed to cheat/hack.
4. You are not allowed to spawnkill.
5. You are not allowed to insult others.
6. You are not allowed to beg to be an administrator.
There are special rules for VIPs! Please check
/yaddayaddayadda for more information!
Great - let's do it! We will add colours as well. You can take their definitions from Zh3r0's Easy Colors thread.

pawn Код:
public OnPlayerSpawn(playerid)
{
    ShowPlayerDialog(playerid, 0, DIALOG_STYLE_MSGBOX, ""COL_BLUE"My Super Rules", ""COL_WHITE"Hi, and welcome to my "COL_RED"super duper awesome "COL_WHITE"server!\n"COL_WHITE"Here are some "COL_RED"rules "COL_WHITE"that you should respect:\n"COL_GREEN"1. "COL_WHITE"You are not allowed to spam.\n"COL_GREEN"2. "COL_WHITE"You are not allowed to advertise.\n"COL_GREEN"3. "COL_WHITE"You are not allowed to cheat/hack.\n"COL_GREEN"4. "COL_WHITE"You are not allowed to spawnkill.\n"COL_GREEN"5. "COL_WHITE"You are not allowed to insult others.\n"COL_GREEN"6. "COL_WHITE"You are not allowed to beg for admin.\n"COL_WHITE"There are special rules for "COL_GREEN"VIPs"COL_WHITE"! Please check\n"COL_GREEN"/yaddayaddayadda "COL_WHITE"for more information!", "OK", "Cancel");
    return 1;
}
Try compiling this, and you will notice that your gamemode will never get compiled because your compiler will crash!
3. Demonstrating the solution
Now, we will try the method we recommended to solve this issue.
Declare a variable of size 512 - we do need it that large and sometimes even larger! This is an exception to the "keep the size low" rule. Call it whatever you like, but for demonstration purposes we will call it pDialog.
After that, change the message argument in ShowPlayerDialog to our variable - pDialog!
pawn Код:
public OnPlayerSpawn(playerid)
{
    new pDialog[512];
    ShowPlayerDialog(playerid, 0, DIALOG_STYLE_MSGBOX, ""COL_BLUE"My Super Rules", pDialog, "OK", "Cancel");
    return 1;
}
This will work, but there is no text! Why? Because we haven't added it yet. Let's get you used to using strcat.
Write strcat with the dest[] parameter set to pDialog, and with source[] to the first line of text that you'd like to see in the dialog.
pawn Код:
public OnPlayerSpawn(playerid)
{
    new pDialog[512];
    strcat(pDialog, ""COL_WHITE"Hi, and welcome to my "COL_RED"super duper awesome "COL_WHITE"server!\n", sizeof(pDialog));
    ShowPlayerDialog(playerid, 0, DIALOG_STYLE_MSGBOX, ""COL_BLUE"My Super Rules", pDialog, "OK", "Cancel");
    return 1;
}
Make sure to add \n after a line of text, as that creates a new line!
Now, do so with all lines in your dialog! The text doesn't have to be be same as mine, by the way. Change it to whatever you'd like!
pawn Код:
public OnPlayerSpawn(playerid)
{
    new pDialog[512];
    strcat(pDialog, ""COL_WHITE"Hi, and welcome to my "COL_RED"super duper awesome "COL_WHITE"server!\n", sizeof(pDialog));
    strcat(pDialog, ""COL_WHITE"Here are some "COL_RED"rules "COL_WHITE"that you should respect:\n", sizeof(pDialog));
    strcat(pDialog, ""COL_GREEN"1. "COL_WHITE"You are not allowed to spam.\n", sizeof(pDialog));
    strcat(pDialog, ""COL_GREEN"2. "COL_WHITE"You are not allowed to advertise.\n", sizeof(pDialog));
    strcat(pDialog, ""COL_GREEN"3. "COL_WHITE"You are not allowed to cheat/hack.\n", sizeof(pDialog));
    strcat(pDialog, ""COL_GREEN"4. "COL_WHITE"You are not allowed to spawnkill.\n", sizeof(pDialog));
    strcat(pDialog, ""COL_GREEN"5. "COL_WHITE"You are not allowed to insult others.\n", sizeof(pDialog));
    strcat(pDialog, ""COL_GREEN"6. "COL_WHITE"You are not allowed to beg for admin.\n", sizeof(pDialog));
    strcat(pDialog, ""COL_WHITE"There are special rules for "COL_GREEN"VIPs"COL_WHITE"! Please check\n", sizeof(pDialog));
    strcat(pDialog, ""COL_GREEN"/yaddayaddayadda "COL_WHITE"for more information!", sizeof(pDialog));
    ShowPlayerDialog(playerid, 0, DIALOG_STYLE_MSGBOX, ""COL_BLUE"My Super Rules", pDialog, "OK", "Cancel");
    return 1;
}
Now, the gamemode will compile; the compiler is merciful!
If you ever need to make dialogs of a reasonable length, this is your salvation.

Have fun scripting!
3. For those who were using format();
Were you formatting your dialog to show the values of specific variables, like a player's name? We'll do things differently, then.
Let's try a dialog saying this:

Код:
Welcome back to our server, [playername]!
Enter your password to log in. You have %d tries left.
[more text here]
If you try to do this with strcat, you will have issues - where to put the player's name?

pawn Код:
public OnPlayerConnect(playerid)
{
    new pDialog[196], pName[MAX_PLAYER_NAME], nTries;
    GetPlayerName(playerid, pName, sizeof(pName));

    format(pDialog, sizeof(pDialog), "Welcome back to our server, %s!\n", pName);
    format(pDialog, sizeof(pDialog), "%sEnter your password to log in. You have %d tries left.\n", szDialog, nTries);
    format(pDialog, sizeof(pDialog), "%sMore text here.", szDialog);
    ShowPlayerDialog(playerid, 0, DIALOG_STYLE_LIST, "My Super Login", pDialog, "OK", "I refuse to log in, for I am jealous of your tidy code.");
    return 1;
}
We are assuming you know how to use format, so here is the short explanation: each time you reformat the string, it overwrites itself. To avoid this, we must add the original string in each time we reformat in. Therefore, the first formatted variable in each line beneath the first must be the variable containing the dialog itself.
Do not forget to add \n at the end of each line.

You may also use both format and strcat in situations where each are needed:
pawn Код:
public OnPlayerConnect(playerid)
{
    new pDialog[196], pName[MAX_PLAYER_NAME], nTries;
    GetPlayerName(playerid, pName, sizeof(pName));

    format(pDialog, sizeof(pDialog), "Welcome back to our server, %s!\n", pName);
    format(pDialog, sizeof(pDialog), "%sEnter your password to log in. You have %d tries left.\n", szDialog, nTries);
    strcat(pDialog, "More text here.", sizeof(pDialog));
    ShowPlayerDialog(playerid, 0, DIALOG_STYLE_LIST, "My Super Login", pDialog, "OK", "I refuse to log in, for I am jealous of your tidy code.");
    return 1;
}
Enjoy. If you have any questions, reply in the thread!
Happy scripting!

P.S: If you actually read the whole tutorial and you have found mistakes in the text, please tell me. Thank you in advance!
Reply
#2

Nice work. rep+
Reply
#3

Hmm? I've created a tutorial which similar to this.
Anyway, Good job +rep.
Reply
#4

Quote:
Originally Posted by ilikenuts
Посмотреть сообщение
Hmm? I've created a tutorial which similar to this.
Anyway, Good job +rep.
I learned a lot more reading this than I did compared to reading yours.
You may want to expand your tutorial, as you don't really explain enough, imo.
Reply
#5

Just 'fixed' something - I had written this in Word before and somehow I copy-pasted an older version.

Quote:
Originally Posted by Rudy_
Посмотреть сообщение
Nice work. rep+
Thanks!
Quote:
Originally Posted by ilikenuts
Посмотреть сообщение
Hmm? I've created a tutorial which similar to this.
Anyway, Good job +rep.
Thanks, and:
Quote:

I've seen a few tutorials regarding this lately, but they aren't descriptive enough of what they are doing.

Reply
#6

You can use "format" as well
Reply
#7

Quote:
Originally Posted by Lorenc_
Посмотреть сообщение
You can use "format" as well
Its very nice tutorial but i agree with Lorenc_ why don't you use format for a simpler and faster way?Isn't faster?If i am wrong explain me why.
Reply
#8

Format works just as well, yes, but strcat looks cleaner imo, especially because I have each line of the dialog separated.
Reply
#9

you can use format the same way!
example
pawn Код:
new strDialog[1024];//this could... be smaller i know
    format(strDialog, sizeof (strDialog), "%s\t\t(%d)\n"                ,"Land"         ,GetTotalVehCount(VEH_FLAG_LAND));
    format(strDialog, sizeof (strDialog), "%s%s\t\t(%d)\n"  ,strDialog  ,"Air"          ,GetTotalVehCount(VEH_FLAG_AIR));
    format(strDialog, sizeof (strDialog), "%s%s\t\t(%d)\n"  ,strDialog  ,"Sea"          ,GetTotalVehCount(VEH_FLAG_BOAT));
    format(strDialog, sizeof (strDialog), "%s%s\t\t(%d)\n"  ,strDialog  ,"Law"          ,GetTotalVehCount(VEH_FLAG_LAW));
    format(strDialog, sizeof (strDialog), "%s%s\t\t(%d)\n"  ,strDialog  ,"Bikes"        ,GetTotalVehCount(VEH_FLAG_BIKE));
    format(strDialog, sizeof (strDialog), "%s%s\t\t(%d)\n"  ,strDialog  ,"Sport"        ,GetTotalVehCount((VEH_FLAG_CONVERTIBLE | VEH_FLAG_SPORT)));
    format(strDialog, sizeof (strDialog), "%s%s\t(%d)\n"    ,strDialog  ,"Industrial"   ,GetTotalVehCount(VEH_FLAG_INDUSTRIAL));
    format(strDialog, sizeof (strDialog), "%s%s\t\t(%d)\n"  ,strDialog  ,"Trailers"     ,GetTotalVehCount(VEH_FLAG_TRAILER));
    format(strDialog, sizeof (strDialog), "%s%s\t(%d)\n"    ,strDialog  ,"Lowrider"     ,GetTotalVehCount(VEH_FLAG_LOWRIDER));
    format(strDialog, sizeof (strDialog), "%s%s\t(%d)\n"    ,strDialog  ,"OffRoad"      ,GetTotalVehCount(VEH_FLAG_OFFROAD));
    format(strDialog, sizeof (strDialog), "%s%s\t\t(%d)\n"  ,strDialog  ,"Service"      ,GetTotalVehCount(VEH_FLAG_PUBLICSERVICE));
    format(strDialog, sizeof (strDialog), "%s%s\t\t(%d)\n"  ,strDialog  ,"Saloon"       ,GetTotalVehCount(VEH_FLAG_SALOON));
    format(strDialog, sizeof (strDialog), "%s%s\t\t(%d)\n"  ,strDialog  ,"Wagon"        ,GetTotalVehCount(VEH_FLAG_WAGON));
    format(strDialog, sizeof (strDialog), "%s%s\t\t(%d)\n"  ,strDialog  ,"Unique"       ,GetTotalVehCount(VEH_FLAG_UNIQUE));
however i think strcat might be faster from what i read in another thread.
Reply
#10

Quote:
Originally Posted by Lorenc_
Посмотреть сообщение
You can use "format" as well
There is really no need to use format in this case, AFAIK it'd only make it slower.
Reply
#11

Please, guys, don't start a debate on whether I should use format or strcat. If you want, I will edit the tutorial and also present the format 'way' later.
Reply
#12

Quote:
Originally Posted by TheBetaFox
View Post
Please, guys, don't start a debate on whether I should use format or strcat. If you want, I will edit the tutorial and also present the format 'way' later.
strcat is faster, so I don't think you should add a format section. Plus, strcat doesn't require you to use a format.
Reply
#13

oh i see now usage of strcat , never knew much about it
Nice tut
Reply
#14

Nice
Reply
#15

Nice tutorial, very well explained and useful.
Reply
#16

I have extended this tutorial and I have corrected several mistakes. Enjoy, and happy scripting!
Reply
#17

Nice work!thank you very muchh
Reply
#18

Thanks, this helped me alot! REP+
Reply


Forum Jump:


Users browsing this thread: 4 Guest(s)