SA-MP Forums

Go Back   SA-MP Forums > SA-MP Scripting and Plugins > Scripting Help > Tutorials

Reply
 
Thread Tools Display Modes
Old 04/01/2017, 10:54 PM   #1
Freaksken
Gangsta
 
Freaksken's Avatar
 
Join Date: Mar 2009
Location: Belgium
Posts: 523
Reputation: 209
Default How to create a speedometer

How to create a speedometer
This tutorial is in response to this thread in which I offered to create a tutorial. Most of the tutorials on speedometers are pretty old (some from 2010), don't use per-player textdraws and are thus seriously outdated. The following tutorial is based on Fallout's SpeedoMeter I came across long ago. This tutorial assumes you know basic pawn. That is variable declaration, variable initialization, arrays, loops, tags, callbacks and functions. If you don't know what some of these mean, maybe you know the concepts, but you just didn't knew their names. So just read on.

This is what we'll be creating (sort of):


1. Introduction:
(Note: it seems that this introduction has enough information, that it has become its own tutorial.)
This tutorial involves textdraws so we'll need to know what those are first. Even though this information can be found on the wiki, what follows are some things that I find important enough to include in this tutorial. If you already know what the difference is between a global and a per-player textdraw, skip to 2. But I do recommend just reading it quickly, maybe you find out something you didn't knew.

1.1 What is a textdraw:
A textdraw is text that can be drawn anywhere on a player's screen for an indefinite period of time. It can be simple text like a clock, a website address, a score and so on. It can also be a something complex like a health bar, show preview models, show sprites and so on. The text can be drawn in a box. We can also only use the box, by providing empty text. When you search on ******, you can find some nice examples of what is possible with textdraws.

1.2 Kinds of textdraws:
There are two kinds of textdraws: global and per-player, which we'll explore in the following sections.

1.2.1 Global textdraw:
A global textdraw is the same for every player, for example a clock. Either it is shown to a player or it is not. You can only create 2048 global textdraws! A solution to this problem is explored in the following section about Per-player textdraws. Continue first with this section though, so the next one will be easier to understand.

Example:
  • We have a clock textdraw that shows 10:50.
  • Player0 sees the textdraw.
  • Player1 sees the textdraw.
  • Player2 doesn't see the textdraw.
  • When the time changes, we want this textdraw to show the new time, and every player currently seeing the textdraw will see the updated time.

1.2.1.1 Declaration:
Code:
new Text:myFancyTD;
As you can see, we use the 'Text' tag to indicate that the 'myFancyTD' variable is a textdraw. Another example of a tag is 'Float'.
Code:
new Float:myFancyFloat;
See the similarities?

1.2.1.2 Initialization:
We also need to initialize the variable with something, otherwise this textdraw might conflict with others as you add more. It is actually very important that you do this, otherwise the first textdraw you create will work fine, but when you add more and more some might start to show information of others and have some other weird behaviour. It's really hard to debug and to find where the problem lies, because the compiler will give you no error or warning. So don't forget to do this.
Code:
new Text:myFancyTD = Text:INVALID_TEXT_DRAW;
Don't forget to use the 'Text' tag as well before 'INVALID_TEXT_DRAW'.

1.2.1.3 Functions:
A list of the functions can be found here. Note that they all have 'TextDraw' in their name. You can not use a global textdraw function on a per-player textdraw, or vice versa. Otherwise the compiler will give you a tag mismatch warning.

1.2.2 Per-player textdraw:
A per-player textdraw is unique for every player, for example the speed of his vehicle. That means that every player can see the textdraw with personal information in it, or not see the textdraw. You can create 256 per-player textdraws for every player! That's a whole lot more than just 2048 global ones.

Example:
  • We have a score textdraw that shows the player's score.
  • Player0 has score 50, so his textdraw needs to show 50.
  • Player1 has score 100, so his textdraw needs to show 100.
  • Player2 doesn't see his textdraw.
  • When player0's score changes we only want his textdraw to change, not other player's textdraws.

1.2.2.1 Declaration:
Code:
new PlayerText:myFancyTD[MAX_PLAYERS];
As you can see, we use the 'PlayerText' tag this time, not the 'Text' tag. The 'myFancyTD' textdraw is also an array this time. This is necessary because as we stated before, the textdraw is unique for every player, so we need a separate instance for every player.

1.2.2.2 Initialization:
Again, we need to initialize the variable with something to avoid conflicts. This time, we need to initialize every elemnent of the array. This can be done with the {, ...} syntax.
Code:
new PlayerText:myFancyTD[MAX_PLAYERS] = {PlayerText:INVALID_TEXT_DRAW, ...};
Don't forget to use the 'PlayerText' tag as well before 'INVALID_TEXT_DRAW'.

1.2.2.3 Functions:
A list of the functions can be found here. Note that they all have 'PlayerTextDraw' in their name, not just 'TextDraw'! Again, you can not use a global textdraw function on a per-player textdraw, or vice versa. Otherwise the compiler will give you a tag mismatch warning.

1.3 Tool to simplify the creation of textdraws:
Since textdraws can only be created with code, it can be quite difficult to get some things right. So to develop your textdraws visually, there exists a handy tool by adri1. Just keep on reading for now, you can play with that tool later when you understand how everything works.

2. Declaring and initializing the necessary variables:
We'll be using both kinds of textdraws in this tutorial. Global textdraws will be used to create a nice looking UI. They are definitely not needed to make the speedometer work, but I wanted to show both kinds of textdraws. Per-player textdraws will be used to show the personal information. If you don't understand what some of following code does, go back to 1.

The following code should be placed at the top of your script, under the includes and defines.

2.1 Global textdraw variables:
We need 5 global textdraws: 4 black lines and 1 transparent background (see picture). The black lines and background are the same for every player, so that's why we can use global textdraws here.
Code:
new Text:SpeedoBackground = Text:INVALID_TEXT_DRAW;
new Text:SpeedoLineAbove = Text:INVALID_TEXT_DRAW;
new Text:SpeedoLineLeft = Text:INVALID_TEXT_DRAW;
new Text:SpeedoLineRight = Text:INVALID_TEXT_DRAW;
new Text:SpeedoLineUnder = Text:INVALID_TEXT_DRAW;
2.2 Per-player textdraw variable:
We need 1 per-player textdraw, that holds the information about the vehicle the player is currently in (see picture).
Code:
new PlayerText:SpeedoCarInfo[MAX_PLAYERS] = {PlayerText:INVALID_TEXT_DRAW, ...};
2.3 Bool variable:
We also need to keep track if the speedometer is shown to a player. For example, we don't need to hide it when it's already hidden. Therefore we need an array of bools, and thus the 'bool' tag. We also use array initialization to initialize every element of the array.
Code:
new bool:SpeedoShown[MAX_PLAYERS] = {false, ...};
2.4 Timer variable:
At last, we need one timer that will work for all players. No need to use a timer for each player.
Code:
new SpeedoStatusTimer = -1;
3. Setting up everything before we use it + cleanup:
I'm not going to explain the functions and parameters, since this tutorial is already longer than I wanted it to be and this is not a tutorial on textdraws or timers. Refer to the wiki to know what every function does.

3.1 Global textdraws:
Since global textdraws are the same for every player, we only need to create them once. We will do this when the server starts, more specifically, under OnGameModeInit. All functions have 'TextDraw' in their name, not 'PlayerTextDraw'!

3.1.1 OnGameModeInit:
None of the global textdraws have text. We can create a textdraw without text by using an underscore as the text. We can make a textdraw box transparent by using the alpha values of the color.
Code:
SpeedoBackground = TextDrawCreate(481.0,353.0,"_"); //No text
TextDrawUseBox(SpeedoBackground,1);
TextDrawBoxColor(SpeedoBackground,0x00000033); //20% visible, so very transparent
TextDrawTextSize(SpeedoBackground,596.0,0.0);
TextDrawAlignment(SpeedoBackground,0);
TextDrawBackgroundColor(SpeedoBackground,0x000000ff);
TextDrawFont(SpeedoBackground,3);
TextDrawLetterSize(SpeedoBackground,1.0,9.5);
TextDrawColor(SpeedoBackground,0xffffffff);
TextDrawSetOutline(SpeedoBackground,1);
TextDrawSetProportional(SpeedoBackground,1);
TextDrawSetShadow(SpeedoBackground,1);

SpeedoLineAbove = TextDrawCreate(481.0,353.0,"_"); //No text
TextDrawUseBox(SpeedoLineAbove,1);
TextDrawBoxColor(SpeedoLineAbove,0x000000ff); //100% visible, so solid
TextDrawTextSize(SpeedoLineAbove,596.0,0.0);
TextDrawAlignment(SpeedoLineAbove,0);
TextDrawBackgroundColor(SpeedoLineAbove,0x000000ff);
TextDrawFont(SpeedoLineAbove,3);
TextDrawLetterSize(SpeedoLineAbove,1.0,-0.10);
TextDrawColor(SpeedoLineAbove,0xffffffff);
TextDrawSetOutline(SpeedoLineAbove,1);
TextDrawSetProportional(SpeedoLineAbove,1);
TextDrawSetShadow(SpeedoLineAbove,1);

SpeedoLineLeft = TextDrawCreate(481.0,353.0,"_"); //No text
TextDrawUseBox(SpeedoLineLeft,1);
TextDrawBoxColor(SpeedoLineLeft,0x000000ff); //100% visible, so solid
TextDrawTextSize(SpeedoLineLeft,480.0,0.0);
TextDrawAlignment(SpeedoLineLeft,0);
TextDrawBackgroundColor(SpeedoLineLeft,0x000000ff);
TextDrawFont(SpeedoLineLeft,3);
TextDrawLetterSize(SpeedoLineLeft,1.0,9.50);
TextDrawColor(SpeedoLineLeft,0xffffffff);
TextDrawSetOutline(SpeedoLineLeft,1);
TextDrawSetProportional(SpeedoLineLeft,1);
TextDrawSetShadow(SpeedoLineLeft,1);

SpeedoLineRight = TextDrawCreate(597.0,353.0,"_"); //No text
TextDrawUseBox(SpeedoLineRight,1);
TextDrawBoxColor(SpeedoLineRight,0x000000ff); //100% visible, so solid
TextDrawTextSize(SpeedoLineRight,596.0,0.0);
TextDrawAlignment(SpeedoLineRight,0);
TextDrawBackgroundColor(SpeedoLineRight,0x000000ff);
TextDrawFont(SpeedoLineRight,3);
TextDrawLetterSize(SpeedoLineRight,1.0,9.50);
TextDrawColor(SpeedoLineRight,0xffffffff);
TextDrawSetOutline(SpeedoLineRight,1);
TextDrawSetProportional(SpeedoLineRight,1);
TextDrawSetShadow(SpeedoLineRight,1);

SpeedoLineUnder = TextDrawCreate(481.0,440.0,"_"); //No text
TextDrawUseBox(SpeedoLineUnder,1);
TextDrawBoxColor(SpeedoLineUnder,0x000000ff); //100% visible, so solid
TextDrawTextSize(SpeedoLineUnder,596.0,0.0);
TextDrawAlignment(SpeedoLineUnder,0);
TextDrawBackgroundColor(SpeedoLineUnder,0x000000ff);
TextDrawFont(SpeedoLineUnder,3);
TextDrawLetterSize(SpeedoLineUnder,1.0,-0.10);
TextDrawColor(SpeedoLineUnder,0xffffffff);
TextDrawSetOutline(SpeedoLineUnder,1);
TextDrawSetProportional(SpeedoLineUnder,1);
TextDrawSetShadow(SpeedoLineUnder,1);
3.1.2 OnGameModeExit:
It's always good to clean up everything, especially when you use the '/rcon gmx' command. Destroy the global textdraws and reset the variables.
Code:
TextDrawDestroy(SpeedoBackground);
TextDrawDestroy(SpeedoLineAbove);
TextDrawDestroy(SpeedoLineLeft);
TextDrawDestroy(SpeedoLineRight);
TextDrawDestroy(SpeedoLineUnder);
SpeedoBackground = Text:INVALID_TEXT_DRAW;
SpeedoLineAbove = Text:INVALID_TEXT_DRAW;
SpeedoLineLeft = Text:INVALID_TEXT_DRAW;
SpeedoLineRight = Text:INVALID_TEXT_DRAW;
SpeedoLineUnder = Text:INVALID_TEXT_DRAW;
3.2 Per-player textdraws:
Since per-player textdraws are unique for every player and are automatically destroyed in OnPlayerDisconnect (see wiki), we need to create them every time a player joins. So, that is under OnPlayerConnect. All functions have 'PlayerTextDraw' in their name, not just 'TextDraw'!

3.2.1 OnPlayerConnect:
This textdraw will contain text, but not at the start, so we just provide an empty string with the underscore in the meantime. Note that for some reason we need to create a per-player textdraw with CreatePlayerTextDraw instead of PlayerTextDrawCreate. All other functions do have 'PlayerTextDraw' in front. Since 'SpeedoCarInfo' is an array of per-player textdraws, we need to provide which element of the array we are using in every function. At last there is also an additional parameter that we need in every function, to know which player we are talking about. If you don't understand this, read on.
Code:
SpeedoCarInfo[playerid] = CreatePlayerTextDraw(playerid, 485.0, 355.0, "_"); //No text
PlayerTextDrawBackgroundColor(playerid, SpeedoCarInfo[playerid], 0x000000ff);
PlayerTextDrawAlignment(playerid, SpeedoCarInfo[playerid],0);
PlayerTextDrawFont(playerid, SpeedoCarInfo[playerid], 1);
PlayerTextDrawLetterSize(playerid, SpeedoCarInfo[playerid], 0.30, 1.0);
PlayerTextDrawColor(playerid, SpeedoCarInfo[playerid], 0xffffffff);
PlayerTextDrawSetOutline(playerid, SpeedoCarInfo[playerid], 1);
PlayerTextDrawSetProportional(playerid, SpeedoCarInfo[playerid], 1);
PlayerTextDrawSetShadow(playerid, SpeedoCarInfo[playerid], 1);
See the following code for the difference between a global and per-player textdraw function.
Code:
TextDrawFont(SpeedoBackground, 3); //Global textdraw
PlayerTextDrawFont(playerid, SpeedoCarInfo[playerid], 1); //Per-player textdraw
You might think that since we already use the playerid in 'SpeedoCarInfo[playerid]', why we need an additional playerid parameter?

When you use 'SpeedoCarInfo[playerid]' you're using a variable of the PlayerText type. When you use 'playerid' you're using a variable of the Integer type. Remember that a per-player textdraw is unique for each player? In other words, it is linked to that player. So the 'playerid' parameter is needed to know which player the textdraw belongs to and the 'SpeedoCarInfo[playerid]' is needed to know which textdraw of that player we mean. Here's another explanation:
  • SpeedoCarInfo is an array.
  • Every element of the array contains a PlayerText textdraw.
  • So the array is of type PlayerText.
  • To access an element of the array, we use an index.
  • An index is an integer.
  • We've chosen a logical system in which the textdraw of player with ID 0 is located in the array at the element with index 0.

3.2.2 OnPlayerDisconnect:
Destroy the per-player textdraw and reset the variable.
Code:
PlayerTextDrawDestroy(playerid, SpeedoCarInfo[playerid]);
SpeedoCarInfo[playerid] = PlayerText:INVALID_TEXT_DRAW;
This is actually not needed, since per-player textdraws get destroyed automatically when the player disconnects. So you don't need to add this code. It won't do anything wrong if you do though.

3.3 Bool variable:
We need to reset the variable when a player joins, because the speedometer is not shown at that moment.

3.3.1 OnPlayerConnect:
Initialize the variable when the player connects.
Code:
SpeedoShown[playerid] = false;
3.3.2 OnPlayerDisconnect:
Reset the variable when the player disconnects.
Code:
SpeedoShown[playerid] = false;
This is not really needed, because we already reset it when the player connects. You will need to do this if you use this variable for something else, like counting how many players have the speedometer visible or something.

3.4 Timer variable:
We have one global timer that should be run always.

3.4.1 OnGameModeInit:
Start a timer that should tick once every tenth of a second (that's definitely fast enough) and that should repeat forever. We don't need timer parameters, since we will loop through all players.
Code:
SpeedoStatusTimer = SetTimer("SpeedoStatus", 100, 1); //The name of the function we will use later
3.4.2 OnGameModeExit:
Kill the timer and reset the variable.
Code:
KillTimer(SpeedoStatusTimer);
SpeedoStatusTimer = -1;
4. The timer:
Now, finally, what we've been working towards. The timer that will handle everything.

The following code should be placed somewhere in your script. I always put it at the bottom. But it doesn't really matter.

4.1 Forwarding and implementation:
We have a timer that calls a function without parameters. So we need to use empty parentheses. As always with public functions, you also need to forward.
Code:
forward SpeedoStatus(); //Remember this name and no parameters from 3.4.1?
public SpeedoStatus() { //Same name and parameters as forward
    //Loop (see next part)
}
4.2 Looping through all online players:
Since this timer will handle every player, we need to use a loop. We don't need to do anything if the player is not online, so don't forget to include the 'IsPlayerConnected' check.
Code:
for(new playerid = 0, highestPlayerid = GetPlayerPoolSize(); playerid <= highestPlayerid; playerid++) {
    if(IsPlayerConnected(playerid)) {
        //In vehicle check (see next part)
    }
}
Note the use of <= instead of <.

Don't use the following.
Code:
for(new playerid = 0; playerid < MAX_PLAYERS; playerid++) {
    if(IsPlayerConnected(playerid)) {
    }
}
With this code, if you have only 5 players and your MAX_PLAYERS is 1000 you will have 995 unnecessary iterations.

Also don't use the following.
Code:
for(new playerid = 0; playerid <= GetPlayerPoolSize(); playerid++) {
    if(IsPlayerConnected(playerid)) {
    }
}
Otherwise it will execute the GetPlayerPoolSize() function every time the 'playerid <= GetPlayerPoolSize()' condition is checked. It's better to get the output of GetPlayerPoolSize() once and put it in another variable. You might not notice the difference if the function you call is not resource expensive. But you definitely will if it has to do something very resource expensive. It's just good practice to make a habit of the first implementation.

4.3 Checking if the player is in a vehicle:
If the player is not in a vehicle, we need to hide the speedometer, otherwise we need to show it.
Code:
if(IsPlayerInAnyVehicle(playerid)) {
    //Not shown check (see next part)
} else {
    //Shown check (see next part)
}
4.4 Checking if the speedometer is hidden to a player:
We only need to show the speedometer when it is not shown yet. But we do need to update the content always, so that must be outside of the check. Don't forget to put the boolean to true, which lets us know that the speedometer is now shown.
Code:
if(!SpeedoShown[playerid]) {
    //Show (see next part)
    SpeedoShown[playerid] = true;
}
//Update the content (explained at the end)
4.5 Checking if the speedometer is shown to a player:
We only need to hide the speedometer when it is not hidden yet. Don't forget to put the boolean to false, which lets us know that the speedometer is now hidden.
Code:
if(SpeedoShown[playerid]) {
    //Hide (see next part)
    SpeedoShown[playerid] = false;
}
4.6 Show the speedometer for a player:
Show both the global and per-player textdraws.
Code:
TextDrawShowForPlayer(playerid, SpeedoLineAbove);
TextDrawShowForPlayer(playerid, SpeedoLineLeft);
TextDrawShowForPlayer(playerid, SpeedoLineRight);
TextDrawShowForPlayer(playerid, SpeedoLineUnder);
TextDrawShowForPlayer(playerid, SpeedoBackground);
PlayerTextDrawShow(playerid, SpeedoCarInfo[playerid]);
4.7 Hide the speedometer for a player:
Hide both the global and per-player textdraws.
Code:
TextDrawHideForPlayer(playerid, SpeedoLineAbove);
TextDrawHideForPlayer(playerid, SpeedoLineLeft);
TextDrawHideForPlayer(playerid, SpeedoLineRight);
TextDrawHideForPlayer(playerid, SpeedoLineUnder);
TextDrawHideForPlayer(playerid, SpeedoBackground);
PlayerTextDrawHide(playerid, SpeedoCarInfo[playerid]);
4.8 Update the content for a player:
Finally the content itself.
Code:
//We need to get in which vehicle the player is
new vehicleid = GetPlayerVehicleID(playerid);

//We need to get what the velocity of that vehicle is
new Float:VelX, Float:VelY, Float:VelZ;
GetVehicleVelocity(vehicleid, VelX, VelY, VelZ);

//We do some calculations with those values, got to this thread for more information
new Float:Speed;
Speed = (floatsqroot(((VelX*VelX)+(VelY*VelY))+(VelZ*VelZ))* 181.5);

//Put the information in a string
new String[8+ 1];
format(String ,sizeof(String), "%ikm/h", floatround(Speed, floatround_floor)); //floatround rounds the float to an integer

//Put the string in the textdraw
PlayerTextDrawSetString(playerid, SpeedoCarInfo[playerid], String);
This code only includes what you'll need to do to show the speed of the vehicle. Other than the health and speed bars it's not that difficult. Now it's up to you to try to implement the other information yourself. Start with the text first, afterwards have a look at the bars (use the search function to know how to create those). If you're adding more text, don't forget to update the size of the string, otherwise it won't show.

5. End word:
Damn this took longer than I expected it would take... Anyway, as always, constructive criticism is definitely welcome.
__________________
Always keep in mind that a lot of people are active on this forum in their spare time.
They are sacrificing time they could easily spend on things they would rather do, to help you instead.


[Include] FCNPC A.I. - [Tutorial] Speedometer - [WIP] Single-player-like Mission - [Other] List of all my work

Last edited by Freaksken; 06/09/2017 at 02:12 PM.
Freaksken is online now   Reply With Quote
Old 04/01/2017, 11:00 PM   #2
Eoussama
High-roller
 
Eoussama's Avatar
 
Join Date: Jul 2016
Location: Kingdom of Morocco // Tangier
Posts: 1,071
Reputation: 149
Default Re: How to create a speedometer

NOICE,k keep up
__________________
Eoussama is offline   Reply With Quote
Old 04/01/2017, 11:10 PM   #3
Freaksken
Gangsta
 
Freaksken's Avatar
 
Join Date: Mar 2009
Location: Belgium
Posts: 523
Reputation: 209
Default Re: How to create a speedometer

Quote:
Originally Posted by Eoussama View Post
NOICE,k keep up
Fastest reading ever?
__________________
Always keep in mind that a lot of people are active on this forum in their spare time.
They are sacrificing time they could easily spend on things they would rather do, to help you instead.


[Include] FCNPC A.I. - [Tutorial] Speedometer - [WIP] Single-player-like Mission - [Other] List of all my work
Freaksken is online now   Reply With Quote
Old 04/01/2017, 11:13 PM   #4
Dignity
High-roller
 
Dignity's Avatar
 
Join Date: May 2013
Location: Belgium
Posts: 1,771
Reputation: 1037
Default Re: How to create a speedometer

Quote:
Originally Posted by Freaksken View Post
Fastest reading ever?
He's a shitposter. Ninety percent of his content is absolute garbage.

Either way, it looks really good. I didn't read all of it but I wish I had something like this when I was experimenting with speedometers. :P
__________________


Shoot me or Reyo a PM for more information.
Dignity is offline   Reply With Quote
Old 04/01/2017, 11:22 PM   #5
Freaksken
Gangsta
 
Freaksken's Avatar
 
Join Date: Mar 2009
Location: Belgium
Posts: 523
Reputation: 209
Default Re: How to create a speedometer

Quote:
Originally Posted by Dignity View Post
I didn't read all of it but I wish I had something like this when I was experimenting with speedometers. :P
Well, it's not something that's meant for someone like you obviously .
__________________
Always keep in mind that a lot of people are active on this forum in their spare time.
They are sacrificing time they could easily spend on things they would rather do, to help you instead.


[Include] FCNPC A.I. - [Tutorial] Speedometer - [WIP] Single-player-like Mission - [Other] List of all my work
Freaksken is online now   Reply With Quote
Old 04/01/2017, 11:37 PM   #6
BornHuman
Huge Clucker
 
BornHuman's Avatar
 
Join Date: Sep 2013
Location: 127.0.0.1
Posts: 333
Reputation: 31
Default Re: How to create a speedometer

Looks pretty solid man.
__________________


_________________________________________________

Retired Director of Development
_________________________________________________


Gamemodes:
Vortex Roleplay 1 [EDIT]
Yours Gaming Roleplay

Filterscripts:
Jason's Dynamic Housing System

Tutorials:
Creating Dynamic Saved Groups
BornHuman is offline   Reply With Quote
Old 05/01/2017, 01:26 AM   #7
Lordzy
High-roller
 
Join Date: Mar 2012
Location: NetherRealm
Posts: 2,801
Reputation: 1095
Default Re: How to create a speedometer

Nice! You've taken a great effort writing and explaining this tutorial very well. Something I'd like to point out though - The global timer runs every 100ms and loops till the highest connected player id. You could also add an explanation regarding the loop can be improved using a custom list or foreach where it contains the player ids of the ones having speedometer activated. It could reduce a lot of time and provide better performance.
__________________
[Include]safeDialogs - Complete protection against dialog responses! (dialog ids, list-items, input-text of list-item and user)

Currently inactive - I don't play at any SA-MP servers nor work on anything in PAWN for now. The projects that I've done so far in PAWN, which requires updates will be taking some time.
Lordzy is offline   Reply With Quote
Old 05/01/2017, 01:41 AM   #8
SyS
High-roller
 
SyS's Avatar
 
Join Date: Oct 2015
Posts: 1,974
Reputation: 424
Default Re: How to create a speedometer

Good job Even though the concept is small you did a great job in explaining it with some extra points and that's how an ideal tutorial should look like.
__________________

SyS is offline   Reply With Quote
Old 05/01/2017, 02:02 PM   #9
RyderX
Banned
 
Join Date: Oct 2016
Location: Lebanon,Beirut Rank: SA-MP Scripter
Posts: 603
Reputation: 53
Default Re: How to create a speedometer

Pretty Good job! Thanks man Helped me! REP+
RyderX is offline   Reply With Quote
Old 05/01/2017, 04:18 PM   #10
Logic_
High-roller
 
Logic_'s Avatar
 
Join Date: Jun 2015
Location: Next to Oblivion (Kalcor's place)
Posts: 1,212
Reputation: 171
Default Re: How to create a speedometer

Amazing tutorial, nicely explained, this should be an example for new tutorial posters/ makers.
__________________
Chaos Cops and Robbers [Website]
Call of Duty: Black Ops 3 [Website] - Former developer

SA-MP, G-MOD and Web hosting @ https://www.prestigesteve.com.
Logic_ is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Speedometer iBots Scripting Help 1 15/05/2014 01:12 PM
How to create a clock speedometer ? MisterMania67 Scripting Help 3 30/04/2014 07:06 PM
[Tutorial] How to create a speedometer thimo Tutorials 10 08/03/2012 03:41 PM
How can I create a Speedometer with OnPlayerUpdate ? Littl3j0hNy Help Archive 3 15/02/2009 06:25 PM


All times are GMT. The time now is 02:56 AM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.