Jump to content
assignment_ind Existing user? Sign In

Sign In



person_add Sign Up
Go-Code.pl - Support SourceMod i Pluginy CS:GO

Leaderboard


Popular Content

Showing content with the highest reputation since 02/14/2020 in all areas

  1. 3 points
    Korzystając ze strony CSGO Models i pobierając z niej skiny zauważyłem, że składają się one z wielu pomniejszych plików, których pobieranie muszę wymuszać graczom przez AddFilesToDownloadsTable. Z racji, iż jest to strasznie upierdliwe zadanie (szukanie wszystkich ścieżek), można na serwer wgrać plugin, który będzie pobierał całą zawartość folderu. Ja jednak stwierdziłem, że napiszę prosty skrypcik, który wszystkie ścieżki będzie rekurencyjnie pobierał i wypluwał ładny wynik, który po prostu kopiuj/wklejam do OnMapStart Jest to skrypt pythonowy, który działa najzwyczajniej w świecie tak, że rekurencyjnie przeszukuje wszystkie foldery w lokalizacji w której obecnie się znajduje i wypisuje ich pełną ścieżkę, dodając potrzebne przedrostki 'AddFiles.......' Step by step: 1. Utwórz sobie na pulpicie nowy folder o dowolnej nazwie i wrzuć do niego skrypt oraz foldery 'models' i 'materials' ze strony CSGO Models, lub dowolnej innej, której modele mają mnóstwo pomniejszych plików 2. Wejdź do folderu i odpal skrypt 3. Skopiuj wynik 4. elo Przykładowo, przeprowadzając tę procedurę na tym modelu otrzymałem następujący wydruk z konsoli: run.py
  2. 2 points
    Jeśli wszystkie HUDy tworzysz samodzielnie i masz nad nimi kontrole, to spokojnie możesz używać ShowHudText, bo będziesz wiedział gdzie używasz kanału 1-ego, a gdzie 4-ego. Sync mimo wszysto na bezpiecznie ^^
  3. 2 points
    https://gamebanana.com/tuts/9544 #MigaRadarBoŹleZrobiłemVMT
  4. 1 point
    Coming soon... Tablice dynamiczne w dokumentacji Formatowanie czasu Poradnik o tablicach dynamicznych na forum
  5. 1 point
    https://forums.alliedmods.net/showthread.php?p=594854 ?
  6. 1 point
    No nie tyle co kiedyś ale ostatnio testowane na nowym serwerze AWP (20/7) i coś tam dało więc nie zupełnie "nic". A co do tematu to nie rozumiem pytania zbytnio, opisz swój problem dokładniej.
  7. 1 point
    Kompilujesz pod wersję SM 1.10, a zephyrus jest przestarzały przez co nie skompilujesz go pod 1.10 Pobierz kompilator 1.9 i będzie dobrze
  8. 1 point
    @bombels w sensie , że jakie błędy? Mi przy kompilacji wywaliło tylko ostrzeżenia, które tak na prawdę mogłem zignorować. Najlepiej wyślij mi ss z kompilacji. @edit Nie wiem skąd masz te includy, ale wygląda na to, że wszystkie miałeś zepsute. Polecam na nowo pobrać kompilator albo te includy. Pod spodem wrzucam 2, które wywaliły tam i po zmianie ich normalnie skompilował się. regex.inc datapack.inc
  9. 1 point
  10. 1 point
    Jak masz mało rzeczy na hud to ShowHudText, ale jak już masz tego więcej to polecam ShowSyncHudText
  11. 1 point
    Nie oczekuj ze dostaniesz odpowiedzi na "e bo nie działa help" . Musisz dać z siebie coś więcej, poszukać errorów, powiedziec jak to wgrales etc.
  12. 1 point
    Nie wiem czy temat rozwiązany czy nie, ale tak jeszcze dopiszę. Możesz to zrobić jeszcze w taki sposób: To: Rounds >= g_menu_round Zamieniasz na to: ((GetTeamScore(CS_TEAM_T) + GetTeamScore(CS_TEAM_CT)) >= g_menu_round) To pobiera ci ilości wygranych rund przez oba team'y. Wystarczy, że te g_menu_round zmienisz o 1 mniej i będzie ok. Np. Chcesz w 3 rundzie to dajesz g_menu_round = 2
  13. 1 point
    error wystepuje taki: error 028: invalid subscript (not an array or too many subscripts): "lastPaintEnabled", wiec te globalne powinny wygladac tak: bool paintEnabled[MAXPLAYERS + 1]; bool lastPaintEnabled[MAXPLAYERS + 1]; i teraz wszystko ladnie dziala, dzieki. @edit podczas malowania troche przycina jak sie szybko poruszy myszka, ale tak to jest ok
  14. 1 point
    witam, mam pytanie: Jak sprawdzić czy gracz naciska więcej niż jeden klawisz?. Chodzi mi o klawisz IN_USE(domyślnie 'e') oraz IN_SPEED(domyślnie 'shift'). Chciałbym zaimplementować to do pluginu na malowanie(laser), że kiedy gracz naciśnie 'shift + e' zacznie malować. Dzięki za pomoc. pspspsps: happy vd
  15. 1 point
  16. 1 point
    A mogę wiedzieć jak dopisać? Edit: https://forums.alliedmods.net/showthread.php?p=602270 Ten plugin rozwiązał problem
  17. 1 point
    Też się musiałem chwilę zastanowić dlaczego to nie działa, ale znalazłem wyjaśnienie: Kiedy chcesz zacząć malować to naciskasz dwa klawisze, czyli shift i e. Zauważ, że praktycznie nigdy nie naciśniesz dwóch klawiszy idealnie w tym samym momencie. Z tego powodu, najpierw funkcja uruchamia się z wciśniętym IN_USE, a dopiero potem drugi raz z IN_USE oraz IN_SPEED (lub odwrotnie). Wówczas spełnia się ten warunek: if ((buttons & (IN_USE|IN_SPEED)) == (IN_USE|IN_SPEED)) niestety, wchodząc do kolejnego, zagnieżdżonego warunku masz już takie coś: if (!(g_iLastButtons[client] & IN_USE) && !(g_iLastButtons[client] & IN_SPEED)) lastButtons przechowuje zwyczajnie informacje jakie klawisze trzymałeś w ostatnim wywołaniu funkcji OnPlayerRunCmd. W momencie kiedy trzymasz obydwa klawisze w zmiennej 'buttons' będzie IN_USE oraz IN_SPEED, natomiast w lastButtons...tylko jeden klawisz. Dlatego właśnie if nigdy nie przechodzi i nie rozpoczyna się proces malowania. Po co w ogóle jest ten warunek? Ponieważ TraceEye(client, g_fLastPainter[client]); służy do rozpoczęcia procesu malowania. Później mógłbyś trzymać shift oraz e i przykładowo poruszać się WSAD - gdyby tego zagnieżdżonego warunku nie było, TraceEye uruchamiałby się za każdym razem. Rozwiązanie które teraz przychodzi mi do głowy (może da się to zrobić lepiej, ale to co wymyśliłem jest w miarę sensowne) to stworzenie dwóch globalnych zmiennych typu bool: paintEnabled oraz lastPaintEnabled. lastPaintEnabled będzie działał podobnie do lastButtons - sprawdza, czy malowanie zaczęło być dozwolone przy ostatnim wywołaniu OnPlayerRunCmd i będzie zapobiegało wielokrotnemu wywoływaniu TraceEye: // dodaj sobie do globalnych bool paintEnabled[MAXPLAYERS]; bool lastPaintEnabled; public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon) { if (!g_bEquipt[client]) return Plugin_Continue; if (!gc_bEnable.BoolValue) return Plugin_Continue; if ((buttons & (IN_USE|IN_SPEED)) == (IN_USE|IN_SPEED)) { if (!lastPaintEnabled[client]) { TraceEye(client, g_fLastPainter[client]); g_bPainterUse[client] = true; paintEnabled[client] = true; } } else if ((g_iLastButtons[client] & IN_USE) && (g_iLastButtons[client] & IN_SPEED)) { g_fLastPainter[client][0] = 0.0; g_fLastPainter[client][1] = 0.0; g_fLastPainter[client][2] = 0.0; g_bPainterUse[client] = false; paintEnabled[client] = false; } g_iLastButtons[client] = buttons; lastPaintEnabled[client] = paintEnabled[client]; return Plugin_Continue; } Sprawdź czy to działa w ogóle, bo musze zmykać i nie przekminiłem tego do końca
  18. 1 point
    To fajne pytanie, bo zahacza mocno o operacje bitowe Jeśli wcześniej nie operowałeś na bitach i chcesz dowiedzieć się więcej, możesz poczytać sobie o tym tutaj: Zakładając, że wiesz już o co chodzi, możemy przejść dalej... Aby wykryć naciśnięcie klawiszy, najlepiej użyć funkcji: OnPlayerRunCmd public Action OnPlayerRunCmd(int client, int & buttons, int & impulse, float vel[3], float angles[3], int & weapon, int & subtype, int & cmdnum, int & tickcount, int & seed, int mouse[2]) { // tutaj kod... } zmienna buttons zawiera wszystkie informacje o naciśniętych przyciskach W normalnej sytuacji, gdybyśmy chcieli przykładowo sprawdzić czy gracz naciska tylko klawisz E, robi się to tak: if (buttons & IN_USE) { ..... } Gdyby natomiast interesowało nad naciśnięcie dwóch klawiszy naraz, po prostu używamy ANDa: if (buttons & IN_USE && buttons & IN_SPEED) { .... } Ilość ampersantów '&' jest trochę przerażająca, ale jeśli ciężko to rozszyfrować można sobie pododawać nawiasy: if ((buttons & IN_USE) && (buttons & IN_SPEED)) { .... } @EDIT Można to załatwić jednym warunkiem: if ((buttons & (IN_USE|IN_SPEED)) == (IN_USE|IN_SPEED)) { ... } Albo ładniej: int yourFlags = IN_USE|IN_SPEED; if ((buttons & yourFlags) == yourFlags) { ... }
  19. 1 point
  20. 1 point
    Dzieje się tak dlatego, że PrintToChat (i wszystkie jego odmiany) działają tak, że każda wpisana na czat fraza "sama dodaje nową linię" Dlatego każde użycie PrintToChat to de facto nowa linia Nie używaj \n tylko zwyczajnie wypisuj po kolei czego potrzebujesz, a jeśli chciałbyś w jednym miejscu w kodzie zrobić dwie linie - po prostu dwa razy użyj PrintToChat
  21. 1 point
    Hej @MAGNET,mam pytanie. Ponieważ chce żeby tekst pojawił sie w nowej linijce i gdy używam \n tekst nie przemieszcza sie do nowej linijki tylko zmieia kolor. #include <sourcemod> #include <multicolors> #define Interval 30.0 Handle timerr; int counter = 0; char ads[][] = { "abc", "dfg", "Test\nTest" }; public void OnMapStart() { timerr = CreateTimer(Interval, Reklamy, _, TIMER_REPEAT); } public void OnMapEnd() { KillTimer(timerr); } public Action Reklamy(Handle timer, any data) { CPrintToChatAll("%s", ads[counter]); if (counter == sizeof(ads)-1) { counter = 0; } else { ++counter; } }
  22. 1 point
    Co to są KeyValues? KeyValues to prosta struktura bazująca na organizacji "drzewkowej" która zawiera zagnieżdżone w sobie sekcje które to zawierają klucze i wartości. Dla wzrokowców i objaśnienia sprawy, najprostsza struktura KeyValues wygląda w ten sposób: "sekcja" { "klucz" "wartosc" } Jak napisałem na samym początku, sekcje mogą być w sobie zagnieżdżone, czyli do sekcji możemy dopisać kolejną sekcję, do niej kolejną, itd. Przykład: "sekcja1" { "sekcja2" { "klucz" "wartosc" } } Przy budowaniu struktury KeyValues warto zaznaczyć, że nazwy sekcji i kluczy nie mogą się powtarzać w obrębie danej sekcji. Trochę zagmatwane, ale mówiąc prościej tworząc sekcję "admin" nie możemy później wewnątrz tej sekcji stworzyć np. 2 razy sekcję "Kowalski", czy 2 razy klucza "Kowalski", nie powinniśmy też tworzyć klucza "Kowalski" a potem sekcji "Kowalski" czy też odwrotnie - myślę, że zrozumiałe. Dodatkowo do KeyValues możemy swobodnie dodawać komentarze. Komentarze pozwalają Nam dodawać tekst, który zostanie pominięty przy wczytywaniu KeyValues poprzez plugin. Dodajemy je poprzez użycie dwóch slashy (//) oraz wypisaniu za nimi jakiegoś tekstu. Komentarz jest jednolinijkowy, czyli od kolejnego wiersza będziemy mogli dalej budować naszą strukturę. "sekcja" { "klucz1" "wartosc1" //To jest komentarz. Tekst ten zostanie pominiety przy wczytywaniu KeyValues przez plugin SourceMod "klucz2" "wartosc2" } Z KeyValues mogłeś(aś) się już spotkać wcześniej, np. przy konfigurowaniu połączenia z bazą danych w pliku addons/sourcemod/configs/databases.cfg. Dla przypomnienia taki plik wygląda mniej więcej tak: "Databases" { "driver_default" "mysql" // When specifying "host", you may use an IP address, a hostname, or a socket file path "default" { "driver" "mysql" "host" "localhost" "database" "db" "user" "root" "pass" "" //"timeout" "0" //"port" "0" } "storage-local" { "driver" "sqlite" "database" "sourcemod-local" } } Jak pracować z KeyValues w pluginie SourceMod? Na początku przyjmijmy pewne założenia. Mianowicie napiszemy sobie plugin, który będzie tworzył główne menu serwera. Plugin ten będzie wywoływał komendę w konsoli gracza po naciśnięciu konkretnej opcji w menu. Nasz plik KeyValues będzie w addons/sourcemod/configs, nazwiemy go main_server_menu.ini. Jego struktura będzie wyglądała w ten sposób (wiem, można by to zrobić lepiej): "MainServerMenu" { "sm_vip" { "name" "Sprawdź opis VIP'a" "command" "sm_vip" } "res" { "name" "Menu RoundSoundów" "command" "res" } "rs" { "name" "Resetuj statystyki" "command" "rs" } } Na początku zadeklarujmy zmienną globalną która będzie uchwytem dla naszego menu głównego oraz od razu dodajmy RegConsoleCmd do OnPluginStart: Menu g_mainServerMenu; public void OnPluginStart() { RegConsoleCmd("sm_menu", cmd_MainServerMenu); } public Action cmd_MainServerMenu(int client, int args) { g_mainServerMenu.Display(client, MENU_TIME_FOREVER); return Plugin_Handled; } Następnie zbudujmy funkcję, która będzie odpowiedzialna za stworzenie menu na podstawie naszych KeyValues. Niech to będzie funkcja BuildMenu void BuildMenu() { // kodzik... } Na samym jej początku stworzymy nasze menu: //tworzymy menu g_mainServerMenu = new Menu(MainServerMenu_Handler); g_mainServerMenu.SetTitle("Główne menu serwera", MENU_ACTIONS_ALL); Następnie stworzymy uchwyt do KeyValues oraz wczytamy jego strukturę z naszego pliku konfiguracyjnego: //budujemy sciezke do pliku addons/sourcemod/configs/main_server_menu.ini char path[256]; BuildPath(Path_SM, path, sizeof(path), "configs/main_server_menu.ini"); //tworzymy KeyValues oraz importujemy strukture z pliku KeyValues keyValues = new KeyValues("MainServerMenu"); keyValues.ImportFromFile(path); Warto powiedzieć. że KeyValues wcale nie muszą wykorzystywać żadnego pliku. Można operować chociażby na strukturze podanej jako ciąg znaków wczytanej z zewnętrznego źródła (np. zawartość zewnętrznej strony WWW). Jednak najczęściej oczywiście struktura jest wczytywana z pliku, tak jak w przykładzie wyżej. Co jeszcze jest istotne, to przy deklaracji new KeyValues jako paramtetr podajemy nazwę pierwszej sekcji w naszym pliku, znaną również jako sekcja główna czy węzeł główny (więcej niżej). Mamy już wczytany pliczek do uchwytu, teraz trzeba by się odpowiednio po tej całej strukturze poruszać, a potem wczytać odpowiednie wartości do menu. Przy poruszaniu się po pliku należy wiedzieć, że: Sekcja to też w pewnym sensie klucz, o czym warto pamiętać przy poruszaniu się po strukturze. Sekcja to taka oddzielna nazwa dla kluczy, które posiadają w sobie jeszcze inne klucze. Poruszając się po pliku mamy do czynienia z pozycją. Pozycja określa nam na którym poziomie podsekcji jesteśmy (inaczej poziom zagnieżdżenia) oraz na którym kluczu w danej sekcji jesteśmy. Mówiąc o pozycji mamy zatem do czynienia z dwoma wartościami. Jak to wygląda praktyce? A no tak: "MainServerMenu" //sekcja główna (węzeł główny) { "sm_vip" //pierwszy klucz w pierwszym poziomie zagnieżdżenia { "name" "Sprawdź opis VIP'a" //pierwszy klucz w drugim poziomie zagnieżdżenia "command" "sm_vip" //drugi klucz w drugim poziomie zagnieżdżenia } "res" //drugi klucz w pierwszym poziomie zagnieżdżenia { "name" "Menu RoundSoundów" //pierwszy klucz w drugim poziomie zagnieżdżenia "command" "res" //drugi klucz w drugim poziomie zagnieżdżenia } "rs" //trzeci klucz w pierwszym poziomie zagnieżdżenia { "name" "Resetuj statystyki" //pierwszy klucz w drugim poziomie zagnieżdżenia "command" "rs" //drugi klucz w drugim poziomie zagnieżdżenia } } Podstawowe funkcje do poruszania się po KeyValues: GotoFirstSubKey(); // Przesuwa pozycje do pierwszej podsekcji (poziom zagniezdzenia nizej) // Zwraca false w przypadku nieznalezienia podsekcji GotoNextKey(); // Przesuwa pozycje do kolejnego klucza/sekcji w danej sekcji // Zwraca false w przypadku nieznalezienia kolejnego klucza GoBack(); // Przesuwa pozycje o poziom zagniezdzenia wyzej. // Zwraca false, kiedy nie da sie juz wyzej przesunac (np. jestesmy w wezle glownym) Rewind(); // Ustawia pozycje wezla glownego. Podobny cel mozna osiagnac poprzez // uzywanie GoBack dopoki nie zwroci false, jednak ta funkcja jest optymalniejsza. JumpToKey(const char[] key, bool create=false); // Przenosi nas do klucza w danej sekcji o podanej nazwie w parametrze "key" // W przypadku create=true oraz jezeli dany klucz nie zostanie znaleziony, funkcja ten klucz stworzy. // Zwraca true w przypadku znalezienia klucza, false jezeli klucza nie znaleziono Pominąłem parametry które mogły by być trudne do zrozumienia a mają one swoje domyślne wartości. Dla ciekawskich wszystkie i w pełni opisane funkcje można znaleźć w dokumentacji. Okejj, więc co dalej po otwarciu pliku? Musimy przejść o jedno zagnieżdżenie niżej, a więc kolejny skrawek kodu będzie wyglądać tak: //nie znaleziono zadnej podsekcji? Plik jest nieprawidłowy, koniec :/ if (!keyValues.GotoFirstSubKey()) { PrintToServer("*** I had a problem while building a menu :/ Check main_server_menu.ini"); delete keyValues; return; } Po prawidłowym przejściu niżej, Nasza pozycja wygląda teraz tak: "MainServerMenu" //przed GotoFirstSubKey bylismy tutaj { "sm_vip" //po GotoFirstSubKey jestesmy tutaj { "name" "Sprawdź opis VIP'a" "command" "sm_vip" } "sm_res" { "name" "Menu RoundSoundów" "command" "sm_res" } "sm_rs" { "name" "Resetuj statystyki" "command" "sm_rs" } } Co teraz? Musimy wczytać dane z danej sekcji, dodać opcję do menu i przejść do kolejnego klucza (w Naszym wypadku kolejnej sekcji). Skorzystamy z pętli do while: char command[64], itemName[64]; do { //wczytujemy dane z danej sekcji keyValues.GetString("command", command, sizeof(command)); keyValues.GetString("name", itemName, sizeof(itemName)); //dodajemy opcje do menu g_mainServerMenu.AddItem(command, itemName); } while (keyValues.GotoNextKey()); //przechodzimy do kolejnej sekcji, dopoki te sekcje nie skoncza sie I to by było na tyle z wczytywanie, nasze menu jest już zbudowane ^^ Nie zapomnijmy o zamknięciu uchwytu no iii dajmy odpowiednie info serwerowi: //info dla serwera oraz oproznianie zmiennej kv delete keyValues; PrintToServer("*** Main server menu has been built"); Funkcję BuildMenu możemy zamknąć, a pod nią dodajmy funkcję Handler do naszego menu. Będziemy tam w momencie wybrania opcji wpisywać do konsoli gracza daną komendę zapisaną pod "info" tej właśnie opcji: //obsluga menu public int MainServerMenu_Handler(Menu menu, MenuAction action, int param1, int param2) { switch (action) { case MenuAction_Select: { int client = param1; //wczytujemy komende z pola "info" z danej opcji w menu oraz wywolujemy komende w konsoli char info[64]; menu.GetItem(param2, info, sizeof(info)); ClientCommand(client, info); } } } W OnPluginStart należy jeszcze wywołać funkcję od budowania menu: public void OnPluginStart() { RegConsoleCmd("sm_menu", cmd_MainServerMenu); BuildMenu(); } Nasz plugin jest gotowy Kod *.sp oraz plik *.ini podaję w załącznikach -> main_server_menu.ini server_menu.sp Co jeszcze warto wiedzieć? Do wczytywania wartości z klucza mamy kilka funkcji, które odpowiadają danemu typowi wartości. Możemy np. wartość wczytać od razu w type int, słuzy do tego funkcja GetNum która zwraca wartość klucza. Jest wiele innych ciekawych funkcji jak GetFloat, GetColor, itd. - więcej w dokumentacji Strukturę można zmieniać, a zmiany potem zapisać poprzez funkcję ExportToFile. Są odpowiednie funkcje do usuwania kluczy, ustawiania ich wartości, itd. Jak wyżej - więcej info na ten temat można znaleźć w dokumentacji KeyValues nie powinny być zbyt wielkie. Niedopuszczalne jest skorzystanie z KeyValues w celu zapisywania ilości zabójstw graczy. Przy tak dużej ilości danych zdecydowanie lepszym rozwiązaniem jest baza danych. Wyjątkiem może być plik w którym tych graczy jest mniej, np. plik z graczami którzy dostają specjalny bonus. Plików KeyValues staraj się nie otwierać zbyt często, najlepiej zrobić to maks. raz na mapę bądź też poprzez komendę do której dostęp ma tylko opiekun serwera. Zadanie domowe! Usuń klucz "command" i zamiast wczytywania go wykorzystaj funkcję GetSectionName dzięki której wczytasz nazwę sekcji, a co za tym idzie od teraz komendę będziesz podawać właśnie w nazwie sekcji. Rozwiązaniem możesz się pochwalić w tym temacie
  23. 1 point
    Opis Plugin pozwala na autobunnyhop gdy gracz przytrzymuje klawisz skoku (IN_JUMP - domyślnie spacja). Plugin jest kompatybilny z multijumpem. Cvary Changelog Download abh.sp Inne Plugin jest przeze mnie wspierany, gdyby pojawiły się jakieś bugi lub sugestie chętnie pomogę/wysłucham jeśli napiszecie poniżej Support Aktualnie support tego pluginu jest prowadzony przez @Vasto_Lorde
  24. 0 points
    dobra za malo spacji zrobilem xD problem rozwianany
  25. 0 points
    W szukanych stanowiskach są gracze i head admini? nie brzmi to poważnie, tak samo jak twoja pseudo-sieć jak możesz takie bzdety pisać xD
This leaderboard is set to Warsaw/GMT+01:00

O NAS Jesteśmy społecznością łączącą ludzi, którzy dzielą pasję poznawania CS:GO od strony programistycznej. Posiadamy duże zaplecze merytoryczne i zawsze cieszymy się, gdy dołączają do nas osoby gotowe do nauki. Gwarantujemy, że z odrobiną wytrwałości i otwartym umysłem bardzo szybko napiszesz swój pierwszy plugin. Zapraszamy! 🙂
Szablon wykonany z dużą ilością przez cyberpixelz / Mesharsky / Sitefuture
Forum dumnie napędzane przez: Invision Power Services, Inc.
×
×
  • Create New...