Глобални променливи или прехвърляне на информация чрез евент

Ако имате затруднения при изработката/преработката на даден плъгин - пишете тук, ще се опитаме да ви помогнем!
Аватар
sianbg
Извън линия
Потребител
Потребител
Мнения: 232
Регистриран на: 13 Ное 2017, 12:18
Получена благодарност: 1 път
Обратна връзка:

Глобални променливи или прехвърляне на информация чрез евент

Мнение от sianbg » 02 Яну 2018, 12:16

Здравейте. Имам опит с програмирането на няколко езика, но в pawn съм още нов. Искам да попитам има ли такова чудо като глобална променлива както в другите езици ? Съмнява ме да го има затова ще питам за друг начин. Мога ли да регистрирам мой евент в единия плъгин, а в другия да прихвана този евент. Целта е от 1 плъгин да синхронизирам някой неща с другия плъгин. Ако може пример как ще стане това.

Аватар
TheRedShoko
Извън линия
Модератор
Модератор
Мнения: 1016
Регистриран на: 06 Окт 2016, 07:42
Местоположение: Бургас
Се отблагодари: 5 пъти
Получена благодарност: 84 пъти

Глобални променливи или прехвърляне на информация чрез евент

Мнение от TheRedShoko » 02 Яну 2018, 12:42

Има как да се направи, но трябва да кажеш какво точно се опитваш да направиш, защото има няколко начина и зависи от контекста.

Аватар
sianbg
Извън линия
Потребител
Потребител
Мнения: 232
Регистриран на: 13 Ное 2017, 12:18
Получена благодарност: 1 път
Обратна връзка:

Глобални променливи или прехвърляне на информация чрез евент

Мнение от sianbg » 02 Яну 2018, 12:46

Еми точно ми трябва заради Gun Xp mod и Chat manager. Искам когато някой дигне лвл да му се смени префикса в чата. Имам ги в ДБ потребителите, но не искам да правя още една заявка за да ги взема и после някакъв тимер да проверява всеки дали е дигнал лвл. По-лесно ще е ако може Gun XP mod-a да извика евент с параметри кой играч е вдигнал лвл. В чат плъгина искам да прихвана този евент и да сменя префикса на потребителя.

Аватар
TheRedShoko
Извън линия
Модератор
Модератор
Мнения: 1016
Регистриран на: 06 Окт 2016, 07:42
Местоположение: Бургас
Се отблагодари: 5 пъти
Получена благодарност: 84 пъти

Глобални променливи или прехвърляне на информация чрез евент

Мнение от TheRedShoko » 02 Яну 2018, 13:32

Има 2 начина.
Първото е да погледнеш CreateMultiForward и ExecuteForward
Това ще направи същото нещо, което искаш.

Другият вариант е register_native и при всяко чат съобщение да взимаш нивото и да слагаш префикса според него. Ако не успееш да се справиш кажи и ще ти направя пример, за да го разбереш.

Аватар
sianbg
Извън линия
Потребител
Потребител
Мнения: 232
Регистриран на: 13 Ное 2017, 12:18
Получена благодарност: 1 път
Обратна връзка:

Глобални променливи или прехвърляне на информация чрез евент

Мнение от sianbg » 03 Яну 2018, 14:39

Пробвах, но нещо не успявам. Имам функция в 1 плъгин с име "client_zminfect" и искам да я изпълня от друг плъгин. Или функцията ми се извика много пъти или сървъра крашва. Ако може пример как да я извикам тази функция от друг плъгин. Искам еднократно да я изпълня.

Аватар
OciXCrom
Извън линия
Администратор
Администратор
Мнения: 7206
Регистриран на: 06 Окт 2016, 19:20
Местоположение: /resetscore
Се отблагодари: 117 пъти
Получена благодарност: 1295 пъти
Обратна връзка:

Глобални променливи или прехвърляне на информация чрез евент

Мнение от OciXCrom » 03 Яну 2018, 17:11

Ако става дума за функция (маркирана с "public"), няма нужда от нативи и подобни неща, обаче все пак е добре да се научиш как става това. Ще ти покажа как става без нативи и с нативи.
№1: Изпълняване на функция от друг плъгин с ползване на callfunc_begin:
  • Ако функцията изглежда така: public client_zminfect(id) и се намира в плъгина с име "zombie_plague.amxx", можеш да я изпълниш в друг плъгин по този начин:

    Код за потвърждение: Избери целия код

    callfunc_begin("client_zminfect", "zombie_plague.amxx")
    callfunc_push_int(id)
    callfunc_end()

№2: Създаване нативи за изпълняване на функцията.
  • В плъгина където е регистрирана, добавяш функция public plugin_natives() (ако вече има такава, игнорирай тази стъпка).
  • В нея добавяш: register_native("function_client_zminfect", "_function_client_zminfect") - първото име е това, което ще го ползваш в други плъгини, тъй че трябва да е различно от самото име на функцията в кода "client_zminfect", а второто е името на функцията която трябва да създадеш по-долу в кода (най-удобно е да сложиш същото име с "_" отпред, за да не става объркване).
  • Добавяш функцията _function_client_zminfect() по следния начин:

    Код за потвърждение: Избери целия код

    public _function_client_zminfect(iPlugin, iParams) // тези два параметри винаги се пишат при нативи, обаче почти никога не се ползват
    {
        client_zminfect(get_param(1)) // това е равно на client_zminfect(id)
    }
  • В другия плъгин добавяш native function_client_zminfect(id) под #include редовете.
  • Вече можеш да я изпълниш като ползваш function_client_zminfect(id).

Ако създаваш повече функции, удобно е да си направиш .inc файл и да вкараш всичките в друг плъгин ползвайки #include. Ако имаш затруднения, предостави това което си направил, за да ти кажем къде имаш грешки.

Аватар
TheRedShoko
Извън линия
Модератор
Модератор
Мнения: 1016
Регистриран на: 06 Окт 2016, 07:42
Местоположение: Бургас
Се отблагодари: 5 пъти
Получена благодарност: 84 пъти

Глобални променливи или прехвърляне на информация чрез евент

Мнение от TheRedShoko » 03 Яну 2018, 21:34

Примера с callfunc, който Crom-a е дал, работи само ако искаш да извикаш функция в точно определен плъгин и то само веднъж. Тоест ако искаш да извикаш дадена функция във всички плъгини, когато даден играч се превърне в зомби, ще трябва в плъгина, който отговаря за превръщането на играча в зомби, да се извиква дадена функция във всички плъгини, където е нужна. Пример: имаш плъгини pesho.amxx, gosho.amxx и ivan.amxx и взимаме някой зомби мод. Искаш в 3те плъгина да се изпълни дадено нещо, когато играч се инфектира. За да стане това чрез callfunc, трябва да отидеш в главния плъгин (в случая главния плъгин на ZM mod-a) и с callfunc да извикваш за всеки 1 от плъгините дадена функция. Не е особено практично.

Ако искаш да направиш event, който се извиква във всички плъгини, които са го прихванали, ще ти трябва forward. Ето един пример как се работи с тях.

Да вземем client_zminfect

Плъгинът, в който се намира главната логика, която определя кога да се извика функцията, се нуждае от промяна.
  • Като за начало ни трябва глобална за плъгина променлива, в която да запазим референция към foward-a. Декларираме си една променлива new g_iForwardHandle в началото на кода, преди plugin_init.
  • В plugin_init добавяме g_iForwardHandle = CreateMultiForward("client_zminfect", ET_IGNORE, FP_CELL) - Можеш да погледнеш тук какво точно е ET_IGNORE и FP_CELL и какви са другите варианти за тези параметри (след 2рият параметър на натива се изброяват типовете на параметрите на forward-a, в случая 1, който е от тип int)
  • Отиваме във функцията, която съдържа логиката. В примера, който е даден, отиваме във функцията, която отговаря за инфектирането на играч. Там казваме на forward-a да се задейства, извиквайки ExecuteForward. В нашият случай добавяме ExecuteForward(g_iForwardHandle,
    _, index)
    - Първият параметър е глобалната променлива (референцията към forward-a), втория параметър може да бъде игнориран (можеш да погледнеш в api-то за какво точно служи и кога да бъде използван), а след това изброяваме параметрите на функцията (в нашият случай има 1 параметър от тип int, който представлява индекса на инфектирания играч).
  • Отиваш в плъгина, където искаш да бъде прихванато действието (в нашият случай ще бъде pesho.amxx, gosho.amxx или ivan.amxx) и в началото, след библиотеките, добавяш forward client_zminfect(id)
  • В същия този плъгин си добавяш функция със същото име, тоест public client_zminfect(id) и в нея пишеш логиката, която искаш да бъде изпълнена, когато forward-a бъде извикан.
Ако ще свържиш само 2 плъгина можеш да използваш callfunc, но ако мислиш да го използваш за повече от 2, то тогава по-практичният вариант е този. Ако нещо не си разбрал, питай.

Аватар
sianbg
Извън линия
Потребител
Потребител
Мнения: 232
Регистриран на: 13 Ное 2017, 12:18
Получена благодарност: 1 път
Обратна връзка:

Глобални променливи или прехвърляне на информация чрез евент

Мнение от sianbg » 04 Яну 2018, 12:19

Благодаря много за точни отговор. Използвах Forward, но май не ми е нужен на мен. Гледах от този урок - http://amxxmodx.ru/core/amxmodxinc/322- ... kciyu.html

Мисля да ползвам най-простият начин - callfunc_begin ... А за бързина има ли разлика ?

Аватар
TheRedShoko
Извън линия
Модератор
Модератор
Мнения: 1016
Регистриран на: 06 Окт 2016, 07:42
Местоположение: Бургас
Се отблагодари: 5 пъти
Получена благодарност: 84 пъти

Глобални променливи или прехвърляне на информация чрез евент

Мнение от TheRedShoko » 05 Яну 2018, 05:51

Не съм сигурен, но е логично forward-a да е по-бърз, защото callfunc се налага да търси функцията и плъгина, а forward-a работи с референции. Все пак трябва да се тества.

Публикувай отговор
  • Подобни теми
    Отговори
    Преглеждания
     Последно мнение

Обратно към “Помощ в скриптирането”

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 5 госта