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
// 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"
// 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"
}
}
}