Skocz do zawartości
(◕‿◕)

Od Zera do PawnMaster - Dialogi, 3DTexty, Textdrawy, Gangzone[6]

Rekomendowane odpowiedzi

I. Extract
Zanim przejdziemy do sedna niniejszej części chcę omówić coś co nie omówiłem wcześniej, chciałem to dopisać, ale czy ktoś by to przeczytał?
A) Czym jest extract?
Zastanawiałeś się kiedyś jakby to było skrócić męczący i powtarzający się kod w komendach z sscanfem? 
 
new a, string:b[32], Float:c;
if (unformat(params, "is[32]f", a, b, c))
{
    return SendClientMessage(playerid, COLOR_RED, "O nie! Coś nie tak!");
}
 
 
Za nim omówię extract chciałbym zwrócić uwagę, że "unformat" to nic innego niż "sscanf", ale w oficjalnym temacie sscanf'a na sa-mp.com było z unformatem więc postanowiłem iż tutaj też go dam, może coś to zmienia? Prawdopodobnie nic, ale cóż.
 
B.)Jak działa extract?
Wcześniej dałem przykład z
 
new a, string:b[32], Float:c;
if (unformat(params, "is[32]f", a, b, c))
{
    return SendClientMessage(playerid, COLOR_RED, "O nie! Coś nie tak!");
}
 
Jak więc to skrócić?
 
 
Małe wyjaśnienie kodu jeżeli ktoś go nie rozumie 

Jeżeli sscanf (warunki) się nie spełnią, czyli gracz nie poda wszystkich argumentów wyskoczy nam komunikat o kolorze "COLOR_RED" "O nie! Coś nie tak!", jeżeli nadal tego nie rozumiesz wróć się kilka lekcji/części w tył 

 
 
Wracając do skracania, jak więc skrócić ten kod? Możemy zrobić tak (korzystając z extracta)
 
extract params -> new a, string:b[32], Float:c; else
{
    return SendClientMessage(playerid, COLOR_RED, "O nie! Coś nie tak!");
}
 
I gotowe, kod
extract params -> new a, string:b[32], Float:c;
Jest niczym innym niż
new a, string:b[32], Float:c;
unformat(params, "is[32]f", a, b, c);
a to jest niczym innym niż (:-))
new a, string:b[32], Float:c;
sscanf(params, "is[32]f", a, b, c);
Zwróć uwagę, że przy 
extract params -> new a, string:b[32], Float:c;
 
Musieliśmy poinformować kompilator o jaki typ danych nam chodzi (dostępne te omawiane na pierwszej i drugiej lekcji)
 
Niestety kompilator sam wstawia za nas znaczniki przez co nie ma możliwości używania innych znaczników prócz "i","s" i "f" (integer, string, float) 
 
II. Dialogi
Nie trzymając nikogo dłużej w niepewności możemy przejść do głównego wątku programowania w gamemodów/skryptów w PAWN. Czym są dialogi? Dialogi to nic innego niż GUI
 
 
(Oczywiście jest kilka innych stylów)
 
 
Dobra dość głupiego pokazywania co to jest GUI...
 
A) Jakie są style GUI?
"Jakie są style GUI?" to dobre pytanie jak na start. W PAWN mamy 3 style "DIALOG_STYLE_LIST", "DIALOG_STYLE_MSGBOX" i "DIALOG_STYLE_INPUT" (dokładnie 4)
 
DIALOG_STYLE_MSGBOX
 
DIALOG_STYLE_INPUT
 
DIALOG_STYLE_LIST
 
DIALOG_STYLE_PASSWORD* (Gwiazdeczka (na sześć ))
 
B.) Wyświetlanie dialogów(GUI)
W jaki sposób wyświetlamy te masakryczne okienka? Używamy do tego funkcji ShowPlayerDialog, ma ona 7 argumentów, ale nie ma czego się bać, są one proste i przy pisaniu GUI nieświadomie je podajemy.
 
ShowPlayerDialog(playerid, dialogid, style, caption[], info[], button1[], button2[]);
Pierwszy argument to słynny playerid, omawiany hmmm, 10 stuleci w tył? :>, drugi to "dialogid", czym on jest? Jest to unikatowy identyfikator naszego GUI, jednym słowem cyferki które nie mogą się powtarzać, często dla ułatwienia ID dialogów podaje się w definicjach (#define)
 
#define ID_MY_GUI 1
 
Kolejnym argumentem funkcji ShowPlayerDialog jest styl naszego GUI, dla przypomnienia "DIALOG_STYLE_LIST", "DIALOG_STYLE_MSGBOX", "DIALOG_STYLE_INPUT" lub "DIALOG_STYLE_PASSWORD" (tak on też się liczy)
 
Teraz mamy trzy najprostsze argumenty, czwarty argument to tytuł naszego okienka, piąty to tekst jaki ma on zawierać, szósty to nazwa pierwszego przycisku (lewego), a siódmy to nazwa drugiego przycisku (jesteś błyskotliwy? Zgadnij)
 
Zbierzmy wszystko do kupy, nasza funkcja za wyświetlanie dialogu będzie czymś podobnym do tego (oczywiście, każdy wstawia to co woli ), przykład na razie na MSBOX'ie
ShowPlayerDialog(playerid, 0, DIALOG_STYLE_MSGOX, "Tekst", "Piękny tekst w równie pięknym GUI, nawet polskie znaki są piękne :)", "Login", "Cancel");
Lub sposób częściej wykorzystywany przy tworzeniu GUI
#define DIALOG_ID_MY 0
ShowPlayerDialog(playerid, DIALOG_ID_MY, DIALOG_STYLE_MSGOX, "Tekst", "Piękny tekst w równie pięknym GUI, nawet polskie znaki są piękne :)", "Ok", "Dzięki za info zią");
Jeżeli nadal nie rozumiesz dlaczego warto wstawiać zamiast cyferek nazwy definicji możesz przeczytać spoiler, lub cofnąć się kilka lekcji w tył (do preprocessora)
 

Trzy zalety używania stałych (definicja = stała):
1. Łatwy sposób zmiany ID dialogu (w tym przypadku)
2. Nie musisz szukać po dialogach (głównie w kodzie, przy dużej ilości kodu robi to się męczące) ostatniego ID, żeby podać to właściwe (jeśli podamy ID które ma inny już dialog otrzymamy chamskie rezultaty )
3. Kod z definicjami ładniej wygląda i jest czytelniejszy :3

 
Oke, był MSGBOX to teraz INPUT (mowa o stylach ofc)
ShowPlayerDialog(playerid,0, DIALOG_STYLE_INPUT, "Login", "Podaj hasło do swojego konta:", "Login", "Papa");
Analogicznie do pierwszego przykładu, tu również możesz zamienić 0 na jakąś stałą (nie podaję tego 2 przykładu do tego ponieważ omówiłem to w 1, a bez sensu jest powtarzać to samo w kółko :/), tak naprawdę ten przykład nie był najlepszym przykładem, dlaczego? W stylu INPUT w miejscu gdzie możesz wpisać tekst widać co wpisujesz, a ten mały przykładzik przypominał okienko logowania, w takim okienku (GUI) lepiej jeżeli wpisujący widzi gwiazdki, a do tego mamy styl PASSWORD (DIALOG_STYLE_PASSWORD)
 
No to teraz lista (DIALOG_STYLE_LIST)
Na pewno nie raz zauważyłeś, że w liście mamy kilka "produktów" do wybrania, np jest
"Chleb"
"Mleko"
"Śmietana"
 
W GUI może być tak samo, każdą nową pozycję "produktu" podajemy po "\n" np
ShowPlayerDialog(playerid,0, DIALOG_STYLE_LIST, "Produkty", "Chleb\nMleko\nŚmietana", "Ok", "Kupie to!");
Każda nazwa będzie miała swoje oddzielne pole i o to nam chodziło 
 
Na koniec mogę podać jeszcze jeden przykład, DIALOG_STYLE_PASSWORD czyli INPUT z maskowaniem wpisywanego tekstu (przydatne do okienek logowania/rejestracji)
 
ShowPlayerDialog(playerid,0, DIALOG_STYLE_PASSWORD, "Login", "Podaj hasło do swojego konta:", "Login", "Papa");
I tyle :-), wpisywany tekst będzie kropeczkami/gwiazdkami (jak kto woli, moim zdaniem to czym są literki/cyferki zakrywane nie da się utworzyć na klawiaturze )
 
C) Reakcja na GUI
Jeżeli postanowiłeś przetestować swoje nowe GUI na pewno zauważyłeś, że klikanie jakiegoś przycisku, czy wybranie jakiejś pozycji z listy nic nie robi (zwraca 1) czyli zamyka okienko. Jak zrobić reakcję na GUI? W OnDialogResponse daj coś takiego (przykład pokazuje do tego pierwszego przykładu z MSGBOX'em
if(dialogid == 0) //Zamiast 0 daj ID swojego dialogu, ja daje 0 ponieważ wszystkie ID jakie dawałem były zerowe :)
{
    if(response == 2) //response == 1 lewy przycisk, response == 2 prawy przycisk, oczywiście ten w GUI :-)
        SendClientMessage(playerid, COLOR_GREEN, "Nie ma za co , dzięki, że przeczytałeś"); //Jeżeli został wciśnięty prawy przycisk wysyłamy wiadomość
    else //Jeśli nie został wciśnięty prawy przycisk czyli response jest inne niż 2
    {
        SendClientMessage(playerid, COLOR_RED, "Czemu nie przeczytałeś mojej wiadomości!?");
        Ban(playerid); //A tu kara, banan!
    } 
}
 
To teraz przykład z inputem
if(dialogid == 0) //Zamiast 0 daj ID swojego dialogu, ja daje 0 ponieważ wszystkie ID jakie dawałem były zerowe 
{
    if(response == 1) //response == 1 lewy przycisk, response == 2 prawy przycisk, oczywiście ten w GUI :-)
        SendClientMessage(playerid, COLOR_GREEN, "Zalogowałeś się na konto");
    else //Jeśli nie został wciśnięty prawy przycisk czyli response jest inne niż 2
    {
        SendClientMessage(playerid, COLOR_RED, "Nie chcesz się logować? To nie... Pff");
        Kick(playerid); //Kick
    } 
}
 
A co jeżeli chcemy sprawdzić co zostało wpisane?
 
if(dialogid == 0) //Zamiast 0 daj ID swojego dialogu, ja daje 0 ponieważ wszystkie ID jakie dawałem były zerowe 
{
    if(response == 1) //response == 1 lewy przycisk, response == 2 prawy przycisk, oczywiście ten w GUI :-)
    f(strcmp(inputtext, "Hasełko", false) == 0)
        SendClientMessage(playerid, COLOR_GREEN, "Zalogowałeś się na konto");
        else //Jeżeli gracz nie wpisał "Hasełko"
       {
        SendClientMessage(playerid, COLOR_RED, "Błędne hasło, papa");
       Kick(playerid);
       }
    else //Jeśli nie został wciśnięty prawy przycisk czyli response jest inne niż 1
    {
        SendClientMessage(playerid, COLOR_RED, "Nie chcesz się logować? To nie... Pff");
        Kick(playerid); //Kick
    } 
}
Jak to tylko działa? Sprawdzamy co zostało wpisane funkcją strcmp i porównujemy czy wpisany tekst jest taki, taki i owaki. Wpisany tekst jest w zmiennej inputtext. Powiem więcej kilka rozdziałów niżej (przy stringach)
 
Przykład z listą
if(dialogid == 0) //Zamiast 0 daj ID swojego dialogu, ja daje 0 ponieważ wszystkie ID jakie dawałem były zerowe 
{
    if(response == 1) //response == 1 lewy przycisk, response == 2 prawy przycisk, oczywiście ten w GUI :-)
         switch(listitem) //Switch na zmienną listitem, listitem to nazwy "produktów z listy"
        {
         case 0: //Wszystkie produkty od góry liczymy od zera!
        SendClientMessage(playerid, COLOR_GREEN, "Dzięki, że kupisz mi chlebek :)");
        case 1:
        SendClientMessage(playerid, COLOR_GREEN, "Kupisz mleczko? Też dobre :)");
       case 2:
       SendClientMessage(playerid, COLOR_GREEN, "Śmietanka będzie na zupkę");
    else //Jeśli nie został wciśnięty prawy przycisk czyli response jest inne niż 1
    {
        SendClientMessage(playerid, COLOR_RED, "Nic nie kupisz? Łaski bez";
    } 
}
 
D) Koniec, słowo pożegnalne GUI
Właśnie zjadłeś całą wiedzę na temat GUI, cieszę się niezmiernie, jeżeli chcesz kiedyś zrobić jeden przycisk w GUI w drugi możesz wstawić
""
Np
ShowPlayerDialog(playerid,0, DIALOG_STYLE_INPUT, "Login", "Podaj hasełko:", "Login", "");
Nie będzie drugiego przycisku
 
Pozdrawiam i zapraszam dalej 
 
III. 3DTexty
Na pewno nie raz je widziałeś na serverze, wyglądają jak obiekty, a są to napisy 3D
 
A) Jak stworzyć taki napis?
Aby stworzyć taki 3DText musimy użyć funkcji Create3DTextLabel która ma następujące argumenty
 
(text[], color, Float:X, Float:Y, Float:Z, Float:DrawDistance, virtualworld, testLOS)
"text[]" - Czyli tekst napisu, oczywiście musi to być string.
"color" - Kolor PAWN naszego tekstu, chodzi tu o takie kolory jak w przypadku SendClientMessage, np 0x452020FF
"Float:X" - Pozycja X napisu
"Float:Y" - Pozycja Y napisu
"Float:Z" - Pozycja Z napisu
"Float:DrawDistance" - Odległość z jakiej ma być widoczny napis
"virtualworld" - Virtual World naszego napisu (każdy gracz domyślnie jest w VW (Virtual Worldzie) 0
"testLOS" - Czy napis ma być widziany przez obiekty? 0 - Nie 1 - Tak
 
Funkcja Create3DTextLabel, zwraca ID nowego 3DTextu
 
Zbierzmy wszystko do kupy
Create3DTextLabel("Jestem Tu!", 0xFF005CFF, 30.0, 40.0, 50.0, 40.0, 0, 0);
Na pozycji X, Y, Z 30.0, 40.0, 50.0 powinniśmy ujrzeć piękny różowy (:-)) napis "Jestem Tu!"
 
B.) Usuwanie napisu
Gdy coś robimy warto po Sobie posprzątać. Aby usunąć 3DText potrzebujemy jego ID, który zwraca nam funkcja Create3DTextLabel, funkcją do usuwania jest Delete3DTextLabel, podajemy jej ID 3D Textu i gotowe
new Text3D:Text;
Tworzymy zmienną globalną typu Text3D
 
Text = Create3DTextLabel("Jestem Tu!", 0xFF005CFF, 30.0, 40.0, 50.0, 40.0, 0, 0);
Przypisujemy jej nasz 3DText (dokładnie to zwracaną przez niego wartość), np w OnGameModeInit
 
Delete3DTextLabel(Text);
Sprzątamy po Sobie, np w OnGameModeExit, podając jako argument funkcji naszą zmienną globalną, która przechowuje zwracaną wartość przez Create3DTextLabel, a Create3DTextLabel zwraca nam ID utworzonego 3D Text'a 
 
C) Dołączanie 3DTextu do gracza, zmienianie napisu i inne funkcje
To teraz pobawimy się trochę na 3DText'ach 
 
Na początku dołączymy jakiegoś 3DText'a graczowi do głowy, służy do tego funkcja
Attach3DTextLabelToPlayer, ma ona 5 argumentów, prostych argumentów.
 
(Text3D:id, playerid, Float:OffsetX, Float:OffsetY, Float:OffsetZ)
"Text3D:id" - ID naszego 3D Text'a, zdobywamy go tak samo gdy chcieliśmy go usunąć
"playerid" - Czyli id naszego gracza, nasz playerid
"Float"OffsetX" - o ile na osi X napis ma odstawać od gracza
"Float"OffsetY" - o ile na osi Y napis ma odstawać od gracza
"Float"OffsetZ" - o ile na osi Z napis ma odstawać od gracza
 
Ponownie wszystko zbieramy do kupy i...
new Text3D:Text;
Tworzymy zmienną globalną typu Text3D
 
Text = Create3DTextLabel("Jestem Tu!", 0xFF005CFF, 30.0, 40.0, 50.0, 40.0, 0, 0);
Przypisujemy jej nasz 3DText (dokładnie to zwracaną przez niego wartość), np w OnGameModeInit
 
Tworzymy komendę aby przypisać nasze 3DText'a graczowi
CMD:dajminapis(playerid, params[])
{
Attach3DTextLabelToPlayer(Text, playerid, 0.0, 0.0, 0.7);
return 1;
}
Gotowe!
 
Teraz omówmy Sobie jak zmienić ten nasz napis. Posłużymy się funkcją Update3DTextLabelText, ma ona 3 argumenty
Cytat
 
(Text3D:id, color, text[])

 

 

"Text3D:id" - ID naszego 3DText'a, ile można powtarzać jego zdobywanie?
"color" - Nowy kolor naszego 3DText'a, oczywiście kolor PAWN
"text[]" - Nowy tekst naszego 3DText'a, oczywiście string
 
Czyli mamy teraz takie coś
new Text3D:Text;
Tworzymy zmienną globalną typu Text3D
 
Text = Create3DTextLabel("Jestem Tu!", 0xFF005CFF, 30.0, 40.0, 50.0, 40.0, 0, 0);
Przypisujemy jej nasz 3DText (dokładnie to zwracaną przez niego wartość), np w OnGameModeInit

CMD:zmiennapisnainny(playerid, params[])
{
Update3DTextLabelText(Text, 0xFFFFFFFF, "Coś nowego");
return 1;
}
Nasza komendą na nowy napis. Jeżeli rozumiesz dobrze sscanf'a (a powinieneś już go rozumieć) bez problemu (może lekko przesadzam, że bez problemu?) powinieneś sam napisać komendę która zmienia napis na taki jaki poda gracz, ja podaje tylko przykłady abyś wiedział jak te funkcje działają 
Na wiki sa-mp'a można potknąć się o kilka funkcji 3DText'ów, ja omówiłem te najważniejsze moim skromnym zdaniem.
 
IV. Pickupy
Na pewno również je nie raz widziałeś.
 
W SA-MP jak i zwykłym GTA istnieją setki lat, widzisz je codziennie w SA-MP'ie, ale pewnie nie zwracasz na nie uwagi, to nic takiego. Proszę bardzo tym razem coś o tych ikonkach 
 
A) Jak stworzyć Sobie takie pickupa?
Tworzenie pickupa jest niczym skomplikowanym, używamy do tego funkcji CreatePickup, która ma 6 argumentów
 
(model, type, Float:X, Float:Y, Float:Z, Virtualworld)
"model" - ID Modelu naszego pickupa, wszystkie ID znajdziesz tutaj http://wiki.sa-mp.com/wiki/Pickup_IDs
"type" - Typ naszego pickupa, wszystkie typy znajdziesz również tutaj http://wiki.sa-mp.com/wiki/Pickup_IDs, lub tutaj http://wiki.sa-mp.com/wiki/PickupTypes
"Float:X" - Pozycja X pickupa
"Float:Y" - Pozycja Y pickupa
"Float:Z" - Pozycja Z pickupa
"Virtualworld" - Virtual World naszego pickupa (domyślnie 0), jeżeli daj -1 pickup będzie na wszystkich VW
 
Funkcja tworząca pickupa zwraca również jego unikatowe ID tak jak w przypadku 3D Textów i wielu innych przypadkach
Zbieramy wszystko w jedność i...
CreatePickup(1242, 2, 1503.3359, 1432.3585, 10.1191, -1);
Pickup o modelu armora, który pojawia się po losowym czasie, na pozycji X, Y, Z, 1503.3359, 1432.3585, 10.1191, na wszystkich virtual worldach
 
B.) Sprzątanie po Sobie
Znów posprzątamy po Sobie
 
new pickup;
Tworzymy zwykła zmienną globalną, która będzie przetrzymywała ID pickupa. Pickupy nie mają własnego typu danych (zmiennych) więc używamy zwykłych liczb
 
pickup = CreatePickup(1242, 2, 1503.3359, 1432.3585, 10.1191, -1);
Przypisujemy pickupa (dokładnie jego ID) zmiennej np w OnGameModeInit
 
DestroyPickup(pickup);
Usuwa pickupa, np w OnGameModeExit
 
C) Statyczne Pickupy
A co jeżeli chcemy aby nasz pickup był zawsze? Nie mam na myśli, że stoi ciągle (chociaż przy właściwym typie da się i tak zrobić), ale o to aby nie dało się go usunąć żadną funkcją. Funkcja AddStaticPickup dodaje takiego pickupa, nie różni się niczym od zwykłego CreatePickup, prócz tym, że nie zwraca ID pickupa, bo go nie ma. Jest ciągle i nie da jej się usunąć funkcją DeletePickup. 
Skoro ma takie same argumenty to...
 
AddStaticPickup(1242, 2, 1503.3359, 1432.3585, 10.1191, 0);
I już!
 
D) Reagowanie
Wszystko ładnie, pięknie, wyśmienicie. Tylko zwykłe typy pickupów nie wystarczą nam gdy chcemy wyświetlić np wiadomość po wejściu w pickupa, jak więc działają takie cuda? Musimy zrobić coś, coś prostego! () w publicu OnPlayerPickUpPickup, dodajemy np takie coś
if(pickupid == pickup_Cash) //Sprawdzamy id pickupa
{
GivePlayerMoney(playerid, 1000);
SendClientMessage(playerid, COLOR, "Proszę bardzo, 1000$ więcej :)");
}
 
Sprawdzamy tym kodem czy id pickupa jest równe tej wartości zapisanej w zmiennej "pickup_Cash" jeżeli tak dodajemy 1000$ graczowi. A co dalej? Musimy w końcu zapisać to ID do zmiennej.
new pickup_Cash;
Robimy zmienną globalną
 
pickup_Cash = CreatePickup(1274, 2, 0.0, 0.0, 9.0);
Dodajemy pickupa i przypisujemy zmiennej jego unikatowe ID (np w OnGameModeInit)
 
A potem wszystko pięknie działa 
 
V. GangZone
Tego zapewne nie widujesz tak często, ale widujesz
 
A) Jak tworzymy gangzone?
Stworzyć gangzone to jedno, ale wyświetlić graczom i ustawić kolor to drugie.
 
Gangzone tworzymy funkcją GangZoneCreate, która ma 4 argumenty
Cytat
 
(Float:minx, Float:miny, Float:maxx, Float:maxy)
"Float:minx" - Kord X na zachód
"Float:miny" - Kord Y na wschód
"Float:maxx" - Kord X na północ
"Float:maxy" - Kord Y na południe
 
Trochę dziwnie to brzmi, najlepiej zrobić Sobie na mapie takiego kwadracika, a potem w grze odmierzyć jego kordy.
 
Funckja GangZoneCreate zwraca nam ID GangZone, dlatego najlepiej od razu zrobić
new gangzone;
gangzone = GangZoneCreate(1248.011, 2072.804, 1439.348, 2204.319);
Mamy nasz gangzone
 
Co dalej? Musimy go wyświetlić graczom funkcją GangZoneShowForAll, ma ona dwa argumenty. ID gangzone i jego kolor. Kolor jak kolor, mowa o kolorze PAWN, a ID ustawialiśmy setki razy (tak, mam na myśli zmienną w której przechowujemy ID gangzone, zwracane przez GangZoneCreate, wcześniej  napisałem, żeby od razu to zrobić, żeby teraz móc od razu wpisać zmienną :-))
GangZoneShowForAll(gangzone, COLOR_RED);
 
Jest jeszcze jedna przydatna funkcja "sprzątania po Sobie" , argumenty? To co zawsze ID naszego gangzone
GangZoneDestroy(gangzone);
 
I tyle z gangzon'ów, dużo prawda? 
 
VI. Stringi
Pewnie się zastanawiasz, po co pisać o typie danych "string" skoro było o tym już kupę czasu w tył? No właśnie, dobrze myślisz, ale... to nie tak , nie mam zamiaru pisać o typie danych, ale o funkcjach które dają nam dużo możliwości w tej dziedzinie.
 
A) Wyszukiwanie stringów w stringach
Podejrzanie dziwnie ta nazwa brzmi :-), czasem może będziesz chciał znaleźć jakieś słówko, a może nawet pełne zdanie w inny słówku lub zdaniu. No właśnie po to jest strfind, do wyszukiwania stringów w stringach. Jak to działa? Strfind ma 4 argumenty, dwa ostatnie są opcjonalne
Cytat
 
(const string[],const sub[],bool:ignorecase=false,pos=0)
"const string[]" - String w którym ma być szukany string
"const sub[]" - String który ma być szukany w "const string[]"
"ignorecase"(opcjonalne) - Czy HeJ ma być równe Hej? Trochę dziwnie to brzmi :X, czy wielkość liter ma być ignorowana? True - Tak, False - Nie, domyślnie jest ustawione False
"pos" - Od której litery w "const string" ma zacząć się szukanie "const sub"? Domyślnie 0
 
No to nasza funkcyjka jest czymś takim
strfind("Jestem Kamil, a ty jesteś?", "Kamil", false, 0)
 
Wzbogaćmy naszą funkcję o jakiegoś if'a, tak, żeby coś się działo gdy tekst zostanie znaleziony
if(strfind("Jestem Kamil, a ty jesteś?", "Kamil", false, 0))
{
SendClientMessage(playerid, 0xFFFFFFFF, "Cieszę się");
}
 
 
B.) Usuwanie danych ze stringa
Nauczyliśmy się znajdować to teraz może coś usuńmy? Posłużymy się do tego funkcją strdel która ma trzy argumenty

 


(string[], start, end)
"string[]" - String z którego mają zostać usunięte dane
"start" - Nr pierwszej literki od której ma zacząć się usuwanie
"end" - Nr literki na której ma się skończyć usuwanie
 
Skąd wytrzasnąć właściwy numerek? Wystarczy liczyć literki i cyferki (+ znaki interpunkcyjne) od lewej strony zaczynając od 0.
 
Przykład
new string[15] = "Pora coś usunąć";
strdel(string, 0, 8);
 
I tyle z usuwania, zostanie "usunąć"
 
C) Sprawdzanie wielkości stringu
Dobrze, a jak sprawdzić wielkość stringa? Miejmy na myśli ile ma literek, nie licząc go. Jest taka funkcja mmm..., Strlen która ma jeden argument, stringa którego wielkość ma być obliczana, jak to działa? Ta dan
 
new string = strlen("String");
W rezultacie zmienna "string" ma wartość liczbową 6
 
 
Opisałem tu tylko 3 funkcję stringów po więcej możesz sięgnąć tu http://wiki.sa-mp.com/wiki/Strcat, z funkcji stringów rzadko się korzysta, ale cóż.
 
VII. TextDraw'y
Kolejna pożyteczna i znana rzecz, TextDrawy (TD)
 
A) Tworzenie TextDrawa
Jak stworzyć taki cudo? Sytuacja się powtarza tak jak w przypadku GangZone, stworzyć, a wyświetlić to nie to samo, jak więc to zrobić? Proste. Tworzymy funkcją TextDrawCreate, ma ona 3 argumenty

 


(Float:x, Float:y, text[])

 

 

"x" - Kord X TextDrawa
"y" - Kord Y TextDrawa
"text[]" - Tekst textdrawa
 
Funkcja TextDrawCreate zwraca jego ID co jest bardzo dla nas ważne zróbmy więc od razu to co zazwyczaj gdy pisze o tym, że funkcja zwraca swoje unikatowe ID. Zróbmy zmienną globalną (typ Text) i przypiszmy jej ID TextDrawa
 
new Text:Text;
Text = TextDrawCreate(240.0,580.0,"SA-MP"); 
I wyświetlmy naszego TD graczowi (w OnPlayerConnect)
TextDrawShowForPlayer(playerid, Text);
 
Jak usunąć TextDrawa? Funkcja TextDrawDestroy potrzebuje ID textdrawa i gotowe
TextDrawDestroy(Text);
 
B.)Przydatne funkcje
TextDrawy mają dużo przydatnych funkcji, np TextDrawBoxColor, służy do zmiany koloru tła, ma on dwa argumenty, ID textdrawa i nowy kolor.
TextDrawBoxColor(Text, 0x000000FF);
 
A jak ustawić kolor tekstu? TextDrawColor, dwa argumenty, ID textdrawa i nowy kolor.
TextDrawColor(Text, 0x000000FF);
 
Jak zmienić czcionkę? TextDrawFont, dwa argumenty, ID textdrawa i ID czcionki, ID bierzemy stąd http://wiki.sa-mp.com/wiki/TextDrawFont
TextDrawFont(Text, 2);
 
Jak zmienić wielkość tekstu? TextDrawTextSize, tym razem trzy argumenty ( :)), ID textdrawa, Wielkość pod kątem X, Wielkość pod kątem Y (liczby float)
TextDrawTextSize(Text, 2.0, 3.6);
 
Jak ustawić położenie tekstu w textdrawie? TextDrawAlignment, dwa argumenty, ID textdrawa, położenie 1 - lewa strona, 2 - środek 3 - prawa strona np
TextDrawAlignment(Text, 2);
 
Trochę tego się nazbierało :)
 
C) Coś na koniec
No to już znasz podstawy tworzenia TextDrawa, czasem potrzeba coś wyświetlić prócz z góry założonego tekstu, wtedy musimy stworzyć textdrawa i zmienić jego tekst na jakiś swój, np na jakąś zmienną która przechowuje jakieś dane. Do tworzenia TD przydaje się ten generator http://codegenerators.pl/textdraw
 
VIII. Publicki
Pora na mądry krok, omówienie wszystkich publicków (tych nie różnych)
 
A) OnFilterScriptInit()
Public ten aktywuje się gdy skrypt jest włączany, nie ma żadnych argumentów.
 
B.)OnFilterScriptExit()
Public ten aktywuje się gdy skrypt jest wyłączany, nie ma żadnych argumentów.
 
C) OnGameModeInit()
Public ten aktywuje się gdy GM jest włączany, nie ma żadnych argumentów.
 
D) OnGameModeExit()
Public ten aktywuje się gdy GM jest wyłączany, nie ma żadnych argumentów.
 
E) OnPlayerRequestClass(playerid, classid)
Public ten aktywuje się gdy gracz jest w wybieralce, jego argumenty to id gracza w wybieralce oraz id  skinów które mają się wyświetlać
 
F) OnPlayerConnect(playerid)
Public ten aktywuje się gdy gracz łączy się z serverem/wchodzi na serverem, jego argumenty to id gracza łączącego się z serverem.
 
G) OnPlayerDisconnect(playerid, reason)
Public ten aktywuje się gdy gracz wychodzi z servera/odłącza się od servera, jego argumenty to id gracza odłączającego się z servera i powód wyjścia, 0 - Timed out (Odłączenie się od servera przez stracenie połączenia Klient-Server (najczęściej gdy stracimy połączenie z internetem), 1 - Left normally (Gracz wyszedł z servera), 2 - Kicked or Banned (Gracz został zbanowany, lub wyłączony). 
 
H) OnPlayerSpawn(playerid)
Public ten aktywuje się gdy gracz spawnuje się na serverze, jego argumenty to id gracza spawnującego się.
 
I) OnPlayerDeath(playerid, killerid, reason)
Public ten aktywuje się gdy gracz umiera, jego argumenty to id gracza umierającego, id gracza zabijającego i powód śmierci (dokładnie to ID broni z jakiej zginął).
 
J) OnVehicleSpawn(vehicleid)
Public ten aktywuje się gdy pojazd się pojawia, jego argumenty to id pojazdu który się pojawia.
 
K) OnVehicleDeath(vehicleid, killerid)
Public ten aktywuje się gdy pojazd "ginie" (zostaje zniszczony), jego argumenty to id pojazdu który został zniszczony i id gracza który go zniszczył.
 
L) OnPlayerText(playerid, text[])
Public ten aktywuje się gdy gracz napisze coś na czacie, jego argumenty to id gracza który coś napisał i tekst który napisał.
 
M) OnPlayerCommandText(playerid, cmdtext[])
Public ten aktywuje się gdy gracz napisze jakąś komendę, jego argumenty to id gracza który napisał komendę i nazwa komendy.
 
N) OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
Public ten aktywuje się gdy gracz wsiądzie do pojazdu, jego argumenty to id gracza który wsiadł to pojazdu, id pojazdu i wartość liczbowa czy jest pasażerem, 0 jeżeli jest kierowcą, 1 jeżeli jest pasażerem
 
O) OnPlayerExitVehicle(playerid, vehicleid)
Public ten aktywuje się gdy gracz wysiądzie z pojazdu, jego argumenty to id gracza który wysiadł z pojazdu i id pojazdu z którego wysiadł.
 
P) OnPlayerStateChange(playerid, newstate, oldstate)
Public ten aktywuje się gdy gracz zmieni swój stan, np jest kierowcą i wysiądzie z pojazdu wtedy jego stan zmienia się, gdyż nie jest już w pojeździe, ale jest już "na nogach". Jego argumenty to gracz którego stan się zmienia, nowy stan i stary stan.
 
R) OnPlayerEnterCheckpoint(playerid)
Public ten aktywuje się gdy gracz wjedzie do CP (Checkpoint'a), ma jeden argument, id gracza który wjeżdża do Checkpoint'a.
 
S) OnPlayerLeaveCheckpoint(playerid)
Public ten aktywuje się gdy gracz wyjeżdża z CP (Checkpoint'a), ma jeden argument, id gracza który wyjeżdża z Checkpoint'a.
 
T) OnPlayerEnterRaceCheckpoint(playerid)
Public ten aktywuje się gdy gracz wjeżdża do Race CP (Checkpoint'a), ma jeden argument, id gracza który wjeżdża do Race Checkpoint'a.
 
U) OnPlayerLeaveRaceCheckpoint(playerid)
Public ten aktywuje się gdy gracz wyjeżdża z Race CP (Checkpoint'a), ma jeden argument, id gracza który wyjeżdża z Race Checkpoint'a.
 
W) OnRconCommand(cmd[])
Public ten aktywuje się gdy komenda rcon jest wpisywana, ma jeden argument, komendę wpisywaną
 
V) OnPlayerRequestSpawn(playerid)
Public ten aktywuje się gdy gracz jest w wybieralce i wciśnie "Spawn", ma jeden argument, id gracza wciskającego przycisk
 
X) OnObjectMoved(objectid)
Public ten aktywuje się gdy obiekt przemieszcza się, ma jeden argument, id obiektu który się przemieszcza
 
Y) OnPlayerObjectMoved(playerid, objectid)
Public ten aktywuje się gdy obiekt przemieszcza się z powodu gracza, czyli gdy gracz przemieszcza obiektem funkcją MovePlayerObject, ma dwa argumenty, id gracza który przemieszcza obiektem i id obiektu przemieszczanego
 
Z) OnPlayerPickUpPickup(playerid, pickupid)
Public ten aktywuje się gdy gracz wejdzie do pickupa, dwa argumenty, id gracza wchodzącego do pickupa i id pickupa
 
BA) OnVehicleMod(playerid, vehicleid, componentid)
Public ten aktywuje się gdy pojazd zostanie zmodyfikowany, public ma trzy argumenty, id gracza który jest kierowcą, id pojazdu i id komponentu pojazdu (to gdy wpisujemy /tune np w sultanie i pojawiają się naklejki, nitro itd, http://wiki.sa-mp.com/wiki/Car_Component_ID << wszystkie komponenty)
 
BB) OnVehiclePaintjob(playerid, vehicleid, paintjobid)
Public ten aktywuje się gdy pojazd jest przemalowywany, public ma trzy argumenty, id gracza który jest kierowcą, id pojazdu i id nowego stylu koloru (te naklejki, lista stylów http://wiki.sa-mp.com/wiki/Paintjob
 
BC) OnVehicleRespray(playerid, vehicleid, color1, color2)
Public ten aktywuje się gdy pojazd jest przemalowywany, public ma cztery argumenty, id gracza który jest kierowcą, id pojazdu, id koloru 1 i id koloru 2 (lista kolorków http://wiki.sa-mp.com/wiki/Hidden_Colour_ID's)\
 
BD) OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid)
Public ten aktywuje się gdy gracz zmieni interior, ma trzy argumenty, id gracza zmieniającego interior, id nowego interiora i id starego interiora.
 
BE) OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
Public ten aktywuje się gdy gracz wciśnie przycisk, ma trzy argumenty, id gracza wciskającego przycisk, nazwa nowego przycisku i nazwa starego przycisku.
 
BF) OnRconLoginAttempt(ip[], password[], success)
Public ten aktywuje się gdy gracz loguje się na administratora RCON, ma trzy argumenty, IP gracza logującego się na rcona, hasło jakie wpisał i "success" wartość liczbową, 0 jeżeli hasło jest nie poprawne, a 1 jeżeli poprawne.
 
BG) OnPlayerUpdate(playerid)
Public ten aktywuje się gdy dochodzi do wysłania pakietów internetowych Klient-Server. Ma jeden argument, id gracza z którym wysyłane są pakiety.
 
BH) OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
Public ten aktywuje się gdy gracz robi coś na GUI, ma pięć argumentów. Pierwszy argument to ID gracza który robi coś na GUI, drugi to id dialogu, kolejny to nr przycisku, czwarty lista "produktów" gdy styl GUI to DIALOG_STYLE_LIST i inputtext czyli tekst w GUI.
 
BI) OnPlayerClickPlayer(playerid, clickedplayerid, source)
Public ten aktywuje się gdy gracz wciśnie na drugiego gracza w tabeli na TAB, ma trzy argumenty, id gracza wciskającego, id gracza wciśniętego i source czyli jaka akcja zaszła (http://wiki.sa-mp.com/wiki/Click_Sources)
 
 
 
IX. Praca Domowa
1. Jak tworzymy GUI?
2. Jak tworzymy TD?
3. Jak tworzymy Pickupa?
4. Jak tworzymy GangZone?
5. Napisz skrypt w GUI który utworzy GangZone po przez podane dane w grze (DLA ODWAŻNYCH), w skrócie mówiąc, zrób dynamiczny system tworzenia GangZone w grze. Powinieneś Sobie poradzić
 
PS: Wiem, że nie ma przykładowych skryptów, będą w następnej części, było, ale nie zapisało się do notatnika :(
PS2: Następna część będzie ostatnia, będzie o MySQL i Pvarach. Co jeszcze można omówić? Czekam na wasze propozycje.
Edytowane przez Failed

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ładny poradnik, przejrzysty. 

 

Przepraszam że Cie poprawię ale ...

 

 

(DLA ODWAŻNYCH)

Dla odważnych? Ja bym to nazwał dla zaawansowanych. Co ma być w tym takiego strasznego że trzeba się odważyć? :p

 

 

Pozdrawiam. 

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Na tym poziomie poradnika każdy ma już dużą wiedzę, więc "dla zaawansowanych" to już dla wszystkich tych którzy dobrze rozumieją i zrozumiale czytają tą serie poradników, a "dla odważnych" fajnie nasyca niż samo "dla zaawansowanych" :p

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Co to za różnica, czy będzie to sscanf, czy unformat, czy extract? Wydaje mi się, że łatwiej jest samą funkcją sscanf niż unformat czy extract (być może przyzwyczajenie). Jeśli to niebyły by funkcje od sscanfa (unformat, extract) to fajnie byłoby :P czytając ten poradnik tak zrozumiałem

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Co to za różnica, czy będzie to sscanf, czy unformat, czy extract? Wydaje mi się, że łatwiej jest samą funkcją sscanf niż unformat czy extract (być może przyzwyczajenie). Jeśli to niebyły by funkcje od sscanfa (unformat, extract) to fajnie byłoby :P czytając ten poradnik tak zrozumiałem

native unformat(const data[], const format[], {Float,_}:...) = sscanf;

Przecież unformat = sscanf. Tylko nazwa zmieniona.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

A przy pomocy extract ekstraktujesz dane które sam tworzysz, więc nie musisz bawić się w warunki, ponieważ zostały one już wcześniej zdefiniowane.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Nie podoba się to wyjdź.

On się stara a ty ubliżasz, przez takich forum spada na dno. -_-

 

Nie pisz postów nie wnoszących nic do tematu. 

Po 1. To nie ja napisałem - takie skutki są zostawienia komputera włączonego.

Po 2. Już usuwam post.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Nie pisz postów nie wnoszących nic do tematu. 

Po 1. To nie ja napisałem - takie skutki są zostawienia komputera włączonego.

Po 2. Już usuwam post.

Twoje konto = twoja odpowiedzialność.

I mogę pisać gdzie chcę i czy na temat czy nie.

A żeby nie było fftopu to mam pytanie Failed, znasz się na mysql ?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

@Wojtek Tak i nie, znam, ale nie lubię robić na MySQL, jakieś przyzwyczajenie do plików :>

Szkoda bo myślałem że wykonał byś jakiś poradnik na temat MySQL. No ale nic. ;)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Twoje poradniki są mało do zrozumienia, nic z nich nie kapuje, powinieneś wszystko tłumaczyć od zera, i zajebiście bardziej w szczegółach, gdzie ?dlaczego? po co ?kiedy? jak? efekt?.

Początkujący pawner nic z tego za chuj* nie zrozumie.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

To co nie było tłumaczone tłumacze :P. Zawsze możesz napisać co nie zostało wytłumaczone , jeżeli w żadnej części o tym nie było to zwróce honor.

Dokładnie wszystkiego aż za nadrze nie czytałem, lecz opisujesz że trzeba podać pozycje X, Y, Z. Lecz nigdzie nie odpisujesz jak je 'wygenerować'.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Twoje poradniki są mało do zrozumienia, nic z nich nie kapuje, powinieneś wszystko tłumaczyć od zera, i zajebiście bardziej w szczegółach, gdzie ?dlaczego? po co ?kiedy? jak? efekt?.

Początkujący pawner nic z tego za chuj* nie zrozumie.

Człowiek musiałby być naprawdę tępy, żeby tego nie zrozumieć. Ot cała ideologia.

Tak poza tym, jeśli robisz już coś po polsku to rób to po polsku a nie polsko-angielsku. Przykładami są:

publicki - neologizm?
Klient-Server
I tym podobne.

Następna sprawą jest to, abyś zamiast MySQL opisał SQLite, który jest wbudowanym modułem w SA-MP-a (szkoda ze mysql nie, kalcor is shit).

Poradnik można ciągnąć sporo, zamiast pisać w jednym temacie wszystko na raz. Zrób w jednym, ale opisz go bardzo dobrze, podaj nam swoje sytuacje z życia czyli doświadczenia. Jeżeli już robisz poradnik to przynajmniej porządnie, a nie na odpierdziel.

Branoc.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

  • Przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×