12.05.2020, 20:15
(
Last edited by XStormiest; 12/05/2020 at 09:08 PM.
)
Introduction
Hello, for those of you who do not know me, I've been here for quite a while. I have created several gamemodes and scripts, some of them I published here, and some of them had laid waste in my computer. So far from past years of experience. I have came to the conclusion that I want to share my knowledge with you so you will be able to create a server for your own.
This tutorial is aimed towards an introduction to simple programming scope and learning how to use simple things like methods, events and variables to attain what you want.
Even though you many deny, most of the time you use only 20% of the programming language to deliver 80%. We use simple things like, ifs, for, while, methods, variable, macros and functions to create that awesome dynamic house system that we so want for our server. While is true that more advanced things like plugins to be able to store data in a database on the internet (MySQL), or be able to use great functions to check if player is colliding with a building (MapAndreeas) or even use simple but powerfull cryptic plugins like Whirlpool. In the end, we still use the same toys but with new power.
Content
- Methods
- Events
- Variables
- Redefinitions
When coming across the internet, you may see a lot of name interpretations, some will those functions, some will call them methods. Methods are just a quick way to deliver a sample of code throughout the code without having to repeat it. We don't want to have to write a 500 line code each time we want to add a new system.
Methods can be used for simple things like, creating a car at the player's position
Code:
CreateCarAtPlayerPosition(playerid, modelid, Float: rotation, color1, color2, siren) { new Float: X, Float: Y, Float: Z; GetPlayerPos(playerid, X, Y, Z); new carid = CreateVehicle(modelid, X, Y, Z, rotation, color1, color2, siren); PutPlayerInVehicle(playerid, carid, 0); return carid; }
We do this so next time we want to create a new vehicle we will just do this
Code:
public OnPlayerSpawn(playerid) { CreateCarAtPlayerPosition(playerid, 411, 0.0, 0, 0, 0); return 1; }
Let's say we don't want to specify the rotation each time, or the color, we just want our code to spawn a red vehicle at the player's position that has no sirens and for that we just need to create a new method
Code:
CreateRedVehicleAtPlayerPosition(playerid, modelid) { return CreateCarAtPlayerPosition(playerid, modelid, 0.0, 3, 0, 0); }
The above code and explanation is a philosophy and also a simple guide of how most of the scripts work at their core. Simple methods, that do simple things. It is said, that a method should not do more than just one thing.
We don't want a method that creates the entirety of the server, we create a method for each thing that we want to do.
For example, we can have methods like:
Code:
CreatePlayerVehicleInRangeOf(playerid, Float:range, Float: X, Float: Y, Float: Z); CreateShopInRangeOf(Float:range, Float: X, Float: Y, Float: Z, interior, virtual_world); CreatePickupBehindPlayer(playerid, pickupid, type);
Events
We describe an event as something that occurs when an entity x is influenced by an exterior force that has some kind of effect on the given entity. Thus, we can see, that sa-mp servers has in fact, many events, for example, we have an event that handles what happens when the player joins a server: OnPlayerConnect or when player types on the main chat: OnPlayerText, when types a command: OnPlayerCommandText, so far and so forth.
We can also create events of our own by using timers. Timers allow the posibility of calling a method to act as an event every x amount of time, where x can be any amount of time we want, yes, even years (don't know why you would want that). You can use timers to check if something happens: example -> player is using the minigun. In the timer main method you can make so that if the player indeed uses a minigun and the player is not an admin, a new event is called: OnPlayerCheating(cheaterid)
A simple example of the explanation above would be this:
Code:
...bla bla #include... blala public OnGameModeInit() { SetTimer("CheckCheaters", 1000, true); return 0; } forward CheckCheaters(); public CheckCheaters() { for(new i = 0; i < MAX_PLAYERS; i++) { if(IsPlayerConnected(i)) { new weapon[13][2]; for(j = 0; j <= 12; j++) { GetPlayerWeaponData(i, j, weapon[j][0], weapon[j][1]); } for(j = 0; j <= 12; j++) { if(weapon[j][0] == 46 && !IsPlayerAdmin(playerid) ) OnPlayerCheating(i); } } } return 1; } forward OnPlayerCheating(cheaterid); public OnPlayerCheating(cheaterid) { new cheater_name[MAX_PLAYER_NAME]; GetPlayerName(cheaterid, cheater_name, sizeof(cheater_name)); new message[50]; format(message, sizeof(message), "%s has been found cheating. Banned", cheater_name); SendClientMessageToAll(-1, message); BanEx(cheaterid, "Hacks"); return 1; }
Code:
...bla bla #include... blala public OnGameModeInit() { SetTimer("CheckCheaters", 1000, true); return 0; } forward CheckCheaters(); public CheckCheaters() { for(new i = 0; i < MAX_PLAYERS; i++) { if(IsPlayerConnected(i)) { // weapon check, you can also create a method like: CheckHackWeapon(playerid, weaponid) and use that instead of this whole code new weapon[13][2]; for(j = 0; j <= 12; j++) { GetPlayerWeaponData(i, j, weapon[j][0], weapon[j][1]); } for(j = 0; j <= 12; j++) { if(weapon[j][0] == 46 && !IsPlayerAdmin(playerid) ) OnPlayerCheating(i); } //flying hack - not in a vehicle check + in a vehicle check new Float: X, Float: Y, Float: Z; GetPlayerPos(playerid, X, Y, Z); new Float: velocityX, Float: velocityY, Float: velocityZ; new Float: vehiclevX, Float: vehiclevY, Float: vehiclevZ; GetVehicleVelocity(GetPlayerVehicleID(i), vehiclevX, vehiclevY, vehiclevZ); GetPlayerVelocity(playerid, X, Y, Z); if(!IsPlayerInAnyVehicle(i)) { new Float: speed = (( velocityX*velocityX ) + (velocityY * velocityY) + (velocityZ*velocityZ)); if(speed > 100) { if(!IsPlayerAdmin(playerid)) OnPlayerCheating(i); } } else { new speed = ( (vehiclevX*vehiclevX) + (vehiclevY*vehiclevY) + (vehiclevZ*vehiclevZ) ); if(speed > 100) { if(!IsPlayerAdmin(playerid)) OnPlayerCheating(i); } } } } return 1; } forward OnPlayerCheating(cheaterid); public OnPlayerCheating(cheaterid) { new cheater_name[MAX_PLAYER_NAME]; GetPlayerName(cheaterid, cheater_name, sizeof(cheater_name)); new message[50]; format(message, sizeof(message), "%s has been found cheating. Banned", cheater_name); SendClientMessageToAll(-1, message); BanEx(cheaterid, "Hacks"); return 1; }
As you can see in the code above, both uses the same method as an event. If the player is passing through this checks in this timer, the method will be called each time, if not, it will not be called
This is an excellent example, of how we could create an event to handle something, let's say for instance, we want an event that handles what happens when the player creates a new account, or what happens when the player is doing something that is worth creating an event for.
Yes, some of you may say that timers are not necesarily needed always, that is true, they consume a lot of power and are quite laggy at times. You can also call the method that acts as an event in certain situations. Example, you have an event that handles what happens when the player levels up on an rpg server. In this case you would create for example a method called: AdvancePlayerLevel:
Code:
AdvancePlayerLevel(playerid) { PLAYER_ACCOUNT[playerid][pLevel]++; OnPlayerHadLevelUp(playerid, PLAYER_ACCOUNT[playerid][pLevel]); }
Code:
forward OnPlayerHadLevelUp(playerid, level); public OnPlayerHadLevelUp(playerid, level) { new name[MAX_PLAYER_NAME]; GetPlayerName(playerid, name, sizeof(name)); new message[256]; format(message, sizeof(message), "%s has advanced to level %d. Congratiolations!", name, level); SendClientMessageToAll(-1, message); }
[TO-BE-CONTINUED]
Conclusions
Well, as an end, I want to say, I am sorry for any gramatical errors that I may had made in this post, I'll come from time to time to update this post and make it better. Also why I made this post? Well, while it makes perfect sense what I just wrote, it's a great mindset to start with when programming, and not just a sa-mp server. We want to be able to create includes, plugins and scripts that allow us to be able to re-use code without having to write the same thing 500 times over the whole sa-mp server project. We also want code that can handle any situation and events or methods that can come to our aid when want to create a simple method that update's a player's password or deletes or creates an account.
What's your own tips and advice?
How do you use methods in your script?
How do you use events in your script?
How do you use timers in your scripts?
How do you use variables in your script, or redefinitions?
Those are simple and good questions, because a great way of creating scripts can save up a long time of struggling to get over an ugly, big and unordered chunk of 27.000 lines code gamemode where everything is shuffled randomly everywhere.