Ru/Dota 2 Workshop Tools/Scripting/Listening to game events

== Введение ==
Эта статья посвящена функции .
=== Пример 1 ===
Каждый раз когда уровень героя повышается, сообщение показывается всем игрокам:
 -- scripts/vscripts/addon_game_mode.lua
 function LevelUpMessage (eventInfo)
 Say(nil, "Один из героев повысил свой уровень!", false)
 end
 function Activate ()
 ListenToGameEvent("dota_player_gained_level", LevelUpMessage, nil)
 end
В данном скрипте используется две функции:
* LevelUpMessage: Здесь используется функция чтобы показать сообщение всем игрокам.
* Activate: Игра вызывает эту функцию один раз при загрузке карты. При запуске этой функции вызывается функция с соответствующими параметрами.
=== Пример 2 ===
Когда уровень героя достигает 6 показываем сообщение всем игрокам:
 -- scripts/vscripts/addon_game_mode.lua
 function Level6Message (eventInfo)
 if eventInfo.level == 6 then
 Say(nil, "Один из героев достиг 6-го уровня", false)
 end
 end
 function Activate ()
 ListenToGameEvent("dota_player_gained_level", Level6Message, nil)
 end
В функции Level6Message используется параметр eventInfo для получения уровня героя.
== Функция ListenToGameEvent ==
Здесь есть описание функции :
 int ListenToGameEvent(string eventName, handle functionToCall, handle context)
=== Параметры ===
; eventName
: Имя события, которое будет прослушиваться(привязываться) к данной функции. Полный список событий можно посмотреть в этом списке .
; functionToCall
: Функия, которая будет вызываться, когда событие будет срабатывать в игре.
; context
: Здесь можно использовать пустое значение nil или объект (например таблицу или функцию). Если вы используете объект в качестве параметра, то он будет передан функции functionToCall в качестве первого параметра, когда событие произойдет.
== Детали события ==
При вызове функции с параметрами, происходит вызов функции, привязанной к событию каждый раз когда происходит это событие. Когда игра вызывает эту функцию, она передает таблицу с параметрами события. Эти параметры содержат информацию о событии. На странице можно найти, какие параметры содержит то или иное событие. Например событие "dota_player_gained_level" имеет параметр level (смотри Пример 2 выше).
== Функция вызываемая при возникновении события ==
Если ваша функция определена как:
 function MyFunction (arg)
 -- здесь ваш код
 end
то вызов будет выглядеть так:
 ListenToGameEvent("some_event_name", MyFunction, nil)
Но что если ваша функция определена так?
 function MyClass:MyFunction (arg)
 -- здесь мой код
 end
Помни: Это короткий стиль
 function MyClass.MyFunction (self, arg)
 -- здесь мой код
 end
Ваша функция принимает два параметра. В данной ситуации вызов ListenToGameEvent будет выглядеть так:
 ListenToGameEvent("some_event_name", MyClass.MyFunction, ?)
или так (смотри ЧАВО ниже):
 ListenToGameEvent("some_event_name", Dynamic_Wrap(MyClass, "MyFunction"), ?)
Замените ? на объект, который будет использоваться в качестве self в функции. Далее идут примеры:
=== Пример 3 ===
Кога NPC создается, выводим на экран сколько раз это произошло:
 -- scripts/vscripts/addon_game_mode.lua
 if MyClass == nil then
 MyClass = class({})
 end
 function MyClass:InitGameMode ()
 self.numSpawned = 0
 ListenToGameEvent("npc_spawned", MyClass.MyFunction, self)
 end
 function MyClass:MyFunction ()
 self.numSpawned = self.numSpawned + 1
 print("NPC создался: " .. self.numSpawned .. " раз")
 end
 function Activate ()
 GameRules.MyAddon = MyClass()
 GameRules.MyAddon:InitGameMode()
 end
== Больше примеров ==
=== Пример 4 ===
Когда игрок выбирает героя, мы даем ему артефакт BlinkDagger:
 -- scripts/vscripts/addon_game_mode.lua
 function GiveBlinkDagger (hero)
 if hero:HasRoomForItem("item_blink", true, true) then
 local dagger = CreateItem("item_blink", hero, hero)
 dagger:SetPurchaseTime(0)
 hero:AddItem(dagger)
 end
 end
 function OnHeroPicked (event)
 local hero = EntIndexToHScript(event.heroindex)
 GiveBlinkDagger(hero)
 end
 function Activate ()
 ListenToGameEvent("dota_player_pick_hero", OnHeroPicked, nil)
 end
=== Пример 5 ===
Команда, которая первая совершила 5 убийств побеждает:
 -- scripts/vscripts/addon_game_mode.lua
 if CustomGameMode == nil then
 CustomGameMode = class({})
 end
 function Activate ()
 GameRules.CustomAddon = CustomGameMode()
 GameRules.CustomAddon:InitGameMode(5)
 end
 function CustomGameMode:InitGameMode (killLimit)
 self.killLimit = killLimit
 ListenToGameEvent("entity_killed", Dynamic_Wrap(CustomGameMode, "OnEntityKilled"), self)
 end
 function CustomGameMode:OnEntityKilled ()
 if PlayerResource:GetTeamKills(DOTA_TEAM_GOODGUYS) == self.killLimit then
 GameRules:SetGameWinner(DOTA_TEAM_GOODGUYS)
 elseif PlayerResource:GetTeamKills(DOTA_TEAM_BADGUYS) == self.killLimit then
 GameRules:SetGameWinner(DOTA_TEAM_BADGUYS)
 end
 end
=== Пример 6 ===
Когда юнит умирает, он оставляет после себя артефакт healing salve (item_flask):
 -- scripts/vscripts/addon_game_mode.lua
 function CreateDrop (itemName, pos)
 local newItem = CreateItem(itemName, nil, nil)
 newItem:SetPurchaseTime(0)
 CreateItemOnPositionSync(pos, newItem)
 newItem:LaunchLoot(false, 300, 0.75, pos + RandomVector(RandomFloat(50, 350)))
 end
 function OnEntityKilled (event)
 local killedEntity = EntIndexToHScript(event.entindex_killed)
 if killedEntity ~= nil then
 CreateDrop("item_flask", killedEntity:GetAbsOrigin())
 end
 end
 function Activate ()
 ListenToGameEvent("entity_killed", OnEntityKilled, nil)
 end
== ЧАВО ==
Вопрос: Что означает Dynamic_Wrap?
Ответ: Используйте Dynamic_Wrap если вы хотите, чтобы консольная команда также перезагружала прослушивание событий.
Больше деталей: предположим вы зарегистрировали прослушку события:
 ListenToGameEvent("some_event_name", MyClass.MyFunction, someObj)
Если вы изменили исходный код функции MyClass.MyFunction и затем вызвали команду "script_reload" в консоли, ваши изменения не будут видны. Это будет до сих пор старая версия функции MyClass.MyFunction. Чтобы это исправить используйте Dynamic_Wrap:
 ListenToGameEvent("some_event_name", Dynamic_Wrap(MyClass, "MyFunction"), someObj)
Теперь, каждый раз при возникновении события, игра проверяет функцию MyFunction вместе с MyClass и запускает его с новой функцией. Когда вы измените исходный код MyClass.MyFunction и вызовете команду "script_reload" в консоли, функция MyFunction будет обновлена.
Category:Dota 2 Workshop Tools