Помогите с трассерами для WSS — код шлёт всё правильно, а трасс всё равно ноль
Всем привет, сообщество!
Есть у меня система кастомных скинов оружия (аналог WSS — под каждым скином своя v/p/w модель, урон, магазин и т.д.), крутится на ReHLDS + AMXX + ReAPI + Hamsandwich. Решил добавить визуальные трассеры пуль — чисто косметика, чтобы заскиненное оружие стреляло красиво, пистолеты потоньше, всё остальное потолще. Никакого влияния на хитрег не планировалось, просто beauty overlay.
Формально всё готово, компилируется без единой ошибки, хук стреляет, данные корректные... а трассера как не было, так и нет. Третий день воюю с векторной алгеброй вместо того, чтобы фиксить нормальные баги. Пришло время звать на помощь зал.
Стек: ReHLDS + AMXX 1.10 + ReAPI + Hamsandwich, cstrike.
Что делаю (упрощённо, без внутренностей системы скинов):
Вешаю хук на выстрел только для оружия, у которого активен кастомный скин:
А дальше собственно рисование луча через TE_BEAMPOINTS:
Что уже проверено и отбраковано:
И вот тут я упёрся в стену: по всем логам всё отправляется правильно, а на экране — пустота. Причём не проверено потом с чужого ракурса (другой игрок/бот/спектатор), может там уже и видно, но руки пока не дошли, а переделывать всё вслепую больше не хочется.
Вопросы к знающим людям:
Сам код системы скинов не выкладываю (не моё, чужая интеллектуальная собственность плюс работает система за пределами вот этого конкретного вопроса), но кусок логики отрисовки самого трассера — вот он выше целиком, дело явно не в скинах, а в самом рисовании луча.
Заранее спасибо всем, кто дочитал до конца и тем более кто ответит по делу.
Всем привет, сообщество!
Есть у меня система кастомных скинов оружия (аналог WSS — под каждым скином своя v/p/w модель, урон, магазин и т.д.), крутится на ReHLDS + AMXX + ReAPI + Hamsandwich. Решил добавить визуальные трассеры пуль — чисто косметика, чтобы заскиненное оружие стреляло красиво, пистолеты потоньше, всё остальное потолще. Никакого влияния на хитрег не планировалось, просто beauty overlay.
Формально всё готово, компилируется без единой ошибки, хук стреляет, данные корректные... а трассера как не было, так и нет. Третий день воюю с векторной алгеброй вместо того, чтобы фиксить нормальные баги. Пришло время звать на помощь зал.
Стек: ReHLDS + AMXX 1.10 + ReAPI + Hamsandwich, cstrike.
Что делаю (упрощённо, без внутренностей системы скинов):
Вешаю хук на выстрел только для оружия, у которого активен кастомный скин:
Код:
RegisterHam(Ham_Weapon_PrimaryAttack, "weapon_ak47", "Tracer_OnFire_Post", true)
// и так по всем классам оружия из списка
public Tracer_OnFire_Post(pWeapon) {
// тут проверка "а точно ли на этом оружии активен скин" - опущено, это внутренности системы
if (!SkinIsActive(pWeapon))
return
new pPlayer = get_member(pWeapon, m_pPlayer)
if (!is_user_connected(pPlayer) || !is_user_alive(pPlayer))
return
DrawTracer(pPlayer, iWidth) // iWidth - 15 для пистолетов, 30 для остального
}
А дальше собственно рисование луча через TE_BEAMPOINTS:
Код:
DrawTracer(pPlayer, iWidth) {
new Float:vecOrigin[3], Float:vecViewOfs[3], Float:vecAngles[3]
pev(pPlayer, pev_origin, vecOrigin)
pev(pPlayer, pev_view_ofs, vecViewOfs)
pev(pPlayer, pev_v_angle, vecAngles)
new Float:vecStart[3]
vecStart[0] = vecOrigin[0] + vecViewOfs[0]
vecStart[1] = vecOrigin[1] + vecViewOfs[1]
vecStart[2] = vecOrigin[2] + vecViewOfs[2]
new Float:vecDir[3]
angle_vector(vecAngles, ANGLEVECTOR_FORWARD, vecDir)
new Float:vecEnd[3]
vecEnd[0] = vecStart[0] + vecDir[0] * 8192.0
vecEnd[1] = vecStart[1] + vecDir[1] * 8192.0
vecEnd[2] = vecStart[2] + vecDir[2] * 8192.0
new tr = create_tr2()
engfunc(EngFunc_TraceLine, vecStart, vecEnd, IGNORE_MONSTERS, pPlayer, tr)
get_tr2(tr, TR_vecEndPos, vecEnd)
free_tr2(tr)
message_begin(MSG_PVS, SVC_TEMPENTITY, vecStart)
write_byte(TE_BEAMPOINTS)
write_coord(vecStart[0])
write_coord(vecStart[1])
write_coord(vecStart[2])
write_coord(vecEnd[0])
write_coord(vecEnd[1])
write_coord(vecEnd[2])
write_short(g_iTracerSprite) // precache_model("sprites/laserbeam.spr"), индекс валидный
write_byte(0) // startframe
write_byte(0) // framerate
write_byte(2) // life, 0.1s
write_byte(iWidth) // width, 0.1 юнита
write_byte(0) // noise
write_byte(255) // r
write_byte(180) // g
write_byte(60) // b
write_byte(200) // brightness
write_byte(0) // speed
message_end()
}
Что уже проверено и отбраковано:
- Спрайт прекешится нормально,
precache_model()возвращает валидный ненулевой индекс, никаких warning в логах. - Ширина луча — это десятые доли юнита, а не пиксели. Спалился на этом сам: сначала стояло
write_byte(3)(то есть 0.3 юнита — практически невидимо), поднял до 15/30 — ничего не изменилось. - Включил дебаг-логирование прямо в хуке: хук стабильно срабатывает, скин определяется правильно, координаты start/end вменяемые (не (0,0,0), не NaN, трасса реально ложится вдоль линии выстрела), сообщение реально уходит через
message_end()— то есть по всем признакам сервер делает всё, что должен. - Заметил, что стрелок не видит собственный трассер, если тот идёт строго вдоль линии взгляда (глаза → направление взгляда). Логика простая: движок считает видимую ширину луча как векторное произведение направления луча и направления "точка → камера", а у самого стрелка эти два вектора коллинеарны — произведение ноль, луч визуально схлопывается в точку. Сдвинул старт луча в сторону (эмуляция позиции ствола, что-то вроде
vecStart += vecDir*10 + vecRight*5 - vecUp*4) — по идее должно было решить проблему для самого стрелка.
И вот тут я упёрся в стену: по всем логам всё отправляется правильно, а на экране — пустота. Причём не проверено потом с чужого ракурса (другой игрок/бот/спектатор), может там уже и видно, но руки пока не дошли, а переделывать всё вслепую больше не хочется.
Вопросы к знающим людям:
- Может, TE_BEAMPOINTS вообще не лучший выбор для таких вещей, и все нормальные люди используют что-то другое (TE_TRACER, кастомный TE_BEAMENTPOINT, что угодно ещё)?
- Может дело в
MSG_PVS— вдруг для какого-то из зрителей точка старта луча не входит в его PVS, и сообщение до него физически не долетает, хотя логика с координатами верна? - Спрайт
sprites/laserbeam.spr— стандартный ресурс CS 1.6, но может у части клиентов он не докачан/не резолвится (fastdl молчит об этом, естественно)? Как это вообще дебажить со стороны клиента? - Кто делал рабочие трассеры под ReHLDS/AMXX — поделитесь, пожалуйста, каким методом рисовали луч, не через TE_BEAMPOINTS ли какие подводные камни словили.
Сам код системы скинов не выкладываю (не моё, чужая интеллектуальная собственность плюс работает система за пределами вот этого конкретного вопроса), но кусок логики отрисовки самого трассера — вот он выше целиком, дело явно не в скинах, а в самом рисовании луча.
Заранее спасибо всем, кто дочитал до конца и тем более кто ответит по делу.