Перейти к содержанию

События#

Каталог всех событий amxpy.events. Метки: pre/post — фазы, на которые можно подписаться (первая — фаза по умолчанию), cancel() — действие можно отменить, result — можно ответить за игру. Поля с меткой «меняется в pre» можно присваивать в pre-обработчике. Руководство: События.

Плагин и карта#

Init#

pre

Плагин запущен: сервер стартовал или плагин загружен или перезагружен.

Здесь — подготовка, которой не место при импорте модуля: создать таблицы, открыть соединения, прочитать файлы.

Поле Тип Описание
hot_reload bool True — плагин перезагружен на лету, False — обычный старт
@plugin.on(events.Init)
async def setup(e: events.Init) -> None:
    await table.create()

MapStart#

pre

Карта загружена, Pawn-плагины инициализированы.

Поле Тип Описание
map str имя карты: de_dust2
@plugin.on(events.MapStart)
def map_start(e: events.MapStart) -> None:
    plugin.log.info("карта %s", e.map)

MapEnd#

pre

Карта заканчивается: последний шанс сохранить статистику раундов.

Поле Тип Описание
map str имя карты, которая заканчивается

Unload#

pre

Плагин останавливается: reason — "reload", "unload" или "shutdown".

При "reload" состояние можно передать новой версии через plugin.keep() или PlayerState(keep=True).

Поле Тип Описание
reason str "reload", "unload" или "shutdown"

Frame#

pre

Каждый кадр сервера (сотни раз в секунду).

Дорогое событие: для периодической работы используйте @plugin.every(сек).

Подключение и чат#

Connect#

precancel()result

Игрок подключается; e.reject("причина") — не пускать.

SteamID ещё не известен — проверки по нему делайте в Authorized.

Поле Тип Описание
player Player подключающийся игрок
name str ник при подключении
ip str IP-адрес без порта
@plugin.on(events.Connect)
def no_bad_names(e: events.Connect) -> None:
    if "admin" in e.name.lower():
        e.reject("Ник занят")

PutInServer#

pre

Игрок вошёл в игру: можно писать ему в чат, показывать меню и HUD.

Поле Тип Описание
player Player игрок, который вошёл в игру
@plugin.on(events.PutInServer)
async def greet(e: events.PutInServer) -> None:
    player = e.player  # событие живёт до первого await
    await sleep(3)
    player.print(f"!gПривет, !t{player.name}")

Authorized#

pre

SteamID игрока известен: место для загрузки его данных из базы.

Поле Тип Описание
player Player игрок, чей SteamID стал известен
steam_id str SteamID: STEAM_0:1:123
@plugin.on(events.Authorized)
async def load(e: events.Authorized) -> None:
    player = e.player
    stats[player] = await table.get(player.steam_id)

Disconnected#

pre

Игрок вышел. Данные PlayerState и задачи игрока удаляются сами после обработчиков.

Поле Тип Описание
player Player вышедший игрок; после обработчиков хэндл недействителен

Say#

precancel()

Сообщение в чат (say и say_team); e.cancel() — скрыть его.

Для команд вида /hp удобнее @plugin.command("/hp").

Поле Тип Описание
player Player кто пишет
text str текст сообщения без кавычек
team bool True — say_team (чат команды)
@plugin.on(events.Say)
def no_ads(e: events.Say) -> None:
    if "http" in e.text:
        e.cancel()

NameChange#

prepostReGameDLLcancel()

Игрок меняет ник.

e.cancel() в pre — останется старый ник.

Мёртвому игроку игра меняет ник только при следующем спавне: pre приходит дважды — при запросе и при самой смене, post — один раз, когда ник сменился.

Поле Тип Описание
player Player кто меняет ник
old str прежний ник
new str новый ник
@plugin.on(events.NameChange)
def no_rename_dead(e: events.NameChange) -> None:
    if not e.player.alive:
        e.cancel()

Игрок в игре#

PlayerSpawn#

prepostReGameDLLcancel()

Игрок возрождается.

В post оружие и здоровье уже выданы — бонусы ставьте там.

Поле Тип Описание
player Player возрождающийся игрок
@plugin.on(events.PlayerSpawn, post=True)
def bonus(e: events.PlayerSpawn) -> None:
    e.player.armor = 100

TakeDamage#

prepostReGameDLLcancel()result

Игрок получает урон.

В pre можно изменить damage и damage_type или отменить урон целиком через e.cancel().

Поле Тип Описание
victim Player кто получает урон
inflictor Player | Entity | None чем нанесён урон: игрок, граната или другая сущность
attacker Player | None кто нанёс урон; None — урон от мира (падение, trigger_hurt)
damage float урон; в pre можно менять: e.damage *= 2 меняется в pre
damage_type int Биты DMG_* (DMG_FALL, DMG_BULLET...); в pre можно менять меняется в pre
@plugin.on(events.TakeDamage)
def no_team_damage(e: events.TakeDamage) -> None:
    if e.attacker is not None and e.attacker.is_teammate(e.victim):
        e.cancel()

PlayerKilled#

prepostReGameDLLcancel()

Игрок убит.

Поле Тип Описание
victim Player убитый игрок
killer Player | None убийца; None — убил мир
headshot bool убийство в голову
weapon str оружие без префикса weapon_: ak47, knife, grenade
@plugin.on(events.PlayerKilled, post=True)
def headshot_bonus(e: events.PlayerKilled) -> None:
    if e.killer is not None and e.headshot:
        e.killer.money += 300

TeamSelect#

prepostReGameDLLcancel()

Игрок выбирает команду в меню.

e.cancel() — не пускать в команду; e.slot можно заменить в pre.

Поле Тип Описание
player Player кто выбирает
slot int пункт меню: 1 — T, 2 — CT, 5 — авто, 6 — зрители; в pre можно менять меняется в pre
@plugin.on(events.TeamSelect)
def no_spectators(e: events.TeamSelect) -> None:
    if e.slot == 6 and not e.player.has_access(Access.KICK):
        e.player.print("!tЗрителями могут быть только админы")
        e.cancel()

MoneyChange#

prepostReGameDLLcancel()

Деньги игрока меняются.

В pre можно изменить amount или отменить начисление.

Поле Тип Описание
player Player чьи деньги
amount int на сколько: плюс — начисление, минус — трата; в pre можно менять меняется в pre
reason MoneyReason за что: убийство, бонус раунда, покупка...
track bool True — игрок увидит изменение на экране
@plugin.on(events.MoneyChange)
def double_kill_reward(e: events.MoneyChange) -> None:
    if e.reason == MoneyReason.ENEMY_KILLED:
        e.amount *= 2

BuyWeapon#

prepostReGameDLLcancel()

Игрок покупает оружие.

e.cancel() в pre — покупка не состоится, деньги не спишутся.

Поле Тип Описание
player Player покупатель
weapon str оружие без префикса weapon_: ak47, awp, shield
@plugin.on(events.BuyWeapon)
def no_awp(e: events.BuyWeapon) -> None:
    if e.weapon == "awp":
        e.player.print("!tAWP на сервере запрещена")
        e.cancel()

DropItem#

prepostReGameDLLcancel()

Игрок выбрасывает предмет.

e.cancel() в pre — предмет останется у игрока.

Поле Тип Описание
player Player кто выбрасывает
item str предмет без префикса weapon_: ak47, c4
box Player | Entity | None выпавший weaponbox (только в post)
@plugin.on(events.DropItem)
def keep_bomb(e: events.DropItem) -> None:
    if e.item == "c4":
        e.cancel()

Раунд#

RoundStart#

post

Начался новый раунд — начало freezetime (RestartRound ReGameDLL).

FreezeEnd#

postReGameDLL

Закончился freezetime: игроки могут двигаться и стрелять.

@plugin.on(events.FreezeEnd)
def go(e: events.FreezeEnd) -> None:
    banner.show_all("Вперёд!")

RoundEnd#

prepostReGameDLLcancel()

Раунд завершается.

В pre можно отменить конец раунда или изменить delay до следующего.

Поле Тип Описание
winner Winner кто победил: Winner.T, Winner.CT, Winner.DRAW
reason int причина конца раунда (ScenarioEventEndRound ReGameDLL)
delay float секунд до следующего раунда; в pre можно менять меняется в pre
@plugin.on(events.RoundEnd, post=True)
def announce(e: events.RoundEnd) -> None:
    if e.winner == Winner.CT:
        server.print("!tКонтр-террористы!y победили")

Бомба и гранаты#

GrenadeThrow#

postReGameDLL 5.5+

Игрок бросил гранату.

Поле Тип Описание
player Player кто бросил
grenade Player | Entity | None сущность летящей гранаты
weapon str hegrenade, flashbang или smokegrenade
@plugin.on(events.GrenadeThrow)
def announce(e: events.GrenadeThrow) -> None:
    if e.weapon == "hegrenade":
        server.print(f"!t{e.player.name}!y бросил гранату")

BombPlanted#

postReGameDLL 5.5+

Бомба заложена.

Поле Тип Описание
player Player | None кто заложил
bomb Player | Entity | None сущность бомбы
@plugin.on(events.BombPlanted)
def planted(e: events.BombPlanted) -> None:
    banner.show_all("Бомба заложена!")

BombDefuseStart#

prepostReGameDLL 5.5+cancel()

Игрок начинает разминировать бомбу.

e.cancel() в pre — разминирование не начнётся.

Поле Тип Описание
player Player сапёр
bomb Player | Entity | None сущность бомбы
kit bool с набором сапёра (5 секунд вместо 10)
@plugin.on(events.BombDefuseStart, post=True)
def defusing(e: events.BombDefuseStart) -> None:
    server.print(f"!t{e.player.name}!y разминирует{' с набором' if e.kit else ''}")

BombDefuseEnd#

postReGameDLL 5.5+

Разминирование закончилось: успешно или прервано.

Поле Тип Описание
player Player | None сапёр
bomb Player | Entity | None сущность бомбы
defused bool True — бомба обезврежена, False — сапёр отпустил «E» или погиб
@plugin.on(events.BombDefuseEnd)
def defused(e: events.BombDefuseEnd) -> None:
    if e.defused and e.player is not None:
        e.player.money += 500

BombExploded#

postReGameDLL 5.5+

Бомба взорвалась.

Поле Тип Описание
player Player | None кто заложил (None — уже вышел)
bomb Player | Entity | None сущность бомбы
@plugin.on(events.BombExploded)
def boom(e: events.BombExploded) -> None:
    if e.player is not None:
        e.player.money += 300

Объект события#

Event #

Event(host: Host, args: list[Any], post: bool = False, result: Any = None)

Базовый класс событий; обработчики объявляются через @plugin.on(events.Имя).

Объект события живёт, пока идёт рассылка: до конца обработчика или до первого await. В pre-фазе можно менять изменяемые поля, отменить действие игры (cancel) и ответить за игру (e.result = ... или return).

cancelled #

cancelled: bool

True — действие игры отменено одним из обработчиков.

result #

result: Any

Ответ игры (в post) или ответ, назначенный обработчиком (в pre).

Назначить можно только у событий с результатом (Connect, TakeDamage) и только в pre: e.result = 0. То же самое — return значение.

cancel #

cancel() -> None

Отменить действие игры (только в pre-обработчике).

Исключения#
  • EventError — событие нельзя отменить или это post-фаза.
Пример#
@plugin.on(events.TakeDamage)
def god_mode(e: events.TakeDamage) -> None:
    if e.victim in gods:
        e.cancel()

stop #

stop() -> None

Не вызывать следующие обработчики этого события (в том числе других плагинов).

EventError #

Недопустимое действие с событием.

EventExpiredError #

Событие уже разослано (обычно — обращение после await).