Authoring a weapon entity

From Valve Developer Community
< Ru
Jump to navigation Jump to search
English (en)Русский (ru)Translate (Translate)


Info content.png
This page is being translated.

You can help by updating the translation.

Also, please make sure the article tries to comply with the alternate languages guide.
Note.pngПримечание:Есть неточности перевода , помеченные (?)

Как не удивительно Source имеет надёжные оружейные системы. Эта статья описывает шаги необходимые для создания пулевых(en) и снарядных оружий и как правильно настроить их для использования в мультиплеере.

Общие сведения

Большинство свойств оружия может быть сконфигурировано с помощью оружейных скриптов(en)
Если всё что тебе требуется - это выстреливать пули с постоянной скоростью, тебе необходимы какие-никакие навыки в программировании.
Оружейный огонь может быть прогнозирован(en) игроком и запозданием(en) сервера
Обычно это выглядит как снаряды в виде ракет, гранат, и других снарядов материализующихся из воздуха на компьютерах наблюдателей.
Моделька от первого лица(en) - это отдельная сущность
Она создается игроком и делится между всеми видами оружия.
В SDK есть широкий выбор оружия для изучения
Valve предоставляет исходный код как однопользовательских, так и многопользовательских игр.

Оружейные скрипты

От оружейных скриптов(en) зависит много свойств оружия , включая её модель(en), амуницию , звуки , размер обоймы , и имя в пользовательском интерфейсе. Использование, расширение и шифрование оружейных скриптов описано в их статье(en).

Скрипт оружия будет автоматически загружен для любого оружия с назначенным именем класса(en). Для более лёгкого кэширования(en) ресурсов, определяемых скриптами вызовите PRECACHE_WEAPON_REGISTER(имя) и никаких кавычек вокруг имени класса.

Точки входа

У оружия есть четыре функции, которые вызываются каждый кадр объектом которым владеет игрок:

ItemPreFrame()
Вызывается перед началом движения игрока. В Episode Two(en), решает , подходящее ли сейчас время чтобы отобразить подсказку по использованию оружия в HUD.
ItemHolsterFrame()
Вызывается перед началом движения игрока, если игрок ничего не делает. В основном ничего не делает.
ItemBusyFrame()
Вызывается перед началом движения игрока, если игрок не стреляет. В основном ничего не делает.
ItemPostFrame()
Вызывается после движения игрока. Это самая важная функция , ведь она ведёт к следующим:
  • PrimaryAttack()
  • SecondaryAttack()
  • HandleFireOnEmpty()
  • Reload()
  • WeaponIdle()

Стрельба

Оружие обычно стреляет если кнопка отвечающая за +attack активна и (m_flNextPrimaryAttack <= gpGlobals(en)->curtime). Для дополнительного режима стрельбы, +attack2 и m_flNextSecondaryAttack проверяются вместо предыдущей функции (?).

Нужно сделать: Как заставить NPC атаковать?

Пули

Пули(en) выстреливаются при соответствии , где FireBulletsInfo_t(en) противоречит GetOwner()->FireBullets().

Если всё что вам нужно это основная атака , которая выстреливает постоянный поток пуль (Не важно отделяют их 2 или 0.2 секунды) CBaseCombatWeapon уже выполняет нужную работу и вам надо только написать две функции:

float GetFireRate()
Время в секундах между каждым выстрелом.
const Vector& GetBulletSpread()
Конус , внутри которого пули будут иметь случайный разброс. Для него используйте VECTOR_CONE_* #определяет, как избежать самостоятельной работы с математикой.

Переходим к секции с нетворкингом если это соответствует вашим требованиям; Эффекты будут сделаны за вас. Иначе смотрите FireBulletsInfo_t(en) за подробностями , чтобы настроить вашу собственную hitscan атаку.

Снаряды

Ракеты, гранаты, и другие снаряды это самостоятельные энтити которые существуют независимо (почти) от оружия из которого они вылетели. Оружие должно создать их с помощью Create()(en):

CBaseEntity::Create( "my_projectile", GetOwner()->Weapon_ShootPosition(), GetOwner()->EyeAngles(), GetOwnerEntity() );

Обратите внимание , что их владелец тот же , что и владеет оружием (GetOwnerEntity()), а само не оружие как таковое.

Tip.pngСовет:Не компенсируйте лаги(en) или прогнозируйте(en) этот вызов - делай прогнозируемую анимацию отсутствия патронов и перезарядки для viewmodel(en).

Читайте следующее:

Эффекты

Здесь предполагается , что вы используете систему партиклов(en), которая создаётся художниками. Старая технология "закодирования партиклов намертво" никогда не документировалась.

Следы от пуль

Следы должны быть отправлены 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);
}

Код сверху позволяет создать новую систему частиц(en) , которая подходит для эффектов одиночной стрельбы для каждой пули . Если ваше оружие стреляет быстро рассмотрите вместо этого возможность создания эффекта который создаёт поток партиклов когда игрок начинает стрелять , и используйте StopParticleEffects(this) чтобы завершить работу эффекта, когда он закончит стрелять. Попробуйте (CBasePlayer::m_nButtons & IN_ATTACK) чтобы достичь данного эффекта.

Note.pngПримечание:Если ваше оружие имеет другие партикл-эффекты вам понадобиться остановить след ParticleProp()->StopEmission(CNewParticleEffect* pEffect) вместо того , который находится на стороне игрока.

Смотрите также UTIL_ParticleTracer(en).

Эффект попадания

Нужно сделать: CBaseEntity::DoImpactEffect()

Networking

Нужно сделать: Shared code, prediction, predicted viewmodels, compensation...

Оружие-пример

Смотрите Добавление нового оружия в ваш мод(en).