[SourcePawn] Уроки (Содержание)

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

  1. R1KO

    R1KO Супер-модератор

    Сообщения:
    6.005
    Симпатии:
    2.994
    [SourcePawn] Уроки - Содержание

    1. Основы языка (Часть 1) (Часть 2)
    2. Установка и компиляция плагинов
    3. События (Events)
    4. Форматирование текста и мультиязычность
    5. DataPack
    6. Таймеры
    7. Панели и меню
    8. Структуры Key Values
    9. Atd array
    10. Atd trie
    11. Админ меню

    • Работа с файлами
    • Работа с базами данных
    • Нативы, Функции, форварды (API) или "Как создать свой inc"

    Возможны изменения и дополнения.

    Без номера - не определился в последовательности.
    Кто что еще хочет увидеть - пишите.

    Уроки будут выходить в txt виде, а тех уроках где нужна визуализация будет видео формат.
     
    Последнее редактирование: 22 ноя 2016
    antonnn598, Rabb1t, SHAREN и 5 другим нравится это.
  2. tonline_kms65

    tonline_kms65 Read Only

    Сообщения:
    77
    Симпатии:
    10
    @R1KO,
    У меня один, для меня очень серьёзный вопрос. Как определить какие таймеры запущены?
    И еще вопрос - могу я ID таймера объявить не HANDLE а int или new?
    Например:
    Код:
    new таймер;
    таймер = CreateTimer("Функция",.......);
    Я здесь четко знаю ID таймера. И по нему могу отследить работу этого таймера, со всеми вытекающими.
    А HANDE я не врубаюсь. Не могу понять.

    И третье - как правильно получить работает таймер или нет
    if (Timers[client] != null)
    или так
    if (Timers[client] != INVALID_HANDLE)
    как правильнее?

    Меня этот INVALID_HANDLE просто убивает.
     
    Последнее редактирование: 17 окт 2016
  3. CrazyHackGUT

    CrazyHackGUT Меня здесь нет

    Сообщения:
    902
    Симпатии:
    556
  4. tonline_kms65

    tonline_kms65 Read Only

    Сообщения:
    77
    Симпатии:
    10
    Несколько таймеров создаются CreateDataTimer (данных несколько - приходится паковать).
    объявление
    new Handle:Timer[MAXPLAYERS + 1] = INVALID_HANDLE;

    Код:
    public Action:OnRoundStart(Handle:event, const String:name[], bool:dontBroadcast){   // при рестарте хочу сбросить (поубивать) все таймеры
    
    for(new i = 1; i <= MaxClients; i++){                      // цикл по всем игрокам
    
    if (Timer[i] != INVALID_HANDLE){                      // если например этот таймер запущен у кого то        
    KillTimer(Timer[i]);                                                     // убиваем таймер
    Timer[i] = INVALID_HANDLE;
    L 10/17/2016 - 17:59:00: [SM] Exception reported: Invalid timer handle 130c02d3 (error 3)
    L 10/17/2016 - 17:59:00: [SM] Call stack trace:
    L 10/17/2016 - 17:59:00: [SM] [0] KillTimer
    такого плана ошибка. Где косяк?
     
    Последнее редактирование: 17 окт 2016
  5. AlmazON

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

    Сообщения:
    4.591
    Симпатии:
    1.996
    Таймер возвращает Handle, иначе будет несовпадение тегов. Да и какой в этом смысл? Через int таймер не остановить, а условно и сам можешь подписать, приравняв глобальную переменную к "номеру" работающего таймера.
    Первое - новый синтаксис, второе - старый. Разницы абсолютно никакой.
    После выполнения таймера (не повторяющегося) также необходимо делать сброс его Handle (внутри таймера):
    Код:
    Timer[i] = INVALID_HANDLE;
     
    CrazyHackGUT нравится это.
  6. tonline_kms65

    tonline_kms65 Read Only

    Сообщения:
    77
    Симпатии:
    10
    Все таймеры повторяющиеся. Про разовые зачем бы я писал?
     
    Последнее редактирование: 17 окт 2016
  7. AlmazON

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

    Сообщения:
    4.591
    Симпатии:
    1.996
    Частая ошибка: флаг TIMER_FLAG_NO_MAPCHANGE у таймера, а его Handle не сброшено в OnMapEnd().
    Оффтоп Хочешь конкретный, точный ответ - изволь приложить код, где фигурируют таймеры и их Handle.
     
    CrazyHackGUT нравится это.
  8. tonline_kms65

    tonline_kms65 Read Only

    Сообщения:
    77
    Симпатии:
    10
    Может быть нужно в OnMapEnd() это сделать. Я не делал там.
     
  9. R1KO

    R1KO Супер-модератор

    Сообщения:
    6.005
    Симпатии:
    2.994
    @tonline_kms65, покажи код создания таймера и других действий с ними
     
  10. tonline_kms65

    tonline_kms65 Read Only

    Сообщения:
    77
    Симпатии:
    10
    @R1KO,
    Ок. Домой приеду,покажу. Я поэтому и хотел делать в цикле такие дела. Но не хочет здесь цикл на бесконечный зацикливаться. Сколько не пробовал,где то ограничение стоит.
    --- Добавлено позже ---
    Что вообще такое это самое Handle.
    Это переменная, функция или еще что.
    Не могу сообразить что это за хрень.
    Если понять что это, то возможно и проблемы отпадут.
    Написали бы тутор по это. Таких как я наверняка много. А так просто тыкать абы что это не дело. Нужно знать что это такое.
     
    Последнее редактирование: 17 окт 2016
  11. Grey83

    Grey83

    Сообщения:
    367
    Симпатии:
    106
    PHP:
    new Handle:Timer[MAXPLAYERS 1] = INVALID_HANDLE;
    Насколько я помню при использовании new переменная всегда равняется нулю, строка - нулевой строке, а хэндл - INVALID_HANDLE.
    Плюс тут у тебя массив, которому назначают значение обычно так:
    PHP:
    new SomeInt[SomeConst] = {-1, ...};
    new 
    Float:SomeFloat[AnotherConst] = {0.1, ...};
    new 
    String:SomeString[][] = {"FistString""SecondString""ThirdString"};
    new 
    bool:SomeBool[OneMoreConst] = {true, ...}
    Если значения массива все одинаковые и известен размер массива, то достаточно только один раз указать это значение. В случае разных значений делается как и со строчной переменной в примере.

    Так вот я к чему: у тебя при компиляции не всплывало предупреждение, что у тебя размеры массива не соответствуют или аналогичное что-то?
     
  12. CrazyHackGUT

    CrazyHackGUT Меня здесь нет

    Сообщения:
    902
    Симпатии:
    556
    Handle - ссылка на объект в памяти сервера.
     
  13. R1KO

    R1KO Супер-модератор

    Сообщения:
    6.005
    Симпатии:
    2.994
    дескриптор, который указывает на объект.
     
  14. Grey83

    Grey83

    Сообщения:
    367
    Симпатии:
    106
  15. tonline_kms65

    tonline_kms65 Read Only

    Сообщения:
    77
    Симпатии:
    10
    Конечно нет. Если бы сообщение было, то и проблем бы не возникло. Компилятор отрабатывает четко, без ошибок.

    @R1KO,
    Создаю таймер:
    Код:
    //------------------------------------------------------------------------------
    LoopShowHudCountSM_Grenade(client, ent) {                                       //
    int iCount = sm_count[ent];   // это кол-во гранат этого типа (дымовые). Глобал. данные изменяются при создании гранат++ и их уничтожении--.
    if (iCount > 0){
    
    if (camera[client] == true){                                                    // в HUD  один раз
    SetHudTextParamsEx(0.85, 0.85, 3.0, {0,147,3,255}, {181,255,84,255}, 2, 0.1, 0.1, 0.1);
    ShowHudText(client, -1, "Smoke %i", iCount);
    }
    if (ShowHud_smokeGrenadeCount[client]  != INVALID_HANDLE){       // вот этот головняк. Если таймер запущен
    KillTimer(ShowHud_smokeGrenadeCount[client]);                                       //  убиваю его
    ShowHud_smokeGrenadeCount[client]  = INVALID_HANDLE;               // очищаю данные
    }
    
    new Handle:Pack3;
    ShowHud_smokeGrenadeCount[client] = CreateDataTimer(3.0, timer_LoopShowHudCountSM_Grenade, Pack3, TIMER_FLAG_NO_MAPCHANGE|TIMER_DATA_HNDL_CLOSE);
    WritePackCell(Pack3, GetClientUserId(client));                // Пакуем обновленные данные в таймер
    WritePackCell(Pack3, ent);
      }
    return;
    }
    //------------------------------------------------------------------------------
    public Action:timer_LoopShowHudCountSM_Grenade(Handle:timer, any:Pack3) {
    ResetPack(Pack3);                                                   
    int iClient      = ReadPackCell(Pack3);
    int iEnt         = ReadPackCell(Pack3);
    iClient          = GetClientOfUserId(iClient);
    LoopShowHudCountSM_Grenade(iClient, iEnt);
    }

    Почему сделал так? Я пробовал делать в самом таймере TIMER_REPEAT.
    Чем-то мне этот вариант не понравился. Почему то я эту затею оставил.
    Поэтому остановился на своём, он мне как то привычнее и понятнее.
    --- Добавлено позже ---
    Убиваю таймеры при:
    1. Разрушении Дрона (с приатаченными гранатами, и соответственно запущенными таймерами)
    2. Если граната к которой привязан этот таймер брошена Дроном и взорвалась.(Во, кстати, гранат может быть не одна, может быть отсюда и косяк? В таймер я получаю данные только о количестве гранат для определенного Дрона)
    3. При рестарте (если таймеры вдруг остались запущенны, а такое уже было)
    Больше таймеры я нигде не трогаю.

    Сделал краткое видео для именно этих таймеров.
     
    Последнее редактирование: 18 окт 2016
  16. CrazyHackGUT

    CrazyHackGUT Меня здесь нет

    Сообщения:
    902
    Симпатии:
    556
    Оффтоп
     
    AlmazON нравится это.
  17. tonline_kms65

    tonline_kms65 Read Only

    Сообщения:
    77
    Симпатии:
    10
    @CrazyHackGUT,

    А ты бы как сделал? Запускать из основной вспомогательную? Я же говорю - почему то меня это не устроило. Я не помню уже почему.
    Я так и делал сначала. потом плюнул и вернулся к своему проверенному.
    Старый, новый, работает - работает. И так головняка хватает помимо sourcepawnа. Да честно сказать я даже и не знаю где там новый где старый. Мне как то по барабану:biggrin:. Я даже и не знал что там есть где то новый а где-то старый. Для меня все едино. Ну вооооообще.
    Всегда число - интегром, строка - строкой, бол - болом и т.д, поэтому этот инвалид HANDLE меня загрузил просто по полной. Всегда старался держаться от него подальше, но вот пришлось встретится, т.к. другого решения пока не вижу.
    Не могу сообразить что это такое и всё. Возможно это огромная помощь и облегчение задачи, но для меня это есть проблема.

    Насчет табуляции, всегда без отступов, уж не обессудь.
    У меня синтаксис Python, я всегда в нем работал. Подсветка намного удачнее.
    Я на будущее, для этого сайта, буду переводить в другой синтаксис.
     
    Последнее редактирование: 18 окт 2016
  18. R1KO

    R1KO Супер-модератор

    Сообщения:
    6.005
    Симпатии:
    2.994
  19. tonline_kms65

    tonline_kms65 Read Only

    Сообщения:
    77
    Симпатии:
    10
    @R1KO,
    Я попробую еще один вариант, если не получится я тебе скину код который непосредственно касается этой проблемы. Подбирание с земли ENT, запуск таймера, выброс ENT, разрушение ENT. (ENT гранат)
    Весь код это уже почти 2000 строк.
     
  20. AlmazON

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

    Сообщения:
    4.591
    Симпатии:
    1.996
    Последний флаг итак включается в таймер-пак.