HLFX.Ru Forum
Показать все 4 сообщений этой темы на одной странице

HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Half-Life SDK (https://hlfx.ru/forum/forumdisplay.php?forumid=8)
-- проблема с вылетом игры. (https://hlfx.ru/forum/showthread.php?threadid=6149)


Отправлено илья2 13-02-2026 в 10:10:

Question проблема с вылетом игры.

в общем я делаю новый худ бар для игрока добавляя к монстру в функцию:

C++ Source Code:
1
void CGargantua :: PrescheduleThink( void )
2
{
3
  MESSAGE_BEGIN( MSG_ONE, gmsgTankView, NULL, UTIL_PlayerByIndex( 1 )->pev );
4
  WRITE_BYTE	( 1 );
5
  MESSAGE_END();
6
}


но есть одна проблема когда я ставлю переменную в функции:
C++ Source Code:
cvar_t	allowmonsters={"mp_allowmonsters","0", FCVAR_SERVER };

mp_allowmonsters с 0 на 1 игра в мультиплеере не запускается почему так происходит и как это исправить ?

__________________
илья


Отправлено Ku2zoff 13-02-2026 в 14:32:

илья2 вывод консоли бы показал, что ли. Там должна быть написана причина. У тебя скорее всего мессага gmsgTankView ещё не зарегана на момент вызова CGargantua :: PrescheduleThink, поскольку вызывается эта функция через цепочку других функций из спавна монстра. Из спавна сообщения отправлять нельзя, чтобы это обойти в спирите была придумана функция DesiredAction. В старом ксашмоде PostActivate. В первой паранойе SendInitMessage. Лично мне больше всего нравится паранойевская реализация, она работает в мультиплеере для всех игроков, и не только при старте карты, а при коннекте игрока к серверу.

C++ Source Code:
1
void CBasePlayer::SendInitMessages(void)
2
{
3
  edict_t* pEdict = g_engfuncs.pfnPEntityOfEntIndex(1);
4
  CBaseEntity* pEntity;
5
 
6
  if (!pEdict) return;
7
 
8
  for (int i = 1; i < gpGlobals->maxEntities; i++, pEdict++)
9
  {
10
    if (pEdict->free) continue;
11
 
12
    pEntity = CBaseEntity::Instance(pEdict);
13
    if (!pEntity) continue;
14
 
15
    pEntity->SendInitMessage(this);
16
  }
17
}

Это функция для игрока, она перебирает все энтити на уровне, и отсылает этому игроку сообщения от них.
C++ Source Code:
if (!m_bInitMessagesSent)
{
  SendInitMessages();
  m_bInitMessagesSent = TRUE;
}

Это нужно вставить в UpdateClientData игрока. m_bInitMessagesSent = FALSE вставить в CBasePlayer :: Precache
Ну, собсно, добавить классу CBaseEntity функцию virtual void SendInitMessage(CBasePlayer* pPlayer) {};
И уже в коде гаргантюа сделать вот так:
C++ Source Code:
1
void CGargantua::SendInitMessage(CBasePlayer* pPlayer)
2
{
3
  MESSAGE_BEGIN( MSG_ONE, gmsgTankView, NULL, pPlayer->pev );
4
  WRITE_BYTE	( 1 );
5
  MESSAGE_END();
6
};


Отправлено илья2 13-02-2026 в 21:01:

да сработало офигеть спасибо после этого кода заработало как надо не вылетает теперь

правда у меня тоже есть своя вариация исправления вылета но она немного нестандартная но тоже работает вот сам код:

if ( g_pGameRules->IsMultiplayer() )
{
m_iFirePhase++;
switch ( m_iFirePhase )
{
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
break;
case 10:
break;
case 11:
break;
case 12:
break;
case 13:
break;
case 14:
break;
case 15:
MESSAGE_BEGIN( MSG_ONE, gmsgTankView, NULL, UTIL_PlayerByIndex( 1 )->pev );
WRITE_BYTE( 1 );
MESSAGE_END();
m_iFirePhase = 14;
break;
}
}
else
{
MESSAGE_BEGIN( MSG_ONE, gmsgTankView, NULL, UTIL_PlayerByIndex( 1 )->pev );
WRITE_BYTE ( 1 );
MESSAGE_END();
}

работает так функция идет по таймингу и запускается через некоторое время но потом запускается обратно через m_iFirePhase = 14; но здесь есть условие g_pGameRules->IsMultiplayer которая работает по двум пути если сингл то else без m_iFirePhase если мультиплеер то с m_iFirePhase вот как то так но это функция тоже работает. Я так подумал что если функция не работает сразу то ей нужно некоторое время чтобы заработала вот и придумал совой самостоятельный костыль и был прав.

Добавлено 14-02-2026 в 00:01:

Видать после некоторого время она сама по себе регается и вылет исправляется сам по себе. Но это я уже не совсем втюкиваю как это работает но тоже работает.

__________________
илья


Отправлено Ku2zoff 14-02-2026 в 06:47:

Цитата:
илья2 писал:
работает так функция идет по таймингу и запускается через некоторое время

К этому времени срабатывает LinkUserMessages из player.cpp, и пользовательские мессаги успевают зарегаться.
Цитата:
илья2 писал:
после некоторого время она сама по себе регается

LinkUserMessages вызывается из двух мест: ServerActivate и CBasePlayer::Precache. Продублировано скорее всего именно по причине мультиплеера. Из ServerActivate вызывается и гарантированно срабатывает в сингле, а из CBasePlayer::Precache для каждого игрока в мультиплеере. Потому что игроки могут коннектиться к серверу в разное время.
Цитата:
илья2 писал:
ей нужно некоторое время чтобы заработала

Подход с плюсованием переменной ненадёжный. Нужно знать конкретную точку, когда мессаги зареганы, чтобы не промахнуться. То, что я предложил - система для всех энтить, чтобы при заходе на сервер каждый игрок получал мессагу от энтити, если есть необходимость. В твоём случае (если только один гарг отправляет сообщения, а остальные энтити нет) можно сильно всё упростить, и привести код вот к такому виду:
C++ Source Code:
1
void CGargantua :: PrescheduleThink( void )
2
{
3
  CBaseMonster::PrescheduleThink();
4
 
5
  if ( !gmsgSelAmmo ) // проверка, обратная той, что используется в LinkUserMessages. Если сообщения не зареганы, ничего не отправляем
6
  {
7
    return;
8
  }
9
 
10
  if (!tank_view_sent)
11
  {
12
    MESSAGE_BEGIN( MSG_ONE, gmsgTankView, NULL, UTIL_PlayerByIndex( 1 )->pev );
13
    WRITE_BYTE	( 1 );
14
    MESSAGE_END();
15
    tank_view_sent = TRUE;
16
  }
17
}

BOOL tank_view_sent добавить в класс гарга. В CGargantua::Precache tank_view_sent = FALSE.

Добавлено 14-02-2026 в 13:47:

А, блин. Опять же последний вариант только для сингла, потому что UTIL_PlayerByIndex(1). Надо ещё перебирать игроков.


Временная зона GMT. Текущее время 19:29.
Показать все 4 сообщений этой темы на одной странице

На основе vBulletin версии 2.3.0
Авторское право © Jelsoft Enterprises Limited 2000 - 2002.
Дизайн и программирование: Crystice Softworks © 2005 - 2024