HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Технические вопросы (https://hlfx.ru/forum/forumdisplay.php?forumid=20)
-- [help] помогите с кодом брашей (https://hlfx.ru/forum/showthread.php?threadid=5135)
Отправлено ~ X ~ 21-09-2018 в 11:45:
[help] помогите с кодом брашей
Доброго дня!
Очень нужна помощь с кодом конпок, дверей и прочих движущихся брашей.
Проблема началась с того что Spark() у кнопок вызывался как-то рандомно и криво. В итоге оказалось, что надо отвязывать механизм MoveDone() от Think(), иначе что-то сделать неовзможно. Пробовал делать такое, но тут вообще рандом получается, т.к. ltime ведет себя непредсказуемо.
C++ Source Code:
//-----------------------------------------------------------------------------
// Purpose: Additional layer to replace engine's calls to MoveDone as THINK funcitons.
// Warning: In XDM thinking should work regardless of movement.
// Callers: engine: DispatchThink()
//-----------------------------------------------------------------------------
void CBaseToggle::Think(void)
{
bool bWasAlwaysThinking = FBitSet(pev->flags, FL_ALWAYSTHINK);
if (m_flArrivalTimeMov != 0.0f)
{
if (m_flArrivalTimeMov + pev->ltime <= gpGlobals->time && !pev->velocity.IsZero())
LinearMoveDone();
else
conprintf(2, "%s[%d] \"%s\"::Think() origin %f %f %f -> dest %f %f %f\n", ENTFMT_P, pev->origin.x, pev->origin.y, pev->origin.z, m_vecFinalDest.x, m_vecFinalDest.y, m_vecFinalDest.z);
}
if (m_flArrivalTimeRot != 0.0f && m_flArrivalTimeRot + pev->ltime <= gpGlobals->time && !pev->avelocity.IsZero())// TODO
AngularMoveDone();
if (!FBitSet(pev->flags, FL_ALWAYSTHINK) || (pev->nextthink != 0 && pev->nextthink <= gpGlobals->time))// XDM3039
CBaseEntity::Think();
if (bWasAlwaysThinking)
{
SetBits(pev->flags, FL_ALWAYSTHINK);// in case someone cleared it
SetNextThink(0);
}
}
//-----------------------------------------------------------------------------
// Purpose: XDM3039: Is this entity actually moving right now?
//-----------------------------------------------------------------------------
bool CBaseToggle::IsMoving(void) const
{
return !pev->velocity.IsZero() || !pev->avelocity.IsZero();
}
//-----------------------------------------------------------------------------
// Purpose: Calculate pev->velocity and pev->nextthink to reach vecDest from pev->origin traveling at flSpeed
// Note : Better to SetMoveDone() BEFORE calling this.
// Input : vecDest - absolute destination coordinates
// flSpeed - units per second
//-----------------------------------------------------------------------------
void CBaseToggle::LinearMove(const Vector &vecDest, const float &flSpeed)
{
if (vecDest == pev->origin)// Already there?
{
m_vecFinalDest = vecDest;
LinearMoveDone();
return;
}
if (flSpeed == 0.0f)// XDM3038c
return;
m_vecFinalDest = vecDest;
// set destdelta to the vector needed to move
Vector vecDestDelta(vecDest); vecDestDelta -= pev->origin;
// divide vector length by speed to get time to reach dest
float flTravelTime = vecDestDelta.Length() / flSpeed;
m_flArrivalTimeMov = pev->ltime + flTravelTime;// XDM3039: WTF TESTME
SetBits(pev->flags, FL_ALWAYSTHINK);// XDM3039
SetNextThink(0);
// scale the destdelta vector by the time spent traveling to get velocity
pev->velocity = vecDestDelta / flTravelTime;
DBG_PrintF("%s[%d] \"%s\"::LinearMove(): velocity %f %f %f, time %g, ArrivalTime %g\n", ENTFMT_P, pev->velocity.x, pev->velocity.y, pev->velocity.z, flTravelTime, m_flArrivalTimeMov);
}
//-----------------------------------------------------------------------------
// Purpose: Another hack
// After moving, set origin to exact final destination, call "move done" function
//-----------------------------------------------------------------------------
void CBaseToggle::LinearMoveDone(void)
{
Vector delta(m_vecFinalDest); delta -= pev->origin;// HL20130901
vec_t error = delta.Length();
if (error > MOVEMENT_POSIITON_ERROR_MAX)
{
LinearMove(m_vecFinalDest, error/max(0.001, gpGlobals->frametime));// move one frame, prevent resonance?
return;
}
UTIL_SetOrigin(this, m_vecFinalDest);
pev->velocity.Clear();
m_flArrivalTimeMov = 0.0f;
if (m_pfnCallWhenMoveDone)
(this->*m_pfnCallWhenMoveDone)();
}
//-----------------------------------------------------------------------------
// Purpose: Calculate pev->avelocity and pev->nextthink to reach vecDestAngles from pev->angles traveling at flSpeed
// Input : vecDestAngles - absolute destination angles
// flSpeed - degrees per second
//-----------------------------------------------------------------------------
void CBaseToggle::AngularMove(const Vector &vecDestAngles, const float &flSpeed)
{
if (vecDestAngles == pev->angles)// Already there?
{
m_vecFinalAngle = vecDestAngles;
AngularMoveDone();
return;
}
if (flSpeed == 0.0f)// XDM3038c
return;
m_vecFinalAngle = vecDestAngles;
// set destdelta to the vector needed to move
Vector vecDestDelta(vecDestAngles); vecDestDelta -= pev->angles;
// divide by speed to get time to reach dest
float flTravelTime = vecDestDelta.Length() / flSpeed;
m_flArrivalTimeRot = pev->ltime + flTravelTime;// XDM3039: WTF TESTME
SetBits(pev->flags, FL_ALWAYSTHINK);// XDM3039
SetNextThink(0);
// scale the destdelta vector by the time spent traveling to get velocity
pev->avelocity = vecDestDelta / flTravelTime;
DBG_PrintF("%s[%d] \"%s\"::LinearMove(): avelocity %f %f %f, TravelTime %g, ArrivalTime %g, CurTime %g, LocalTime %g\n", ENTFMT_P, pev->avelocity.x, pev->avelocity.y, pev->avelocity.z, flTravelTime, m_flArrivalTimeRot, gpGlobals->time, pev->ltime);
}
//-----------------------------------------------------------------------------
// Purpose: another hack
// After rotating, set angle to exact final angle, call "move done" function
//-----------------------------------------------------------------------------
void CBaseToggle::AngularMoveDone(void)
{
pev->angles = m_vecFinalAngle;
pev->avelocity.Clear();
m_flArrivalTimeRot = 0.0f;
if (m_pfnCallWhenMoveDone)
(this->*m_pfnCallWhenMoveDone)();
}
GUYZ, PLZ HLP!
Скрытый текст:
Этот текст скрытый. Вы должны оставить хотя бы одно сообщение в теме, чтобы его увидеть.
__________________
Минутка полезного:
Бесплатный UT-подобный Half-Life mod.
Бесплатный редактор для 32-битных текстур. Без дотнета.
Бесплатный IDE для любых компиляторов и ЯП.
Бесплатная Windows-подобная ОС.
Проверка грамматики русского языка.
Связь со мной здесь: [email protected]
Отправлено XaeroX 21-09-2018 в 13:42:
Цитата:
~ X ~ писал:
как-то
Цитата:
~ X ~ писал:
что-то
Цитата:
~ X ~ писал:
тут вообще рандом
Цитата:
~ X ~ писал:
непредсказуемо
Я так и не понял, какая поставлена задача и что именно не получается? 
__________________
So she began again: 'Où est ma chatte?' which was the first sentence in her French lesson-book. The Mouse gave a sudden leap out of the water, and seemed to quiver all over with fright. 'Oh, I beg your pardon!' cried Alice hastily, afraid that she had hurt the poor animal's feelings. 'I quite forgot you didn't like cats.'
Отправлено Дядя Миша 21-09-2018 в 16:22:
Если уж стоит флаг FL_ALWAYSTHINK, для чего тогда нужен весь остальной код?
__________________
В действительности всё может оказаться иначе, чем оно есть на самом деле
My Projects: download page
Отправлено ~ X ~ 21-09-2018 в 16:38:
Скрытый текст:
Этот текст скрытый. Вы должны оставить хотя бы одно сообщение в теме, чтобы его увидеть.
XaeroX по-моему, задача предельно простая: надо отвязвать механизм MoveDone() от Think(). Т.е. чтобы MoveDone() вызывался независимо ни от чего, и SetThink() - тоже. Желательно и linear/angular (в терминах ХЛ) сделать независимыми друг от друга.
В данный момент все пробелмы в приведенном выше Think(). Я не знаю как отследить тот момент когда надо вызывать MoveDone() при условии возникновения всяких Blocked() и прочих исключений. Для этого явно служит ltime, но не понятно как его использовать.
FL_ALWAYSTHINK - это хак чтобы заставить движок вызывать Think() каждый кадр и уже руками сравнивать nextthink и вызывать коллбэки. Без него время вызова для брашей регулируется "погодой на марсе".__________________
Минутка полезного:
Бесплатный UT-подобный Half-Life mod.
Бесплатный редактор для 32-битных текстур. Без дотнета.
Бесплатный IDE для любых компиляторов и ЯП.
Бесплатная Windows-подобная ОС.
Проверка грамматики русского языка.
Связь со мной здесь: [email protected]
Отправлено Дядя Миша 21-09-2018 в 18:55:
Чтобы развязать - надо кастомную физику, иначе никак.
__________________
В действительности всё может оказаться иначе, чем оно есть на самом деле
My Projects: download page
Отправлено ~ X ~ 21-09-2018 в 20:42:
Дядя Миша ты хочешь сказать, что отталкиваться от ltime вообще не получится? Должен же быть способ!
__________________
Минутка полезного:
Бесплатный UT-подобный Half-Life mod.
Бесплатный редактор для 32-битных текстур. Без дотнета.
Бесплатный IDE для любых компиляторов и ЯП.
Бесплатная Windows-подобная ОС.
Проверка грамматики русского языка.
Связь со мной здесь: [email protected]
Отправлено Дядя Миша 21-09-2018 в 21:40:
~ X ~ pev->nextthink = pev->ltime + 0.1; попробуй.
__________________
В действительности всё может оказаться иначе, чем оно есть на самом деле
My Projects: download page
Отправлено XaeroX 21-09-2018 в 21:55:
Цитата:
~ X ~ писал:
m_flArrivalTimeRot + pev->ltime <= gpGlobals->time
Так делать нельзя, ты сравниваешь локальное время мувера и глобальное время. Они не сравнимы.
Нужно отнимать фреймтайм от m_flArrivalTimeRot (ну или тчинктайм - тогда надо кешировать предыдущий локалтайм, чтобы узнать дельту) и сравнивать его с нулём.__________________
So she began again: 'Où est ma chatte?' which was the first sentence in her French lesson-book. The Mouse gave a sudden leap out of the water, and seemed to quiver all over with fright. 'Oh, I beg your pardon!' cried Alice hastily, afraid that she had hurt the poor animal's feelings. 'I quite forgot you didn't like cats.'
Отправлено ~ X ~ 22-09-2018 в 11:21:
Цитата:
Дядя Миша писал:
~ X ~ pev->nextthink = pev->ltime + 0.1; попробуй.
Так это ж будет фиксированный интервал в 10ФПС, не?
И где попробовать? И что оно должно сделать?
В оригинале LinearMove() так и было. Только там было pev->nextthink = pev->ltime + movement_time. И движок внутри этот nextthink как-то сдвигал во время Blocked(), если я не ошибаюсь.
XaeroX:
а как же тогда ДМ пишет сообщением выше чтобы я локальное время совал в глобальное? Вообще я не понял концепцию локального времени мувера. Я честно много раз пытался смотреть код PushMove(), но от него откровенно голова идет крУгом. Я думал что ltime начинает расти во время блока, но нет. Оно могло бы быть версией глобального времени с отставанием, но тоже нет. Можешь тогда кодом написать, что и с чем сравнивать каждый кадр?__________________
Минутка полезного:
Бесплатный UT-подобный Half-Life mod.
Бесплатный редактор для 32-битных текстур. Без дотнета.
Бесплатный IDE для любых компиляторов и ЯП.
Бесплатная Windows-подобная ОС.
Проверка грамматики русского языка.
Связь со мной здесь: [email protected]
Отправлено Дядя Миша 22-09-2018 в 14:03:
Цитата:
~ X ~ писал:
Так это ж будет фиксированный интервал в 10ФПС, не?
А сколько надо?
Цитата:
~ X ~ писал:
Вообще я не понял концепцию локального времени мувера
Глобальное время идёт от начала уровня, локальное - от начала движения мувера. Ну или если задать nextthink.__________________
В действительности всё может оказаться иначе, чем оно есть на самом деле
My Projects: download page
Отправлено ~ X ~ 22-09-2018 в 14:39:
Дядя Миша "думать" надо каждый кадр. Тога получается, что время прибытия для браша надо определять так:
C++ Source Code:
Think()
{
if (pev->ltime >= m_fMovementTime)
LinearMoveDone();
}
? Где m_fMovementTime будет задана в начале движения т.е. m_fMovementTime = flTravelTime;
Как-то оно слишком просто получается. Где-то там были подводные камни. Имхо, была ситуация когда ltime вело себя нелинейно или вообще не менялось... надо дампануть всё в spreadsheet и построить график... 
__________________
Минутка полезного:
Бесплатный UT-подобный Half-Life mod.
Бесплатный редактор для 32-битных текстур. Без дотнета.
Бесплатный IDE для любых компиляторов и ЯП.
Бесплатная Windows-подобная ОС.
Проверка грамматики русского языка.
Связь со мной здесь: [email protected]
Отправлено Дядя Миша 22-09-2018 в 14:45:
Цитата:
~ X ~ писал:
Имхо, была ситуация когда ltime вело себя нелинейно или вообще не менялось...
Ну да, есть такое. Поэтому я и говорю что надо кастомную физику. Меня это говно тоже не устраивало.__________________
В действительности всё может оказаться иначе, чем оно есть на самом деле
My Projects: download page
Отправлено ~ X ~ 22-09-2018 в 17:22:
Дядя Миша а со стандартным HL API такое возможно?
__________________
Минутка полезного:
Бесплатный UT-подобный Half-Life mod.
Бесплатный редактор для 32-битных текстур. Без дотнета.
Бесплатный IDE для любых компиляторов и ЯП.
Бесплатная Windows-подобная ОС.
Проверка грамматики русского языка.
Связь со мной здесь: [email protected]
Отправлено Дядя Миша 22-09-2018 в 18:02:
Теоретически да, надо всем энтитям поставить MOVETYPE_NONE и в StartFrame делать кастомную физику. Но я сам не пробовал.
Добавлено 22-09-2018 в 20:02:
Прикинул так-сяк, да наверное должно сработать, если затрагивать только муверы. А остальные типы нет смысла переделывать.
__________________
В действительности всё может оказаться иначе, чем оно есть на самом деле
My Projects: download page
Отправлено ~ X ~ 24-09-2018 в 12:02:
Понятно. Т.е. не совсем понятно, конечно, но главное что это сильно затратно будет по жизненным ресурсам. Я так никогда рисовать не сяду 
В общем, придется, навное, вернуть как было. Спарки кнопкам сделаю рендерсистемой.
Но вообще - уныние 
__________________
Минутка полезного:
Бесплатный UT-подобный Half-Life mod.
Бесплатный редактор для 32-битных текстур. Без дотнета.
Бесплатный IDE для любых компиляторов и ЯП.
Бесплатная Windows-подобная ОС.
Проверка грамматики русского языка.
Связь со мной здесь: [email protected]