Пятница, 22.11.2024, 00:54

logo

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

Меню сайта
Категории раздела
Разное [13]
Tutorials
Создание моделей [2]
Создание карт [26]
Кодинг [24]
Форма входа
Наш сервер CS 1.6
Поиск
Наш опрос
Ваш телефон
Всего ответов: 183
Друзья сайта


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


Кодим оружие HL2

Сегодня я расскажу вам как сделать простой Ak 47 с подробным описанием его функций и опций :) хз как вам на понятном языке обьяснить
сложные термены C++

Итак приступим...
Для того чтобы внедрить такое орудие убийства в ваш мод вам потребуется минимум знать как компилить проэкт в C++
И как туда добовлять cpp файл :)

Нус обьяснение самого тутора будет на примере кода.
И так для начала зайдём в Visual Studio и добавим в ваш проэкт с++ файл.
добавим его в Server.dll вот таким методом



И копируем туда этот код.
Прочитав сам код вы поймете как сделать простое оружие



// 15.02.06
// Кто кодил? Кодил Lolmen
// Как кодил? Сам! :D
// Весь код принадлежит протасову виталию и отправлен на изучение
// людьми сообщества Nashalife :)
// Вам разрешается его использовать по полной программе :)
#include "cbase.h" // засунем базу без неё никуда
#include "basehlcombatweapon.h" // определим какие свойства юзать бум юзать
#include "NPCevent.h" // для NPC
#include "basecombatcharacter.h" // для игрока
#include "AI_BaseNPC.h" // для AI
#include "player.h" // сам игрок
#include "game.h" // игра
#include "in_buttons.h" // для кнопок мыши
#include "AI_Memory.h" // для AI память
#include "soundent.h" // хз вродь звуки или чёто такое
// Обозначили все в своём классе
// Класс оружиеАк47 юзаем для него класс Автоматов :)
class CWeaponAK47 : public CHLSelectFireMachineGun
{
DECLARE_DATADESC();
public:
DECLARE_CLASS( CWeaponAK47, CHLSelectFireMachineGun );

CWeaponAK47();

DECLARE_SERVERCLASS();

void Precache( void ); // подгрузка
void AddViewKick( void ); // как нас будет трясти при стрельбе
void SecondaryAttack( void ); // вторичная атака
void ItemPostFrame( void ); // оружие на каждый кадр
int GetMinBurst() { return 2; } // взять минимальный разброс
int GetMaxBurst() { return 6; } // взять максимальный разброс

virtual void Equip( CBaseCombatCharacter *pOwner ); // когда NPC снабжен пушкой
bool Reload( void ); // обозначим тип BOOL переключатель для перезарядки

float GetFireRate( void ) { return 0.1f; } // скорость стрельбы
int CapabilitiesGet( void ) { return bits_CAP_WEAPON_RANGE_ATTACK1; }

virtual const Vector& GetBulletSpread( void ) // берем конус разброса
{
static const Vector cone = VECTOR_CONE_5DEGREES; // конус разброса от дула
return cone;
}

const WeaponProficiencyInfo_t *GetProficiencyValues(); // приоритеты

void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
switch( pEvent->event )
{
case EVENT_WEAPON_SMG1: // Дает понять что мы юзаем опции SMG1 для NPC
{
Vector vecShootOrigin, vecShootDir; // дадим названия вкторам
QAngle angDiscard;
if ((pEvent->options == NULL) || (pEvent->options[0] == '�') || (!pOperator->GetAttachment(pEvent->options, vecShootOrigin, angDiscard)))
{
vecShootOrigin = pOperator->Weapon_ShootPosition(); // позиция откуда вылетают пули
}

CAI_BaseNPC *npc = pOperator->MyNPCPointer(); // найдём NPC
ASSERT( npc != NULL ); // если NPC нету то ждём его

vecShootDir = npc->GetActualShootTrajectory( vecShootOrigin ); // куда NPC стрелять

WeaponSoundRealtime( SINGLE_NPC ); // звук для NPC

CSoundEnt::InsertSound( SOUND_COMBAT, pOperator->GetAbsOrigin(), SOUNDENT_VOLUME_MACHINEGUN, 0.2, pOperator ); // параметры звука
pOperator->FireBullets( 1, vecShootOrigin, vecShootDir, VECTOR_CONE_PRECALCULATED,
MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 2, entindex(), 0 ); //чем будет NPC стрелять
pOperator->DoMuzzleFlash(); // Будет мерцать Вспышка от выстрелов
m_iClip1 = m_iClip1 - 1; // сколько патронов займем за один выстрел
}
break;

default:
BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
break;
}
}

DECLARE_ACTTABLE();
};
// начали использовать функции из класса
IMPLEMENT_SERVERCLASS_ST(CWeaponAK47, DT_WeaponAK47)
END_SEND_TABLE()

LINK_ENTITY_TO_CLASS( weapon_ak47, CWeaponAK47 );
PRECACHE_WEAPON_REGISTER(weapon_ak47);

BEGIN_DATADESC( CWeaponAK47 )

END_DATADESC()
acttable_t CWeaponAK47::m_acttable[] = // Активности (Анимации для NPC)
{
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SMG1, true }, // Скажем NPC что ему при выстреле нужно юзать анимку от SMG1
};
IMPLEMENT_ACTTABLE(CWeaponAK47);

//=========================================================
CWeaponAK47::CWeaponAK47( )
{
// Конструктор для калаша
m_fMinRange1 = 64;// нет минимальной дальности полёта пули.
m_fMaxRange1 = 1400; // максимальная дальность полёта пули;
}
//-----------------------------------------------------------------------------
// Что делаем? : Подгружаем
//-----------------------------------------------------------------------------
void CWeaponAK47::Precache( void )
{

// что подгружаем? ничего просто инициализируем подгрузку
// но ниче не грузим :)
BaseClass::Precache();
}
//-----------------------------------------------------------------------------
// Что делаем? : даем NPC более длинный маштаб полета пули.
//-----------------------------------------------------------------------------
void CWeaponAK47::Equip( CBaseCombatCharacter *pOwner )
{
if( pOwner->Classify() == CLASS_PLAYER_ALLY ) // если пушка у игрока то
{
m_fMaxRange1 = 3000; // максммальный полёт пули
}
else // потому что пока она не у игрока полёт пули равен
{
m_fMaxRange1 = 1400; // равен 1400
}

BaseClass::Equip( pOwner );
}
//-----------------------------------------------------------------------------
// Что делаем? Делаем все для перезарядки
//-----------------------------------------------------------------------------
bool CWeaponAK47::Reload( void )
{
bool fRet; // переключатель
float fCacheTime = m_flNextSecondaryAttack; // время для перезарядки

fRet = DefaultReload( GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD ); // что перезаряжаем? обойму 1 обойму 2 и юзаем анимку перезарядки ACT_VM_RELOAD
if ( fRet ) // если переключатель fRet включён , то
{
// Перекрываем доступ к вторичной атаке чтобы небыло багов
// Неразрешено стрелять когда мы перезаряжаемся
m_flNextSecondaryAttack = GetOwner()->m_flNextAttack = fCacheTime;

WeaponSound( RELOAD ); // звук из скрипта проиграем RELOAD
}

return fRet; // возратим fRet
}
//-----------------------------------------------------------------------------
// Что делаем? Добовляем потясывание экрана при стрельбе
//-----------------------------------------------------------------------------
void CWeaponAK47::AddViewKick( void )
{
#define EASY_DAMPEN 0.5f // легкое подергивание
#define MAX_VERTICAL_KICK 15.0f //макс вертикальный наклон в градусах
#define SLIDE_LIMIT 3.0f // всю эту батву будем делать за столько то секунд

//Кого трясти будем?
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); // игрока :D

if ( pPlayer == NULL )
return; // если игрока у нас нету то и трясти не будем!

DoMachineGunKick( pPlayer, EASY_DAMPEN, MAX_VERTICAL_KICK, m_fFireDuration, SLIDE_LIMIT ); // а вот это уже инициализирует все что мы набрали
}
//-----------------------------------------------------------------
// Че делаем? Проверяем не нажали ли геймер по кнопке мыши :)
// Первичный огонь у пушки вызывается по дефолту его не трогаем
// А вот что делать, если мы нажали по правой мыше,
// которая у нас стоит в настройках как вторичная атака?
//-----------------------------------------------------------------
void CWeaponAK47::ItemPostFrame( void )
{
// Если геймер есть то все ока :)
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
// Если геймера нету то пипец ниче не делаем :)
if ( pOwner == NULL )
return;
// Если геймер нажал кнопку ATTACK2(подефолту правая кнопка мыши)
// то время вторичной атаки меньше либо равно текущему времени
if ( pOwner->m_nButtons & IN_ATTACK2 )
{
if (m_flNextSecondaryAttack <= gpGlobals->curtime)
{
SecondaryAttack(); // и тут мы вызовем функцию вторичной стрельбы оружия
pOwner->m_nButtons &= ~IN_ATTACK2; // а вот если ненажал кнопку ATTACK2
return;// то будем ждать пока нажмет :)
}
}

BaseClass::ItemPostFrame(); // используем и базовый класс тоже
}
//-----------------------------------------------------------------------------
// Что делаем? определяем что у нас будет вторичной Атакой :)
//-----------------------------------------------------------------------------
void CWeaponAK47::SecondaryAttack( void )
{
// А вот тут пока пусто сюда мы можем сделать :
// Приближение,Выстрел из подстволки,Удар штыком и тд
}
//------------------------------------------------------------------
// Что делаем? Опа самая непонятная чать "приоритеты оружия"
// Короче это определяет насколько крут наш ствол
// Если например в пистолете закончились патроны на что же сменить оружие
// В первую очередь? На самый крутой ствол :)
// Наш ствол будет покруче чем SMG :)
//-----------------------------------------------------------------
const WeaponProficiencyInfo_t *CWeaponAK47::GetProficiencyValues()
{
static WeaponProficiencyInfo_t proficiencyTable[] =
{
{ 8.0, 0.75 },
{ 6.00, 0.75 },
{ 10.0/2.0, 0.75 },
{ 5.0/3.0, 0.75 },
{ 2.00, 1.0 },
};

COMPILE_TIME_ASSERT( ARRAYSIZE(proficiencyTable) == WEAPON_PROFICIENCY_PERFECT + 1); // а это нам сократит время компила пушки :)

return proficiencyTable;
}
Теперь зайдем в X:\папку с вашим проэктом\src\cl_dll\hl2_hud\c_weapon__stubs_hl2.cpp
Откроем этот файлец и добавим туда строку
после:
STUB_WEAPON_CLASS( weapon_smg1, WeaponSMG1, C_HLSelectFireMachineGun );
вот эту
STUB_WEAPON_CLASS( weapon_ak47, WeaponAK47, C_HLSelectFireMachineGun );
Теперь компельнём проэкт :)
теперь самя малось осталось написать скрипт.
Скрипт напишем следующим образом
зайдем в папку с стимом там в SteamApps\SourceMods\папка с вашим модом\scripts
и создадим там текстовик c именем weapon_ak47 след содержания :

// Small Machine Gun 1

WeaponData
{
// Weapon data is loaded by both the Game and Client DLLs.
"printname" "AK47"
"viewmodel" "models/weapons/v_smg1.mdl" // Замените модельку на вашу
"playermodel" "models/weapons/w_smg1.mdl" //Замените модельку на вашу
"anim_prefix" "smg2"
"bucket" "2"
"bucket_position" "9"

"clip_size" "39"
"default_clip" "30"

"primary_ammo" "SMG1"
"secondary_ammo" "None"

"weight" "3"
"item_flags" "0"

// Sounds for the weapon. There is a max of 16 sounds per category (i.e. max 16 "single_shot" sounds)
SoundData
{
"reload" "Weapon_SMG1.Reload"
"reload_npc" "Weapon_SMG1.NPC_Reload"
"empty" "Weapon_SMG1.Empty"
"single_shot" "Weapon_SMG1.Single"
"single_shot_npc" "Weapon_SMG1.NPC_Single"
"special1" "Weapon_SMG1.Special1"
"special2" "Weapon_SMG1.Special2"
"double_shot" "Weapon_SMG1.Double"
"burst" "Weapon_SMG1.Burst"
}

// Weapon Sprite data is loaded by the Client DLL.
TextureData
{
"weapon"
{
"font" "WeaponIcons"
"character" "a"
}
"weapon_s"
{
"font" "WeaponIconsSelected"
"character" "a"
}
"ammo"
{
"font" "WeaponIcons"
"character" "r"
}
"ammo2"
{
"font" "WeaponIcons"
"character" "t"
}
"crosshair"
{
"font" "Crosshairs"
"character" "Q"
}
"autoaim"
{
"file" "sprites/crosshairs"
"x" "0"
"y" "48"
"width" "24"
"height" "24"
}
}
}

Затем запускаем ваш мод...
В игре прописываем give weapon_ak47
и наблюдаем за тем как это дело работает. Автор: Lolmen aka Протасов Виталий Александрович.

www.source-inside.ru
Категория: Кодинг | Добавил: SuperStart (17.10.2010)
Просмотров: 5459 | Рейтинг: 1.0/1 |



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

Copyright www.akksimo.net © 2024