Ru/Authoring a weapon entity

Как не удивительно Source имеет надёжные оружейные системы. Эта статья описывает шаги необходимые для создания и снарядных оружий и как правильно настроить их для использования в мультиплеере.
== Общие сведения ==
; Большинство свойств оружия может быть сконфигурировано с помощью 
: Если всё что тебе требуется - это выстреливать пули с постоянной скоростью, тебе необходимы какие-никакие навыки в программировании.
; Оружейный огонь может быть игроком и сервера
: Обычно это выглядит как снаряды в виде ракет, гранат, и других снарядов материализующихся из воздуха на компьютерах наблюдателей.
; - это отдельная сущность
: Она создается игроком и делится между всеми видами оружия.
; В SDK есть широкий выбор оружия для изучения
: Valve предоставляет исходный код как однопользовательских, так и многопользовательских игр.
== Оружейные скрипты ==
От зависит много свойств оружия , включая её , амуницию , звуки , размер обоймы , и имя в пользовательском интерфейсе. Использование, расширение и шифрование оружейных скриптов описано в .
Скрипт оружия будет автоматически загружен для любого оружия с . Для более лёгкого ресурсов, определяемых скриптами вызовите PRECACHE_WEAPON_REGISTER(имя) и никаких кавычек вокруг имени класса.
== Точки входа ==
У оружия есть четыре функции, которые вызываются каждый кадр объектом которым владеет игрок:
; ItemPreFrame()
: Вызывается перед началом движения игрока. В , решает , подходящее ли сейчас время чтобы отобразить подсказку по использованию оружия в HUD.
; ItemHolsterFrame()
: Вызывается перед началом движения игрока, если игрок ничего не делает. В основном ничего не делает.
; ItemBusyFrame()
: Вызывается перед началом движения игрока, если игрок не стреляет. В основном ничего не делает.
; ItemPostFrame()
: Вызывается после движения игрока. Это самая важная функция , ведь она ведёт к следующим:
:* PrimaryAttack()
:* SecondaryAttack()
:* HandleFireOnEmpty()
:* Reload()
:* WeaponIdle()
== Стрельба ==
Оружие обычно стреляет если кнопка отвечающая за +attack активна и (m_flNextPrimaryAttack <= ->curtime). Для дополнительного режима стрельбы, +attack2 и m_flNextSecondaryAttack проверяются вместо предыдущей функции (?).
=== Пули ===
 выстреливаются при соответствии , где противоречит GetOwner()->FireBullets().
Если всё что вам нужно это основная атака , которая выстреливает постоянный поток пуль (Не важно отделяют их 2 или 0.2 секунды) CBaseCombatWeapon уже выполняет нужную работу и вам надо только написать две функции:
; float GetFireRate()
: Время в секундах между каждым выстрелом.
; const Vector& GetBulletSpread()
: Конус , внутри которого пули будут иметь случайный разброс. Для него используйте VECTOR_CONE_* #определяет, как избежать самостоятельной работы с математикой.
Переходим к секции с нетворкингом если это соответствует вашим требованиям; Эффекты будут сделаны за вас. Иначе смотрите за подробностями , чтобы настроить вашу собственную hitscan атаку.
=== Снаряды ===
Ракеты, гранаты, и другие снаряды это самостоятельные энтити которые существуют независимо (почти) от оружия из которого они вылетели. Оружие должно создать их с помощью :
CBaseEntity::Create( "my_projectile", GetOwner()->Weapon_ShootPosition(), GetOwner()->EyeAngles(), GetOwnerEntity() );
Обратите внимание , что их владелец тот же , что и владеет оружием (GetOwnerEntity()), а само не оружие как таковое.
Читайте следующее:
* (для проблем с дизайном модели снарядов)
* (для создания энтити)
* (для создания энтити)
=== Эффекты ===
Здесь предполагается , что вы используете , которая создаётся художниками. Старая технология "закодирования партиклов намертво" никогда не документировалась.
==== Следы от пуль ====
Следы должны быть отправлены CBaseEntity::MakeTracer(). CBasePlayer который настроен на излучение "намертво закодированных" эффектов; если вы хотите внести изменения, лучше всего осуществить партиклы(?). Это делается несложно:
// ВСЁ В ОБЩЕМ КОДЕ
// всегда излучать следы; пусть система партиклов сама определяет объём
// (если вы не собираетесь редактировать CBasePlayer, просто измените m_iTracerFreq )
void CMyPlayer::FireBullets( const FireBulletsInfo_t &info )
{
	FireBulletsInfo_t new_info(info);
	new_info.m_iTracerFreq = 1;
	BaseClass::FireBullets(new_info);
}
// перейдите к оружию, если есть необходимость
void CMyPlayer::MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType )
{
	GetActiveWeapon()->MakeTracer(vecTracerSrc,tr,iTracerType);
}
// излучает эффект этого оружия
void CMyWeapon::MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType )
{
	// 1 это аттачмент #1, который является дулом
	UTIL_ParticleTracer("my_tracer",vecTracerSrc,tr.endpos,entindex(),1);
}
Код сверху позволяет создать новую , которая подходит для эффектов одиночной стрельбы для каждой пули . Если ваше оружие стреляет быстро рассмотрите вместо этого возможность создания эффекта который создаёт поток партиклов когда игрок начинает стрелять , и используйте StopParticleEffects(this) чтобы завершить работу эффекта, когда он закончит стрелять. Попробуйте (CBasePlayer::m_nButtons & IN_ATTACK) чтобы достичь данного эффекта.
Смотрите также .
==== Эффект попадания ====
== Networking ==
== Оружие-пример ==
Смотрите .