Guide to pawn(o), from Beginner to Advanced
#1

This tutorial is meant for mainly beginners. Some advanced might get some benefit from this tutorial aswell.

Indexing:
  • 1.10 Math and Programming
  • 1.20 Basic Variables in global understanding
  • 1.30 Functions handling
  • 1.40 Syntaxing
  • 1.50 Advanced Variables in Pawn environment (arrays)
  • 1.60 Conditions,if/else statement, Looping, switching and line jumping
  • 2.10 Writing your first sucky but fully working code
  • 2.20 Effective coding
  • 2.25 Explanation why the hell you should do that
  • 3.10 Creating a concept
  • 3.20 Extending the concept
  • 3.30 Why the shit you need it
  • 4.10 Seemly unnoticable powerz of pawn called classes/local-remote functions
  • 5.10 Error Handling
  • 1000 Being smart
small index right?

1.10 Math and Programming
Assuming you are new to programming, you kinda suck at this all. Scripting that is.I just want to note that there is a difference between scripting and programming. I don't remember what exactly it is but who cares. whatever you do, if you use PAWN, tell people you script, not programming.

In order to program, common sense tells you you need to be decent at mathematics. If your sense doesn't tell you that, please start walking towards a train because you are mentally ill.
A basic mathematical problem would be:
5*5
We know the answer is 25, and so does the computer. If not, buy a new one cuz your computer doesn't deserve to be used.
now imagine, that instead of numbers, we use values that are not rounded.
5,5 * 5,5
now for us it gets harder to calculate even though this still is way to easy. Computer is at it's usual speed and found the answer 30,25.
using a metric system, you can obtain the surface by multiplying 2 sides with eachother.
in this example, we gave 5 the unit of centimeters where we can obtain square centimeters from.

5cm*5cm=25cm2

1.20 Basic Variables in global understanding
Some of you might know or not know, mathematics is all about using variables and functions.
for example, you can use sin cos tan to calculate the angle of a corner of a triangle, or use it to find a wavelength for whatnot.
let's assume we do not wanna know the answer of a basic mathematical equation but yet we need to use the answer from it.
you can use a variable to store the answer in it.
for example, a = variable that holds the answer
5*5 = a
in this example, we know a = 25, because this is the equation. However, if we wish to assign the value of the equation into the variable a, it is the oposite.
a= 5*5
in this example, we assign the value of the equation 5*5 into a.
now I want to use it into another equation.
b=a*1
for obvious reasons, b = 25. If I would change the equation 5 * 5 = a into a = 4* 5, I haven't changed equation b=a*1. Yet, the answer is different.
which is 20 if you didn't knew that.

This is the concept of a variable. Having a certain equation using a variable, and get different results without changing the equation.
Also, it saves effort. You can store an answer from the beginning into one variable and later on have new input into the same equation and compare those outputs.
for those shitheads: output = results from a function where input = the information you put in.

in programming itself, you have different types of variables. Here is a god damn list:
1. Integer (over the common, a rounded value between I dunno, only if pawn could tell me how much bytes integer get signed with)
2. Float (an integer that supports unrounded values. Usefull for storing coordinates or speeds and distances)
3. Boolean (basicly, holds either yes/true/1 or no/false/0), takes up only little asigned memory)
4. String (keep it simple, this is text)
//These are the common variables. meh I am to lazy to post more variable types. you can look them up if you are interested.

variables are used so functions can take a certain routine without having the need to change itself (that much)(Or just pure lazyness from calculating out of their plain heads, lazy bastards).

1.30 Functions handling
You know this right? No, oh my god I thought I had seen it all but no, you keep surprising me.

how do you explain a function? I see it as a short replacement for a longer complicated code.

let's say our function is this: calc will be the function's name and input will be the input put in.
PS: in this example I use some common programming rules.
calc(input)
{
return 5*input;
}
I want to note, even though it might seem so, programmaticly this isn't the most efficient programming style. Further explanation will follow later on.

anyways:
a=calc(5)+5
calc(5) is a replacement for 5*input. We can make a equation here.
calc(5) = 25
a= 5*input+5
a=25+5
a=30
however, this answer is solid now. this is the reason why variables are used.
assume a = 10
b=calc(a)+a;
what answer would this equation give? You don't know? Really you should learn some more math.
b=60

calc(input) is a function that returns an unsolid value based upon the input.

1.40 Syntaxing
Yay wtf, roflmao pornstar we finally made it to the more pawn orientated stuff.
what about syntaxing. syntaxing is the most important part of programming. In the end of this section, you will see why.
pawn Code:
public OnPlayerUpdate(playerid)
{
   return 1;
}
brackets are fine, YES FINE AS HELL. Lol but this is still a so called newb code. This is nothing. Basicly this only states the existence of the public function OnPlayerUpdate. It will call for it, like a werewolf calls for the innocent sheep and then eats them to pieces but without realising those weren't sheep he ate but plain air that tasted like sheep? Wth anyways it's better not to have these things inserted into your code if not necessary. Prevent the calling of functions that do nothing!

But let me explain this syntax:
public << Defines that the following information is a symbol that acts as a function that is accessible globally.(Globally accessibility means that in the complete program, this function can be called)
OnPlayerUpdate << This is the name of the function, which is used as a reference to call the code.
(playerid) <<The argument that is expected to get called with.
//Note: public OnPlayerUpdate(playerid) is called a function header.
{ << Indicating that with the function's header, the following functions are a part of what should be done when calling this function.
return << Function that holds the ability to return a value when a function is called. In most Pawn(o) Call-Backs, it usually means nothing or success/fail.
1 << The value returned
; << Indicator that a function inside this callback has finished and proceed if possible.(In this case, it will not. Return ends the function OnPlayerUpdate and therefore will not continue to do the rest of the code.
} << Indicator for the function OnPlayerUpdate has ended when talking in called functions, and therefore close the memory assigned to it.

Plain simple right?
However, this gets harder when an error occured. Putting a bracket {,} wrong, might result in hundred errors, even though there is only 1 bracket wrong.
This is why that is:
pawn Code:
public OnPlayerUpdate(playerid)
{//No return, error 1;
   }//we didn't opened this down properly
   {//Seems we accidentally switched these brackets.
  //No function header, error 2
   return 1;//Unexpected function or declaration
}//Unexpected closure

public OnPlayerDisconnect(playerid)
}//Inverted bracket, invalid expression
   return 1;
{//Inverted bracket, no error since this bracket indicates a group of actions, which is sometimes used in variables aswell.
//Error for line x to x+1
public OnPlayerConnect(playerid)
{
   return 1;
}
//Waiting for the return 1, the function OnPLayerDisconnect hasn't closed. Making the compiler think OnPlayerConnect is a function inside OnPlayerDisconnect and causes not to be called as a independent function
In this example, only 4 brackets where placed wrong, and already caused over 7 errors. Now imagine you have your gamemode up and running. Suddenly, you get 100 errors at once, since the function you worked lately on had it's brackets placed wrong and it happens to be in top of your script. This will result in the complete disaster movie where your gamemode is the meteorite and your server a person who gets squashed under the meteorite.

This is why syntaxing is important!

1.50 Advanced Variables in Pawn environment (arrays)
I'd never thought you could be able to read this far. I am impressed for real. You dip shits are strong enough to keep on reading. So here we go!
first of, in order to understand more advanced variable in pawn, you should know what arrays are.
an array is a variable that can hold multiple dimensions. In other words, instead of assigning 1 value to a variable, you can assign more than one. Arrays are usually used to show the user or computer that certain information belongs together. Or in the computer's case, it gets assigned the same memory space but all under the same header. Which saves computer memory. Ok, now to give you an example:
normal non-array variables:
where g = gravity, and v = velocity in kilometres per hour
pawn Code:
g=10;//from now on, we will use pawn syntaxing.
v=20;
2 different variables that hold in a way related to each other.
However, for a variable it would go more like this:
where f = array forces, indicator (g)ravity = 0 and (v)elocity in kilometres per hour is 1
pawn Code:
f[g]=10;
f[v]=20;
In this case, g and v are no variables, but indicators to show which array index to use.
basicly what is says is this:
pawn Code:
f[0]=10;
f[1]=20;
But for your eyes and reasoning, using a mask sort of speak is much easier to understand what you made.
this is where defines can kick in for usefullness.
imagine we want to create a gravity detection and handling system.
PS: this is a example to explain definitions. Usually you should use define to create settings as they are permanent.
pawn Code:
#define g 0 //This syntax is a syntax used by the compiler. # states that the following code is meant for the compiler. define << function define is called.
//g 10 just like a variable, assign g=0. However, when defining these things, you cannot change them later on, unless you undefine them first.
#define v 1
//Note, zero or null is the default value for newly created variables. This includes arrays.
new f[2];//new is a function that is able to define a new variable. We give f a max array index of 2, which equals to the posibility to use all array sizes (positive TILL 2, so not including 2).
f[g]=10;
f[v]=20;
This is how it works, this is how it goes.
However, this can be done much easier aswell. The enum statement.
pawn Code:
enum forces//indicate start of statement inside forces
{//open assigned definitions
 g,//add new index, the first one equals index 0, using null/zero as index when using an enum is not supported.
 v//add new index, equals 1
}//close assigned definitions
new f[forces];//assign the enum above to f.
f[g]=10;
f[v]=20;
as you can see, it makes no difference for the computer itself. However as a programmer it is much better as you can see exactly what variables hold what information.

Now how do we create a string?
Pawn(o) is used to be a integer oriented language. Meaning this language wasn't meant for using strings at all. Nevertheless, there are strings available in pawn for you to use.
pawn Code:
#define roflmao 20
new stringname[roflmao]="your sucky string";
side note: You can use -1 array indexes of the value you entered. I like to believe that the first index is used to indicate the arrays information. How much space it takes etc.
in this case, the string may be at maximum 19 characters long. My assigned string is 17 characters long so it is OK to assign this.
to use a string, you do not need to indicate the array index like an integer.
pawn Code:
new anotherstring[roflmao];
anotherstring=stringname;//assigns the value of stringname to anotherstring
Pretty simple right?
Let's move on, array strings. No not like just before, having arrays for strings this time.
pawn Code:
new stringname[20][roflmao];
stringname[0]="this is the first accessible array index for a string.";//PS: this string is out of arraysize, please do not mind it.
stringname[1]="this is the second accessible array index for a string.";//PS: this string is out of arraysize, please do not mind it.
stringname[19]="this is the last accessible array index for a string.";//PS: this string is out of arraysize, please do not mind it.
Assigning starting values can be done more efficient than this. Will be discussed later!
The use of array strings might be usefull. However it depends on how you work.
please know that using multiple dimensions for arrays is very limited for Pawn(o). Pawn(o) only supports 3 different dimensions. In case of a string, you could only use 2 different dimensions.
Dimension 1 2 3
| | |
new array[20][20][20];
Dimension 3 is also used to indicate a string, therefore 2 dimensions for strings.

1.60 Conditions,if/else statement, Looping, switching and line jumping etc
Here are the conditions and operators:
pawn Code:
== //equals to
!= //Does not equals to
<= // is smaller than or equals to
>= // is bigger than or equals to
> // is bigger than
< // is smaller than
&& //and use following condition
|| // Or use the following condition
++ // add (1) value
-- // substract (1) value
+ // add any following value to the starting value
- // substract any following value to the starting value
+= // add any following value //Variables only!
-= // substract any following value //Variables only!
* // Obvious, right? It means square root! (no seriously, you know what it means jackass)
/ // divide by any following value to the starting value
Basic things, easy to use. if you don't understand this, you better stop reading cuz you should kiss some monkeys ass

if and else statements are very commonly used.
basicly, these statements allow you to variablize a function.
for example, you don't want a code to open a gate that is already open. you want to close it. therefore, we introduce you the if and else statements.
if(condition is true) do action function.
or
if(!condition is true) do action function.// ! means the oposite of the true condition, basicly a check if the condition is false.
very easy to say: if condition is true, to this or else do that:
pawn Code:
new gateopened=1;//is true
public handlegate()
{
   if(gateopened==1)//is true
   {
     CloseGate();
     gateopened=0;//is false
   }else
   {
     OpenGate();
     gateopened=1;
   }
   return gateopened;
}
Basic principle of using if and else statements

Question where I know the answer on: Why do we use while or for?
for looping through variables most of the time. Let's say you have an array carrying only 1 dimension, but all these numbers are secret keys that together can give you power to immortality.
Then a friend of yours suddenly told you the answer you where waiting for. He told you if you add all those values to together, you get the key of total damnation and you can get immortality. However, you are way to lazy to add all those values one by one.
therefore, you will loop through your array to have the computer get you the number using a for statement.

for(starting function; when condition; do action)
for is a special kind of function, that does not end till the condition is true. for every END of a loop, it does the action you entered.
now let's create our setup and function to have the computer calculate the key for immortality.
note: this function usually is used with variables. Don't mistake that otherwise isn't possible!
pawn Code:
new store;//the variable that will hold the complete key.
new destructionkeys[6];
destructionkeys[0]=12345;
destructionkeys[1]=21345;
destructionkeys[2]=31245;
destructionkeys[3]=41235;
destructionkeys[5]=51234;

a for statement cannot be called outside any function. Therefore, we create our own imaginative function. (without defining the origin, this will be done later)
public OnRequestImmortalityKey(playerid)
{
   //store still is zero, it is never called yet.
   for(new i=0;i<6;i++)
   {
    store+=destructionkeys[i];
   }
   return store;
}
you should know about return and function header and such by now, so let's skip that and more on to the loop and it's functions.
for(new i=0;i<6;i++)
action= create new variable i and assign value zero.
condition is, if i is smaller than 6, THEN do action.
if the condition was true, on the end of the loop, add 1 to i.
Continue to next loop.
the brackets that come along are just like the ones within a function.
they assign functions between the brackets as a part of that code. In this case, the loops will do the following actions till condition is false or true.
store+=destructionkeys[i];
for every loop, use i as array index.
add the value of destructionkeys[i] to store

if you paid attention well, you should know or at least figured that the answer or value returned is store = 157404.
this was the looping part, and using array inside a loop. in short, you can use a loop to get all values of an array and manipulate them to your bidding.
Damn u manipulator.

Besides for, there is a while statement.
the while statement basicly is the same as for, but on the end of a loop there isn't any function done.
while basicly is for(starting action, condition)
while (starting action, condition)
see yourself how to use this.

The following part is copied right from the sa-mp wiki:
==
do-while

A do-while loop is a while loop where the condition comes after the code inside the loop instead of before. This means that the code inside will always be executed at least once because it is done before the check is done:

new
a = 10;
do
{
// Code inside the loop
a++;
}
while (a < 10); // Note the semi-colon
// Code after the loop
==
The use of do while, is that you can variablize the functions added using if and else statements.

IMPORTANT NOTE: You cannot use local/remote functions as the action as there will be no valid actions taking place for the statements for and while!

explaining switch/case.
example uses imaginative variable registered users as REG_USERS non-array
pawn Code:
switch(REG_USERS)
{
  //using brackets, implying on that multiple actions are going to be used
  case 25://if value is 25
  {
    //there are 25 people registered
  }
  case 50: //if value is 50
  {
    //there are 50 people registered
  }
  //no brackets, imply only 1 action upon case
  case 100://there are 100 people registered  //if value is 100
  default: //If all above conditions are false, do this:  //if value is not 25, 50 or 100

}
in theory, switch is the same as a long chain of else/if conditions.
However, if you compare the speed of both ways, switch case is much faster when dealing with large numbers and the amount of calls.
Note: switch can only compare values when switching a variable. It is only faster when larger amount of cases/if else conditions!

Line jumping and used isn't used much therefore I won't discuss it here.
Reply
#2

2.10 Writing your first sucky but fully working code
For this, we need to define the existence of a new function. Therefore, it can be used. Most commonly, there is a kind of reference used to indicate the existence of a code that isn't defined yet. But first, Let's talk about the function types:

Public/Global || This statement indicates a function that will be defined globally. This usually indicates the existence and usability of a function that can be accessed thorough the complete application
Private // Not available in pawn I believe || you could say private equals stock
Stock || stock, a statement that indicates a function defined locally. Only functions in the same stream can access these functions. They cannot have a reference and therefore they need to be defined before the other functions can make any use of it. Nevertheless, a stock takes lesser memory space.

referencing in pawno is quite easy though.
there is a statement called forward for this.
let's say we want to forward the statement OnPlayerKissMonkeyAss(playerid);
pawn Code:
forward OnPlayerKissMonkeyAss(playerid);
//note that forward statement only is used in pawn to define a public
//another note: The number of and the arguments itself inside the forward MUST equal to the arguments in the defined public!
public OnPlayerKissMonkeyAss(playerid)
{
   return 1;//Public functions cannot return arrays and must return any value. Don't ask me why.
}
Wasn't that easy?
that was all that was needed to write your own function.
Now to define more than one statement:

pawn Code:
forward OnPlayerKissMonkeyAss(playerid, funnystring[],Float:lolz);
public OnPlayerKissMonkeyAss(playerid, funnystring[],Float:lolz)
{
   return 1;//Public functions cannot return arrays and must return any value. Don't ask me why.
}
explanation:
OnPlayerKissMonkeyAss is the functions name
( Open up bracket to indicate the existence of arguments or not.
playerid Indicate existence of argument integer called playerid
, Indicate the existence of another argument yet to come
funnystring[] New argument as string/array with unknown size, passed down with the entered value upon call.
, Indicate the existence of another argument yet to come
Float:lolz Indicate the existence of argument float called lolz
) Close up bracket to indicate that no more arguments are going to be defined, which completes the function header.

basicly that is all about creating your own functions. If you don't get it, well I don't know what to say.

2.20 Effective coding
This might be the most important thing in the whole programming business.
It's something even some of the pros here cannot do properly.

Sample one: Assigning starting arrays
pawn Code:
new Skins[] = {//No need to define the index, this will happen automaticly and it saves effort aswell.
0,105,106,107,269,270,271,102,103,104,114,
115,116,108,109,110,173,174,175,183,122,12,
10,101,12,13,136,14,142,143,144,15,151,156,
168,169,17,170,180,182,54,18,184,263,75,186,
185,188,19,216,20,206,21,22,210,214,215,220,
221,225,226,222,223,227,231,228,234,76,235,
236,89,88,24,218,240,25,250,261,28,40,41,
35,37,38,36,44,69,43,46,9,93,39,48,47,
262,229,58,59,60,232,233,67,7,72,55,94,95,
98,56,224,230,239,249,241,242,252,253,255,29,
30,49,50,57,61,62,66,73,77,82,83,84,11,141,
147,148,150,153,167,68,171,176,177,172,179,187,
189,203,204,155,205,209,217,211,219,260,16,27,
70,134,135,137,181,213,212,78,79,258,259,26,51,
52,80,81,23,96,99,152,178,237,238,243,244,207,
245,246,85,256,257,64,63,87,90,128,129,130,131,
132,133,157,158,159,160,196,197,198,199,161,162,
200,201,202,31,32,33,34,138,139,140,145,146,
154,251,92,97,45,18,190,191,192,193,194,195,
71,274,275,276,277,278,279,287,166,165,286,280,
281,282,283,288,265,266,267,264
};
to create such array with starting value, where the id is entry position, (in the sample above, the first entry is zero, the ID is zero!, and id 1 is 105)
there is a simple trick to it.
pawn Code:
new array[[i]ENTER NO SIZE[/i]]=
{//assign the following values as part of the array
value1,//== ID 0
value2,// == ID 1
value3 // == id 2
}//close assigning information
//Note, in some cases it is important to leave the , (comma) away in the last entry.
Now the same but for a multi-dimensional array:
pawn Code:
new positions[][3]={//For a multi-dimensional array you have to assign a size //Open up assigning
{//Open up another assigning, indicating that the following values are part of 1 entry
1,2,3
//Again, the last value shouldn't have a comma ,
}//close assigning entry 1
, indicate that another assignment is going to happen
{2,3,4}
,
{5,6,7}
}//close the multi-dimensional array

//The same array without the comments and nicely indented:
[pawn]new positions[][3]={
{1,2,3},
{2,3,4},
{5,6,7}}
[/pawn]

if else, loop return:

pawn Code:
public OnRequestAnswer(playerid)
{
  if(You=="stupid")
  {
    for(new i=0;i<everyone;i++)
    {
       Message("%d is stupid!",playerid);
    }
  }else
  if(you=="smart")
  {
    Message("I do not believe you!");
  }
}
So far for efficiency. If you haven't noticed, this code is far from efficient.
In any case, you should imagine that the function you create will be called every second, for a year long.
now think about it, you are going to loop for all players that are there, and for every second a new variable is created.
now let's do a basic calculation:
there are 365 days in a year.
there are 60*60*24 = 86400 seconds in one day.
365*86400=31536000
basicly, this function needs to declare a new variable 31536000 times ( if you assume the server always is on and never restarts )
let's calculate back to a minute, which is 60 times

even though defining 60 times a minute isn't that much at all, 31536000 surely is. Therefore, even the little things can have a big impact over time.
Please know that using this method, you do need more computer memory but not processor power. The goal of this is to convert computer processor power into ram memory instead. Since variables take so less space, I strongly recommend this method! However when dealing with non-array smaller lesser used variables, it is better to declare them as a new variable. This is because resetting a variable ( jumping to the address of the variable, set information to null, then jump back) is as fast as registering new space that automaticly has no information in it. ( address jumping required).

about if else conditions. Yes, I am telling you not to use else conditions at all. Use return instead. the function is created to exit a code, therefore efficient enough to stop a code from executing unwanted codes. you will need to add a return value on the end of the function to use it, however lines are not important.

If you think the number of lines are important, jump in front of a train because it's not about how many lines you have, but about how you put them down!

optimised version would be:
pawn Code:
new i;//automatic assign zero
public OnRequestAnswer(playerid)
{
  if(You=="stupid")
  {
    for(i=0;i<everyone;i++)
    {
       Message("%d is stupid!",playerid);
    }
    return 1;
  }
  if(you=="smart")
  {
    Message("I do not believe you!");
    return 2;
  }
  return 0;
}
why return and not else?
Why not? I mean else statement isn't that efficient as it looks like. So exiting a code when you can is better then checking if a condition is true else jumping to another code location. having this doesn't require certain routines to be called which in massive usage could slow down the complete process.
besides, putting else if everywhere doesn't seem that nice looking at to me.

The biggest mistake ever: Looping all players
I rarely see people actually being smart. They keep on looping through all playerslots and sometimes even checking whether they are online or not.
What is the use of looping through slots that aren't used? Since when is there any use in slots that are empty except when it comes to bots?

Therefore, I will put down a certain code to optimise your looping through active players only, looping through active slots only and no non-taken or bots.

This is more like a source code with explanation though, so bear with me:

pawn Code:
#define MAX_SLOTS MAX_PLAYERS
new UsedSLots[MAX_SLOTS]=-1; //do not use default value zero, since zero is a valid playerid
new ConnectdPlayers;//Do use zero, since the amount of connected players is zero upon (re)start.
//Temporary used variable:
new plx[2];
new ii;
//Define the player loop
#define LoopAllPlayers StartPlayerLooper();for(plx[1]=0;plx[1]<ConnectedPlayers;PlayerLooper(plx[1]))
//Define the existence of the functions we are going to use
forward AddSlot(playerid);
forward RemoveSlot(playerid);
forward PlayerLooper(&ref);

public OnPlayerConnect(playerid)
{
   AddSlot(playerid);//add this to onplayerconnect
   return 1;
}
public OnPlayerDisconnect(playerid, reason)
{
  RemoveSlot(playerid);
  return 1;
}

public PlayerLooper(&ref){ref++;ii=UsedSLots[ref];}
stock StartPlayerLooper()
{
  ii=UsedSLots[0];
}
stock StopPlayerLoop()plx[1]=ConnectedPlayers;
//PlayerLooper only with spaces and such
public PlayerLooper(&ref)
{
  ref++;
  ii=UsedSLots[ref];
}

public RemoveSlot(playerid)
{
    for(plx[0]=0;plx[0]<MAX_SLOTS;plx[0]++)if(playerid==UsedSLots[plx[0]])break;
    ii=plx[0];
    ConnectedPlayers--;
    //from here, plx[0] holds the index of the variable that holds the playerid
    for(plx[0]=ii;plx[0]<(MAX_SLOTS-1);plx[0]++)
    {
    UsedSLots[plx[0]]=UsedSLots[(plx[0]+1)];
    }
    UsedSLots[MAX_SLOTS-1]=-1;
    return 1;
}

public AddSlot(playerid)
{
  UsedSLots[ConnectedPlayers]=playerid;
  GetPlayerName(playerid,PlayerName[playerid],MAX_PLAYER_NAME);
  PlayerAdminName[playerid]=PlayerName[playerid];
    GetPlayerIp(playerid,Playerip[playerid],17);
  format(PlayerFile[playerid],MAX_FILE_NAME,"Accounts/%s.sav",PlayerName[playerid]);
  PlayerShotTimer[playerid]=-1;
  return ConnectedPlayers++;
}
Usage would be:
pawn Code:
Public SendGlobalMessage()
{
  LoopAllPlayers
  {
    Message(ii,"Hello there folks");
  }
  return 1;
}
So how does this works, how is this more efficient?
first about why this is more efficient:
  • 1. It calls localfunction, therefore playerlooper will act as if it is inside a class, which over time can optimise speed if you compare the speeds.
  • 2. It loops all active playerslots only. Meaning all players who are active are always inside that array, the others who are not are not in the array.
  • 3. Not sizeof, but a variable that holds the players connected. The function sizeof counts the maximum amount of indexes available. Not what we need at all.
  • 4. It uses globally declared variables. It doesn't need to create new variables every time it gets used.
  • 5. It looks nicer in my opinion.
How it works explained by function:
AddSlot(playerid): This function assigns the newly connected player to the latest available entry.
RemoveSlots(playerid): This function loops from the position of the playerslot leaving, and moves all players after this slot back by 1, making the leaving playerslot to be filled with the other connected players leaving no gap in the Playerloop.
PlayerLooper(&ref): uses a refence to add 1 to the loop, and assigns ii as the playerid of the player looped.
LoopAllPlayers: Calls the valid ID for ID zero, then loops through the rest of the array.
StopPlayerLoop(): Stops a playerloop by setting used variable to loop end value
StartPlayerLooper(): Retrieve the information for SlotID 0
In short:
When you call LoopAllPlayers, it will loop through an array that only holds valid connected ids.
Therefore, any playerslot that isn't connected will not be handled.
Calling functions onplayerconnect and onplayerdisconnect is fine. They aren't called that often so you will get no lag whatsoever from these functions on pretty much any connection.
Does your server has around 500 slots where normally 50 are occupied? Or even 100 maybe? Using this method is strongly recommended.
It saves alot of processor power especially when it comes with loops inside loops.
Many commands loop these players and therefore saves much computer effort.


2.25 Explanation why the hell you should do that
For obvious reasons actually. To preserve pressure on the computer and application and probably trade it for RAM memory.
However RAM memory isn't a problem at all nowadays.

3.10 Creating a concept
Actually, before you start coding anything, you should consider concept before doing anything.
For example, if you want to have a property system, you must think for the following event and conditions:
When should I be able to enter and exit?
What are the limits of a property?
What are the general usage of a prop?
How many properties can you build at maximum?
Can they be destroyed or motified in any way?

when creating a concept, you should ask yourself these kind of questions. When doing so, yo should consider this in various conditions.
for example for the question When should I be able to enter and exit?, you should consider things like the following:
Can I enter with a car?
Can I enter when I am moving?
Can I enter only if I am in range?
basicly, you have to ask questions on the basic questions.


3.20 Extending the concept
Once the base of a concept is there, you should consider extending it to integrate it with another concept. 1 giant concept is better than 2 lesser concepts.
Not just that, you can merge variables better when you combine these concepts together.

3.30 Why the shit you need it
Writing out of mind without a concept (written or unwritten) is possible, but is far from efficient. You could compare it with having your room full of junk. You can live in it, but not without stepping on the junk. If your room is clean, you don't need to mind the yunk since it isn't there.

4.10 Seemly unnoticable powerz of pawn called classes/local-remote functions
For those who do not know what classes are, keep on reading. Else skip to 'usage'

http://en.wikipedia.org/wiki/Class_%...ter_science%29
However, pawn isn't really object orientated.
A class is a group of functions. However when calling a class function, the function that calls the class function will not care how it is achieved as long as there is a result.
For example, if you loop outside an array, the code normally would return false and stop immediately. However, when putting the same code as a class function, it will return false as function value upon the same crash, but the code still continues. This is one benefit of class functions.

Usage
Even though classes aren't really available in Pawn(o), something else that makes a public function act the same as if it is in a class.
These features can be called by functions CallLocalFunction and CallRemoteFunction.
CallLocalFunction calls a public function that is defined inside the same main stream. This basicly means it only will search for this function inside the same document the function is called from.
CallRemoteFunction calls All public function in all documents loaded. So it will call the function in filterscripts and gamemode.

5.10 Error Handling
The thing people struggle the most of the times.
Sucky somehow impossible errors.
I will tell you how you can solve these problems.
Let's see:
\RandomGM.pwn(6 : error 029: invalid expression, assumed zero

On line 68 is an error occurring. The funny part is, the real error is located at line 67.
What happens is that a certain line is improperly closed or used. Therefore, a new statement is seen as invalid part of the improper code. Therefore, it will error on that line.
error 029 is most likely caused when you have a certain action, such as a loop, but you haven't closed it properly and therefore it takes another statement as the ending statement. Obviously, since it's not the expected statement, it will error. This example was a loop. This could happen to If and else conditions aswell, aswell for switch.

1000 Being smart
Ok this is the most important point of all, be smart.
Over the years, I seen enough of you asking for the most impossible things.
Most important and stupid question is the following:
Hey, I can't/can script myself, but I would like to have a scripter.
Now the most funny thing:
I will grant you right to admin or I might pay you.

I rolfmao'ed so hard the first time I read this thing.
Since when do scripters who can build a complete gamemode theirselves agree with such offer? Putting in paid vip would make the producer getting more profit than you will ever will pay. Admin? Lol seriously running your own server and be the server owner. Highest rank possible and you are the one in control.

This is the point where I realised, people grow up. You kids should start brighten up. Lame offers aren't going to fool anyone.
Of course some of these people actually fall for such an offer. I call them lameys.

Anyways, before you do something as a producer,think about it. Is it realistic? Don't work on faith only, do some research.

Copying this tutoral IS allowed. All I ask is some credit for writing this crap.

PS: I haven't tested anything I wrote down. Therefore some information listed might be "slightly" wrong.
Please pm me with the flaud and I will correct it.
Reply
#3

NICE!!
RLY NICE!
I have allot from this tutorial
RESPECT!!!
Reply
#4

Quote:
Originally Posted by Second
NICE!!
RLY NICE!
I have allot of this tutorial
RESPECT!!!
Yes :O It looks like you have a lot of free time to make a tutorial :P
________
Toyota paseo specifications
Reply
#5

Nah I just happen to hate most of you guys enough to make me do it.
I happen to have a free day off and since there wasn't anything else challenging enough to do that needs more attention, I just think let's start with that.
Reply
#6

Quote:
Originally Posted by 1.10
5*5
We know the answer is 10
LoL, should be 25, btw great tutorial, will help so many beginners!
Reply
#7

Really Nice lolz
Reply
#8

tl;dr but it looks great, hope this gets stickied so we don't have as many n00bz posting ^^
Reply
#9

I wasn't even done yet, but still these forums do not allow me to post more than 20000 characters inside a single post.
I also wanted to post how to use the usefull stuff such as zcmd, and some replacements functions I wrote that I haven't posted yet.
meh but 2 full pages should be enough, for now.
Reply
#10

Amazing, Great work.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)