Jump to content

Wojak

Members
  • Posts

    321
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by Wojak

  1. In order to use executeCommandHandler You need to add ACL permissions to the resource that calls this function, the lazy man method would be to add the resource to the Admin ACL group. https://wiki.multitheftauto.com/wiki/ACL <group name="Admin"> ...stuff... <object name="resource.resourceName" /> ...stuff... </group> Since You don't own the server You will need to tell the owner to modify His ACL...
  2. If you have more then one server side script (or more then one client side) You simply make the function global (all function ale global by default, you need to use local keyword to make them local) and that function will be accessible in any file of the specific side. In order to call a server side function from client you can use triggerServerevent and add the event server side, In order to call a client side function from server you can use triggerClientevent and add the event client side. The alternative to the event system is to use the "shared" keyword in meta.xml, though I never do that... So in theory you can create a file called utility.lua write some global functions there and add this line to meta.xml: The mta server browser displays that information, you can also look for sites like this: http://www.game-state.com/index.php?spp=50&game=mta
  3. local login = "themisiakprostadsg" for i=1, #login do local toprint = login:sub(i,i) print(toprint) end tutaj można przetestować: http://www.lua.org/cgi-bin/demo Jeśli działa jak potrzeba zo zamieniasz print() na outputChatBox() i gotowe
  4. Ok już to widzę... Ale czy nie lepiej zamiast "#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]" wpisać "#%x%x%x%x%x%x" ?
  5. ##FF0000FF0000 - to raczej nie ma żadnego sesnu #FF0000 - powinno działać zawsze, chyba że na serwerze jest skrypt który to blokuje... A działa to tak: znak # informuje MTA aby sprawdzić czy 6 następnych znaków czy to przypadkiem nie liczny zapisane w systemie szesnastkowym. Co to jest ten system szesnastkowy? My ludzie używamy na co dzień systemu dziesiętnego - mamy 10 cyfr: 0-9. Zapewne każdy słyszał o systemie dwójkowym (binarnym), gdzie są tylko 2 cyfry: 0-1. W systemie szesnastkowym jest 16 cyfr: 0-9A-F, gdzie A =10, B=11, C=12, D=13, E=14 i F=15. Kolory zapisujemy za pomocą 3 liczb (po jednej dla każdego koloru składowego - czerwony, zielony i niebieski), wartosci tych liczb mogą być w przedziale od 0 do 255, a tak się składa że liczba 255 w systemie szesnastkowym to FF (15*16+15=255) - tylko 2 cyfry. Posiadając tą wiedzę możemy przerobić każdy kolor, np: purpurowy (157,0,157) 157/16 = 9,8125 - wywalamy to co jest po przecinku 9*16 = 144, 157-144=13(D) czyli mamy liczbę w systemie szesnastkowym 9D a kod na kolor będzie #9D009D składowe koloru w postaci liczb dziesietnych mozna pozyskać za pomocą painta: kolory->edytuj kolory->definiuj kolory niestandardowe
  6. zamiast 'gracz' powinno być 'source' ponieważ każda funkcja podpięta do eventu ma ukryty argument o nazwie 'source' (źródło eventu) a w przypadku "onPlayerJoin" jest to 'player' (gracz). To jest podstawowa wiedza niezbędna do napisania każdego zasobu, nie tylko gamemodu, rodzaj elementu będący źródłem eventu jest opisane na wiki w artykule poświęconym temu eventowi. Po za tym wydaje mi się że zamiast powinno być
  7. ale jak masz te dane zapisane w skrypcie? w tabeli czy każdy ID i Amo w osobnej zmiennej? Mój poprzedni post raczej pokrywa wszystko o tabelach, ale jak masz zapisane w osobnych zmiennych to: bronID0 = 0 bronID1 = 0 bronID2 = 0 --itp bronAmo5 =0 bronAmo6 =0 bronAmo7 =0 text1 = bronID0..","..bronID1..","..bronID2 -- kontynuuj dla wszystkich ID text2 = bronAmo5..","..bronAmo6..",".bronAmo7 -- kontynuuj dla wszystkich Amo -- odczytywanie: tab1 = split(text1,string.byte(",") bronID0 =tab1[1] bronID1 = tab1[2] bronID2 = tab1[3] tab2 = split(text2,string.byte(",") bronAmo5 =tab2[6] bronAmo6 =tab2[7] bronAmo7 =tab2[8] -- przy założeniu że prawidłowo zapisałeś od Amo0 do Amo7
  8. wiersz,kolumna = guiGridListGetSelectedItem(twoja_lista) zaznaczony_text = guiGridListGetItemText(twoja_lista,wiersz,nrkolumcy) -- jeśli masz więcej niż 1 kolumnę i domyslny tryb zaznaczania (cały wiersz) to nrkolumny najlepiej wpisać ręcznie
  9. jesli twoja tabela ma format: {0,0,0,0,0,...,0} to jaknajbardziej skożystaj z table.concat: tab = {0,0,0,0,0,...,0} local text = table.concat(tab,",") potem zapisujesz tekst do bazy danych, proces odwrotny wymaga funkcji split: text = "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" tab = split(text,string.byte(",")) Jeśli natomiast tabela jest w stylu {["bronID0"]=0,["bronID1"]=0,["bronID2"]=0,...,["bronAmo7"]=0} to sprawy nieco się komplikują: tab = {["bronID0"]=0,["bronID1"]=0,["bronID2"]=0,...,["bronAmo7"]=0} tab2 = {} i=0 for id,v in pairs(tab) do i=i+1 tab2[i]=id.."_"..v end text = table.concat(tab2,",") --odwrotnie tab2 = split(text,string.byte(",")) for i=1,#tab2 do local t = split(tab2[i],string.byte("_")) tab[t[1]]=t[2] end kożystając z mojego kodu nalezy brać poprawki na literówki
  10. To prawda że outputChatBox po stronie klienta będzie widoczne tlko dla teko klienta który wykonał funkcję, ale... event "onClientPlayerWasted" podczepiony do root będzie wykonywany gdy zginie KAŻDY gracz, nie tylko LocalPlayer, ale i "zdalni" gracze... Rozwiązania: - zamiast do root podczepić eventa do getLocalPlayer() lub - w funkcji podczepionej do ewenta sprawdzić czy source == getLocalPlayer()
  11. Nie działa, bo nie do końca wiesz co robisz: - funkcja guiCreateEdit nie zwraca tekstu, tylko element (utworzony właśnie editbox), żeby wychwycić kiedy ten tekst się zmienił potrzebujesz eventu onClientGUIChanged i funkcji guiGetText - "Zmienna to: $zmienna" nie jest formatem lua, powinno być: "Zmienna to: "..zmienna polecam zapozać się z: https://wiki.multitheftauto.com/wiki/Main_Page http://www.lua.org/pil/contents.html a przykłąd jak zrobić to czego potrzebujesz masz tu: https://wiki.multitheftauto.com/wiki/OnClientGUIChanged
  12. Taki przycisk jak 'kp' nie istnieje w twoim skrypcie, dlatego jest nil, Ty stwprzyłeś przycisk o nazwie 'kphone'... Po za tym podanie przycisku do funkcji "addEventHandler" nie sprawi że event będzie wykonany tylko dla tego przycisku, ale że będzie on źrudłem (source) eventu, dla tego w funkcji musisz sprawdzić czym jest source, w przypadku zamknijgui(): function zamknijgui() if source == zamknij then guiSetVisible (okienko, not guiGetVisible) showCursor(false) end end a jeśli chodzi o pytanie dodatkowe: takePlayerMoney
  13. Lepiej zacząć od podstaw: Server – komputer na którym jest zainstalowana i uruchomiona aplikacja serwera, służy do synchronizacji danych pomiędzy klientami, a w grach które są od początku projektowane jako multiplayer (nie MTA) może także obsługiwać fizykę świata. Client – w przypadku MTA to komputer na którym zainstalowane jest GTA i aplikacja klienta MTA, służy do wyświetlania interfejsu użytkownika i grafiki, a w przypadku MTA w 100% odpowiada za fizykę świata... Jedyny przypadek kiedy client i server to ten sam komputer jest wtedy gry uruchamiasz server na swoim domowym PC a potem się z nim bezpośrednio łączysz, w pozostałych przypadkach mamy do czynienia z 1 serverem i od 0-(mak ilość graczy na serverze) clientami i każdy jest osobnym komputerem. Ponieważ w MTA server nie ma bezpośredniego dostępu do silnika gry informacje o wszystkim przechowywane są w strukturze o nazwie 'drzewo elementów' (element tre) – drzewiasta struktura rodzic-dziecko w której każde dziecko ma tylko 1 rodzica, ale rodzic może mieć dowolną liczbę dzieci. U podstaw struktury leży korzeń (rootelement lub po prostu root) który nie ma rodzica, a sam jest bezpośrednim rodzicem graczy (gracz i client to praktycznie to samo) i zasobów. Gracze natomiast są rodzicami swoich awatarów (pedów) a np. zasób play jest rodzicem wszystkich samochodów przez niego utworzonych. W przypadku niektórych funkcji wykonanych na rodzicu, funkcja ta będzie wykonana także dla wszystkich dzieci o typie właściwym dla tej funkcji: local markers = getElementsByType('marker') -- funkcja ta domyślnie wykonywana jest dla 'root' więc znajdzie wszystkie markery na serverze local markers = getElementsByType('marker',getResourceRootElement(getResourceFromName('jakiś tam zasób')))-- teraz funkcja znajdzie wszystkie markery utworzone przez jakiś tam zasób Każdy Client ma własną kopię drzewa elementów i jeśli jakoś nowy element zostanie stworzony przez server to kopia drzewa wszystkich clientów jest uaktualniona, natomiast jeśli coś jest utworzone przez clienta, to z reguły wie o tym tylko ten client który to stworzył – celowo lub nie może dojść do sytuacji że dwóch graczy stojących obok siebie widzi różne rzeczy! Kolejne ważne pojęcie to gracz lokalny (loaclPlayer) jest to element który istnieje tylko po stronie clienta (na serverze wszyscy gracze są równorzędni) i przedstawia gracza który jest właścicielem danego clienta. Fizyka gry istnieje tylko w promieniu 500m od gracza lokalnego, dalej niż ta odległość większość elementów (na samochody) po prostu znika, a wszelkie obiekty tracą kolizję. Gracz lokalny zawsze jest synchronizowany (niezbędne informacje takie jak pozycja awatara wysyłane są na server, i dalej do innych clientów) Przechodnie (pedy) nie kontrolowane przez żadnego gracza domyslnie synchronizowane są tylko w promieniu 100m od lokalnego gracza (jeśli ped był utworzony przez server to zmiana jego pozycji po stronie clienta, pod warunkiem że pozycja startowa i końcowa są w zasięgu synchronizacji, będzie widoczna dla wszystkich graczy) W przypadku pojazdów nie sperowanych przez gracza zasięg synchronizacji jest nieco większy (chyba 150), ale ped w pojeździe traktowany jest jako ped (zasięg 100) Pozostałe elementy nie są synchronizowane (przesunięcie bramy po stronie clienta będzie widoczne tylko dla clienta który dokonał zmiany) W danym momencie dany element (ped, pojazd) może być synchronizowany tylko przez jednego gracza, zmiana odbywa się automatycznie gdy element wyjdzie poza zasięg jednego gracza, ale znajdzie się w zasięgu innego lub ręcznie na pomocą setElementSyncer (Uwaga – zasada zasięgu dalej obowiązuje). Skrypty: Skrypty po stronie serwera działają od razu po ich uruchomieniu, natomiast te po stronie clienta muszą być pobrane z servera (pobierane są także pliki z obrazkami i dźwiękiem jeżeli dany zasób takowe zawiera), domyślnie skrypt clienta zacznie działać dopiero po pobraniu wszystkich niezbędnych plików. Czasu pobierania nie da się przewidzieć bo każdy gracz ma inny sprzęt (ale istnieje pewien trick o którym później) Uwaga: różnice w sprzęcie oznaczają że ten sam skrypt może działać inaczej na niektórych komputerach lub w przypadku szaderów w ogóle nie zadziałać! Ręczna komunikacja Client-Server Server-Client: setElementData – jest to funkcja która wprowadza zmianę do drzewa elementów i pozwala na edycję istniejących wpisów lub też tworzenie całkiem nowych w obrębie danego elementu. triggerServer/Client/Event po jednej stronie w połączeniu z addEvent i addEventHandler – ten zestaw funkcji pozwala na przesyłanie pakietów danych i nie wprowadza zmian w drzewie elementów (ale z niego korzysta) funkcja trigger (odpal) wymaga podania: -clienta w przypadku triggerClientEvent, root jest domyślny i oznacza wszystkie clienty -tekstu oznaczającego nazwę wydarzenia -elementu źródłowego (po drugiej stronie będzie ukrytym parametrem 'source') -opcjonalnie dodatkowych parametrów po drugiej stronie: -rejestrujemy wydarzenie (robimy to tylko raz) za pomocą addEvent (podajemy nazwę eventu i podajemy czy może być uruchamiany zdalnie – prawie zawsze chcemy żeby był uruchamiany zdalnie) -następnie dodajemy funkcję obsługującą (tu nie ma limitu tych funkcji) za pomocą addEventHandler. Musimy podać nazwę eventu, element do którego event jest przyczepiony (może być konkretny lub root) oraz funkcje która ma być uruchomiona. Funkcja będzie miała ukryty parametr o nazwie source oraz tyle innych parametrów ile podaliśmy w funkcji trigger. Przykład – dajmy serverowi znać że client pobrał wszystkie pliki i można bez problemu dzielić się z nim informacjami: client: triggerServerEvent('onFileDownloadNazwaZasobu',getLocalPlayer())--na końcu pliku clienta server: addEvent('onFileDownloadNazwaZasobu',true) addEventHandler('onFileDownloadNazwaZasobu',root,function() outputChatBox ( getPlayerFromName(source).." pobrał plik" ) end)
  14. Tylko mi nie mów że te szpagaty z pętlą i sting.gsub to lepsze rozwiązanie? Fakt – tłumaczenie pojedynczych słów nie ma sensu, najlepiej jest przetłumaczyć całe zdanie formułując je tak żeby w każdym języku argument był na końcu: „Wygrałeś następującą ilość kasy: 1000” wykorzystując tą metodę można sprawić że każdy gracz będzie widział tylko tekst w języku, który zadeklarował przy wejściu na serwer, więc chyba jakiś problem to rozwiązuje
  15. Pewnie to już nieaktualne, ale co tam: local tab={ eng={ grat="Congratulations!", cos="You won", money="1000", }, pl={ grat="Gratulacje!", cos="wygrales", money="1000", }, } local lang="eng" print(tab[lang].grat.." "..tab[lang].cos.." "..tab[lang].money) lang="pl" print(tab[lang].grat.." "..tab[lang].cos.." "..tab[lang].money) http://luachunks.com/chunk/F216vf0a6m
  16. Jeśli nie do końca wiesz jak zrobić to co pisze lopezloo to możesz sprawdzić mój stary projekt: viewtopic.php?f=108&t=35931 Jeśli chcesz to możesz wykorzystać fragmenty mojego kodu, ale zapoznaj się z listą efektów ubocznych (problem z zablokowaną kamerą na 100% da się rozwiązać, ale nie do końca wiem jak...) Po za tym musisz wiedzieć że w grach fizyka jest tylko tam gdzie jest kamera, więc jeśli awatar jest np. w LS a ty odczepisz od niego kamerę i przeniesiesz ją do SF to awatar zapadnie się pod ziemię... Dodatkowo funcje takie jak dxCreateScreenSource mogą nie działać na starych kartach graficznych. Jeśli chodzi o przeniesienie obrazu na bilbord to prawdopodobnie (sam tego nigdy nie robiłem, więc to może być bzdura) musisz użyć tych funkcji: dxCreateScreenSource dxCreateTexture -- podawając ScreenSource jako "pixels" engineImportTXD
  17. This resource show the time and CP difference between the first player and You/player in front You/player behind You. It is based on the race_delay_indicator default MTA resource, and It's made exclusive for my server. There may be still some bugs to remove so nay feedback is welcome, You may test it on this server: http://www.game-state.eu/94.23.251.227:22017/ Some images (upper right corner of the screen):
  18. Nie testowane (funkcja getPointFromDistanceRotation z tąd: https://wiki.multitheftauto.com/wiki/Ge ... ceRotation) function getPointFromDistanceRotation(x, y, dist, angle) local a = math.rad(90 - angle); local dx = math.cos(a) * dist; local dy = math.sin(a) * dist; return x+dx, y+dy; end function CreateBarrier ( thePlayer ) local odleglosc = 2 if ( thePlayer ) then local x, y, z = getElementPosition ( thePlayer ) local _,_,rotz = getElementRotation(thePlayer) x,y = getPointFromDistanceRotation(x, y, odleglosc, rotz) local theObject = createObject ( 1228, x, y , z - 0.7, 0, 0, 0) -- tutaj zamiast ostatniego 0 chyba tez rotz if ( theObject ) then outputConsole ( "Stworzono barierkę.", thePlayer ) else outputConsole ( "Nie można stworzyć barierki.", thePlayer ) end end end addCommandHandler ( "barierka", CreateBarrier )
  19. A czy przypadkiem nie jest tak że w przypadku graczy życie jest zawsze synchronizowane? nawet jeśli ustawisz je po stronie klienta? bo jeśli tak nie jest to jest to bardzo poważne niedopatrzenie (funkcja setElementHealth działa po stronie klienta więc jeśli ustawisz sobie życie na 0 to giniesz u siebie, a dla innych dalej jesteś żywy?)
  20. po za tym ustawiłeś timer na 1 sekundę a nie minutę... powinno być 60000 a nie 1000
  21. Jeśli masz serwer 24/7 to najprawdopodobniej znajdziesz go na GameMonitor: http://www.game-monitor.com/mta_GameSer ... .html#info potem możesz wejść w zakładkę "WebsiteModule" i wygeneruje ci kod do wklejenia na forum:
  22. Jeśli mówimy tu o kodzie profesjonalnym, który nie był pisany przez jedną osobę, a przez team, to zazwyczaj taki kod jest zorganizowany i zawiera sporo przydanych komentarzy i z czegoś takiego jak najbardziej można się wiele nauczyć... Ja także jestem właścicielem serwera (co prawda mało popularny 2paq Race Server), ale niestety nie mam czasu na rozwój serwera (jestem w tej mniejszości użytkowników tego forum, która posiada pracę i moja praca nie ma nic wspólnego z programowaniem) dlatego jeśli jest taka możliwość to wykorzystuję publicznie dostępne skrypty (czasem łatwiej jest dostosować do swoich potrzeb czyjąś pracę niż napisać coś od podstaw, chociaż nie jest to regułą).
  23. Czy ten zasób ma jakiś związek z tym serwerem: http://funtruck.xaa.pl/ bo miejsca pokazane na twoich zdjęciach wygląają identycznie jak mapa tamtego serwera:
  24. Moim zdaniem to powinno być tak: local gameTime0 = getTickCount() -- ta linijka wykonywana tylko raz, gdy gracz wejdzie na serwer local gameTime = getTickCount() - gameTime0 -- ta linijka i te poniżej wykonywane gdy potrzeba sprawdzić jak długo gracz jest na serwerze local gameTimeS = math.floor(gameTime/1000) playerGameTime = math.floor(gameTimeS/60+1)
  25. Przypadkiem znalazłem ten temat w angielskiej sekcji: https://forum.multitheftauto.com/viewto ... ecd29d382c więc prawdopodobnie się da przy pomocy tej funkcji: engineSetModelLODDistance
×
×
  • Create New...