Я к сожалению уделил слишком мало времени этой проблеме в своё время, поэтому прошу тех знает (Ксерокса или Бузера) помочь осветить некоторые моменты:
1. сохраняется ли текущее положение дел на карте в файл, после вызова CHANGE_LEVEL ? или тихо лежит в оперативке, до вызова настоящего сохранения?
2. в каком порядке движок вызывает Dispatch - функции при:
а. первичной загрузке карты
b. по команде restart
c. при загрузке из сохранялки
d. после changelevel
Имеются в виду DispatchSpawn, DispatchSave, DispatchRestore
1. нет
2. не понял вопрос. при создании вызывается DispatchSpawn, при сейве - DispatchSave, при загрузке - DispatchRestore. Что значит - "в каком порядке"? В индивидуальном порядке
DispatchRestore может сам вызвать DispatchSpawn, если у энтити стоит капс FCAP_MUST_SPAWN.
XaeroX AmbientSound юзается для воспроизведения electro4.wav
а он вроде бы не закольцован
Самый главный вопрос:
при рестарте или смене карты дллка выгружается полностью из памяти, как это происходит во всех трех квейках?
или попросту вызывает resetGlobals или что-то такое?
Вопрос по MAKE_STRING и ALLOC_STRING:
Система в хл очень простая - по сути string_t хранит смещение от куска памяти, указывающего на начало строки до некоей абсолютной точки, на которую указывает gpGlobals->pStringBase;
Вопрос - к чему привязать указатель этой точки?
Я тупо привязал к указателю на GiveFnptrsToDll - MAKE_STRING не работает из дллок. ALLOC_STRING работает нормально.
В чем причина может быть?
Мучился полчиса, потом плюнул и заюзал встроенную xash StringTable.
Сразу все ошыбки исчезли. И заодно избавился от этой дури с MAKE_STRING, поскольку Xash StringTable перед регистрацией новой строчки проверяет её наличие.
Там на клиенте их массив хранится, где-то в pmove. Выводи его каждый кадр в консоль и проанализируй, какие объекты в него входят. По-моему, в него входят все солидные брашевые объекты.
>> По-моему, в него входят все солидные брашевые объекты.
судя по исходникам q1\q2 так оно и есть.
ну пофиг, добавлю еще моделек и спрайтов.
Добавлено 23-12-2008 в 17:25:
И снова я
Прикручиваю пользовательские мессаги из халфы.
Алгоритм их работы, мне представляется следующим образом:
Регистриуем мессагу на сервере по имени, при загрузке карты передаем все имена и размеры на клиент, но эта информация так же доступна на сервере. Создаем на клиенте структурку вида
code:
typedef struct cl_msg_s
{
const char *msgName; // указатель на клиентское хранилище имени мессаги
int svcnum; // номер мессаги
int iSize;
pfnUserMessage func; // указатель на клиентскую функцию мессаги
typedef struct cl_msg_s *next;
} cl_msg_t;
Затем линкуем мессаги на клиенте, сопоставляя имя из массива на клиенте и имени, которое передает pfnHookMessage
Ставим указатель на функцию, сохраняем номер мессаги и её размер.
(я так подробно это все пишу, чтобы другим пригодилось)
В клиентском парсере, если пришедшая мессага имеет пользовательский номер svc (ну скажем от 1 до 127, 0 юзать нельзя, на нем висит svc_bad),
то выполняем поиск по нашему списку.
Вариантов поиска два - получить из клиентского массива имен имя нашей мессаги по индексу и затем сравнивать имена в списке. Но можно и просто сравнивать номер мессаги с пришедшим, поскольку мы его предусмотрительно добавили в нашу структуру.
Далее, внимание!, самое интересное:
Пришедший пакет данных с помощью простейшего цикла
code:
for( i = 0; i < iSize; i++ )
{
*buffer++ = MSG_ReadByte()
}
мы копируем в маленький кусочек памяти. динамический выделенный нами прямо перед циклом, и вызываем pfnMessage, с указателем на начало буффера и размером буффера, соответственно. Таким образом, независимо от того, соизволил ли наш юзер прочитать мессагу в клиентке или нет, работа сети не нарушится - мы уже сдвинули сетевой буффер вперед, ровно на размер мессаги.
Внимание вопрос: как читать мессаги с размером -1 ?
Все что мне пришло в голову - это зарезервировать место после svcnum,
подсчитать кол-во отправленных байтов, вернуться к зарезервированному месту и вписать туда получившуюся длину. А на клиенте, если мессага имеет размер -1 считать первый байт мессаги после идентификатора размером всей мессаги (думаю 255 байт для мессаги вполне достаточно).
Есть ли способы лучше? может кто-то знает как у valve устроено?
BUzer, Xaerox ? )