Skocz do zawartości

Witamy w Nieoficjalnym polskim support'cie AMX Mod X

Witamy w Nieoficjalnym polskim support'cie AMX Mod X, jak w większości społeczności internetowych musisz się zarejestrować aby móc odpowiadać lub zakładać nowe tematy, ale nie bój się to jest prosty proces w którym wymagamy minimalnych informacji.
  • Rozpoczynaj nowe tematy i odpowiedaj na inne
  • Zapisz się do tematów i for, aby otrzymywać automatyczne uaktualnienia
  • Dodawaj wydarzenia do kalendarza społecznościowego
  • Stwórz swój własny profil i zdobywaj nowych znajomych
  • Zdobywaj nowe doświadczenia

Dołączona grafika Dołączona grafika

Guest Message by DevFuse
 

Zdjęcie

Problem z timerem


Najlepsza odpowiedź Gargamel, 14.06.2014 17:01

Bardzo dziękuję, teraz wszystko działa :)

Przejdź do postu


  • Zamknięty Temat jest zamknięty
5 odpowiedzi w tym temacie

#1 Gargamel

    Nowy

  • Nowy

Reputacja: 0
Nowy

  • Postów:3
  • Imię:Piotr
  • Lokalizacja:Lublin
Offline

Napisano 13.06.2014 19:11

Witam.
Dzisiaj zacząłem pisać swój pierwszy plugin do CS'a.
Wraz z poradnikami, i z dawniejszymi doświadczeniami z Pawn (pisałem skrypty do gry SAMP), napisałem coś takiego:
#include <amxmodx>
#include <amxmisc>

#define PLUGIN "KickBots"
#define VERSION "0.1"
#define AUTHOR "Pan_Gargamel"

new g_kickmenu; // tworzymy zmienną globalną, uchwyt dla menu
new g_kickmenu_tak;
new g_kickmenu_nie;

public plugin_init() {
    register_plugin(PLUGIN, VERSION, AUTHOR);

    register_clcmd("say /kickbots", "kickmenu");
}

public plugin_cfg() { // tworzymy menu, np. w tej funkcji, bo wykonuje się ona tylko raz na mapę
    g_kickmenu = menu_create("Jestes za wyrzuceniem botow?", "kickmenuhandle");
    menu_additem(g_kickmenu, "Tak"); // item = 0
    menu_additem(g_kickmenu, "Nie"); // item = 1

    menu_setprop(g_kickmenu, MPROP_EXITNAME, "Wyjscie");
    
}

public kickmenu(id) {
    for(new i=0; i<32; i++)
    {
        if(!is_user_alive(i)) continue;
    
        menu_display(i, g_kickmenu)
        client_print(i, print_chat, "Gracz %id% rozpoczal glosowanie o wyrzucenie botow z serwera.");
        CreateTimer(30.0, kickmenu_wyniki);
    }
    
    return PLUGIN_HANDLED;
}

public kickmenuhandle(id, menu, item) { // funkcja posiada trzy parametry, id gracza, uchwyt menu oraz klawisz/item/opcję, która została wybrana
    if(item == MENU_EXIT) {
        return PLUGIN_HANDLED; // zamykamy menu, generalnie nie trzeba dodawać tutaj tego warunku, ale z przyzwyczajenia ja go tutaj dodaję, zresztą czasami nawet lepiej to robić na samej górze funkcji
    }

    switch(item) { // używamy switcha, pamiętamy, że wartość klawisza/itemu/opcji zaczyna się od 0
        case 0: {
            client_print(id, print_chat, "Zaglosowales za wyrzuceniem botow.");
            g_kickmenu_tak = g_kickmenu_tak + 1
        }
        case 1: {
            client_print(id, print_chat, "Zaglosowales przeciwko wyrzuceniu botow.");
            g_kickmenu_nie = g_kickmenu_nie + 1
        }
    }
public Action:kickmenu_wyniki(Handle:timer)
    {
        if(g_kickmenu_tak > g_kickmenu_nie || g_kickmenu_nie == g_kickmenu_tak)
        {
            amx_exec @SERVER "epb_removebots"
            for(new i=0; i<32; i++)
            {
                if(!is_user_alive(i)) continue;
                client_print(i, print_chat, "[Glosowanie] Boty zostaly wyrzucone z serwera!");
            }
        }
    }
    return PLUGIN_HANDLED;
}
Skrypt ma na celu robienie głosowania dla wszystkich graczy po wpisaniu /kickbots. Każdemu graczowi powinno się wyświetlić pytanie czy boty mają być wyrzucone, a jeśli po trzydziestu sekundach od startu głosowania suma głosów na tak będzie większa niż suma głosów na nie, boty zostaną wyrzucone.
 
Niektóre błędy udało mi się naprawić, ale kilku nie udało mi się rozwiązać:
bco7o8.jpg
GwynBleidD (14.06.2014 08:22):
Staraj się na przyszłość wklejać kod pluginu z numeracją linii i jako "czysty tekst" (przełączając się na edytor nie-graficzny lub używając przycisku wstawiania kodu), gdyż niektóre edytory (szczególnie amx_studio) wstawiają dodatkowo śmieci, jak dodatkowe puste linie, gdy wklejasz w edytorze graficznym. Więcej o tym tutaj: http://amxx.pl/topic...-kodu-na-forum/

  • +
  • -
  • 0

#2 VertekS

    Zaawansowany

  • Użytkownik

Reputacja: 48
Pomocny

  • Postów:80
  • Lokalizacja:amxxpc.exe
Offline

Napisano 14.06.2014 06:35

1. Nie ma takiej funkcji jak CreateTimer. Użyj set_task.

2. 

Action:kickmenu_wyniki(Handle:timer)

Zamień na:

public kickmenu_wyniki()

3. Funkcja kickmenuhandle nie jest zamknięta (brakuje nawiasu klamrowego na końcu funkcji).

4. W ten sposób nie wyrzuca się botów na serwerach CS'a. Najpierw musisz sprawdzić, czy gracz jest botem i wtedy wykonać na nim komendę AMXX - kick:

server_cmd("kick #%d ^"Gracz jest botem!^"", get_user_userid(id));

5. Po funkcji kickmenu_wyniki jest o jedna klamra za dużo.

6. Funkcja kickmenuhandle powinna zwracać wartość na końcu. Najlepiej zwrócić PLUGIN_HANDLED (i tak już nic nie robisz z tym menu po wybraniu opcji). Dodatkowo jeżeli wartość wybrana w menu to MENU_EXIT, zniszcz menu za pomocą:

menu_destroy(menu)

Kod jest brzydko napisany, ale to będziesz potrafił zoptymalizować sam p przeczytaniu artykułów w dziale tutoriale na tym forum (nie zawsze się operuje na 32 graczach / używa do tego pętli for). 


  • +
  • -
  • 1

#3 GwynBleidD

    Godlike

  • Przyjaciel

Reputacja: 1 869
Godlike

  • Postów:3 066
  • Steam:steam
  • Lokalizacja:Przemyśl
Offline

Napisano 14.06.2014 08:28

4. W ten sposób nie wyrzuca się botów na serwerach CS'a. Najpierw musisz sprawdzić, czy gracz jest botem i wtedy wykonać na nim komendę AMXX - kick:

A to zależy od botów :) Niektóre po kicknięciu ich z serwera po prostu wrócą i należy wykonać komendę, która wyłącza całkowicie boty, a nie je kickować. Ale to:
            amx_exec @SERVER "epb_removebots"
nie jest poprawnym wykonaniem jakiejkolwiek komendy. Do tego używamy server_exec.
server_cmd("kick #%d ^"Gracz jest botem!^"", get_user_userid(id));

Dodatkowo jeżeli wartość wybrana w menu to MENU_EXIT, zniszcz menu za pomocą:

menu_destroy(menu)

NIE NIE I JESZCZE RAZ NIE!! W tym przypadku menu_destroy NIE UŻYWAMY !!

menu_destroy używamy, gdy generujemy menu tuż przed jego wyświetleniem dla pojedynczego gracza i nie mamy zamiaru wyświetlać tego samego menu drugi raz. W tym przypadku menu jest generowane na początku działania pluginu i jest wyświetlane jedno dla wszystkich graczy, więc po użyciu menu_destroy będzie mógł zagłosować TYLKO JEDEN GRACZ, bo po zagłosowaniu menu już nie będzie istnieć!
  • +
  • -
  • 2

NIE pomagam na PW. Nie trudź się, na zlecenia nie odpiszę... Od pomagania jest forum.
NIE zaglądam w tematy wysłane na PW. Jeśli są na forum to prędzej czy później je przeczytam. Jeśli mam co w nich odpisać, to odpiszę.
 
1988650.png?theme=dark


#4 Gargamel

    Nowy

  • Autor tematu
  • Nowy

Reputacja: 0
Nowy

  • Postów:3
  • Imię:Piotr
  • Lokalizacja:Lublin
Offline

Napisano 14.06.2014 13:41

Teraz plugin kompiluje się bez żadnych błędów, lecz timer się nie uruchamia, a przynajmniej nie wykonuje się to co powinno po upłynięciu czasu.
 
Tutaj dałem set_task:
 

public kickmenu(id) {
    for(new i=0; i<32; i++)
    {
        if(!is_user_alive(i)) continue;
    
        menu_display(i, g_kickmenu)
        client_print(i, print_chat, "Gracz %id% rozpoczal glosowanie o wyrzucenie botow z serwera.");
        set_task(30.0, "kickmenu_wyniki", 666);
    }
    
    return PLUGIN_HANDLED;
}

 
A tutaj jest to co powinno się wykonać po 30 sekundach:
 

public kickmenu_wyniki()
{
    if(g_kickmenu_tak > g_kickmenu_nie || g_kickmenu_nie == g_kickmenu_tak)
    {
        server_cmd("pb removebots");
        for(new i=0; i<32; i++)
        {
            if(!is_user_alive(i)) continue;
            client_print(i, print_chat, "[Glosowanie] Boty zostaly wyrzucone z serwera!");
        }
    }
    else
    {
        for(new i=0; i<32; i++)
        {
            if(!is_user_alive(i)) continue;
            client_print(i, print_chat, "[Glosowanie] Boty nie zostaly wyrzucone z serwera!");
        }
    }
    return PLUGIN_HANDLED;
}

Użytkownik Gargamel edytował ten post 14.06.2014 13:47

  • +
  • -
  • 0

#5 VertekS

    Zaawansowany

  • Użytkownik

Reputacja: 48
Pomocny

  • Postów:80
  • Lokalizacja:amxxpc.exe
Offline

Napisano 14.06.2014 16:41

Więc tak...

To co napisze poniżej piszesz w public kickmenu(id).

Tworzysz 31 elementową tablicę na nick gracza (31 elementów = 31 znaków):

new voteplayer[31];

Następnie pobierasz nick gracza, który wpisał komendę:

get_user_name(id, voteplayer, sizeof(voteplayer));

Natyw register_clcmd przekazuje ID gracza jako parametr, więc warto to wykorzystać. Parametry funkcji zobacz w dokumentacji. Operator sizeof sprawdza wielkość łańcucha znaków (i nie tylko jego), co można w tym wypadku użyć do poinformowania get_user_name, ile liter nicku gracza ma pobrać. Warto pamiętać, że nick gracza w CS może mieć maksymalnie 31 liter. 

Następnie przejdź do linii:

client_print(i, print_chat, "Gracz %id% rozpoczal glosowanie o wyrzucenie botow z serwera.");

...która była powodem błędów. ID gracza w CS jest traktowane jak zwykła liczba całkowita. Trzeba tylko pamiętać, że to musi być liczba z zakresu 1 - 32.

W celu wyświetlenia, kto zaczął głosowanie wykorzystaj wcześniej przygotowaną zmienną na nick. Poprawny zapis wygląda tak:

client_print(i, print_chat, "Gracz %s rozpoczal glosowanie o wyrzucenie botow z serwera.", voteplayer);

Plugin będzie działać w 99% poprawnie. Podczas testów zauważyłem, że musisz się zabezpieczyć przed sytuacją, kiedy żaden gracz nie głosuje (obecnie w takiej sytuacji boty są wyrzucane z serwera).


Użytkownik VertekS edytował ten post 14.06.2014 16:41

  • +
  • -
  • 1

#6 Gargamel

    Nowy

  • Autor tematu
  • Nowy

Reputacja: 0
Nowy

  • Postów:3
  • Imię:Piotr
  • Lokalizacja:Lublin
Offline

Napisano 14.06.2014 17:01   Najlepsza odpowiedź

Bardzo dziękuję, teraz wszystko działa :)


  • +
  • -
  • 0




Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych