[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


Messages In This Thread

Forum Jump:


Users browsing this thread: 1 Guest(s)