Как лучше написать плагин?

Тема в разделе "Программирование / Скриптинг", создана пользователем Vladius, 6 фев 2016.

  1. Vladius

    Vladius

    Сообщения:
    18
    Симпатии:
    0
    Такая ситуация. Я ввожу команду, и на следующем раунде игроки спавнятся с калашами. Как лучше реализовать:
    1) Хукнуть эвенты при загрузке плагина и в каждом евенте проверять переменную bool, которую команда будет ставить на true.
    2) В команде хукать эвенты, а в конце раунда разхукивать.
    Так:
    Код:
    #include <sourcemod>
    #include <sdktools>
    
    new bool:round=false;
    
    public void OnPluginStart()
    {
        HookEvent("player_spawn", Event_PlayerSpawned);
        HookEvent("round_end", Event_RoundEnd);
    }
    public void Event_PlayerSpawned(Handle:event, const String:name[], bool:dontBroadcast)
    {
        if(round)
        {
            int ent = GetPlayerWeaponSlot(GetClientOfUserId(GetEventInt(event,"userid")), 0);
            if(ent != -1)
            {
                RemovePlayerItem(GetClientOfUserId(GetEventInt(event,"userid")), ent);
                RemoveEdict(ent);       
            }
            GivePlayerItem(GetClientOfUserId(GetEventInt(event,"userid")), "weapon_ak47");
        }
    }
    public void Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
    {
            if(round){
                round=false;
            }
    }
    public Action:SpecialRound(client, args)
    {
        if (args != 1)
        {
            ReplyToCommand(client, "[SM] Usage: sm_specround <weapon>");
            return Plugin_Handled;
        }
        GetCmdArg(1, weapon, sizeof(weapon));
        round=true;
       
        return Plugin_Handled;
       
    }
    Или так:
    Код:
    #include <sourcemod>
    #include <sdktools>
    
    public void OnPluginStart()
    {
       
        HookEvent("round_start", Event_RoundStart);
        HookEvent("player_spawn", Event_PlayerSpawned);
        HookEvent("round_end", Event_RoundEnd);
       
    }
    public void Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
    {
        HookEvent("round_end", Event_RoundEnd);
    }
    public void Event_PlayerSpawned(Handle:event, const String:name[], bool:dontBroadcast)
    {
       
            int ent = GetPlayerWeaponSlot(GetClientOfUserId(GetEventInt(event,"userid")), 0);
            if(ent != -1)
            {
                RemovePlayerItem(GetClientOfUserId(GetEventInt(event,"userid")), ent);
                RemoveEdict(ent);       
            }
            GivePlayerItem(GetClientOfUserId(GetEventInt(event,"userid")), weapon);
       
    }
    public void Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
    {
        UnhookEvent("round_start");
        UnhookEvent("player_spawn");
        UnhookEvent("round_end");
           
       
    }
    public Action:SpecialRound(client, args)
    {
        if (args != 1)
        {
            ReplyToCommand(client, "[SM] Usage: sm_specround <weapon>");
            return Plugin_Handled;
        }
        GetCmdArg(1, weapon, sizeof(weapon));
        HookEvent("round_start", Event_RoundStart);
        HookEvent("player_spawn", Event_PlayerSpawned);
       
        return Plugin_Handled;
       
    }
    Надеюсь, что понятно объяснил.
     
  2. AlmazON

    AlmazON деревянный © yand3xmail

    Сообщения:
    4.590
    Симпатии:
    1.995
    Если не часто исполняется, то это. Но в самих событиях ещё тот бардак.
     
  3. DarklSide

    DarklSide

    Сообщения:
    685
    Симпатии:
    174
    Если (ан)хукать события, то отказатся в использовании команды в первом раунде.

    По идее сами события не часто исполняются, поэтому лучше их микс.

    При вслучае с булевой: использовать команду можно, только на этапе (после конца раунда и до начала следующего). Поэтому убрать событие "round_end" и попытаться проверять булевую при старте раунда, и (ан)хукать событие спавн игрока, а если csgo то лучше событие "round_prestart").
    Еще добавить булевую - на состояние собития спавна (есть его хук или нет).
     
    Последнее редактирование: 6 фев 2016
  4. AlmazON

    AlmazON деревянный © yand3xmail

    Сообщения:
    4.590
    Симпатии:
    1.995
    В событии round_start? Бесполезная затея, событие спавна вызывается до начала раунда. Оффтоп
    Вот тут сработает верно. Оффтоп
    Вообще, вместо события спавна лучше использовать хук "игрок взял/поднял оружие", так как оно может лежать на карте/выдаваться другими плагинами, да и покупать никто не запретил... Оффтоп
     
    Последнее редактирование: 6 фев 2016
  5. Vladius

    Vladius

    Сообщения:
    18
    Симпатии:
    0
    Я для своего авп сервера делаю, так что на карте точно ничего не валяется.

    Если дописать 1 код, то можно будет использовать и в середине раунда, я пока так и делаю. Можете пояснить, что такое микс?
     
  6. DarklSide

    DarklSide

    Сообщения:
    685
    Симпатии:
    174
    Их сочетание:
    PHP:
    #include <sdktools>
    #pragma newdecls required
    bool round false;
    bool spawn false;
    char weapon[20];
    public 
    void OnPluginStart()
    {
       
    HookEvent("round_prestart"Event_RoundStart);
       
    RegAdminCmd("sm_specround"SpecialRoundADMFLAG_GENERIC"sm_specround ak47");
    }
    public 
    void Event_RoundStart(Event event, const char[] namebool dontBroadcast)
    {
       if (
    round)
       {
         
    HookEvent("player_spawn"Event_PlayerSpawned);
         
    round false;
         
    spawn true;
       }
       else if (
    spawn)
       {
         
    UnhookEvent("player_spawn"Event_PlayerSpawned);
         
    spawn round;
       }
    }
    public 
    void Event_PlayerSpawned(Event event, const char[] namebool dontBroadcast)
    {
       
    int client GetClientOfUserId(event.GetInt("userid"));
       
    int ent GetPlayerWeaponSlot(client0);
       if (
    ent != -1)
       {
         
    RemovePlayerItem(clientent);
         
    RemoveEdict(ent);
       }
       
    GivePlayerItem(clientweapon);
    }
    public 
    Action SpecialRound(int clientint args)
    {
       if (
    args != 1)ReplyToCommand(client"[SM] Usage: sm_specround <weapon>");
       else
       {
         
    GetCmdArgString(weaponsizeof(weapon));
         
    Format(weaponsizeof(weapon), "weapon_%s"weapon);
         
    round true;
       }
       return 
    Plugin_Handled;
    }
    public 
    Action CS_OnBuyCommand(int client, const char[] weapons)
    {
       if (
    spawn)
       {
         
    printCl(client);
         return 
    Plugin_Handled;
       }
       return 
    Plugin_Continue;
    }
    void printCl(int client)
    {
       
    PrintToChat(client"Раунд на выданное оружие");
    }
    public 
    Action CS_OnCSWeaponDrop(int clientint weaponIndex)
    {
       if (
    spawn && !GetEntityClassname(weaponIndexweaponsizeof(weapon))) // && GetEntityClassname... - не разрешить дроп на выданное оружие.
       
    {
         
    printCl(client);
         return 
    Plugin_Handled;
       }
       return 
    Plugin_Continue;
    }
     
    Последнее редактирование: 8 фев 2016
  7. AlmazON

    AlmazON деревянный © yand3xmail

    Сообщения:
    4.590
    Симпатии:
    1.995
    Ничего не забыто? Нет логики.
    Забавно даже) Пытаемся форматировать строку для оружия из количества записанных символов)
    На
    Обычно нет зон покупок, как я понимаю - не требуется.
    Сейчас никуда не ведёт... Оффтоп
     
    Последнее редактирование: 6 фев 2016
  8. Monomizer

    Monomizer Мимо пробегал Супер-модератор

    Сообщения:
    1.527
    Симпатии:
    201
    Оффтоп
     
  9. DarklSide

    DarklSide

    Сообщения:
    685
    Симпатии:
    174
    Есть.
    Забавно.
    P.S.: если сначала не идет получение any.
    Некоторое мульти (без использования pickup'a и получения тайма времени).
     
  10. AlmazON

    AlmazON деревянный © yand3xmail

    Сообщения:
    4.590
    Симпатии:
    1.995
    @Monomizer, Оффтоп
    Наконец заметил фигурную скобочку... Ты бы ещё 2 стиля написания впихнул)
    Ну какая нам разница, удалось получить classname оружия или нет? Вот если бы его после сравнить... Тогда получим фильтр:
     
    Последнее редактирование: 6 фев 2016
  11. DarklSide

    DarklSide

    Сообщения:
    685
    Симпатии:
    174
    PHP:
    public void Event_RoundStart(Event event, const char[] namebool dontBroadcast)
    {
       if (
    round)
       {
         
    HookEvent("player_spawn"Event_PlayerSpawned);
         
    round false;
       }
       else if (
    spawn){UnhookEvent("player_spawn"Event_PlayerSpawned);
       
    spawn round;
    }}

    P.S.: при вставке сообщения удалил блок, после парсинга TextFX'ом.
     
  12. AlmazON

    AlmazON деревянный © yand3xmail

    Сообщения:
    4.590
    Симпатии:
    1.995
    Оффтоп
    Не будет работать из-за этого, не выдаст ничего. Количество символов, полученное от 1 аргумента здесь пытаемся вставить в строку строкой.
     
  13. DarklSide

    DarklSide

    Сообщения:
    685
    Симпатии:
    174
    PHP:
    public Action SpecialRound(int clientint args)
    {
        if (
    args != 1)ReplyToCommand(client"[SM] Usage: sm_specround <weapon>");
        else
        {
            
    GetCmdArgString(weaponsizeof(weapon));
            
    Format(weaponsizeof(weapon), "weapon_%s"weapon);
            
    spawn true;
            
    round true;
        }
        return 
    Plugin_Handled;
    }
    В этом случае лучше получать все строку, раз она задана.
     
    Последнее редактирование: 10 фев 2016
  14. Vladius

    Vladius

    Сообщения:
    18
    Симпатии:
    0
    Честно говоря, я так до конца и не уяснил ответ на свой вопрос.
     
  15. inklesspen

    inklesspen После "Р" в слове "Лопата"

    Сообщения:
    856
    Симпатии:
    201
    Возможно это не то, что вам нужно, но времени у меня щас не особо много, а помочь хочу:)
     

    Вложения:

  16. Vladius

    Vladius

    Сообщения:
    18
    Симпатии:
    0
    Спасибо, но дело в том, что у меня уже есть рабочий плагин, просто хотел оптимизировать. Сейчас у меня уже другая проблема. После последнего обновления на карте awp_lego_2 если был установлен раунд на калашх, то в следующем раунде у выживших игроков калаши не пропадут, как раньше. То есть нужно самому удалять у них калаши. А как это сделать я не знаю.
     
  17. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Получаешь слот оружия GetPlayerWeaponSlot и делаешь цикл по всем слотам оружия и удаляешь.
    Цикл: for (int i = 0; i < 5; ++i)
     
  18. Vladius

    Vladius

    Сообщения:
    18
    Симпатии:
    0
    Так не получится, потому что умершие игроки останутся без оружия. Я пока жду фикса, но вот уже 4 обновления ничего не решают.
     
  19. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    А зачем тебе умершим оружие? что за бред.
     
  20. Vladius

    Vladius

    Сообщения:
    18
    Симпатии:
    0
    Короче, у игроков оружия просто не будет от таких действий.