Воскресенье, 24.11.2024, 05:16

Цена на Лечение алкоголизма в Курске medelit46.ru.
logo

Пользовательский поиск

Меню сайта
Категории раздела
Разное [15]
Tutorials
Создание карт [13]
Создание моделей [2]
Кодинг [14]
Создание карт CS [197]
Учебник cs-mapper
Свойства entity HL-CS [117]
Форма входа
Наш сервер CS 1.6
Поиск
Наш опрос
Ваш телефон
Всего ответов: 183
Друзья сайта


Главная » Статьи » HL Development » Кодинг


1.Xash movewith system 0.1 beta

1.Xash movewith system 0.1 beta

Мовечитч спирита при всех его достоинствах обладает одним очень существенным недостатком - он рассчитан исключительно на брашевые энтити, т.е. цеплять с его помощью всякие двери, вагончики и лифты - одно удовольствие, а вот при прицпелении точечных энтитей начинаються уже нехорошие проблемы. Если эта самая точечная энтитя скажем прицеплена к обычной двери, то проблем не возникает.
А вот если скажем вы захотите прикрепить фары (env_glow) к трактрейну то столкнетесь с одной очень нехорошей траблой - объекты будут крутиться только вокруг оси вагончика, сбившись в его центр. Сам Лаури любезно предлагает замутить что-то эдакое из calc_ энтитей и motion_manager однако, все что я видел прикрепленным таким нехитрым способом либо бешенно крутиться на одном месте, либо моргает, либо куда-то улетает, к тому же в кальках надо какой-то угол настраивать, короче дурдом полный.

И я подумал: как было бы здорово, если бы можно было аттачить точечные энтити к брашевым и друг к другу по принципу классического мовевчита - настроил их положение на карте, прописал имя родителя в нужном поле - и голова не болит. Так на свет появился Xash Movewith System - хотелось бы сказать сразу - он НЕ ЗАМЕНЯЕТ собой стандартный movewith, а скорее дополняет его.

В этой бета версии для аттача энтитей используется дополнительное поле "parent" в последующих версиях, система сама будет определять какую из систем задействовать без участия маппера. Итак вот код системы(система глобальная, прицепить можно любую энтитю к любой, кроме игрока).

cbase.h

добавьте в описание класса CbaseEntity

//parent system (Xash® movewith system v1.0)
    Vector                 ChildOffsetOrigin;  //offset between child and parent origins
    Vector                ChildOffsetAngles;  //offset between child and parent angles
    Vector                 pParentAngles;    //temp container for save parent angles
    Vector                 pParentOrigin;    //temp container for save parent origin
    CBaseEntity            *m_pParent;       //pointer to parent entity   
    int                m_iParent;        //name of parent
    void                SetParent       ( int m_iNewParent );
    virtual void             SetParent    ( void ) { SetParent(m_iParent); }
    void                 ProcessChild ( void );

 


спуститесь чуть ниже, найдите функцию keyvalue и добавьте туда еще одно ветвление

else if (FStrEq(pkvd->szKeyName, "parent"))
        {
            m_iParent = ALLOC_STRING(pkvd->szValue);
            pkvd->fHandled = TRUE;
        }

 
Теперь откройте файл const.h найдите флаги и замените FL_IMMUNE_WATER на FL_CHILD - разницы конечно никакой, но чтобы не перепутать.

В TYPEDESCRIPTION CBaseEntity::m_SaveData[] = нам необходимо добавить сохранение наших указателей и углов


    DEFINE_FIELD( CBaseEntity, ChildOffsetOrigin, FIELD_VECTOR ),
    DEFINE_FIELD( CBaseEntity, ChildOffsetAngles, FIELD_VECTOR ),
    DEFINE_FIELD( CBaseEntity, m_pParent, FIELD_CLASSPTR ),
    DEFINE_FIELD( CBaseEntity, m_iParent, FIELD_STRING ),



Пойдем дальше :)

cleint.cpp

добавьте в самое начало файла вот эту функцию
(в самое начало - для того, чтобы нам не пришлось ее декларировать)

void ProcessChilds( void )
{
    //we found entity with flag FL_CHILD and just call
    //to ProcessChild() function
    edict_t        *pEdict = g_engfuncs.pfnPEntityOfEntIndex( 1 );
    CBaseEntity        *pEntity;
    if ( !pEdict ) return;
   
    for ( int i = 1; i < gpGlobals->maxEntities; i++, pEdict++ )
    {
        if ( pEdict->free )    continue;
       
        if ( pEdict->v.flags & FL_CHILD ) //we found child
        {
            pEntity = CBaseEntity::Instance(pEdict);
            pEntity->ProcessChild();
        }
    }
}
 
функция работает очень просто - ищет все энтити с флагом FL_CHILD и активирует им функцию ProcessChild каждый кадр (по крайней мере очень хочется верить, что она успевает :D) Спуститесь к функции StartFrame и сделайте в самом ее конце вызов ProcessChilds(); - эта функция вызывается каждый кадр.

cbase.cpp

закиньте в void CBaseEntity::Activate (тоже в самый конец) вызов этой функции SetParent();//set all parents

void CBaseEntity :: SetParent( int m_iNewParent )
{
    if(!m_iNewParent) return;

    m_pParent = UTIL_FindEntityByTargetname( NULL, STRING(m_iNewParent));   

    if(!m_pParent)
    {
        ALERT(at_console, "======/Xash Debug System/======\n");
        if(pev->targetname) ALERT(at_console, "Warning! Not found parent for %s with name %s\n", STRING(pev->classname), STRING(pev->targetname) );
        else        ALERT(at_console, "Warning! Not found parent for %s\n", STRING(pev->classname) );
        return;
    }

    //check for himself parent
    if(m_pParent == this)
    {
        ALERT(at_console, "======/Xash Debug System/======\n");
        if(pev->targetname) ALERT(at_console, "ERROR! %s with name %s has illegal parent\n", STRING(pev->classname), STRING(pev->targetname) );
        else        ALERT(at_console, "ERROR! %s has illegal parent\n", STRING(pev->classname) );
        m_pParent = NULL; //clear parent
        return;
    }
    //ok, we passed all tests
    SetBits (pev->flags, FL_CHILD); //entity has really parent
   
    //calculate offeset between child and parent coordinates
    pParentOrigin = m_pParent->pev->origin;
    ChildOffsetOrigin = pev->origin - pParentOrigin;

    //calculate offset between child and parent angles
    pParentAngles = m_pParent->pev->angles;
    ChildOffsetAngles = pev->angles - pParentAngles;
}

void CBaseEntity :: ProcessChild( void )
{
    if(!m_pParent) return;

    pParentOrigin = m_pParent->pev->origin;
    pParentAngles = m_pParent->pev->angles;
   
           //ALERT(at_console, "Child origin: %.f, %.f, %.f, Parent origin: %.f, %.f, %.f\n", pev->origin.x, pev->origin.y, pev->origin.z, pParentOrigin.x, pParentOrigin.y, pParentOrigin.z);
           //ALERT(at_console, "Child angles: %.f, %.f, %.f, Parent angles: %.f, %.f, %.f\n", pev->angles.x, pev->angles.y, pev->angles.z, pParentAngles.x, pParentAngles.y, pParentAngles.z);
           //ALERT(at_console, "Length x: %.f, Length.y: %.f, Length.z: %.f\n", ChildOffsetOrigin.x, ChildOffsetOrigin.y, ChildOffsetOrigin.z );

    Vector forward, right, up; //create temp vectors
    UTIL_MakeVectorsPrivate( pParentAngles, forward, right, up );
   
    //monsters use gp_Globals->left system. running simply check for a monsters
    if(m_pParent->pev->flags & FL_MONSTER)
        pev->origin = pParentOrigin + (forward * ChildOffsetOrigin.x) + (right * ChildOffsetOrigin.y) + (up * ChildOffsetOrigin.z);   
    else    pev->origin = pParentOrigin + (forward * ChildOffsetOrigin.x) + (-right * ChildOffsetOrigin.y) + (up * ChildOffsetOrigin.z);   
   
    UTIL_SetOrigin (this, pev->origin); // это вариант функции для спирита                  
    //UTIL_SetOrigin (pev, pev->origin);//это вариант функции для обычного ХЛ
    pev->angles = pParentAngles + ChildOffsetAngles;
}

Первая функция находит родителя и рассчитывает смещения углов и координат.
а вторая каждый кадр поправляет положение прикрпеленной энтити - т.е. собсно и занимается мовечитчем.

Система работает для всех энтитей - например можно прикрепить спрайт к пушаблу или что-то в этом духе, при этом пушаблу не придется ставить оригин - система сама сообразит, что к чему :)

На заметку кодерам - обратите внимание на перегруженную функцию SetParent - это для динамической смены родителя, можно вызывать например для всяких валлспрайтов, попавших на брашевую энтитю :)

ЗЫ. Буду очень благодарен за найденные баги и прочие глюки.

g-cont 

Категория: Кодинг | Добавил: SuperStart (18.10.2010)
Просмотров: 2943 | Рейтинг: 0.0/0 |



Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Copyright www.akksimo.net © 2024