Ru/Authoring a Brush Entity

Нашим последним примером было . В этой же статье мы будем использовать архитектуру мира (или брашей), для представления нашей entity, как она сталкивается и перемещается по миру. Также рассмотрим функцию "touch", доступную для всех entity. Это позволит нам создать объект, двигающийся при прикосновении игрока.
=Создаем .cpp файл для новой entity=
* Создадим файл, называемый sdk_brushentity.cpp.
* Скопируем и вставим его в наш новый файл.
* В последнею очередь добавляем этот файл в ваш проект server.dll. Если вы открыли game_sdk.sln solution, тогда вы можете щелкнуть правой кнопкой на проекте hl в окне Solution Explorer и выбрать Add, затем Add Existing Item.
=Рассмотрение кода=
==Создание класса==
class CMyBrushEntity : public CBaseToggle
{
public:
 DECLARE_CLASS( CMyBrushEntity, CBaseToggle );
 DECLARE_DATADESC();
 void Spawn( void );
 bool CreateVPhysics( void );
 void BrushTouch( CBaseEntity *pOther );
};
Мы наследуем нашу entity от класса CBaseToggle. Он предоставляет некоторые базовые функции для помощи в движении брашевой модели по миру.
==Определяем описание данных==
LINK_ENTITY_TO_CLASS( my_brush_entity, CMyBrushEntity );
// Начинаем описание наших данных для класса
BEGIN_DATADESC( CMyBrushEntity )
 
 // Описываем функцию которая будет touch функцией
 DEFINE_ENTITYFUNC( BrushTouch ),
END_DATADESC()
Мы объявляем touch-функию которую потом будем использовать. Смотрите документ о для дополнительной информации.
==Создаем Spawn функцию==
void CMyBrushEntity::Spawn( void )
{
 // Мы не можем перехватывать соприкасания из других энтитей
 SetTouch( &CMyBrushEntity::BrushTouch );
 // Мы должны сталкиваться с физикой
 SetSolid( SOLID_VPHYSICS );
 
 // Мы должны отталкивать вещи с нашего пути
 SetMoveType( MOVETYPE_PUSH );
 
 // Используем нашу модель brush
 SetModel( STRING( GetModelName() ) );
 // Создаем физический корпус объекта
 CreateVPhysics();
}
Первым делом в этом блоке мы установим touch-функцию, указывающую на BrushTouch() в которой разместим наш код движения. Затем мы должны сообщить entity использовать SOLID_VPHYSICS, создающую коллизию для объекта. Установим использование MOVETYPE_PUSH что означает позволить двигать энтити втречающиеся на нашем пути, вместо обычной блокировки.
В этом примере мы используем SetModel() с именем модели из редактора. В связи с этим entity использует ту брашевую модель, которая определена на карте.
bool CMyBrushEntity::CreateVPhysics( void )
{
 // Для столкновения с объектами физики
 VPhysicsInitShadow( false, false );
 return true;
}
Напоследок, вызываем CreateVPhysics() для установки отражения коллизии. Это то, что создает отталкивание с физическими объектами мира. Без этого браш бужет пролетать сквозь эти объекты.
==Создаем BrushTouch() функцию==
Entity должна оповестить нас когда она была дотронута через функцию BrushTouch(). Затем мы принимаем это уведомление, мы должны сообщить энтити двигаться в сторону от энтити которая дотронулась до нее. Для этого, мы нуждаемся в информации о событиях связанных с дотрагиванием. Эта информация предоставляется структурой trace_t</code>, возвращаемая функцией GetTouchTrace(). Она возвращает текущее трассирование коллизии вызвавшее сообщение.
void CMyBrushEntity::BrushTouch( CBaseEntity *pOther )
{
 // Получаем информацию о коллизии
 const trace_t &tr = GetTouchTrace();
 // Мы должны переместить прочь от удара вдоль нашей поверхности
 Vector vecPushDir = tr.plane.normal;
 vecPushDir.Negate();
 vecPushDir.z = 0.0f;
 // Перемещаем медленно в этом направление
 LinearMove( GetAbsOrigin() + ( vecPushDir * 64.0f ), 32.0f );
}
Первым делом мы извлекаем нормаль поверхности которая была дотронута. Для этого, нужна одна из плоскостей браш-энтити. Мы вычитаем это значение для указания относительного направления столкновения, затем убираем Z компоненту направления для сохранения паралельности к полу.
Напоследок, используем функцию LinearMove() заставляющая двигаться браш в направлении с заданной скоростью. Функция LinearMove() имплементируется классом CBaseToggle и заботится о рутинной работе связанной с тем как обеспечивается движение брашевой модели.
==Создаем запись в FGD файле==
Для использования энтити в Хаммере, мы должны создать запись в FGD файле. Хаммер будет использовать эти данные для того чтобы понять различные ключевые значения и функции которые предоставляет энтитя. Смотрите для дополнительной информации о FGD файлах.
Запись FGD позволяет вам привезать энтити к браше.
@SolidClass base(Targetname) = my_brush_entity : "Tutorial brush entity."
[
	
]
Если ваш .FGD не пустой, убедитесь что добавили строку @include "base.fgd", которая даст вам некоторые нужные функции Хаммера. (При полном преобразование. Мод основанный на существующем содержимом, включайте соответствующие FGD файлы; на пример для мода, включите halflife2.fgd вместо base.fgd.)