События#
Каталог всех событий amxpy.events. Метки: pre/post — фазы, на которые можно
подписаться (первая — фаза по умолчанию), cancel() — действие можно отменить,
result — можно ответить за игру. Поля с меткой «меняется в pre» можно присваивать
в pre-обработчике. Руководство: События.
Плагин и карта#
Init#
Плагин запущен: сервер стартовал или плагин загружен или перезагружен.
Здесь — подготовка, которой не место при импорте модуля: создать таблицы, открыть соединения, прочитать файлы.
| Поле | Тип | Описание |
|---|---|---|
hot_reload |
bool |
True — плагин перезагружен на лету, False — обычный старт |
MapStart#
Карта загружена, Pawn-плагины инициализированы.
| Поле | Тип | Описание |
|---|---|---|
map |
str |
имя карты: de_dust2 |
@plugin.on(events.MapStart)
def map_start(e: events.MapStart) -> None:
plugin.log.info("карта %s", e.map)
MapEnd#
Карта заканчивается: последний шанс сохранить статистику раундов.
| Поле | Тип | Описание |
|---|---|---|
map |
str |
имя карты, которая заканчивается |
Unload#
Плагин останавливается: reason — "reload", "unload" или "shutdown".
При "reload" состояние можно передать новой версии через plugin.keep()
или PlayerState(keep=True).
| Поле | Тип | Описание |
|---|---|---|
reason |
str |
"reload", "unload" или "shutdown" |
Frame#
Каждый кадр сервера (сотни раз в секунду).
Дорогое событие: для периодической работы используйте @plugin.every(сек).
Подключение и чат#
Connect#
Игрок подключается; 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#
Игрок вошёл в игру: можно писать ему в чат, показывать меню и 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#
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#
Игрок вышел. Данные PlayerState и задачи игрока удаляются сами после обработчиков.
| Поле | Тип | Описание |
|---|---|---|
player |
Player |
вышедший игрок; после обработчиков хэндл недействителен |
Say#
Сообщение в чат (say и say_team); e.cancel() — скрыть его.
Для команд вида /hp удобнее @plugin.command("/hp").
| Поле | Тип | Описание |
|---|---|---|
player |
Player |
кто пишет |
text |
str |
текст сообщения без кавычек |
team |
bool |
True — say_team (чат команды) |
NameChange#
Игрок меняет ник.
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#
Игрок возрождается.
В post оружие и здоровье уже выданы — бонусы ставьте там.
| Поле | Тип | Описание |
|---|---|---|
player |
Player |
возрождающийся игрок |
@plugin.on(events.PlayerSpawn, post=True)
def bonus(e: events.PlayerSpawn) -> None:
e.player.armor = 100
TakeDamage#
Игрок получает урон.
В 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#
Игрок убит.
| Поле | Тип | Описание |
|---|---|---|
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#
Игрок выбирает команду в меню.
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#
Деньги игрока меняются.
В 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#
Игрок покупает оружие.
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#
Игрок выбрасывает предмет.
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#
Начался новый раунд — начало freezetime (RestartRound ReGameDLL).
FreezeEnd#
Закончился freezetime: игроки могут двигаться и стрелять.
RoundEnd#
Раунд завершается.
В 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#
Игрок бросил гранату.
| Поле | Тип | Описание |
|---|---|---|
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#
Бомба заложена.
| Поле | Тип | Описание |
|---|---|---|
player |
Player | None |
кто заложил |
bomb |
Player | Entity | None |
сущность бомбы |
@plugin.on(events.BombPlanted)
def planted(e: events.BombPlanted) -> None:
banner.show_all("Бомба заложена!")
BombDefuseStart#
Игрок начинает разминировать бомбу.
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#
Разминирование закончилось: успешно или прервано.
| Поле | Тип | Описание |
|---|---|---|
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#
Бомба взорвалась.
| Поле | Тип | Описание |
|---|---|---|
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
#
Базовый класс событий; обработчики объявляются через @plugin.on(events.Имя).
Объект события живёт, пока идёт рассылка: до конца обработчика или до
первого await. В pre-фазе можно менять изменяемые поля, отменить действие
игры (cancel) и ответить за игру (e.result = ... или return).
EventError
#
Недопустимое действие с событием.
EventExpiredError
#
Событие уже разослано (обычно — обращение после await).