Registration - or - Enter
Operation Black ThunderOperation Black Thunder

Мод о спец-операции недалёкого будущего...

25/04/2004
Get a LifeGet a Life

Шутер от первого лица...

25/04/2008

ак 47


  • Description
  • Link and installation

Кодим оружие

ак 47


Views : 2342 ( +1 )
Downloads : 0
Uploaded by : alix1995alix
Created : 03/26/2011 5:08:40 PM
Rating :
 ( 3.93 ) 
Share :


Available following translations : | russian |

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

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

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

2786316377.weaponTut01.jpg

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

// 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 Протасов Виталий Александрович.



You cannot comment, because you are not registered.
    UT3 Evangelion Model Pack v1.1 Final
    Unreal Tournament 3UT3 Evangelion Model Pack v1.1 Final
    OldSkool Amp'd
    Unreal Tournament 99OldSkool Amp'd
    Csejte Castle HerdCoop Map Pack V3
    Unreal Tournament 99Csejte Castle HerdCoop Map Pack V3
    Unreal Tournament 3 Original Soundtrack
    Unreal Tournament 3 Original Soundtrack