Skocz do zawartości

Mr_Auto

Użytkownik
  • Zawartość

    4183
  • Rejestracja

  • Ostatnia wizyta

  • Wygrane w rankingu

    19

Zawartość dodana przez Mr_Auto

  1. Mr_Auto

    Szukam mapy RP

    Nie wiem gdzie się podział poprzedni temat wiec piszę nowy, tu możecie pisać prośby o gamemody RP @down ja żadnego gamemoda nie będę robił/szukał wiec nie zwracaj się z prośba do mnie tylko ogólnie
  2. Mr_Auto

    Google tłumacz

    Wklejamy tutaj teksty przetłumaczone przez google błędnie, idiotycznie, według wzoru: Tekst pierwszy, jeśli nie polski z tłumaczeniem Tekst drugi jeśli nie polski z tłumaczeniem oczywiście zacznę, tłumaczenie z pl. na ang. 1. "w mojej opinii to powinno być niemożliwe" 2. "in my opinion it should be possible" 2. "w mojej opinii powinno być możliwe"
  3. Mój prosty system vip'a Komendy: /dajvipa [id gracza] - daje vipa (wysyła do gracza dialog z prośbą o podanie hasła) /zabierzvipa [id gracza] - zabiera vipa /dajvipanick [nick] [hasło] - daje vipa na nick i hasło (po prostu wrzuca je do pliku) /zabierzvipanick [nick] - usuwa nick wraz z jego hasłem z pliku Gdy gracz dostał vip'a zapisuje się w pliku jego nick i hasło, gdy gracz o zapisanym nick'u wejdzie na serwer wyświetla mu dialog z prośbą o podanie hasła, po podaniu poprawnego hasła gracz zostaje zalogowany by sprawdzić czy gracz ma konto vip dajemy: if(GetPVarInt(playerid, "vip")) to tyle, systemu używam od dłuższego czasu i nie miałem z nim problemów Wymagany do pracy jest plugin YFS DOWNLOAD (.pwn + .amx) (dorzuciłem color.inc jak by ktoś nie miał) gdyby ktoś chciał edytować system wymaga mojego tfile: http://pawno.pl/index.php?topic=620.0
  4. Mr_Auto

    [DM]System gangów v1.0

    Napisałem taki dość prosty system gangów, taki typowy jaki można spotkać na serwerach DM komendy: /gang - wyświetla komendy /gang [] [] [] ... /gang create [nazwa] - tworzy gang /gang out - opuszczasz gang /gang stats - statystyki gangu /gang zapr [id gracza] - zapraszasz do gangu /gang members - lista członków twojego gangu /gang members [id/nazwa gangu] - lista członków danego gangu /gang money - wyświetla komendy kasy gangu /gang money [] /gang money get - pobiera daną ilość pieniędzy z kasy gangu (GUI) /gang money give - wpłaca daną ilość pieniędzy do kasy gangu (GUI) /gang lider - dla członków wyświetla na czacie nick i id lidera gangu, dla lidera lista komend /gang lider [] /gang lider rozwiaz - rozwiązuje gang /gang lider kick [id gracza] - wyrzuca gracza z gangu /gang lider zmiana [id gracza] - lider zamienia się z danym członkiem gangu, lider zostaje członkiem, a członek gangu liderem /gang lider ankieta - admin tworzy ankietę w gagnu lub informację w gui /gangs - lista gangów wraz z ich id /g [tekst] - czat gangu /zprzyjmij - komenda dla gracza by przyjąć zaproszenie do gangu skrypt ma też możliwość konfiguracji w define, można wybrać czy tylko lider może zapraszać do gangu czy wszyscy oraz co ma się stać gdy lider opuści serwer wszelkie limity (ilość gangów/długość nazwy gangu/ilość członków gangu) dałem także w define także id dialogów GUI wyciągnąłem w define na początek skryptu by można je łatwo zmienić DOWNLOAD (.pwn + .amx) UWAGA: nie miałem czasu przetestować wszystkich funkcji/komend więc mogą być błędy, w razie zauważenia proszę napisać w tym temacie
  5. 1. Jak zmienić napis gdy źle wpiszemy komendę ? wyszukujemy public OnPlayerCommandText(playerid, cmdtext) pod wszystkimi komendami powinien być return 0; (chyba że mapę robił kiepski skrypter lub ten napis jest już zmieniony) i zamiast 0; dajemy SendClientMessage(playerid,0xFF0000AA,"Nie ma takiej komendy!"); całość: było return 0; teraz jest return SendClientMessage(playerid,0xFF0000AA,"Nie ma takiej komendy!"); UWAGA: można stosować tylko w Gamemodach (mapach) jeśli chcecie coś bardziej skomplikowanego np. w tekście treść komendy to usuwamy return 0; a dajemy: else { new str[100]; //tablica format(str,sizeof(str),"Komenda %s nie istnieje",cmdtext); //formatowanie tekstu i zapis do tablicy SendClientMessage(playerid,0xFF0000AA,str); //wysyłanie z formatowanego tekstu do gracza } Uwaga: jeśli używacie zwykłego systemu komend + strtok to w kodzie powyżej zmieńcie cmdtext na cmd, ponieważ cmdtext to tekst całej komendy (np. w komendzie /report będzie id oraz powód) a cmd to tylko sama komenda od / do spacji public OnGameModeInit() { UsePlayerPedAnims(); lub public OnFilterScriptInit() { UsePlayerPedAnims(); public OnGameModeInit() { SetGameModeText("Super Mapa"); + mały sposób, jeśli macie mapę w amx a chcecie zmienić jej nazwę to robimy timer w OnFilterScriptInit() (w skrypcie) np. public OnFilterScriptInit() { SetTimer("zmiana",2000,0); i nowy public forward zmiana(); public zmiana()return SetGameModeText("Super Mapa"); jest to konieczne ponieważ mapa wczytuje się po skryptach i jeśli ma tam zmianę nazwy to ją zmienia, oczywiście jest też prostszy sposób, po włączeniu serwera wchodzimy na niego i używamy komendy rcon AntyDeAMX() { new amx[][] ={"Unarmed (Fist)","Brass K"}; #pragma unused amx } Nie można jej dodawać wewnątrz publick'ów czy innych funkcji I teraz w OnGameModeInit() lub OnFilterScriptInit() (zależy czy to mapa czy skrypt) dodajemy AntyDeAMX(); przykład: OnGameModeInit() { AntyDeAMX(); i to na tyle, AntyDeAMX() można też dodać w innych public'kach zamiast w OnGame... ale najlepiej właśnie tutaj OnGameModeInit() { AddPlayerClass(29,0,0,0,0,0,0,0,0,0,0); CreateObject(3108, 1513.2, -1169.7, 23.117, 0, 0, 0); CreatePickup(342, 2, 2502.5075683594, 2823.6154785156, 11.026031494141); CreateVehicle(522,-1826.2233886719,542.88024902344,149.8125,0,-1,-1,100); new string[60]; format(string, 60, "Gracz %s wszedł na serwer", PlayerName(playerid)); SendClientMessageToAll(KOLOR, string); po kolei, new string tworzy tablicę do zapisu znaków, potem format tworzy tekst wklejając do niego nick gracza (potrzebna funkcja PlayerName, można znaleźć np. w Przydatne Funkcje), a potem wysyłamy wiadomość do all graczy, w miejsce KOLOR trzeba podać kolor w wartości HEX Mamy już napis gdy gracz wchodzi na serwer, teraz przechodzimy do OnPlayerDisconnect new string[60]; switch(reason) { case 0: format(string, 60, "Gracz %s opuścił serwer (Crash)", PlayerName(playerid)); case 1: format(string, 60, "Gracz %s opuścił serwer", PlayerName(playerid)); case 2: format(string, 60, "Gracz %s opuścił serwer (Kick/Ban)", PlayerName(playerid)); } SendClientMessageToAll(KOLOR, string); new string jak zawsze, potem używamy switch by sformatować tekst zgodnie z typem opuszczenia serwera przez gracza (reason przyjmuje wartości: 0 - gdy gracz straci połączenie z serwerem, 1 - gdy normalnie wyjdzie np. /q, 2 - gdy zostanie wyrzucony przez serwer), na koniec ten sformatowany tekst wysyłamy, oczywiście trzeba podać KOLOR Float:DrawDistance = 0.0 powinno być dwa razy (2 funkcje) wystarczy zmienić to na: Float:DrawDistance = 150.0 150 to odległość w jakiej widzimy obiekt, najlepiej nie przesadzać Teraz wystarczy ponownie prze-kompilować mapę/skrypt (F5), można to też zrobić nico trudniejszym sposobem, po prostu za każdym obiektem dopisujemy wartość np. 150.0 czyli ręcznie ustawiamy odległość widzenia Dla tych który są tak słabi że nawet nie umieją jednej rzeczy w pliku zmienić a_objects.inc w załączniku 8. Dlaczego obiekty się obracają? W wersji 0.3d wszedł update który dodaje możliwość obracania obiektu tak samo jak przemieszczania go, problem w tym że nie dodano nowej funkcji przez co każdy obiekt podczas używania MoveObject powraca do rotacji 0.0,0.0,0.0 Problem łatwo rozwiązać, wystarczy skopiować obrót obiektu, zaznaczone na czerwono: i dokleić je do linijki MoveObject, linijka przed wygląda: a po doklejeniu powinna wyglądać tak: 2. Jak zmienić animacje graczy na te z gry jednoosobowej? Służy do tego jedna mała funkcja UsePlayerPedAnims(); wystarczy wkleić ją w public OnGameModeInit() lub OnFilterScriptInit() jeśli wklejamy to na początku to wyglądać będzie to tak: 3. Jak zmienić nazwę naszej mapy? Służy do tego funkcja SetGameModeText, jeśli mapa ma już swoją nazwę to w kodzie mapy wyszukujemy po prostu SetGameModeText i zmieniamy tą nazwę, jeśli nie ma to w OnGameModeInit() dajemy tą funkcję, przykład: 4. Jak zabezpieczyć mapę/skrypt przed DeAmx (programem do zmiany .amx na .pwn)? Bardzo proste, dodajemy tylko do mapy jedną małą funkcję: 5.Gdzie wklejać obiekty, pojazdy, pickup'y oraz nowe skiny? Otóż pojazdy tworzymy dla całego serwera, nie dla gracza dlatego najlepiej wklejać je w OnGameModeInit() lub OnFilterScriptInit() ponieważ te dwa public'ki wykonują się zanim ktokolwiek będzie mógł wejść na serwer, przykład: 6. Jak dodać informację o wejściu/wyjściu gracza na/z serwera Użyjemy do tego 2 funkcji publicznych: czyli teraz w OnPlayerConnect dajemy to: 7. Dlaczego mam przezroczyste obiekty i jak to naprawić? W najnowszej wersji sa:mp dodano nowy argument przy tworzeniu obiektów, a mianowicie odległość widzenia: Łatwo to naprawić jeśli nie używacie streamer'a, po po prostu otwórzcie plik a_objects.inc znajdziecie go w Pawno/include (otworzyć można notatnikiem) Teraz wyszukujemy coś takiego:
  6. Jest to skrypt dzięki któremu po śmierci gracza wypadają z niego bronie w formie pickup'ów, jeśli nikt ich nie podniesie znikną po minucie, skrypt zapisuje ilość amunicji jaką miała dana broń gracza (niektóre tego typu skrypty dawały określoną ilość amunicji za każdym razem) Daję format PWN z dość dokładnym opisem więc nie powinno być problemu z modyfikacją Download Uwaga: na serwerach gdzie nieustannie jest walka, gdzie ciągle ludzie giną i jest ich dość dużo polecam zmienić czas zniknięcia pickup'ów by czasem nie zapełniły limitu pickup'ów (tyczy się to serwerów raczej z ilością graczy 500 więc to tylko taka informacja)
  7. Mr_Auto

    Przydatne komendy

    Komendy /lock i /zaparkuj do sa:mp 0.3 Opiszę jak zrobić te dwie komendy do sa:mp, /LOCK na górze mapy: new lock[MAX_VEHICLES][2]; zmienna do której będziemy przypisywać 1 lub 0 by sprawdzić czy pojazd jest zamknięty komenda /lock (taka trochę na szybko) if (strcmp(cmdtext, "/lock", true) == 0) { if(IsPlayerInAnyVehicle(playerid)) { lock[GetPlayerVehicleID(playerid)][0]=1; lock[GetPlayerVehicleID(playerid)][1]=playerid; SendClientMessage(playerid, Fioletowy, "Zamknąłeś swój pojazd"); } return 1; } chyba wszystko wiadomo, standardowy początek komendy, potem sprawdzanie czy gracz jest w jakimkolwiek pojeździe, jeśli tak to do zmiennej lock a dokładniej do numeru tablicy o id pojazdu przypisujemy jeden i wysyłamy tekst do gracza, komenda /unlock wygląda identycznie tylko zamiast: lock[GetPlayerVehicleID(playerid)][0]=1; lock[GetPlayerVehicleID(playerid)][1]=playerid; dajemy: lock[GetPlayerVehicleID(playerid)][0]=0; lock[GetPlayerVehicleID(playerid)][1]=-1 By w ogóle komenda nam zadziałała to przechodzimy do public'ka OnVehicleStreamIn i wklejamy tam: if(lock[vehicleid][0]==1 && lock[vehicleid][1]!=forplayerid) { SetVehicleParamsForPlayer(vehicleid, forplayerid, 0, 1); } Teraz by gracze którzy widzieli nasz pojazd w momencie wpisania komendy /lock też nie mogli do niego wejść potrzebujemy kodu w public'ku OnPlayerEnterVehicle if(lock[vehicleid][0]==1 && lock[vehicleid][1]!=playerid) { SetVehicleParamsForPlayer(vehicleid, playerid, 0, 1); } Uwaga!: jeśli ktoś będzie chciał nam wtedy ukraść pojazd prawdopodobnie za pierwszym razem wyrzuci nas z pojazdu ale mimo tego że niby na chwilę wejdzie do pojazdu to u niego odtworzy się animacja szarpania za klamkę Końcowe udoskonalenia: Jeśli pojazd po wybuchu/respawnie ma już nie być otwarty to dajemy tak w public OnVehicleSpawn: lock[vehicleid][0]=0; lock[vehicleid][1]=-1; Jeśli pojazd po wyjściu gracza który go zamknął ma stać się otwarty to przechodzimy do public'ka OnPlayerDisconnect i dajemy tam: for(new i=0; i<MAX_VEHICLES; i++) { if(lock[i][1]==playerid) { lock[i][0]=0; lock[i][1]=-1; } } Uwaga może nieco obciążyć serwer, niestety :/ Ostatnia rzecz którą należy wykonać na wszelki wypadek to w publick'u OnGameModeInit lub OnGameModeInit dajemy taki kod: for(new i=0; i<MAX_VEHICLES; i++) { lock[i][1]=-1; } DOWNLOAD(.pwn ps. zapomniałem w komendzie /unlock zmienić tekst) /ZAPARKUJ Uwaga: często na serwerach po zaparkowaniu zamyka się pojazd więc opiszę jak zrobić by tylko kierowca mógł wsiadać do zaparkowanego wozu. Na górze mapy robimy nową zmienną z tablicą new zaparkowany[MAX_VEHICLES][2]; oraz 4 zmienne z tablicami do których przypisywać będziemy współrzędne new Float:saveX[MAX_VEHICLES], Float:saveY[MAX_VEHICLES], Float:saveZ[MAX_VEHICLES], Float:saveA[MAX_VEHICLES]; Komenda: if (strcmp(cmdtext, "/zaparkuj", true) == 0) { if(IsPlayerInAnyVehicle(playerid)) { new veh=GetPlayerVehicleID(playerid); zaparkowany[veh][0]=1; zaparkowany[veh][1]=playerid; GetVehiclePos(veh, saveX[veh], saveY[veh], saveZ[veh]); GetVehicleZAngle(veh, saveA[veh]); SendClientMessage(playerid, Fioletowy, "Zaparkowałeś swój pojazd"); } return 1; } komenda odparowująca powinna być taka sama, bez linijek GetVehiclePos i GetVehicleZAngle a z kodem: zaparkowany[veh][0]=0; zaparkowany[veh][1]=-1; Teraz przechodzimy do public'ka OnVehicleSpawn: if(zaparkowany[vehicleid][0]==1) { SetVehiclePos(vehicleid, saveX[vehicleid], saveY[vehicleid], saveZ[vehicleid]); SetVehicleZAngle(vehicleid, saveA[vehicleid]); } Teraz jeśli pojazd po wybuchu ma się już nie pojawiać w miejscu gdzie zaparkowano pojazd przechodzimy do public'ka OnVehicleDeath: zaparkowany[vehicleid][0]=0; zaparkowany[vehicleid][1]=-1; po nim odtworzy sie OnVehicleSpawn ale że pojazd w tablicy [0] ma wartość zero pojawi się on w miejscu gdzie został stworzony Kod by inni gracze nie mogli wsiadać do pojazdu zaparkowanego przez kogoś innego: (kod prawei taki sam jak w komendzie /lock) public OnVehicleStreamIn: if(zaparkowany[vehicleid][0]==1 && zaparkowany[vehicleid][1]!=forplayerid) { SetVehicleParamsForPlayer(vehicleid, forplayerid, 0, 1); } oraz OnPlayerEnterVehicle: if(zaparkowany[vehicleid][0]==1 && zaparkowany[vehicleid][1]!=playerid) { SetVehicleParamsForPlayer(vehicleid, playerid, 0, 1); } By po wyjściu gracza z serwera jego pojazd spawnował się z powrotem tam gdzie go utworzono: public OnPlayerDisconnect for(new i=0; i<MAX_VEHICLES; i++) { if(zaparkowany[i][1]==playerid) { zaparkowany[i][0]=0; zaparkowany[i][1]=-1; } } Uwaga może nieco obciążyć serwer, niestety :/ I dla bezpieczeństwa w OnGameModeInit lub OnFilterScriptInit for(new i=0; i<MAX_VEHICLES; i++) { zaparkowany[i][1]=-1; } DOWNLOAD (.pwn)
  8. Przedstawiam wam skrypt dzięki któremu admin może tworzyć dowolną ilość pojazdów na mapie oraz je usuwać a także zapisywać do pliku, co skutkuje tym że zapisany w pliku pojazd po restarcie serwera stworzy się na nowo (zrespawnuje) Komendy: /veh - wyświetla nam GUI z możliwością wyboru sposobu odnalezienia wybranego modelu pojazdu, możemy wybrać wpisanie id lub nazwy (lub fragmentu nazwy) pojazdu lub też wybranie go z listy pojazdów (lista podzielona jest na 9 kategorii) /veh [id/nazwa/fragment/nazwy] - to samo co powyżej jak widać tylko bez GUI /getout - komenda napisana z myślą o pojazdach RC, pozwala wyjść z nich (normalny enter nie działa, chyba ze ma się napisany specjalny kod na to) /vehsave - czyli zapisanie naszego pojazdu do pliku, jeśli dany pojazd już na mapie zapisaliśmy otrzymamy dwie opcje do wyboru w GUI, zmiana pozycji zapisanej w pliku na tą lub też stworzenie takiego samego nowego pojazdu w tej pozycji, w ostatnim przypadku stary pojazd jest respawnowany, w reszcie usuwany i po 3 sekundach jest tworzony nowy (zabezpieczenie dla bugu pociągami). Nasz pojazd po zapisie usuwa się i tworzy co oznacza że po np. respawnie aut nie wróci na miejsce gdzie został stworzony (/veh) ale wróci do tej zapisanej pozycji /dveh - usuwa pojazd, mamy 3 opcje do wyboru, usunięcie pojazdu tylko z gry, tylko z pliku lub też i z gry i z pliku (oczywiście w GUI) /vehinf - prosta komenda dająca nam info czy ten pojazd jest zapisany w pliku czy też nie (np. stworzono go komendą /veh ale nie zapisano, lub pochodzi z innego systemu/skryptu/gamemodu) /vehopt - otóż po usunięciu pojazdu z pliku by skrypt zachował stabilność po linijce pojazdu zostaje puste pole (pojazdy nie są jeden pod drugim tylko jest linijka odstępu), oczywiście to niczemu nie szkodzi jednak duża ilość może powodować wolniejsze wczytywanie się pojazdów na starcie serwa, ta komenda to naprawia, przy okazji respawnując wszystkie pojazdy zapisane w pliku Skrypt zajmuje ID dialogu od 295 do 308 włącznie Skrypt nie zapisuje kolorów pojazdów Skrypt domyslnie wymaga dwóch pluginów sscanf oraz directory Skrypt wykorzystuje include tfile (wymagany tylko do kompilacji) Jeśli nie chcesz by skrypt wymagał pluginu directory usuń z linijki //#define DO_NOT_USE_PLUGINznak komentarza czyli //Zalecam jednak korzystać z pluginu, poprawia on optymalność operacji na pliku DOWNLOAD (.pwn + .amx) Download wersja small (bez komend, GUI itp. tylko ładuje pojazdy) Pomysły na rozwój: - zmiana plików na sqlite - dodanie zapisu koloru pojazdów - teleport do pociągu gdy go tworzymy (obecnie nawet nas do nich nie wsadza w przeciwieństwie od innych aut) Proszę o oceny, komentarze, opinie na temat pomysłów na rozwój, może jakiś jeszcze pomysły
  9. Bot zaczyna trasę w SF, potem zatrzymuje się na każdym przystanku po za podziemnym przystankiem w LS, bot jeździ tramwajem, można do niego wejść jako pasażer lub stanąć na dachu: Doawnload (sam plik bota daję w .amx ale plik podłączający bot'a do serwera .pwn) instrukcja instalacji w środku:
  10. Mr_Auto

    Odpowiedzi na proste pytania

    char jest, ale jest bezsensowne
  11. Chciałbym wam pokazać jak zacząć pisać swoją własną, może pierwszą mapę/skrypt Na początku podkreślę że w SAMP nie ma czegoś takiego jak mapy i powinno się raczej stosować nazwę gamemod (czyli mod gry), jednak mapa brzmi bardziej po polsku dlatego też będę używał tego wyrazu (także dlatego że łatwiej się go odmienia) czyli uruchamiamy pawno, klikamy NEW, powinnyśmy mieć dość duży kawałek kodu, teraz ważne info, nie korzystajcie z wstępu sa:mp, tam jest jakieś #if defined #endif na co to komu ... Ok, co my w ogóle w tej chwili mamy? są to funkcje publiczne wywoływane przez serwer gdy zdarzy się jakaś akcja (ktoś wejdzie/wyjdź, umrze etc.) nie będę ich opisywał, opisy znajdziecie tu: Callbacks Na razie jedyną funkcją w naszej mapie/skrypcie jest print("Test");jest to jedna z podstawowych i prostszych funkcji która wyświetli nam tekst w konsoli, najlepiej dać tam info że dana mapa się załadowała poprawnie powinienem powiedzieć też o funkcji od której zapewne pochodzi powyższa, otóż printf("Start Gamemodu, wersja: %f", 1.0);jest to praktycznie to samo lecz możemy tutaj dawać dodatkowe argumenty by wyświetlić np. liczbę w konsoli, bardzo przydatna do testowania kodu np. gdy chcemy się dowiedzieć dlaczego nasz warunek nie działa i chcemy wyświetlić jakąś liczbę Mapa: Oczywiście najpierw musi być pomysł, ogólnie trudno opisać ogólnie mapę gdyż każdy opis jest inny i zależy od typu jaki wybierzemy, powiem tylko o ważniejszych funkcjach, otóż w public OnGameModeInit dajemy wszelkie podstawowe funkcje które wykonają się raz zaraz po uruchomieniu serwera, możemy tutaj np. tworzyć potrzebne pliki których będziemy potem używać, ustawiać wszelkie nazwy, dawać wszystkie obiekty,pojazdy,pickup'y,skiny etc. Do podstawowych rzeczy które prawie zawsze tutaj dajemy to: SetGameModeText("Mode DM");funkcja która ustawia nam nazwę która pokazana jest w liście serwerów w tabelce Modedajemy tu najczęściej typ serwera, nazwę mapy, info o wykonazwy DisableInteriorEnterExits();funkcja usuwa nam pozostałości po singlu, a mianowicie drzwi, usuwa także kaiserów i inne boty podające nam coś, umożliwiające kupno czegoś w sklepie UsePlayerPedAnims();Funkcja używana prawie na każdym serwerze na którym liczy się chodzenie, otóż zmienia ona wszystkim skinom animacje chodzenia na te od naszego głównego bohatera CJ, dzięki temu bieg wygląda bardziej realistycznie EnableStuntBonusForAll(0);funkcja która usuwa nam inną pozostałość, otóż kasę za skoki/triki etc.uwaga niektóre mody do gta jak się dowiedziałem mogą mimo tej funkcji dawać pieniądze za skoki, dlatego zawsze warto jest mieć anty mone hack SetWeather(0);Naprawdę polecam używać tej funkcji w każdej mapie, służy do ustawiania id pogody, według samp każda podstawowa mapa ma pogodę o id 10 ale to nie prawda gdyż ma pogodę o id 0 (tak jak na tym przykładzie), używając tej funkcji tutaj dajecie graczom już jakieś info że wasz serwer to nie jakiś tam przeciętniak, oczywiście to tylko mój punkt widzenia SetWorldTime(12);funkcja ustawiająca czas na serwerze, domyślnie jest zawsze 12, chciałbym tylko powiedzieć ze dla nieznających się na zegarku godziny są od 0 do 23, to znaczy nie ma czegoś takiego jak godzina 24! SendRconCommand("mapname San Andreas");coś co dla mnie powinno być osobną funkcją, mianowicie zmiana nazwy w tabelce Map, ogólnie funkcja SendRconCommand ma więcej zastosowań, zmieniamy tutaj tylko San Andreas, mapname zostawiamy w spokoju SetGravity(Float:gravity);coś dla bardziej zaawansowanych, ustawienie grawitacji, nieraz na serwerach RP jest ona zmieniana by skoki wyglądały bardziej realistycznieUwaga!: dużo admin scriptów etc. wmawia że domyślna grawitacja to 8, to nie prawda gdyż domyślna to 0.008 gdyby dać 8 all gracze po spawnie by umierali, nie było by pojazdów lub nawet serwer mógł by mieć crash SetNameTagDrawDistance(Float:distance);ustawiamy odległość w jakiej będziemy zauważać nick gracza DisableNameTagLOS();jeśli użyjemy tej funkcji to jeśli gracz znajdzie się w obszarze w którym możemy zobaczyć jego nick to nie ważne czy jest w budynku, czy za jakimś drzewem i tak zobaczymy jego nick ShowNameTags(0);wyłącza pokazywanie nad graczami ich nick'ów oraz paska hp ShowPlayerMarkers(0);wyłącza pokazywanie kwadracików graczy na mapie SetTeamCount(4);ustawia liczbę drużyn na mapie, przydatne do map TDM/RP, ogólnie nie jest wymagane stosowanie tego jeśli mamy używać drużyn, to tylko takie jakby usprawnienie, jeśli mi się dobrze wydaje to pierwsza drużyna ma id 0 dlatego jeśli ostatnia ma np. 3 to dajemy tak jak na przykładzie 4 inne rzeczy których opisywać nie będę: AddPlayerClass AddPlayerClassEx AddStaticPickup CreatePickup CreateVehicle AddStaticVehicle AddStaticVehicleEx CreateObject W tym publick'u powinniśmy także tworzyć wszystkie TextDraw'y, 3DText'y idt. Skrypt: ogólnie nie powinniśmy dawać tutaj nic co napisałem wyżej, chyba że robimy skrypt ponieważ nie mamy .pwn mapy ale trzeba pamiętać jedno, że najpierw są wczytywane skrypty i ich funkcje a dopiero potem mapa, np. w skrypcie ustawimy godzinę 10, a w mapie 12 to na serwerze będzie godzina 12 raczej nie ma tu funkcji które powinienem omówić, skrypt ma być raczej dodatkiem, większość rzeczy powinniśmy wklejać w mapę powiem tylko jeszcze ogólnie do obydwu: Jeśli zamierzacie wydać tą mapę w .amx lub dać ja komuś do kogo pewności nie macie dobrze jest zabezpieczyć plik .amx przed programem DeAmx (zmieniającym .amx z powrotem na .pwn) ogólnie zabezpieczenie to jest banalne, gdzieś po za naszymi wszelkimi funkcjami, np. na samym końcu mapy/skryptu dajemy to: AntyDeAMX() { new amx[][] = {"Unarmed (Fist)", "Brass K"}; #pragma unused amx }oraz w OnGameModeInit lub OnFilterScriptInit (zależy czy mapa czy skrypt) dodajemy: AntyDeAMX();(najlepiej na początku) i już jesteśmy zabezpieczenie przed jakimiś neokidami Cóż mogę więcej dodać? często korzystajcie z Wiki pawno.pl dobrze przemyślcie każdy swój kod starajcie się układać kod, próbować optymalizować kod etc.
  12. Chciałbym wszystkich który uwieszają tutaj swoje skrypty by nie wybierali serwisów hostujących typu speedyshare.com przeklej.pl sendspace.pl i innych mało znanych serwisów, zwłaszcza zagranicznych, chodzi tutaj głównie o to że serwisy tego typu usuwają po jakimś czasie pliki które nie maja jakieś tam danej liczby pobrań, a jak wiadomo skrypty nie są raczej rozchwytywanym towarem odradzam też umieszczania plików na megaupload, rapidshare i innych serwisach które ograniczają możliwość pobierania z nich (np. czasowo) gdyż jest uciążliwe dla pobierających i całkowicie bez sensu ale w takim razie gdzie wrzucać skrypty? pierwszą najłatwiejszą opcją są załączniki, wystarczy podczas wysyłania postu/tematu kliknąć napis pod ramką do tekstu "Załączniki i opcje dodatkowe" klikamy przycisk "Przeglądaj..." tam dostępny i już, możemy też dodać kilka plików klikając "(więcej załączników)" no i w końcu opcja dla wydających skrypt również w .pwn, ciężko jest wkleić cały tekst do postu ponieważ ogranicza nas maksymalna ilość znaków lecz istnieją serwisy dzięki którym możemy wrzucić nasz kod praktycznie bez ograniczeń długości http://pastebin.com/ mamy tam też opcję by kodu nie można znaleźć w serwisie, trzeba mieć link do niego, jeśli wrzucamy taki kod polecam też wybrać język by kod był kolorowy, jeśli nie znajdziemy naszego PAWN zawsze możemy wybrać C/C++ który jest prawie zawsze w tego typu serwisach a ma bardzo podobny styl kolorowania fragmentów Myślę że pomogłem i następnym razem wrzucając plik wybierzecie jeden z polecanych tu sposobów ;)
  13. Przedstawiam wam mój konwerter napisany w języku PAWN działanie jest bardzo proste, wrzucamy plik o rozszerzeniu .map do folderu scriptfiles, uruchamiamy skrypt i w konsoli piszemy: konvert nazwa-mapy.mapczyli np. jeśli do scriptfiles wrzuciliśmy plik mapka.map to piszemy w konsoli konvert mapka.mapSkrypt konwertuje mapy z wersji MTA Race 1.0 (dokładnie sam nie wiem, wszystkie mapy z napisem na początku MTA Race 1.0) oraz MTA DM 1.0 Po skonwertowaniu w folderze scriptfiles powinien znaleźć się plik z nazwą naszej mapy z rozszerzeniem .txt czyli np. mapka.txt Skrypt pisany całkowicie przeze mnie, nie zezwalam na rozpowszechnianie na innych forach itp. bez mojej zgody DOWNLOAD: [PWN + AMX] P.S w wersji Race skrypt konwertuje także godzinę i pogodę, CP ze względu na ich używanie konwertuje w postaci: {X, Y, Z},W razie jakichkolwiek problemów pisać w tym temacie
  14. Mr_Auto

    W jakim pliku?...

    Możesz A) zrobic to za pomocą C++ pisząc po prostu plugin, ale serwer i tak będzie wymagać pliku pwn i będzie gowykonywac, tyle ze nie będzie tam żadnych funkcji po za odsyłaniem do pluginu, jednek na myśl przychodzi raczej pisanie wtedy w C++ (gamemod jako plugin) a nie przesyłanie tego dalej B) możesz pobawić sie w dekodowanie plików sa:mp ale, po pierwsze taki serwer może nie działać dobrze (chyba za naprawdę dobrze sie na tym znasz) oraz taki serwer będzie 'nielegalny' ponieważ autor sa:mp nie udostępnia kodu źródłowego wiec było by to naruszenie praw autorskich zapewne Rada: odpuśc sobie, sa:mp to gówno a jego twórca idiota, jak chcesz się pobawić w takie rzeczy lepiej zobacz MTA, jest on na licencji open soucre więc bez problemu zrobisz to co chcesz, a może nawet znajdziesz pomoc na jakiś forach o MTA
  15. Najpierw potrzebujemy nagrania w formacie .rec, najprostszy sposób to użycie skryptu npc_record komendy: po zakończeniu nagrywania (/stoprec) w pliku scriptfiles znajdziemy plik nazwa.rec, przenosimy go do folderu npcmodes/recordings Teraz uruchamiamy program PAWNO, klikamy NEW (ikonka białej karki papieru), kasujemy wszystko by została nam tylko pierwsza linijka oznaczona jako 1. Na górze dajemy: #include <a_npc> jest to includ do stosowania tylko dla bot'ów następnie potrzebujemy standardowej linijki main, można w niej wpisać informacje w print/printf że np. uruchomiono bota, ale można zostawić tak jak jest: main()return; Teraz musimy uruchomić nagranie, jeśli to bot który będzie biegać (chodzić) to będziemy używali public OnNPCConnect(myplayerid), czyli tak: public OnNPCConnect(myplayerid) { StartRecordingPlayback(PLAYER_RECORDING_TYPE_ONFOOT,"nazwa"); } wystarczy zmienić "nazwa" na nazwę nagrania, możemy też użyć public OnNPCSpawn() , wtedy będzie to bardziej dokładne Uwaga! nazwa nagrania może być inna niż tego pliku który właśnie tworzymy, funkcja StartRecordingPlayback uruchamia odtwarzanie zachowań bota zapisanych w pliku .rec Jeśli nasz bot będzie się poruszać jakimś pojazdem start powinniśmy dać dopiero gdy wejdzie do pojazdu, czyli OnNPCEnterVehicle public OnNPCEnterVehicle(vehicleid, seatid) { StartRecordingPlayback(PLAYER_RECORDING_TYPE_ONFOOT,"nazwa"); } tu tak samo jak wyżej, nazwa zmieniamy na nazwę pliku z nagraniem (bez końcówki .rec) Powinniśmy tez ustawić co ma się dziać jeśli bot opuści pojazd (np. przez przypadek teleportowaliśmy naszego bota do nas), czyli public OnNPCExitVehicle public OnNPCExitVehicle() { StopRecordingPlayback(); } po taki kodzie jeśli bot opuści pojazd zatrzyma się odtwarzanie nagrania i nie będzie się ruszał Teraz musimy określić co ma się dziać z botem po zakończeniu nagrania/ po wykonaniu swojej pracy, służy do tego public OnRecordingPlaybackEnd, ja dodam by ponownie odtworzył trasę public OnRecordingPlaybackEnd() { StartRecordingPlayback(PLAYER_RECORDING_TYPE_DRIVER,"nazwa"); } w miejsce nazwa wpisujemy tak jak wyżej, jest to rozwiązanie dla bota który jeździ pojazdem, jeśli ma to być bot który np. biega to zmieniamy: PLAYER_RECORDING_TYPE_DRIVER na PLAYER_RECORDING_TYPE_ONFOOT teraz zapisujemy i kompilujemy plik w folderze npcmodes Wszystkie funkcje możecie znaleźć w a_npc, wymienię kilka ważniejszych: StartRecordingPlayback - to już powiedziałem, uruchamia nagranie z pliku .rec StopRecordingPlayback - zatrzymuje nagranie (aktualne, nie można odtworzyć 2 nagrań na raz) PauseRecordingPlayback - zatrzymuje (na chwilę, pauzuje) nagranie ResumeRecordingPlayback - wznawia nagranie zatrzymane powyższą funkcją Końcowe objaśnienia co do tego pliku Sam plik bez żadnych public'ków itp. z samym #include <a_npc> i main to już jest bot !! tyle że nie będzie on wykonywał żadnych ruchów (coś jak boty w kasynach czy sklepach), bot nie ma przypisanego pliku .rec dlatego możemy dla jednego bota nagrać kilka akcji i potem odtwarzać, ten plik to tylko konfiguracja zachowania, wszystkie cechy zewnętrzne typu wygląd itp. nadamy mu dopiero w zwykłym skrypcie czy mapie Konfiguracja bota: (ustawienia na serwerze) otóż ludzie myślą że do bota potrzeba specjalnego skryptu... otóż wcale nie, powiem więcej lepiej jest dodać bota w mapce niż osobnym skrypcie bo najprawdopodobniej i tak mapę nieco będziemy musieli przerobić. Dlatego opiszę jak bota dodać do mapy, na początek przechodzimy do public'ka OnGameModeInit lub OnFilterScriptInit, musimy podłączyć naszego bota i nadać mu jakąś nazwę (nick) ConnectNPC("Nick","nazwa"); w miejsce Nick, wpisujemy jaki ma mieć nick nasz bot, najlepiej wpisać coś prostego, w miejsce nazwa wpisujemy nazwę pliku .amx (nie nagrania !! ) który utworzyliśmy w folderze npcmodes Teraz w public'ku OnPlayerConnect na początku dajemy taki kod: if(IsPlayerNPC(playerid)) return 1; nie jest to wymagane jeśli skrypt jest tylko dla bota, dzięki temu np. bot nie zostanie wyrzucony przez system rejestracji itp. polecam dodać taką formułkę do wszystkich skryptów które robią jakieś operacje na graczach Następnie public OnPlayerRequestClass if(IsPlayerNPC(playerid)) { new playername[MAX_PLAYER_NAME]; GetPlayerName(playerid, playername, sizeof(playername)); if(!strcmp(playername, "Nick", false)) { SetSpawnInfo(playerid,69,255,1462.0745,2630.8787,10.8203,0.0,0,0,0,0,0,0); } return 1; } po kolei, sprawdzamy czy gracz jest botem (NPC) jeśli tak tworzymy zmienną z tablicą, pobieramy imię gracza/nick i przypisujemy go do tej zmiennej, sprawdzamy (if) czy imię/nick gracza zgadza się z "Nick" (należy podaj dokładnie taką samą nazwę) dałem tu false by sprawdzano także wielkość liter (można zmienić na true, ale polecam zostawić tak jak jest) i używamy funkcji SetSpawnInfo można poczytać na wiki co oznaczają dane argumenty, i return 1; by dalsza cześć kodu była tylko dla zwykłych graczy. Uwaga: SetSpawnInfo ma argumenty X,Y,Z, jeśli bot jest kierowcą to praktycznie są to argumenty mało ważne, ale na wszelki wypadek pozycja powinna być jak najbliższa tej w której zaczęliśmy nagrywać jeżeli mamy już wybrany skin to pozostaje nam kilka rzeczy końcowych, otóż jeśli nasz bot jest kierowcą trzeba mu stworzyć pojazd, nie ma całkowicie znaczenia czy nagrywaliśmy zachowanie bota infernusem czy traktorem, bot i tak będzie jechał z nagraną prędkość itp. (nie jestem pewien ale chyba jeśli nagramy bota np. w samolocie a potem stworzymy pojazd jako samochód to bot będzie latał samochodem :P ) Co do pojazdu to standardowo, na górze mapy new pojazd; i w OnGameModeInit lub OnFilterScriptInit pojazd = AddStaticVehicle(402, 1700.7551, -1953.6531, 14.8756, 200.0, -1, -1);// LS po wsadzeniu bota do pojazdu będzie nim mógł jeździć tylko i wyłącznie bot, co więcej bot nie może wywalić gracza z pojazdu ani odwrotnie, gracz w pojeździe bota może być tylko pasażerem Ostatnia ważna część kodu to public OnPlayerSpawn (nieobowiązkowe dla botów biegających/chodzących) if(IsPlayerNPC(playerid)) { new playername[MAX_PLAYER_NAME]; GetPlayerName(playerid, playername, sizeof playername); if(!strcmp(playername, "Nick", false)) { PutPlayerInVehicle(playerid, pojazd, 0); SetPlayerColor(playerid, 0xFFFFFFFF); } return 1; } początek jest dokładnie taki sam, w miejsce "Nick" wpisujemy imię/nick bota nadany na początku, następnie mamy PutPlayerInVehicle(playerid,pojazd); czyli wrzucamy naszego bota do wcześniej utworzonego pojazdu (w tym momencie odtworzy się public w pliku bota o nazwie OnNPCEnterVehicle) i SetPlayerColor, dzięki temu bot nad głową będzie miał swój nick/swoje imię oraz id. I na koniec return 1; by reszta kodu była tylko dla zwykłych graczy Bot jest jak zwykły gracz, możemy mu nadawać animacje itp. (choć niektóre funkcje mogą nie działać np. nie jestem pewny co do zamrożenia gracza). Uwagi jeśli bot jeździ pojazdem to nie wyrzucajmy go z niego bo już go wsadzimy go z powrotem (chyba że napiszemy taką komendę), nie wiem dokładnie ale chyba można zrobić by bot był widziany jak normalny gracz (chodzi o te kolorki na radarze/mapie) za pomocą pewnej funkcji. Dodatek, funkcja zwracająca id bot'a (podajesz nazwę): FindNPC(imie[]) { new id=-1; new playername[MAX_PLAYER_NAME]; for(new i = GetMaxPlayers() - 1; i >= 0; i--) { GetPlayerName(i, playername, sizeof playername); if(IsPlayerNPC(i) && !strcmp(playername, imie, false)) { id=i; break; } } return id; } używamy tak: FindNPC("Bot") nazwa bota musi być dokładnie taka jaką nadaliśmy mu na początku (łącznie z wielkością liter) jeśli funkcja nie znajdzie bot'a o takim nick'u/imieniu zwraca -1.
  16. Mr_Auto

    Optymalność

    Dużo ludzi ostatnio pyta się o optymalność niektórych rzeczy, postaram się opisać w tym poradniku parę rzeczy które warto wziąć pod uwagę pisząc nową mapę lub poprawiając starą Na początek pomówmy o tym co warto i powinno się optymalizować Na pewno pętle, każda pętla wykonująca się około 300 lub więcej razy i wykonująca parę funkcji jest bym powiedział że nawet nie wskazana w PAWN, ale co zrobić, tylko ten język daje nam sa:mp, chcę tylko powiedzieć że kod w takich pętlach na pewno trzeba dobrze przemyśleć, co do pętli ważne też jest by nie tworzyć w nich zmiennych (new), po to pętla typu for ma sekcję na tworzenie zmiennych by je tam tworzyć (pętla while tego nie posiada ale zawsze można dać zmienną nad pętla, będzie ona działać przez całe wykonywanie pętli i dłużej) zalecam też by w warunku pętli nie używać funkcji, np. GetMaxPlayers (oczywiście cały czas mówię o pętlach wykonywujących się kilkaset lub więcej razy), później jeszcze podam przykłady optymalnych pętli dla wszystkich graczy etc. Jest jeden wyjątek, chodzi tutaj o sekcje main() OnGemeModeInit/Exit OnFilterScriptInit/Exit są one wykonywane tylko raz po uruchomieniu lub wyłączeniu dlatego nie jest zbytnio ważna optymalność w nich, najwyżej nieco dłużej będzie nam się serwer uruchamiał/wyłączał Druga rzeczą są funkcje lokalne, może ktoś zna temat y_less'a, chodzi tutaj szczególnie o rzeczy typu: stock funkcja(a) { return funKcja2(a, "xyz", 1.3); } (to tylko przykład) jak widać funkcja zwraca to samo co funKcja2, różnica jest w tym że używając funkcja wystarczy używać jednego argumentu, jest to idiotyczne rozwiązanie mówiąc w prost, program zamiast od razu wykonać funKcja2 musi odwołać się do funkcja, musi utworzyć miejsce w pamięci na zmienne występujące w tej funkcji, musi uwzględnić return etc. rozwiązaniem optymalnym jest albo używanie po prostu funKcja2 i zawsze wpisywanie/wklejanie tych samych argumentów albo makrodefinicja czyli na górze mapy/skryptu #define funkcja(%0) funKcja2(%0, "xyz", 1.3) wszelkie operacje makro są wykonywane przed kompilacja mapy (zmianą w amx) czyli w pliku .amx nie ma żadnej funkcja tylko funKcja2, dużo ludzi nie zdaje sobie nawet sprawę co można zrobić dzieki #define, może ona nie tylko robić zamianę funkcji ale także dodawać coś jeszcze, jeśli ktoś widział #define dcmd może wie o co chodzi, nie będę się zbytnio rozpisywał o tym bo to nie temat od tego Kolejną rzeczą są tablice lokalne new tablica1[MAX_PLAYERS]; // tablica globalna public OnGameModeInit() { new tablica2[MAX_PLAYERS]; // tablica lokalna return 1; } chodzi o wielkości 100 lub więcej, często właśnie do każdego formatowania tekstu na nowo tworzy się tablicę lokalną, jest to niepotrzebne marnowanie pamięci i czasu na zajęcie tej pamięci (rezerwowanie pamięci w PAWN to także jej wyzerowanie, kto bawił się w C/C++ pewnie wie o co chodzi), otóż każda operacja w PAWN może być wykonana pojedynczo i dopiero po jej zakończeniu wykonywana jest inna, czyli po co w public OnPlayerText tworzyć tablicę string[128]; a potem w OnPlayerCommandText tworzyć znowu string[128], te public'ki mimo nawet 500 gracz online nie mogą wykonać się jednocześnie, to czemu raz nie zarezerwować tylko tej pamięci (globalnie), jedyny minus tej operacji to to że tablica może nie być pusta, ale jeśli nie używacie funkcji typu strcat na początku to jest ok (np. format czyści a raczej nie pobiera dawnej wartości tablicy docelowej) Inną rzeczą którą często widuję jest tworzenie tablic używanych do chwilowego zachowania informacji (tylko w obrębie jednej funkcji) służących tylko do jednego, np. new cmd[128]; tylko do przechowania treści komendy (OnPlayerCommandText) i new string[128]; tylko do dopisania id na czacie (OnPlayerText), dlaczego, przecież do tablicy cmd też możemy zapisać wiadomość gracza wraz z jego id a do string treść komendy, różnią się tylko nazwą, ogólnie takie stosowanie jest dość wygodne dla nas ale względem kodu dość nieoptymalne, lepiej jest zastosować jedną tablicę globalną dla wszystkich formuł formatujących tekst, są tu 3 wyjścia, albo tablica [128] + dużo większa (np. dla pliku, zależy co kto potrzebuje), wtedy bez problemu możemy używać format(string, sizeof string, ... do formatowania tekstów etc. a drugą tablicę tylko w wyjątkowych sytuacjach (formatowanie tekstu okienka GUI etc.), druga opcja [ 160 ? ] (chodzi o max długość tekstu w SendClientMessage etc. kiedyś było 128, po dodanie kolorów zmieniono ale nie pamiętam na ile) + duża tablica, chodzi o to samo lecz to rozwiązanie dla tych którzy maja zamiar używać kolorów, i trzecie, tylko duża tablica, lecz wtedy trzeba pamiętać by nie używać zawsze sizeof w funkcji format etc. chodzi o to by nasza mapa nie pobierała niepotrzebnie pamięci (w tym wypadku w C++ dla funkcji format) która nie będzie użyta często też widzę obawy przed funkcja format, może pokaże to na przykładzie: new tablica1[20], tablica2[20]; format(tablica1, 20, "abc ..."); print(tablica1); format(tablica2, 20, "xyz: %s", tablica1); print(tablica2); jak widać używane są tutaj dwie tablice, najpierw tablica1 przypisujemy tekst, wyświetlamy jego zawartość, potem przepisujemy do tablica2 z dodatkowym nowym tekstem, po co nam tablica2 ? dlaczego by nie dopisać tego tekstu od razu do tablica1, w tym przypadku najlepiej jest użyć funkcji strins czyli: new tablica1[20]; format(tablica1, 20, "abc ..."); print(tablica1); strins(tablica1, "xyz:", 0); // wklejenie tekstu na pozycję 0, znajdujący się już tekst zostaje przesunięty print(tablica2); ale co jeśli mamy więcej rzeczy i musimy użyć format, po co tworzyć dwie tablice, funckja format po to ma argument 2 wielkość by mogła sobie określić w C++ tablicę, następnie zapisuje do niej wszystkie parametry i pobiera tekst z argumentów i dopiero potem zmienia tablicę główną, czyli bez obaw ten kod możemy zapisać w postaci new tablica1[20]; format(tablica1, 20, "abc ..."); print(tablica1); format(tablica1, 20, "xyz: %s", tablica1); print(tablica1); PVar'y jedna z nowości o której mnoży się mnóstwo różnych plotek etc. po pierwsze, nie są one optymalniejsze od tablic, czas zmiany/pobierania danych z nich jest dużo dłuższy niż z tablic (chce przypomnieć że nadal mówimy tu o wartościach mniejszych od milisekundy), trzeba też wiedzieć że czas tworzenia PVar'a jest dłuższy niż zmiany jego wartości. Ja polecam je używać dla zapisania informacji używanych raz lub w jakimś przedziale czasu lub do przesyłania informacji pomiędzy skryptami/mapą ich wartość jest usuwana po wykonaniu się OnPlayerDisconnect, podobno występują problemy z komendą /rcon gmx Enum'y, enumatory, struktury, czy jak tam kto woli, ogólnie mam tu mało do powiedzenia, tyle że enum i jedna tablica zajmuje więcej niż ich odpowiedniki to znaczy enum xyz { char[10], z } new tablica[5][xyz]; zajmuje więcej miejsca niż new tablica1[5][10]; new tablica2[5]; jest to wielkość pliku .amx, nie wiem czy są jakieś znaczne różnice w użyciu pamięci, wątpię, jedynie kod może być dla programu bardziej skomplikowany, ale nie ma się czym martwić, jedyne co chciałem tu głownie poruszyć to to że nieraz ludzie tworzą struktury nie widząc na prawdę do czego to tak naprawdę służy, chodzi o zamknięcie w obrębie jednej tablicy, jednej nazwy, wartości o różnych typach + do każdego typu przypisanie nazwy, czyli nie ma po co tworzyć struktury jeśli wewnątrz tworzymy tylko tablice lub tylko zmienne, np. enum xyz { name[24], vname[30] } new dane[30][xyz]; jak widać różnica wielkości obu tych tablic nie jest tak duża wiec łatwiej zastosować jest new dane[30][2][30]; to jest praktycznie to samo, tylko zamiast podawać name vname podajemy 0 lub 1 Tablice z MAX_PLAYERS, dużo ludzi tworzy takie tablice, chodzi tylko o to że tworzymy w taki sposób tablicę [500], jest ona nam niepotrzebna gdy mamy 30 slotów np. dlatego lepiej utworzyć sobie własne define np. #define SLOTS 30 i używać new ma_vipa[SLOTS]; lub też przed tworzeniem tablic dać [code#undef MAX_PLAYERS #define MAX_PLAYERS 30 // liczba slotów czyli po prostu zmienić wartość MAX_PLAYERS Teraz parę praktycznych przykładów, często problematycznych Pętla dla wszystkich graczy, niemal każda mapa ja ma, kiedyś stosowało się prostą formułę opierającą się o liczbę MAX_PLAYERS, teraz jednak jest to szaleństwo, zwłaszcza dla serwerów 30 slotowych itp. oto najoptymalniejsze rodzaje pętli: for(new i, mp = GetMaxPlayers(); i < mp; i++) jest to najprostsza odmiana powszechnej pętli, chodzi tutaj o to by GetMaxPlayers wykonała się raz gdyż jej wartość nie ulega zmianie for(new i = GetMaxPlayers() - 1; i > = 0; i--) jak widać w powyższej pętli zmieniono ilość zmiennych do jednej, szczegółem tego rozwiązania jest to że id graczy jest wyliczane od końca, czyli dla 30 slotów będzie: 29 (bo pierwsze id to 0), 28, 27 itd. trzecim i niewątpliwie najlepszym rozwiązaniem jest includ foreach http://forum.sa-mp.com/showthread.php?t=92679&highlight=foreach includ automatycznie tworzy 2 tablice o wielkości MAX_PLAYERS, jeśli kogoś przeraża liczba 500 można ja mzienić dajac przed foreach a pod a_samp: #undef MAX_PLAYERS #define MAX_PLAYERS 30 // liczba slotów nie jest to nic strasznego, wykonuje się naprawdę dużo szybciej niż zwykła pętla, po dodaniu #include <foreach> można już używać pętli dla all graczy foreach(Player, i) // i to zmienna do której będzie przypisywane id gracza { //kod, można używać continue; break; jak w normalnej pętli } Dużo ludzi boi się tablic dla wszystkich pojazdów [MAX_VEHICLES] jeśli nie chcecie tworzyć tak dużej tablicy możecie określić sobie dokładną liczbę pojazdów w mapie, jeśli jednak chcecie używać pełnego limitu nie ma innej opcji, mogę tylko dla szczegółowych danych zalecić stworzenie enuma by nie tworzyć paru takich tablic (jako tako), nie polecam używać foreach dla pojazdów, jest to mało praktyczne, a do pętli można dodać warunek czy pojazd istnieje (GetVehicleModel zwraca 0 gdy pojazdu nie ma) Pobieranie i przechowywanie nick'u gracza, przedstawie tylko dwie najoptymalniejsze metody, 1. jedna tablica globalna new nicki[MAX_PLAYER_NAME]; tera w kodzie gdy potrzebujemy nick gracza używamy GetPlayername z ta tablicą, wadą tego rozwiązania jest to że mamy tylko jeden nick, gdybyśmy chcieli pobrać nicki kilku graczy na raz mógłby być problem 2. jedna tablica globalna new nicki[MAX_PLAYERS][MAX_PLAYER_NAME]; czyli tablica dla wszystkich graczy oraz mogąca przechować długość nicku gracza teraz w OnPlayerConnect dajemy GetPlayerName(playerid, nicki[playerid], MAX_PLAYER_NAME); i już nie musimy więcej używać tej funkcji, tablica nicki[id gracza] ma zapisany nick danego gracza i można jej łatwo używać np. format(string, sizeof string, "Gracz %s wyszedł", nicki[playerid]); wadą tego sposobu jest to że ta tablica to w najgorszym wypadku 500 * 24 czyli 12000 bit'ów pamięci, nie jest to super dużo ale zawsze Jaszcze 2 zdania na temat tablic: Otóż często w programowaniu typu C++ itp. niemal unika się tworzenia tablic globalnych a stosuje lokalne, dlaczego więc w PAWN jest inaczej? C++ jak i inne bardziej rozbudowane języki są przygotowane dla większych rzeczy niż plik operacyjny programu (.amx) tablice globalne maja to do siebie że zaraz po uruchomieniu pamięć dla nich przeznaczona jest wydzielana (pamięć RAM) oraz zerowana, dlatego przy dużych projektach w C++ ten czas zajmowania pamięci mógłby być nieco długi, jednak w PAWN każde tablice, czy lokalne czy globalne są zerowane, to znaczy że utworzenie tablicy lokalnej w PAWN jest niemal dwa razy dłuższe niż w C/C++ (proszę się nie przerażać, nadal mówimy o wartościach zbliżonych do 1 ms) dlatego jeśli mamy dużą tablicę lokalną jest ona nieco obciążeniem dla naszego gamemodu/skryptu, w C/C++ tablice lokalne nie są zerowane jak globalne, dzięki też typom zmiennych/tablic określa się dokładniej ile pamięci pobiera w danej chwili program, w PAWN zawsze każda zmienna pobiera tyle samo pamięci, dlatego w PAWN bardziej opłaca się tworzyć tablice globalne, gdyż są znacznie szybsze od lokalnych
  17. Mr_Auto

    [Szukam] Bug na forum!!!!

    Kiedy to się pojawiło, jak zainstalowałeś forum czy jak wgrałes styl?
  18. Mr_Auto

    Czego teraz słuchasz?

    https://www.youtube.com/watch?v=cQy7U4gnMVw
  19. Mr_Auto

    Tworzenie prostego bot'a (NPC)

    Będzie działać, tylko pomyśl, tworzysz drugiego takiego samego bota (ten sam skin, ta sama pozycja) jeśli ma on też te same nagranie to masz po prostu dwa boty w jednym A jeśli nie to musiałeś coś zrobić źle w innym miejscu kodu
  20. Mr_Auto

    Przydatne funkcje

    Bo sa:mp to gufno ;P A prawda jest taka że niekoniecznie musi to wywować crash, sprawdzałem nieraz na swoim serwerze i niektórych graczy nie wyrzucało (nie wiem czemu), są też inne sposoby na wywołanie crasha, np. stworzenie obiektu gracza (niedaleko gracza) o id modelu pojazdu albo postaci
  21. Mr_Auto

    Prośba dla wrzucających skrypty

    solidfiles niestety ostatnio 'się sprzdał', w sensie nawalił dużo reklam (zwłaszcza że pozwala na reklamy mylące (napis download) etc.), kiedys był spoko hostingiem
  22. Mr_Auto

    [Python] Generator haseł

    case 't': cyfry = true; break; case 'T': cyfry = true; break;wiesz że możesz to skrócić? case 't': case 'T': cyfry = true; break;
  23. Oto mój najnowszy plugin tfile, który łączy łatwość obsługi danych sscanf z zapisywaniem danych z użyciem słów-kluczy Funkcje: fGetData(const file[], const format[], {Float,_}:...) Pobiera dane z pliku w dowolnym formacie const file[] - nazwa pliku z którego pobieramy daneconst format[] - format, czyli klucze oraz typu danych zapisane w formie "Klucz<d>Klucz2<s>"{Float,_}:... - tablice i zmienne do których zostaną zapisane daneZwraca ilość poprawnie pobranych danych (ilość kluczy) fSaveData(const file[], const format[], {Float,_}:...) Zapisuje dane do pliku, zastępuje istniejące const file[] - nazwa pliku do którego zapisujemy daneconst format[] - format, czyli klucze oraz typu danych zapisane w formie "Klucz<d>Klucz2<s>"{Float,_}:... - tablice i zmienne z których zostaną pobrane dane do zpaisuZwraca true jeśli wszystko sie powiodło, false jeśli wynikł jakiś błąd/problem fAddData(const file[], const string[], bool:exist = false) Funkcja po prostu dopisuje coś do pliku const file[] - nazwa pliku docelowegoconst string[] - tekst który dopisujemybool:exist = false - czy plik musi istnieć by do niego coś zapisać, domyślnie nieZwraca true jeśli wszystko się udało, false jeśli wynikł jakiś błąd/problem fDeleteData(const file[], const key[]) Usuwa dane z pliku po nazwie kluczy oddzielonymi przecinkami const file[] - nazwa pliku docelowegoconst key[] - klucz lub nazwy kluczy oddzielone przecinkamiZwraca true jeśli wszystko się udało, false jeśli wynikł jakiś błąd/problem fKeyExist(const file[], const key[]) Sprawdza czy klucz lub klucze istnieją const file[] - nazwa pliku docelowegoconst key[] - klucz lub nazwy kluczy oddzielone przecinkamiDla jednego klucza zwraca true/fale, dla więcej zwraca sumę liczb bitowych (istnienie pojedynczego klucza można sprawdzić za pomocą &) fCreate(const file[], const string[]) Funkcja tworzy plik i zapisuje coś do niego jednocześnie const file[] - nazwa pliku docelowegoconst string[] - tekst który zostanie zapisanyZwraca true jeśli wszystko się udało, false jeśli wynikł jakiś błąd/problem Funkcje dodatkowe, opcjonalne: fConvertTags(const file[], oldtag, newtag) Funkcja konwertuje tagi to znaczy znaki oddzielające nazwę klucza od danych const file[] - nazwa pliku docelowegooldtag - stary tag, standardowy to '='newtag - nowy tag, np. '-'Zwraca true jeśli wszystko się udało, false jeśli wynikł jakiś błąd/problem fChangeConfig(keytab = '=', nicelook = false, ignorekeycase = false, keysize = 30, linesize = 256) Zmienia podstawowe parametry plugina takie jak, standardowy znak oddzielający klucz od danych, wygląd danych, ignorowanie wielkości znaków podczas szukania klucza w pliku oraz maksymalne długości nazw klucza oraz ilość danych keytab = '=' - znak oddzielający klucz od danych, domyślny to = czyli w np. Kasa=5000nicelook = false - czy plik ma lepiej wyglądać, standardowo zapis wygląda tak 'kasa=5000' gdy damy true będzie 'kasa = 5000'ignorekeycase = false - czy ma ignorować wielkość liter w nazwie klucza szukanego w plikukeysize = 30 - maksymalna wielkość nazwy klucza, minimalna wartość to 10linesize = 256 - maksymalna długość linijki pobieranej z pliku (łącznie z nazwą klucza, znakiem oddzielającym '=' i spacjami przy nim) UWAGA: dla nie marnowania pamięci wartość używana także do nazwy pliku, a dokładniej, tablica ta musi pomieścić nazwę pliku + 14, minimalna wartość to 20 (czyli przy minimalnej wartości maksymalna wielkość nazwy pliku to 6)Zwraca true jeśli wszystko się udało, false jeśli wynikł jakiś błąd/problem Download: tfile3.inc tfile.dll tfile.so (kompilowanie na Ubuntu 11.04) Source Code Dla tych co nie mieli nigdy do czynienia z systemami plików: Zapis do pliku opiera się o stworzeniu tak jakby tabeli o dwóch kolumnach, jedna to klucze, słowa kluczowe, czyli nazwy które będą charakteryzować co to za dane są zapisane w tej pozycji, czyli np. kasa, punkty, respekt itp. Nazwa klucza nie może zawierać znaku spacji oraz znaku oddzielającego ją od danych czyli najczęściej =. Przykładowe wnętrze pliku: Teraz by pobrać np. nick gracza co robimy? przecież nie wyszukamy w pliku Terminator3 gdyż to przecież chcemy wiedzieć, cz nick to Terminator3 czy jakiś inny, dlatego szukamy klucza/słowa kluczowego czyli nick które nigdy się nie zmieni, w funkcji wpisujemy "nick" w przypadku mojego plugina "nick<s>" i otrzymujemy nick gracza który wcześniej zapisaliśmy Jak stworzyć system rejestracji, najczęstszym i najlepszym sposobem są te 3 kroki: Logowanie polegające na pobraniu danych z pliku i zapisaniu ich w tablicach/zmiennych czyli w pamięci serweraOperowanie na tych danych, dodawanie, odejmowanie, zmiana hasła itp.Gdy gracz wychodzi z serwera nadpisanie danych z pliku tymi które posiadamy w pamięci serwera (zmienne/tablice)Jeśli zrozumiesz te 3 punkty nie będziesz mieć żadnego problemu Mój plugin, dlaczego warto?: Odpowiedź jest banalnie prosta, w includ'ach typu dini, dof, tfile 2.0 by pobrać 4 rzeczy, np. kasę, score, adminlvl i hasło potrzebujemy użyć 4 funkcji, w moim pluginie używamy zawsze jednej. Różnice: dini: kasa[playerid] = dini_GetInt(PlayerName(playerid), "kasa"); adminlvl = dini_GetInt(PlayerName(playerid), "adminlvl");tfile3: fGetData(Playername(playerid), "kasa<d>adminlvl<d>", kasa[playerid], adminlvl[playerid]);dini: GivePlayerMoney(playerid, dini_GetInt(PlayerName(playerid), "kasa")); SetPlayerScore(playerid, dini_GetInt(PlayerName(playerid), "score"));tfile3: new score, money; fGetData(PlayerName(playerid), "kasa<d>score<d>", money, score); GivePlayerMoney(playerid, money); SetPlayerScore(playerid, score);Typy danych <?> i lub d - liczbas - tekstc - jeden znakf - float, liczba zmiennoprzecinkowa, ułamekPrzykłady: Kasa<d> Score<i> Haslo<s> Plec<c> PozycjaX<f>Inne przykłady: //przykład dopisania danych do pliku new str[32]; format(str, sizeof str, "Interior = %d\nVIP = %d\n", GetPlayerInterior(playerid), Vip[playerid]); fAddData(PlayerName(playerid), str);// przykład usunięcia paru danych z pliku, spacje nie mają znaczenia dlatego można je dawać dowoli fDeleteData(PlayerName(playerid), "Interior, VIP, kasa");// przykład tworzenia pliku gracza, np. po rejestracji new str[32]; format(str, sizeof str, "Hasło = %s\nAdminlvl = 0\nKasa = 0\n", inputtext); // wykorzystanie fstream w pluginie pozwala na używanie także polskich znaków jakich jak ł ó ą ż ź itd. fCreate(PlayerName(playerid), str)
  24. 1.Czy jest w php coś takiego jak zmienne lokalne, np. w większości plików mam coś takiego: require 'config.php';i pytanie, czy da się utworzyć w config.php taką zmienną która nie będzie dostępna poza nim czyli np. w skrypcie w którym jest powyższa linijka ? czy jedyny sposób to zerowanie danej zmiennej lub używanie unset na końcu pliku config.php? 2. Odnośnie powyższego, jak zablokować możliwość otwarcia pliku config.php bezpośrednio, w sensie by strona.pl/config.php pokazywało błąd 404 3. $conn -> exec("DELETE FROM users WHERE id = '$userid'"); $conn -> exec("DELETE FROM mail WHERE id = '$userid'"); $conn -> exec("DELETE FROM login WHERE id = '$userid'");Czy ten kod jest optymalny? czy da się/warto go optymalizować ? (np. zrobić z tego jedno zapytanie czy coś) 4. W pliku htaccess mam domyślnie taką linijkę php_value mbstring.http_input autoMoże mi ktoś wytłumaczyć ocb. ? 5. Czy plik .php zawsze wykonuje się do końca? to znaczy, powiedzmy że kod php jest skomplikowany i wykonuje się dość długo czy jeśli strona nie załaduje się do końca a użytkownik ją zamknie kod wykona się bez problemów do końca? 6. Czy pliki php wykonują się jeden po drugim dla każdego użytkownika? czy jeśli dwie osoby wejdą na stronę niemal jednocześnie to czy wczytane strony .php będą wykonywane 'jednocześnie' czy po kolei, chodzi mi że np. na stronie są dwa zapytania do mysql, czy one mogą nagle wykonać się na zmianę raz jednego użytkownika a potem drugiego i znów pierwszego czy najpierw wykonane zostaną zapytania pierwszego a potem drugiego?
  25. Mr_Auto

    Php / mysql sprawy ogólne, optymalizacje itp.

    Poczytałem trochę o zabezpieczeniach, stronach błędu i znalazłem taki kod .htaccess Order Deny Deny From AllBlokuje on dostęp do folderu i jego zawartości ale pozwala na wczytywanie plików .php poprzez require/include itp. Problem w tym że po wejściu teraz do takiego folderu przez http/www zostaję przekierowany na jakiś dziwny adres, miałem już coś takiego, mój hosting ma coś jakby swoje strony błędu ale pozwala je zmieniać przez htaccess, problem w tym że mimo iż mam listę 38 stron błędu nadal nie przekierowuje mnie do mojego error.php Dlatego chciałbym zapytać, jaki ErrorDocument powoduje kod który podałem, czy może żaden?
×