HLFX.Ru Forum
профиль •  правила •  регистрация •  календарь •  народ •  FAQ •  поиск •  новое •  сутки •  главная •  выход  
HLFX.Ru Forum HLFX.Ru Forum > Теория и практика > Half-Life SDK > проблема с вылетом игры.
  Предыдущая тема   Следующая тема
Автор
Тема Новая тема    Ответить
илья2
Житель форума

Группа: Неопытный
Дата регистрации: Mar 2020
Проживает: Волгоград
Сообщений: 398
Возраст: 25

Рейтинг



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 игра в мультиплеере не запускается почему так происходит и как это исправить ?

__________________
илья

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

Сообщить модератору | IP: Записан
Сообщение: 224899

Старое сообщение 13-02-2026 10:10
- За что?
Ku2zoff
Мастер Ёда из Деревни Дуракоф

Дата регистрации: Apr 2007
Проживает: В Деревне дураков
Сообщений: 6966
Возраст: 35

Рейтинг



илья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
};

Отредактировано Ku2zoff 13-02-2026 в 14:34

Сообщить модератору | IP: Записан
Сообщение: 224900

Старое сообщение 13-02-2026 14:32
- За что?
илья2
Житель форума

Группа: Неопытный
Дата регистрации: Mar 2020
Проживает: Волгоград
Сообщений: 398
Возраст: 25

Рейтинг



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

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

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:

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

__________________
илья

Сообщить модератору | IP: Записан
Сообщение: 224905

Старое сообщение 13-02-2026 21:01
- За что?
Ku2zoff
Мастер Ёда из Деревни Дуракоф

Дата регистрации: Apr 2007
Проживает: В Деревне дураков
Сообщений: 6966
Возраст: 35

Рейтинг



Цитата:
илья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). Надо ещё перебирать игроков.

Отредактировано Ku2zoff 14-02-2026 в 06:54

Сообщить модератору | IP: Записан
Сообщение: 224909

Старое сообщение 14-02-2026 06:47
- За что?
Тема: (Опционально)
Ваш ответ:



Переводчик транслита


[проверить длину сообщения]
Опции: Автоматическое формирование ссылок: автоматически добавлять [url] и [/url] вокруг интернет адресов.
Уведомление по E-Mail: отправить вам уведомление, если кто-то ответил в тему (только для зарегистрированных пользователей).
Отключить смайлики в сообщении: не преобразовывать текстовые смайлики в картинки.
Показать подпись: добавить вашу подпись в конец сообщения (только зарегистрированные пользователи могут иметь подписи).

Временная зона GMT. Текущее время 17:27. Новая тема    Ответить
  Предыдущая тема   Следующая тема
HLFX.Ru Forum HLFX.Ru Forum > Теория и практика > Half-Life SDK > проблема с вылетом игры.
Версия для печати | Отправить тему по E-Mail | Подписаться на эту тему

Быстрый переход:
Оцените эту тему:

Правила Форума:
Вы not можете создавать новые темы
Вы not можете отвечать в темы
Вы not можете прикреплять вложения
Вы not можете редактировать ваши сообщения
HTML Код ВЫКЛ
vB Код ВКЛ
Смайлики ВКЛ
[IMG] Код ВКЛ
 

< Обратная связь - HLFX.ru >

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