HLFX.Ru Forum Страницы (2): [1] 2 »
Показать все 22 сообщений этой темы на одной странице

HLFX.Ru Forum (http://hlfx.ru/forum/index.php)
- Технические вопросы (http://hlfx.ru/forum/forumdisplay.php?forumid=20)
-- [help] помогите с кодом брашей (http://hlfx.ru/forum/showthread.php?threadid=5135)


Отправлено ~ X ~ 21-09-2018 в 11:45:

Question [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]


Временная зона GMT. Текущее время 16:00. Страницы (2): [1] 2 »
Показать все 22 сообщений этой темы на одной странице

На основе vBulletin версии 2.3.0
Авторское право © Jelsoft Enterprises Limited 2000 - 2002.
Дизайн и программирование: Chain Studios © 2005-2018