илья2 вывод консоли бы показал, что ли. Там должна быть написана причина. У тебя скорее всего мессага gmsgTankView ещё не зарегана на момент вызова CGargantua :: PrescheduleThink, поскольку вызывается эта функция через цепочку других функций из спавна монстра. Из спавна сообщения отправлять нельзя, чтобы это обойти в спирите была придумана функция DesiredAction. В старом ксашмоде PostActivate. В первой паранойе SendInitMessage. Лично мне больше всего нравится паранойевская реализация, она работает в мультиплеере для всех игроков, и не только при старте карты, а при коннекте игрока к серверу.
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) {};
И уже в коде гаргантюа сделать вот так:
да сработало офигеть спасибо после этого кода заработало как надо не вылетает теперь
правда у меня тоже есть своя вариация исправления вылета но она немного нестандартная но тоже работает вот сам код:
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:
Видать после некоторого время она сама по себе регается и вылет исправляется сам по себе. Но это я уже не совсем втюкиваю как это работает но тоже работает.
илья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. Если сообщения не зареганы, ничего не отправляем