Четверг, 27.07.2017, 03:53
Приветствую Вас Guest | RSS
Главная страница | Статьи | Регистрация | Вход
Меню сайта

Случайный рисунок

Категории каталога
Туториалы по маппингу (HL2) [68]
Туториалы по маппингу для Half-Life
Туториалы по текстурированию (HL2) [10]
Туторы по текстурированию для Half-Life
Туториалы по моделированию (HL2) [9]
Туторы по моделированию для Half-Life
Туториалы по программированию (HL2) [53]
Туторы по прагроммированию для Half-life
Другие туториалы (HL1 и HL2) [4]
Туторы которые не вошли в другие категории
Half-Life 2 Beta [1]
Статьи о npc и weapon в бете Half-Life 2, а так же мануалы и FAQ.
Туториалы по маппингу (HL1) [14]
Туторы по маппингу для Half-Life 1
Туториалы по текстурированию (HL1) [1]
Туторы по текстурированию для Half-Life 1
Туториалы по моделированию (HL1) [1]
Туторы по моделированию для Half-Life 1
Туториалы по программированию (HL1) [30]
Туторы по программированию для Half-Life 1

Наш опрос
Очистить ли форум от всех сообщений и начать всё с чистого листа?
Всего ответов: 536

Начало » Статьи » Туториалы по программированию (HL2)

OICW (Objective Individual Combat Weapon)

weapon_oicw.cpp и weapon_oicw.h кидать в серверную часть.

weapon_oicw.cpp

//========= Copyright © 1996-2007, DetLeR, Valve LLC, All rights reserved. ============//
//
// Purpose: OICW ## Public Code ##
//
// $NoKeywords: $
//=====================================================================================//

#include "cbase.h"
#include "basecombatweapon.h"
#include "NPCevent.h"
#include "basecombatcharacter.h"
#include "AI_BaseNPC.h"
#include "player.h"
#include "weapon_oicw.h"
#include "grenade_ar2.h"
#include "gamerules.h"
#include "game.h"
#include "in_buttons.h"
#include "AI_Memory.h"
#include "shake.h"

extern ConVar sk_plr_dmg_oicw_grenade;
extern ConVar sk_npc_dmg_oicw_grenade;
extern ConVar sk_max_oicw_grenade;
extern ConVar sk_oicw_grenade_radius;

#define OICW_ZOOM_RATE 0.5f // Interval between zoom levels in seconds.

//=========================================================
//=========================================================

BEGIN_DATADESC( CWeaponOICW )

DEFINE_FIELD( m_nShotsFired, FIELD_INTEGER ),
DEFINE_FIELD( m_bZoomed, FIELD_BOOLEAN ),

END_DATADESC()

IMPLEMENT_SERVERCLASS_ST(CWeaponOICW, DT_WeaponOICW)
END_SEND_TABLE()

LINK_ENTITY_TO_CLASS( weapon_oicw, CWeaponOICW );
PRECACHE_WEAPON_REGISTER(weapon_oicw);

acttable_t CWeaponOICW::m_acttable[] =
{
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_AR2, true },
{ ACT_WALK, ACT_WALK_RIFLE, false },
{ ACT_WALK_AIM, ACT_WALK_AIM_RIFLE, false },
{ ACT_WALK_CROUCH, ACT_WALK_CROUCH_RIFLE, false },
{ ACT_WALK_CROUCH_AIM, ACT_WALK_CROUCH_AIM_RIFLE, false },
{ ACT_RUN, ACT_RUN_RIFLE, false },
{ ACT_RUN_AIM, ACT_RUN_AIM_RIFLE, false },
{ ACT_RUN_CROUCH, ACT_RUN_CROUCH_RIFLE, false },
{ ACT_RUN_CROUCH_AIM, ACT_RUN_CROUCH_AIM_RIFLE, false },
{ ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_AR2, false },
// { ACT_RANGE_ATTACK2, ACT_RANGE_ATTACK_OICW_GRENADE, true },
};

IMPLEMENT_ACTTABLE(CWeaponOICW);

CWeaponOICW::CWeaponOICW( )
{
m_fMinRange1 = 65;
m_fMaxRange1 = 2048;

m_fMinRange2 = 256;
m_fMaxRange2 = 1024;

m_nShotsFired = 0;
}

void CWeaponOICW::Precache( void )
{
UTIL_PrecacheOther("grenade_OICW");
BaseClass::Precache();
}

//-----------------------------------------------------------------------------
// Purpose: Offset the autoreload
//-----------------------------------------------------------------------------
bool CWeaponOICW::Deploy( void )
{
m_nShotsFired = 0;

return BaseClass::Deploy();
}

//-----------------------------------------------------------------------------
// Purpose: Handle grenade detonate in-air (even when no ammo is left)
//-----------------------------------------------------------------------------
void CWeaponOICW::ItemPostFrame( void )
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if (!pOwner)
return;

if ( ( pOwner->m_nButtons & IN_ATTACK ) == false )
{
m_nShotsFired = 0;
}

//Zoom in
if ( pOwner->m_afButtonPressed & IN_ATTACK2 )
{
Zoom();
}

//Don't kick the same when we're zoomed in
if ( m_bZoomed )
{
m_fFireDuration = 0.05f;
}

BaseClass::ItemPostFrame();
}

//-----------------------------------------------------------------------------
// Purpose:
// Output : Activity
//-----------------------------------------------------------------------------
Activity CWeaponOICW::GetPrimaryAttackActivity(void)
{
if ( m_nShotsFired < 2 )
return ACT_VM_PRIMARYATTACK;

if ( m_nShotsFired < 3 )
return ACT_VM_HITLEFT;

if ( m_nShotsFired < 4 )
return ACT_VM_HITLEFT2;

return ACT_VM_HITRIGHT;
}

//---------------------------------------------------------
//---------------------------------------------------------
void CWeaponOICW::PrimaryAttack( void )
{
m_nShotsFired++;

BaseClass::PrimaryAttack();
}

void CWeaponOICW::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
switch( pEvent->event )
{
case EVENT_WEAPON_AR2:
{
Vector vecShootOrigin, vecShootDir;
vecShootOrigin = pOperator->Weapon_ShootPosition();

CAI_BaseNPC *npc = pOperator->MyNPCPointer();
ASSERT( npc != NULL );
vecShootDir = npc->GetActualShootTrajectory( vecShootOrigin );
WeaponSound(SINGLE_NPC);
pOperator->FireBullets( 1, vecShootOrigin, vecShootDir, VECTOR_CONE_PRECALCULATED, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 2 );
pOperator->DoMuzzleFlash();
m_iClip1 = m_iClip1 - 1;
}
break;
default:
CBaseCombatWeapon::Operator_HandleAnimEvent( pEvent, pOperator );
break;
}
}

/*
==================================================
AddViewKick
==================================================
*/

void CWeaponOICW::AddViewKick( void )
{
#define EASY_DAMPEN 0.5f
#define MAX_VERTICAL_KICK 24.0f //Degrees
#define SLIDE_LIMIT 3.0f //Seconds

//Get the view kick
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

if (!pPlayer)
return;

DoMachineGunKick( pPlayer, EASY_DAMPEN, MAX_VERTICAL_KICK, m_fFireDuration, SLIDE_LIMIT );
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponOICW::Zoom( void )
{
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

if ( pPlayer == NULL )
return;

color32 lightGreen = { 50, 255, 170, 32 };

if ( m_bZoomed )
{
pPlayer->ShowViewModel( true );

// Zoom out to the default zoom level
WeaponSound(SPECIAL2);
pPlayer->SetFOV( this, 0, 0.1f );
m_bZoomed = false;

UTIL_ScreenFade( pPlayer, lightGreen, 0.2f, 0, (FFADE_IN|FFADE_PURGE) );
}
else
{
pPlayer->ShowViewModel( false );

WeaponSound(SPECIAL1);
pPlayer->SetFOV( this, 35, 0.1f );
m_bZoomed = true;

UTIL_ScreenFade( pPlayer, lightGreen, 0.2f, 0, (FFADE_OUT|FFADE_PURGE|FFADE_STAYOUT) );
}
}

//-----------------------------------------------------------------------------
// Purpose:
// Output : float
//-----------------------------------------------------------------------------
float CWeaponOICW::GetFireRate( void )
{
if ( m_bZoomed )
return 0.3f;

return 0.1f;
}

//-----------------------------------------------------------------------------
// Purpose:
// Input : NULL -
//-----------------------------------------------------------------------------
bool CWeaponOICW::Holster( CBaseCombatWeapon *pSwitchingTo )
{
if ( m_bZoomed )
{
Zoom();
}

return BaseClass::Holster( pSwitchingTo );
}

//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CWeaponOICW::Reload( void )
{
if ( m_bZoomed )
{
Zoom();
}

return BaseClass::Reload();
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponOICW::Drop( const Vector &velocity )
{
if ( m_bZoomed )
{
Zoom();
}

BaseClass::Drop( velocity );
}

===============================================================================

weapon_oicw.h

//========= Copyright © 1996-2007, DetLeR, Valve Corporation, All rights reserved. ============//
//
// Purpose: Projectile shot from the OICW
// ## Public Code ##
// $Workfile: $
// $Date: $
//
//----------------------------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//==============================================================================================//

#ifndef WEAPONOICW_H
#define WEAPONOICW_H

#include "basegrenade_shared.h"
#include "basehlcombatweapon.h"

class CWeaponOICW : public CHLMachineGun
{
public:
DECLARE_CLASS( CWeaponOICW, CHLMachineGun );

CWeaponOICW();

DECLARE_SERVERCLASS();

void ItemPostFrame( void );
float GetFireRate( void );
void Drop( const Vector &velocity );
void Precache( void );
void DelayedAttack( void );
void PrimaryAttack( void );

void AddViewKick( void );

void FireNPCPrimaryAttack( CBaseCombatCharacter *pOperator, bool bUseWeaponAngles );
void FireNPCSecondaryAttack( CBaseCombatCharacter *pOperator, bool bUseWeaponAngles );
void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );

int GetMinBurst( void ) { return 2; }
int GetMaxBurst( void ) { return 5; }

bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
bool Reload( void );
bool Deploy( void );
void Zoom( void );
int CapabilitiesGet( void ) { return bits_CAP_WEAPON_RANGE_ATTACK1; }

Activity GetPrimaryAttackActivity( void );

virtual const Vector& GetBulletSpread( void )
{
static Vector cone;

cone = VECTOR_CONE_3DEGREES;

return cone;
}

protected:

float m_flDelayedFire;
bool m_bShotDelayed;
bool m_bZoomed;
int m_nVentPose;

DECLARE_ACTTABLE();
DECLARE_DATADESC();
};

#endif //WEAPONAR2_H

===============================================================================

Далее лезем в c_weapon__stubs_hl2.cpp, который торчит в клиенте и после строки:

STUB_WEAPON_CLASS( weapon_ar2, WeaponAR2, C_HLMachineGun );
Вставляем вот это:

STUB_WEAPON_CLASS( weapon_oicw, WeaponOICW, C_HLMachineGun );

Верхняя операция оповестит клиент о том, что мы хотим такой-то веапон (в нашем случае OICW)
===============================================================================

Скачать модель и звуки

Теперь для того чтобы всё работало нормально ищем файл hl2_gamerules.cpp.
Ищем строку:
CAmmoDef *GetAmmoDef()
И под ней вставляем после неё:
def.AddAmmoType("AR2", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_oicw", "sk_npc_dmg_oicw", "sk_max_oicw", BULLET_IMPULSE(200, 1225), 0 );
Так же ищем:
ConVar sk_max_ar2_altfire ( "sk_max_ar2_altfire","0", FCVAR_REPLICATED);
И ниже добавляем:
ConVar sk_plr_dmg_oicw ( "sk_plr_dmg_ar2","0", FCVAR_REPLICATED );
ConVar sk_npc_dmg_oicw ( "sk_npc_dmg_ar2","0", FCVAR_REPLICATED);
ConVar sk_max_oicw ( "sk_max_ar2","0", FCVAR_REPLICATED);
ConVar sk_max_oicw_altfire ( "sk_max_ar2_altfire","0", FCVAR_REPLICATED);

Теперь нужны коробки с патронами?не вопрос.
Ищем item_ammo.cpp в серверной части и добавляем после
LINK_ENTITY_TO_CLASS( item_rpg_round, CItem_RPG_Round );
Следующие строки:


#define AMMO_OICW_GIVE 20
#define AMMO_OICW_MODEL "models/items/boxmrounds.mdl" // УКАЖИТЕ вашу модель для коробочки тут class CItem_OICWAmmo : public CItem
{
public:
DECLARE_CLASS( CItem_OICWAmmo, CItem );

void Spawn( void )
{
Precache();
SetModel( AMMO_OICW_MODEL );
BaseClass::Spawn();
}
void Precache( void )
{
engine->PrecacheModel( AMMO_OICW_MODEL );
}
bool MyTouch( CBasePlayer *pPlayer )
{
if ( ITEM_GiveAmmo( pPlayer, AMMO_OICW_GIVE, "OICW" ) )
{
if ( g_pGameRules->ItemShouldRespawn( this ) == GR_ITEM_RESPAWN_NO )
{
UTIL_Remove(this);
}
return true;
}
return false;
}
};
LINK_ENTITY_TO_CLASS( item_ammo_oicw, CItem_OICWAmmo ); // Название entity
LINK_ENTITY_TO_CLASS( item_oicw_ammo, CItem_OICWAmmo ); // Название entity


===============================================================================
Ага!Вы дума всё?А вот и нет.Скрипт!

Создаём .txt файл с назанием weapon_oicw и вставлям туда следующее:
// OICW

WeaponData
{
// Weapon data is loaded by both the Game and Client DLLs.
// Вся информация об оружии (Модели, расположение, название, количество патронов в рожке)
"printname" "OICW"
"viewmodel" "models/weapons/v_oicw.mdl" // Моделька, которую мы видим в руках
"playermodel" "models/weapons/w_oicw.mdl" // Моделька, которую мы видим со стороны
"anim_prefix" "ar2"
"bucket" "2" // Эта строка определяет столбец, в котором оружие будет появляться
"bucket_position" "2" // Эта строка определяет положение в столбце
// Счёт ведётся с нуля

"clip_size" "30" // Размер обоймы
"default_clip" "30"

"clip2_size" "-1"
"default_clip2" "-1"

"primary_ammo" "OICW" // Тип патронов, который использует оружие
//"secondary_ammo" "AR2AltFire" // Тип патронов вторичной атаки (нам не нужно)

"weight" "5" // Вес оружия
"item_flags" "0"

// Sounds for the weapon. There is a max of 16 sounds per category (i.e. max 16 "single_shot" sounds)
// Прописываем снизу звуки.
SoundData
{
"special1" "Weapon_CombineGuard.Special1"
"empty" "Weapon_AR2.Empty"
"reload" "Weapon_AR2.Reload"
"single_shot" "Weapon_AR2.Single"

// NPC SECTION
"single_shot_npc" "Weapon_AR2.NPC_Single"
"reload_npc" "Weapon_AR2.NPC_Reload"
"double_shot_npc" "Weapon_AR2.NPC_Double"
}

// Weapon Sprite data is loaded by the Client DLL.
// Текстуры и спрайты для оружия
TextureData
{
"weapon"
{
"font" "WeaponIcons"
"character" "l"
}
"weapon_s"
{
"font" "WeaponIconsSelected"
"character" "l"
}
"ammo"
{
"font" "WeaponIcons"
"character" "u"
}
"ammo2"
{
"font" "WeaponIcons"
"character" "z"
}
"crosshair"
{
"font" "Crosshairs"
"character" "Q"
}
"autoaim"
{
"file" "sprites/crosshairs"
"x" "0"
"y" "48"
"width" "24"
"height" "24"
}
}
}


Теперь откроем файл game_sounds_weapons.txt в папке scripts и впысываем туда это чудо:

"Weapon_AR2.NPC_Reload"
{
"channel" "CHAN_ITEM"
"volume" "0.7"
"soundlevel" "SNDLVL_NORM"

"wave" "weapons/ar2/npc_ar2_reload.wav"
}

"Weapon_AR2.NPC_Double"
{
"channel" "CHAN_WEAPON"
"volume" "0.7"
"soundlevel" "SNDLVL_GUNFIRE"

"wave" "weapons/ar2/npc_ar2_altfire.wav"
}

"Weapon_AR2.NPC_Single"
{
"channel" "CHAN_WEAPON"
"volume" "0.7"
"soundlevel" "SNDLVL_GUNFIRE"
"pitch" "95,105"

// "wave" "^weapons/ar2/npc_ar2_fire1.wav"
"wave" "^weapons/ar1/ar1_dist1.wav"

}

"Weapon_AR2.Single"
{
"channel" "CHAN_WEAPON"
"volume" "0.8"
"soundlevel" "SNDLVL_GUNFIRE"
"pitch" "85,95"

"rndwave"
{
"wave" "weapons/ar2/fire1.wav"
}
}

"Weapon_AR2.Reload"
{
"channel" "CHAN_ITEM"
"volume" "0.7"
"soundlevel" "SNDLVL_NORM"

"wave" "weapons/ar2/ar2_reload.wav"
}

"Weapon_AR2.Empty"
{
"channel" "CHAN_WEAPON"
"volume" "0.7"
"soundlevel" "SNDLVL_NORM"

"wave" "weapons/ar2/ar2_empty.wav"
}
================================================================================
Вроде бы всё. Спасибо за внимание.

Категория: Туториалы по программированию (HL2) | Добавил: Duffman™ (28.08.2007) | Автор: DetLeR
Просмотров: 6569 | Комментарии: 5 | Рейтинг: 4.0 |

Всего комментариев: 5
5  
А подстволка работает? И на какую кнопку?

4  
def.AddAmmoType("AR2", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_oicw", "sk_npc_dmg_oicw", "sk_max_oicw", BULLET_IMPULSE(200, 1225), 0 );

Вроде что-то не то)


3  
Ну всё же тутор расщитан на нубов, так что надо поправить, что б потом не было вопросов biggrin

2  
До этого сами додумаются.Не маленькие. biggrin Я даж и не думал что это нада обьяснять.

1  
Так, дафмен, а в стабы в клиентовской части дописать? Без это работать не будет smile

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

Кто в Онлайн

Друзья сайта

Баннеры

  Сайт CrazyArts   Black   Сообщество сайтов о Half-Life   Самый   Только   Все   hl2 top 100     Rambler's Top100  

игры
игры

  Каталог сайтов Планета Топ 100 - Planet Top 100       ТОП ЛУЧШИХ ИГРОВЫХ САЙТОВ           Detroit Team Site :: Моды от Detroit Team, видео, новости.   Naruto-kun[Звезда Наруто]  


The idea of dising: Homie7