Иконка ресурса

Life State Notifier 2026-04-13

_wS_

Участник
Сообщения
401
Реакции
785
  • Автор ресурса
  • #1
_wS_ submitted a new resource:

Life State Notifier - Life State Notifier

Life State Notifier v1.0

PHP:
//    @note    void CBasePlayer::SharedSpawn()
//    @note    Вызывается до `item_pickup`/`SDKHook_WeaponEquip`/`player_spawn`, когда оружие/бронь ещё не выданы, но они могут быть, если остались с прошлого раунда.
forward void OnPlayerSpawnPre(int client);

//    Погиб / перемещён в наблюдатели / покинул сервер.
//    @note    `player_death` недостаточно, т.к. не вызывается после взрыва бомбы и `ChangeClientTeam(client, 1)`.
//    @note...

Read more about this resource...
 

Vit_ amin

Добрая душа
Сообщения
1,594
Реакции
760
Можно создать FL_ALIVE флаг для игрока и проверять его, вместо IsPlayerAlive спама
А как по вашему функция IsPlayerAlive проверяет факт - жив или нет игрок?
 

_wS_

Участник
Сообщения
401
Реакции
785
  • Автор ресурса
  • #4
А как по вашему функция IsPlayerAlive проверяет факт - жив или нет игрок?
1. Находит CPlayer *player
2. Проверяет IsInGame
3. Получает/вычисляет CBaseEntity*
4. Добавляет к нему смещение и читает из памяти

Вызов натива + эти шаги (пусть они и дешёвые) уж точно дороже, чем простейшая битовая операция if (flags & FL_ALIVE).

приаттаченные энтити самим движком игры удаляются автоматически вроде же
Да, но вот trail прикрепили к игроку - тебе нужно:
1. Хукать player_team (заход в наблюдатели) и удалять хвост.
2. Хукать player_death и удалять trail.
3. Хукать как минимум bomb_exploded и вычислять кто там сдох, т.к. player_death молчит, и удалять trail.
4. Не забыть при выходе игрока очистить переменные, в которых хранился trail.
А OnPlayerDied даёт им всем по морде и говорит "и меня хватит, парни".
 

Vit_ amin

Добрая душа
Сообщения
1,594
Реакции
760
1. Находит CPlayer *player
2. Проверяет IsInGame
3. Получает/вычисляет CBaseEntity*
4. Добавляет к нему смещение и читает из памяти

Вызов натива + эти шаги (пусть они и дешёвые) уж точно дороже, чем простейшая битовая операция if (flags & FL_ALIVE).
Это вид оптимизации не стоит такого, если делать всё "по фен шую", тогда надо писать на Metamod Source/VSP, чтобы не было зависимостей (так как ретрансляция из виртуальной машины в x86/x64 - соответственно тоже создают задержки в инструкциях - если вы вопрос ставите об оптимизации) (исключительно моё мнение)
 

_wS_

Участник
Сообщения
401
Реакции
785
  • Автор ресурса
  • #6
Это вид оптимизации не стоит такого, если делать всё "по фен шую", тогда надо писать на Metamod Source/VSP, чтобы не было зависимостей (так как ретрансляция из виртуальной машины в x86/x64 - соответственно тоже создают задержки в инструкциях - если вы вопрос ставите об оптимизации) (исключительно моё мнение)
Ну если так относиться, что это не стоит того, то когда подобные (и хуже) штуки сложатся вместе, то серверу станет тяжелее дышать. Конечно на С++ лучше, но мне, например, вот эта вещь как раз для С++ и нужна, т.к. не хочется в каждом тике вычислять CBaseEntity* и обращаться к памяти, если есть простое очевидное решение -> просто сохранить в флаге состояние жизни игрока. Чтобы из памяти прочитать жизнь игрока на с++, там надо разыменовать, наверно, минимум 4 указателя (просто хранить CBaseEntity* вроде опасно - хотя можно из sdkhooks api узнать уничтожение и очистить, но SM так не делает, всегда вычисляет). Может я повёрнут на оптимизации, но уверен, будет же лучше :)

Кстати, если вы пишете расширения, может знаете как решить проблему, когда в расширении не вызываются хукнутые события, если один из плагинов хукнул те же события и сделал return Plugin_Stop? Хукал так же, как и в расширении cstrike и в итоге пришёл пока к тому, что пусть .smx уведомляет расширение о событиях, а то не хочется в api умолять "не делайте return Plugin_Stop". А если хукнуть события как-то по-другому, то там наверно и на конфликт с sourcehook нарваться можно.
 

Vit_ amin

Добрая душа
Сообщения
1,594
Реакции
760
Кстати, если вы пишете расширения, может знаете как решить проблему, когда в расширении не вызываются хукнутые события, если один из плагинов хукнул те же события и сделал return Plugin_Stop?
Проблема реализации в функционале Source Hook, который используется для перехвата виртуальных функций.

P. S. Alliedmodders на данный момент меняет legacy Source Hook на некий современный инструмент "K Hook", возможно там будет учтено данное - Но далеко не факт, так как я не изучал данный функционал
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,805
Реакции
5,254
@_wS_, вообще у игроков (и NPC тоже, вроде бы, не помню точно), есть проп с именем типа «m_iLifeState», где число от 0 до 3 показывает текущее состояние. одно из них - персонаж жив (не помню уже 0 или 2 за это отвечает).
Возможно IsPlayerAlive() как раз это и использует (для уточнения нуно в исходники SM заглянуть).
 

Vit_ amin

Добрая душа
Сообщения
1,594
Реакции
760
вообще у игроков (и NPC тоже, вроде бы, не помню точно), есть проп с именем типа «m_iLifeState»
Собственно - это логично, ведь переменная относиться к классу CBaseEntity, от которой наследуется CBaseCombatCharacter, от которого идёт наследование CAI_BaseNPC, либо CBasePlayer (без учёта CBaseAnimating, CBaseFlex и другие)
 

_wS_

Участник
Сообщения
401
Реакции
785
  • Автор ресурса
  • #10
@_wS_, вообще у игроков (и NPC тоже, вроде бы, не помню точно), есть проп с именем типа «m_iLifeState», где число от 0 до 3 показывает текущее состояние. одно из них - персонаж жив (не помню уже 0 или 2 за это отвечает).
Возможно IsPlayerAlive() как раз это и использует (для уточнения нуно в исходники SM заглянуть).
Да, sm использует m_lifeState смещение, а если не нашлось, то использует метод IsDead() класса IPlayerInfo, который работает криво - помню тестировал его, сдох от взрыва бомбы и этот IsDead() лишь через несколько секунд понял, что я отъехал :) В общем FL_ALIVE рулит, парни :) Если проверять жизнь нужно в часто вызываемой функции, флажок побеждает с надписью Flawless Victory.
 

Vit_ amin

Добрая душа
Сообщения
1,594
Реакции
760
Да, sm использует m_lifeState смещение, а если не нашлось, то использует метод IsDead() класса IPlayerInfo, который работает криво - помню тестировал его, сдох от взрыва бомбы и этот IsDead() лишь через несколько секунд понял, что я отъехал :) В общем FL_ALIVE рулит, парни :) Если проверять жизнь нужно в часто вызываемой функции, флажок побеждает с надписью Flawless Victory.
Он работает правильно - потому что между Life и Dead есть отдельный статус - Dying (пока физика ragdoll ещё симулируется и игрок не перешёл в режим observed)
 

_wS_

Участник
Сообщения
401
Реакции
785
  • Автор ресурса
  • #12
PHP:
#if defined LIFE_STATE_NOTIFIER1
public void OnPlayerSpawnPre(int client) { LIFE_STATE_NOTIFIER1(client); }
public void OnPlayerDied(int client) { LIFE_STATE_NOTIFIER1(client); }
#elseif defined LIFE_STATE_NOTIFIER2
public void OnPlayerSpawnPre(int client) { LIFE_STATE_NOTIFIER2(client, true); }
public void OnPlayerDied(int client) { LIFE_STATE_NOTIFIER2(client, false); }
#endif

/*
Если хочется ОДИН callback (для удобства), есть два варианта:

//    1
#define LIFE_STATE_NOTIFIER1 OnLifeStateChanged
#include <life_state_notifier>
void OnLifeStateChanged(int client)
{
}

//    2
#define LIFE_STATE_NOTIFIER2 OnLifeStateChanged
#include <life_state_notifier>
void OnLifeStateChanged(int client, bool alive)
{
}
*/

Добавил это в life_state_notifier.inc, т.к. по себе заметил, что часто удобнее, когда всё это в одном callback'е, т.к. бывает даже неинтересно жив игрок или мёртв.
 
Сверху Снизу