Blokowanie strzału broni uwzględniając animacje i dźwięki klienta

Poniższy poradnik stanowi przetłumaczony angielskojęzyczny poradnik który znajduje się tutaj https://forums.alliedmods.net/showthread.php?t=41265
    Rejestracja odpowiednich forwardów i hooków.
    1. Dodanie odpowiednich includów.
    2. Plain text
      Copy to clipboard
      Open code in new window
      EnlighterJS 3 Syntax Highlighter
      #include <fakemeta>
      #include <engine></engine></fakemeta>
      #include <fakemeta> #include <engine></engine></fakemeta>
      #include 
      #include 
    3. Dalszy kod
    4. W plugin_init rejestrujemy forward FM_PlayerPreThink lub możemy użyć znanego z engine client_PreThink.
      Plain text
      Copy to clipboard
      Open code in new window
      EnlighterJS 3 Syntax Highlighter
      public client_PreThink(id)
      {
      }
      public client_PreThink(id) { }
      public client_PreThink(id)
      {
      
      }
      lub
      Plain text
      Copy to clipboard
      Open code in new window
      EnlighterJS 3 Syntax Highlighter
      register_forward(FM_PlayerPreThink, "PlayerPreThink")
      register_forward(FM_PlayerPreThink, "PlayerPreThink")
      register_forward(FM_PlayerPreThink, "PlayerPreThink")
      Dodatkowo w plugin_init dodajemy rejestrację FM_UpdateClientData
      Plain text
      Copy to clipboard
      Open code in new window
      EnlighterJS 3 Syntax Highlighter
      register_forward(FM_UpdateClientData, "UpdateClientData_Post", 1)
      register_forward(FM_UpdateClientData, "UpdateClientData_Post", 1)
      register_forward(FM_UpdateClientData, "UpdateClientData_Post", 1)
    5. Kod PreThinka
    6. W przypadku użycia engine dodajemy taki kod
      Plain text
      Copy to clipboard
      Open code in new window
      EnlighterJS 3 Syntax Highlighter
      public client_PreThink( id )
      {
      //Sprawdzenie gracza
      if( !is_user_alive(id) )
      return PLUGIN_CONTINUE;
      //Usunięcie przycisku ataku z aktualnie naciskanych przycisków
      entity_set_int( id, EV_INT_button, entity_get_int(id,EV_INT_button) & ~IN_ATTACK );
      return PLUGIN_CONTINUE;
      }
      public client_PreThink( id ) { //Sprawdzenie gracza if( !is_user_alive(id) ) return PLUGIN_CONTINUE; //Usunięcie przycisku ataku z aktualnie naciskanych przycisków entity_set_int( id, EV_INT_button, entity_get_int(id,EV_INT_button) & ~IN_ATTACK ); return PLUGIN_CONTINUE; }
      public client_PreThink( id )
      {
      //Sprawdzenie gracza
      
      if( !is_user_alive(id) )
      return PLUGIN_CONTINUE;
      
      //Usunięcie przycisku ataku z aktualnie naciskanych przycisków
      
      entity_set_int( id, EV_INT_button, entity_get_int(id,EV_INT_button) & ~IN_ATTACK );
      
      return PLUGIN_CONTINUE;
      }
      lub w przypadku użycia fakemety
      Plain text
      Copy to clipboard
      Open code in new window
      EnlighterJS 3 Syntax Highlighter
      //fakemeta method
      public PlayerPreThink( id )
      {
      //Sprawdzenie gracza
      if( !is_user_alive(id) )
      return FMRES_IGNORED;
      //Usunięcie przycisku ataku z aktualnie naciskanych przycisków
      set_pev( id, pev_button, pev(id,pev_button) & ~IN_ATTACK );
      return FMRES_HANDLED;
      }
      //fakemeta method public PlayerPreThink( id ) { //Sprawdzenie gracza if( !is_user_alive(id) ) return FMRES_IGNORED; //Usunięcie przycisku ataku z aktualnie naciskanych przycisków set_pev( id, pev_button, pev(id,pev_button) & ~IN_ATTACK ); return FMRES_HANDLED; }
      //fakemeta method
      public PlayerPreThink( id )
      {
      //Sprawdzenie gracza
      
      if( !is_user_alive(id) )
      return FMRES_IGNORED;
      
      //Usunięcie przycisku ataku z aktualnie naciskanych przycisków
      
      set_pev( id, pev_button, pev(id,pev_button) & ~IN_ATTACK );
      
      return FMRES_HANDLED;
      }
    7. Ustawianie UpdateClientData_Post
    8. UpdateClientData_Post posiada 3 argumenty które nas interesują. id – ID Użytkownika sendweapons – jest nieistotanym dla nas argumentem cd_handle – zawiera wszystkie informacje o użytkowniku , oczywiście wszystkie informacje mogą być modyfikowane.
      Plain text
      Copy to clipboard
      Open code in new window
      EnlighterJS 3 Syntax Highlighter
      public UpdateClientData_Post( id, sendweapons, cd_handle )
      {
      }
      public UpdateClientData_Post( id, sendweapons, cd_handle ) { }
      public UpdateClientData_Post( id, sendweapons, cd_handle )
      {
      
      }
    Aby zablokować strzał możemy użyć dwóch metod. Metoda 1 – Zmuszenie silnika aby myślał że gracz nie ma broni Modyfikujemy CD_ID które oznacza id broni. Ustawienie tego parametru na 0 powoduje że gra myśli że gracz nie ma broni więc animacja i dźwięki nie mogą być odegrane.
    Plain text
    Copy to clipboard
    Open code in new window
    EnlighterJS 3 Syntax Highlighter
    public UpdateClientData_Post( id, sendweapons, cd_handle )
    {
    //Sprawdzenie gracza
    if ( !is_user_alive(id) )
    return FMRES_IGNORED;
    //Używamy cd_handle ponieważ chcemy zmienić broń tylko dla jednego gracza jeśli chcieli byśmy zmienić ją dla wszystkich użyli byśmy wtedy 0
    set_cd(cd_handle, CD_ID, 0);
    return FMRES_HANDLED;
    }
    public UpdateClientData_Post( id, sendweapons, cd_handle ) { //Sprawdzenie gracza if ( !is_user_alive(id) ) return FMRES_IGNORED; //Używamy cd_handle ponieważ chcemy zmienić broń tylko dla jednego gracza jeśli chcieli byśmy zmienić ją dla wszystkich użyli byśmy wtedy 0 set_cd(cd_handle, CD_ID, 0); return FMRES_HANDLED; }
    public UpdateClientData_Post( id, sendweapons, cd_handle )
    {
    //Sprawdzenie gracza
    
    if ( !is_user_alive(id) )
    return FMRES_IGNORED;
    
    //Używamy cd_handle ponieważ chcemy zmienić broń tylko dla jednego gracza jeśli chcieli byśmy zmienić ją dla wszystkich użyli byśmy wtedy 0
    
    set_cd(cd_handle, CD_ID, 0);
    
    return FMRES_HANDLED;
    }
    Metoda 2 – Modyfikacja czasu ataku Osiągamy to poprzez modyfikacje CD_flNextAttack co jest wartością kiedy gracz może oddać ponownie zaatakować. Może być to użyte nie tylko do blokowania ale również do modyfikowania szybkości strzelania ( o czym później ). Aktualnie CD_flNextAttack ma tylko wartość większą od 0 tylko podczas przeładowania. Więc ustawienie tej wartości na wartość większą od 0 zmusza silnik do założenia że gracz przeładowuje ale animacja przeładowania nie jest odgrywana.
    Plain text
    Copy to clipboard
    Open code in new window
    EnlighterJS 3 Syntax Highlighter
    public UpdateClientData_Post( id, sendweapons, cd_handle )
    {
    //Sprawdzenie gracza
    if ( !is_user_alive(id) )
    return FMRES_IGNORED;
    //Pobieramy aktualny czas poprzez funkcje half-life i ustawiamy czas następnego ataku minimalnie później
    //Wartość musi być modyfikowana na bieżąca aby cały czas blokować atak
    set_cd(cd_handle, CD_flNextAttack, halflife_time() + 0.001 );
    return FMRES_HANDLED;
    }
    public UpdateClientData_Post( id, sendweapons, cd_handle ) { //Sprawdzenie gracza if ( !is_user_alive(id) ) return FMRES_IGNORED; //Pobieramy aktualny czas poprzez funkcje half-life i ustawiamy czas następnego ataku minimalnie później //Wartość musi być modyfikowana na bieżąca aby cały czas blokować atak set_cd(cd_handle, CD_flNextAttack, halflife_time() + 0.001 ); return FMRES_HANDLED; }
    public UpdateClientData_Post( id, sendweapons, cd_handle )
    {
    //Sprawdzenie gracza
    
    if ( !is_user_alive(id) )
    return FMRES_IGNORED;
    
    //Pobieramy aktualny czas poprzez funkcje half-life i ustawiamy czas następnego ataku minimalnie później
    //Wartość musi być modyfikowana na bieżąca aby cały czas blokować atak
    set_cd(cd_handle, CD_flNextAttack, halflife_time() + 0.001 );
    
    return FMRES_HANDLED;
    }
    Modyfikacja ROF ( Szybkostrzelność Broni ) Najpierw kilka zmiennych których potrzebujemy
    Plain text
    Copy to clipboard
    Open code in new window
    EnlighterJS 3 Syntax Highlighter
    new g_NextAttack[33]; //przechowuje czas następnego ataku
    new g_BlockAnim[33]; //Przechowuje czy plugin ma blokować animacje
    new CVAR_rof; //Pointer do cvaru określającego szybkostrzelność
    new g_NextAttack[33]; //przechowuje czas następnego ataku new g_BlockAnim[33]; //Przechowuje czy plugin ma blokować animacje new CVAR_rof; //Pointer do cvaru określającego szybkostrzelność
    new g_NextAttack[33];   //przechowuje czas następnego ataku
    new g_BlockAnim[33];    //Przechowuje czy plugin ma blokować animacje
    new CVAR_rof;         //Pointer do cvaru określającego szybkostrzelność 
    Metoda 1
    Plain text
    Copy to clipboard
    Open code in new window
    EnlighterJS 3 Syntax Highlighter
    public UpdateClientData_Post( id, sendweapons, cd_handle )
    {
    //Sprawdzenie gracza ( broni i czy jest żywym graczem )
    new Float:global_Time;
    global_get(glb_time, global_Time);
    new Float:ROF = get_pcvar_float(CVAR_rof);
    //Jeśli obecny czas nie jest jeszcze większy lub równy czasowi następnego ataku blokuj dalej atak
    //W innym przypadku pozwól na atak i zresetuj animacje
    if( global_Time < g_NextAttack[id] )
    {
    //Blokowanie ataku
    //Ustawienie zmiennej aby blokada nastąpiła również w prethinku
    g_BlockAnim[id] = 1;
    set_cd(cd_handle, CD_ID, 0);
    }
    else
    {
    //Pozwól na atak
    //Resetowanie zmiennej do blokady w prethinku
    g_BlockAnim[id] = 0;
    //Ustawianie czasu następnego ataku
    g_NextAttack[id] = global_Time + ROF;
    }
    return FMRES_HANDLED;
    }
    public UpdateClientData_Post( id, sendweapons, cd_handle ) { //Sprawdzenie gracza ( broni i czy jest żywym graczem ) new Float:global_Time; global_get(glb_time, global_Time); new Float:ROF = get_pcvar_float(CVAR_rof); //Jeśli obecny czas nie jest jeszcze większy lub równy czasowi następnego ataku blokuj dalej atak //W innym przypadku pozwól na atak i zresetuj animacje if( global_Time < g_NextAttack[id] ) { //Blokowanie ataku //Ustawienie zmiennej aby blokada nastąpiła również w prethinku g_BlockAnim[id] = 1; set_cd(cd_handle, CD_ID, 0); } else { //Pozwól na atak //Resetowanie zmiennej do blokady w prethinku g_BlockAnim[id] = 0; //Ustawianie czasu następnego ataku g_NextAttack[id] = global_Time + ROF; } return FMRES_HANDLED; }
    public UpdateClientData_Post( id, sendweapons, cd_handle )
    {
    //Sprawdzenie gracza ( broni i czy jest żywym graczem )
    
    new Float:global_Time;
    global_get(glb_time, global_Time);
    new Float:ROF = get_pcvar_float(CVAR_rof);
    
    //Jeśli obecny czas nie jest jeszcze większy lub równy czasowi następnego ataku blokuj dalej atak
    //W innym przypadku pozwól na atak i zresetuj animacje
    
    if( global_Time < g_NextAttack[id] )
        {
            //Blokowanie ataku
    
            //Ustawienie zmiennej aby blokada nastąpiła również w prethinku
    
            g_BlockAnim[id] = 1;
    
            set_cd(cd_handle, CD_ID, 0);        
        }
        else
        {
            //Pozwól na atak
    
            //Resetowanie zmiennej do blokady w prethinku
    
            g_BlockAnim[id] = 0;
    
            //Ustawianie czasu następnego ataku
    
            g_NextAttack[id] = global_Time + ROF;      
        }
    
        return FMRES_HANDLED;
    }
    Metoda 2
    Plain text
    Copy to clipboard
    Open code in new window
    EnlighterJS 3 Syntax Highlighter
    public UpdateClientData_Post( id, sendweapons, cd_handle )
    {
    //Sprawdzenie gracza ( broni i czy jest żywym graczem )
    new Float:global_Time;
    global_get(glb_time, global_Time);
    new Float:ROF = get_pcvar_float(CVAR_rof);
    //Jeśli obecny czas nie jest jeszcze większy lub równy czasowi następnego ataku blokuj dalej atak
    //W innym przypadku pozwól na atak i zresetuj animacje
    if( global_Time < g_NextAttack[id] )
    {
    //Blokowanie ataku
    //Ustawienie zmiennej aby blokada nastąpiła również w prethinku
    g_BlockAnim[id] = 1;
    set_cd(cd_handle, CD_flNextAttack, g_NextAttack[id]);
    }
    else
    {
    //Pozwól na atak
    //Resetowanie zmiennej do blokady w prethinku
    g_BlockAnim[id] = 0;
    //Ustawianie czasu następnego ataku
    g_NextAttack[id] = global_Time + ROF;
    }
    return FMRES_HANDLED;
    }
    public UpdateClientData_Post( id, sendweapons, cd_handle ) { //Sprawdzenie gracza ( broni i czy jest żywym graczem ) new Float:global_Time; global_get(glb_time, global_Time); new Float:ROF = get_pcvar_float(CVAR_rof); //Jeśli obecny czas nie jest jeszcze większy lub równy czasowi następnego ataku blokuj dalej atak //W innym przypadku pozwól na atak i zresetuj animacje if( global_Time < g_NextAttack[id] ) { //Blokowanie ataku //Ustawienie zmiennej aby blokada nastąpiła również w prethinku g_BlockAnim[id] = 1; set_cd(cd_handle, CD_flNextAttack, g_NextAttack[id]); } else { //Pozwól na atak //Resetowanie zmiennej do blokady w prethinku g_BlockAnim[id] = 0; //Ustawianie czasu następnego ataku g_NextAttack[id] = global_Time + ROF; } return FMRES_HANDLED; }
    public UpdateClientData_Post( id, sendweapons, cd_handle )
    {
    //Sprawdzenie gracza ( broni i czy jest żywym graczem )
    
    new Float:global_Time;
    global_get(glb_time, global_Time);
    new Float:ROF = get_pcvar_float(CVAR_rof);
    
    //Jeśli obecny czas nie jest jeszcze większy lub równy czasowi następnego ataku blokuj dalej atak
    //W innym przypadku pozwól na atak i zresetuj animacje
    
    if( global_Time < g_NextAttack[id] )
        {
            //Blokowanie ataku
    
            //Ustawienie zmiennej aby blokada nastąpiła również w prethinku
    
            g_BlockAnim[id] = 1;
    
            set_cd(cd_handle, CD_flNextAttack, g_NextAttack[id]);
        }
        else
        {
            //Pozwól na atak
    
            //Resetowanie zmiennej do blokady w prethinku
    
            g_BlockAnim[id] = 0;
    
            //Ustawianie czasu następnego ataku
    
            g_NextAttack[id] = global_Time + ROF;      
        }
    
        return FMRES_HANDLED;
    }
    W PlayerPreThink sprawdzamy zmienną g_BlockAnim ( Metoda fakemety ). Komentarze do kodu można znaleźć w wcześniejszej części wpisu.
    Plain text
    Copy to clipboard
    Open code in new window
    EnlighterJS 3 Syntax Highlighter
    public PlayerPreThink( id )
    {
    if( g_BlockAnim[id] )
    {
    set_pev( id, pev_button, pev(id,pev_button) & ~IN_ATTACK );
    g_BlockAnim[id] = 0;
    }
    return FMRES_HANDLED;
    }
    public PlayerPreThink( id ) { if( g_BlockAnim[id] ) { set_pev( id, pev_button, pev(id,pev_button) & ~IN_ATTACK ); g_BlockAnim[id] = 0; } return FMRES_HANDLED; }
    public PlayerPreThink( id )
    {
        if( g_BlockAnim[id] )
        {
            set_pev( id, pev_button, pev(id,pev_button) & ~IN_ATTACK );
    
            g_BlockAnim[id] = 0;
        }
    
        return FMRES_HANDLED;
    }

Dodaj komentarz

This site uses Akismet to reduce spam. Learn how your comment data is processed.