Итак,
я тут подумал и решил написать про оружие из OF - DesertEagle, так как ссылки на
zzero.fatal.ru битые
Путём долгих и трудных мозгований я написал исходный код - его можно будет взять
здесь(w_deagle.cpp):
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id
Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or
resulting
* object code is restricted to non-commercial enhancements to
products from
* Valve LLC. All other use, distribution, or modification is
prohibited
* without written permission from Valve LLC.
*
* CrazyArts 2009
* Desert Eagle Source File
*
*
****/
#if !defined( OEM_BUILD ) && !defined( HLDEMO_BUILD )
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "weapons.h"
#include "monsters.h"
#include "player.h"
#include "gamerules.h"
enum deagle_e {
DEAGLE_IDLE1 = 0,
DEAGLE_IDLE2,
DEAGLE_IDLE3,
DEAGLE_IDLE4,
DEAGLE_IDLE5,
DEAGLE_SHOOT,
DEAGLE_SHOOT_EMPTY,
DEAGLE_RELOAD,
DEAGLE_RELOAD_EMPTY,
DEAGLE_DRAW,
DEAGLE_HOLSTER
};
///DEAGLE
LINK_ENTITY_TO_CLASS( weapon_deagle, CDeagle );
int CDeagle::GetItemInfo(ItemInfo *p)
{
p->pszName = STRING(pev->classname);
p->pszAmmo1 = "357";
p->iMaxAmmo1 = _357_MAX_CARRY;
p->pszAmmo2 = NULL;
p->iMaxAmmo2 = -1;
p->iMaxClip = DEAGLE_MAX_CLIP;
p->iFlags = 0;
p->iSlot = 1;
p->iPosition = 2;
p->iId = m_iId = WEAPON_DEAGLE;
p->iWeight = PYTHON_WEIGHT;
return 1;
}
int CDeagle::AddToPlayer( CBasePlayer *pPlayer )
{
if ( CBasePlayerWeapon::AddToPlayer( pPlayer ) )
{
MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup,
NULL, pPlayer->pev );
WRITE_BYTE( m_iId );
MESSAGE_END();
return TRUE;
}
return FALSE;
}
void CDeagle::Spawn( )
{
pev->classname = MAKE_STRING("weapon_deagle");
// Making class string
Precache( );
m_iId = WEAPON_DEAGLE;
SET_MODEL(ENT(pev), "models/w_deagle.mdl");
m_iDefaultAmmo = DEAGLE_DEFAULT_GIVE;//7
FallInit();// get ready to fall down.
}
void CDeagle::Precache( void )
{
PRECACHE_MODEL("models/v_deagle.mdl");
PRECACHE_MODEL("models/w_deagle.mdl");
PRECACHE_MODEL("models/p_deagle.mdl");
PRECACHE_MODEL("models/w_357ammobox.mdl");
PRECACHE_SOUND("items/9mmclip1.wav");
PRECACHE_SOUND ("weapons/desert_eagle_reload.wav");
PRECACHE_SOUND ("weapons/357_cock1.wav");
PRECACHE_SOUND ("weapons/desert_eagle_fire.wav");
PRECACHE_SOUND ("weapons/desert_eagle_sight.wav");
PRECACHE_SOUND
("weapons/desert_eagle_sight2.wav");
UTIL_PrecacheOther( "laser_spot" );
m_usFireDeagle = PRECACHE_EVENT( 1,
"events/deagle.sc" );
}
BOOL CDeagle::Deploy( )
{
#ifdef CLIENT_DLL
if ( bIsMultiplayer() )
#else
if ( g_pGameRules->IsMultiplayer() )
#endif
{
// enable laser sight geometry.
m_deLaser = 1;
}
else
{
m_deLaser = 0;
}
return DefaultDeploy( "models/v_deagle.mdl",
"models/p_deagle.mdl", DEAGLE_DRAW, "deagle",
UseDecrement(), pev->body );
}
void CDeagle::Holster( int skiplocal /* = 0 */ )
{
m_fInReload = FALSE;// cancel any reload in progress.
#ifndef CLIENT_DLL
if (m_pSpot)
{
m_pSpot->Killed( NULL, GIB_NEVER );
m_pSpot = NULL;
}
#endif
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 1.0;
m_flTimeWeaponIdle = UTIL_SharedRandomFloat(
m_pPlayer->random_seed, 10, 15 );
SendWeaponAnim( DEAGLE_HOLSTER );
}
void CDeagle::SecondaryAttack( void )
{
m_deLaser = ! m_deLaser;
#ifndef CLIENT_DLL
if (!m_deLaser && m_pSpot)
{
EMIT_SOUND(ENT(m_pPlayer->pev),
CHAN_WEAPON, "weapons/desert_eagle_sight2.wav", 0.8, ATTN_NORM);
m_pSpot->Killed( NULL, GIB_NORMAL );
m_pSpot = NULL;
}
else EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON,
"weapons/desert_eagle_sight.wav", 0.8, ATTN_NORM);
#endif
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.33;
}
void CDeagle::PrimaryAttack()
{
// //don't fire underwater
// if (m_pPlayer->pev->waterlevel == 3)
// {
// PlayEmptySound( );
// m_flNextPrimaryAttack = 0.15;
// return;
// }
if(! ( m_pPlayer->m_afButtonPressed & IN_ATTACK ) )
return;//SEMI_AUTO
if (m_iClip <= 0)
{
if (!m_fFireOnEmpty)
Reload( );
else
{
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON,
"weapons/357_cock1.wav", 0.8, ATTN_NORM);
m_flNextPrimaryAttack
= 0.2;
}
return;
}
m_pPlayer->m_iWeaponVolume = LOUD_GUN_VOLUME;
m_pPlayer->m_iWeaponFlash = BRIGHT_GUN_FLASH;
m_iClip--;
m_pPlayer->pev->effects =
(int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH;
// player "shoot" animation
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
UTIL_MakeVectors( m_pPlayer->pev->v_angle +
m_pPlayer->pev->punchangle );
Vector vecSrc = m_pPlayer->GetGunPosition(
);
Vector vecAiming = m_pPlayer->GetAutoaimVector(
AUTOAIM_10DEGREES );
Vector vecDir;
if ( !m_deLaser )
{
vecDir = m_pPlayer->FireBulletsPlayer(
1, vecSrc, vecAiming, VECTOR_CONE_10DEGREES, 8192, BULLET_PLAYER_357, 0, 0,
m_pPlayer->pev, m_pPlayer->random_seed );
m_flNextPrimaryAttack = 0.11;
}
else
{
vecDir = m_pPlayer->FireBulletsPlayer(
1, vecSrc, vecAiming, VECTOR_CONE_1DEGREES, 8192, BULLET_PLAYER_357, 0, 0,
m_pPlayer->pev, m_pPlayer->random_seed );
m_flNextPrimaryAttack = 0.4;
}
UpdateSpot( );
int flags;
#if defined( CLIENT_WEAPONS )
flags = FEV_NOTHOST;
#else
flags = 0;
#endif
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usFireDeagle,
0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0,
0, 0, 0 );
if (!m_iClip &&
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
// HEV suit - indicate out of ammo
condition
m_pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0);
m_flTimeWeaponIdle = UTIL_SharedRandomFloat(
m_pPlayer->random_seed, 10, 15 );
}
void CDeagle::Reload( void )
{
if ( m_pPlayer->ammo_357 <= 0 )
return;
if (DefaultReload( 7, DEAGLE_RELOAD, 2.0, 0))
{
m_flSoundDelay = 1.5;
}
#ifndef CLIENT_DLL
if ( m_pSpot && m_deLaser )
{
m_pSpot->Suspend( 2.1 );
m_flNextSecondaryAttack =
UTIL_WeaponTimeBase() + 0.1;
}
#endif
}
void CDeagle::WeaponIdle( void )
{
UpdateSpot( );
ResetEmptySound( );
m_pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES );
if (m_flSoundDelay != 0 && m_flSoundDelay <=
UTIL_WeaponTimeBase() )
{
EMIT_SOUND(ENT(m_pPlayer->pev),
CHAN_WEAPON, "weapons/desert_eagle_reload1.wav", RANDOM_FLOAT(0.8,
0.9), ATTN_NORM);
m_flSoundDelay = 0;
}
if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase() )
return;
int iAnim;
float flRand = UTIL_SharedRandomFloat(
m_pPlayer->random_seed, 10, 15 );
if (flRand <= 0.5)
{
iAnim = DEAGLE_IDLE1;
m_flTimeWeaponIdle = (70.0/30.0);
}
else if (flRand <= 0.7)
{
iAnim = DEAGLE_IDLE2;
m_flTimeWeaponIdle = (60.0/30.0);
}
else if (flRand <= 0.9)
{
iAnim = DEAGLE_IDLE3;
m_flTimeWeaponIdle = (88.0/30.0);
}
int bUseScope = FALSE;
#ifdef CLIENT_DLL
bUseScope = bIsMultiplayer();
#else
bUseScope = g_pGameRules->IsMultiplayer();
#endif
SendWeaponAnim( iAnim, UseDecrement() ? 1 : 0, bUseScope );
}
#endif
void CDeagle::UpdateSpot( void )
{
#ifndef CLIENT_DLL
if (m_deLaser)
{
if (!m_pSpot)
{
m_pSpot =
CLaserSpot::CreateSpot();
}
UTIL_MakeVectors(
m_pPlayer->pev->v_angle );
Vector vecSrc = m_pPlayer->GetGunPosition(
);;
Vector vecAiming =
gpGlobals->v_forward;
TraceResult tr;
UTIL_TraceLine ( vecSrc, vecSrc +
vecAiming * 8192, dont_ignore_monsters, ENT(m_pPlayer->pev), &tr );
UTIL_SetOrigin( m_pSpot->pev, tr.vecEndPos
);
}
#endif
}
1.Добавляем
файл w_deagle.cpp в
проект ( для
начала - в
серверной )
2. Для
того
что
бы
всё
работало , нам
нужно
объявить
новый
класс
в weapons.h:
class CDeagle : public CBasePlayerWeapon
{
public:
void Spawn( void );
void Precache( void );
int iItemSlot( void ) { return 2; }
int GetItemInfo(ItemInfo *p);
int AddToPlayer( CBasePlayer *pPlayer );
void PrimaryAttack( void );
void SecondaryAttack( void );
BOOL Deploy( void );
void Holster( int skiplocal = 0 );
void Reload( void );
void WeaponIdle( void );
float m_flSoundDelay;
void UpdateSpot( void );
BOOL m_deLaser; //Laser is 0 initially
CLaserSpot *m_pSpot; //This is Laser
virtual BOOL UseDecrement( void )
{
#if defined( CLIENT_WEAPONS )
return TRUE;
#else
return FALSE;
#endif
}
private:
unsigned short m_usFireDeagle;
};
Только
тут
один
нюанс - нужно
класс
объявить
ПОСЛЕ
определения
класса CLaserSpot - иначе
будет
ошибка .
3. Дальше - переходим
к #define` ам - строчка 147 - 148
Добавляем
новый
дефайн :
#define DEAGLE_MAX_CLIP
7;//Deagle gun max clip
И
ещё
один
на 169 строчке :
#define DEAGLE_DEFAULT_GIVE
7;//Deagle default give
И
последний
на 69 строчке :
#define WEAPON_DEAGLE
17//Our weapon
4.weapons.cpp - открываем
на 348-349:
Добавляем
туды
следующее :
#if !defined( OEM_BUILD ) &&
!defined( HLDEMO_BUILD )
// deagle
UTIL_PrecacheOtherWeapon( "weapon_deagle" );
#endif
5.[ Опцианально ] - Можете
добавить
новое
оружие
в impulse 101 -
Открываем
на 3673 строчке
файл player.cpp и
пишем
там
GiveNamedItem( "weapon_deagle"
);
6.[Опцианально ] - Можно
позволить
ящикам
спавнить
наш
новый
ствол .
Для этого
откроем файл func _ break . cpp
и перейдём
на 60-61 строчку:
" weapon _ deagle ",
Всё - можем компилить!
Но это была лишь серверная часть.
Теперь перейдём к клиенту:
1.Добавим файл w_deagle.cpp в клиентский проект.
2.Откроем ev_hldm.cpp на 72 строчке и добавим:
void EV_FireDeagle( struct event_args_s
*args );
На 871 строчке пишем:
//======================
// DEAGLE START
// ( .357 )
//======================
void EV_FireDeagle( event_args_t *args )
{
int idx;
vec3_t origin;
vec3_t angles;
vec3_t velocity;
vec3_t vecSrc, vecAiming;
vec3_t up, right, forward;
float flSpread = 0.01;
idx = args->entindex;
VectorCopy( args->origin, origin );
VectorCopy( args->angles, angles );
VectorCopy( args->velocity, velocity );
AngleVectors( angles, forward, right, up );
if ( EV_IsLocal( idx ) )
{
// Python uses different body in
multiplayer versus single player
int multiplayer = gEngfuncs.GetMaxClients()
== 1 ? 0
: 1;
// Add muzzle flash to current weapon
model
EV_MuzzleFlash();
gEngfuncs.pEventAPI->EV_WeaponAnimation( DEAGLE_SHOOT, multiplayer ? 1
: 0 );
V_PunchAxis( 0, -10.0 );
}
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin,
CHAN_WEAPON, "weapons/desert_eagle_fire.wav",
gEngfuncs.pfnRandomFloat(0.8, 0.9), ATTN_NORM, 0, PITCH_NORM );
EV_GetGunPosition( args, vecSrc, origin );
VectorCopy( forward, vecAiming );
EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc,
vecAiming, 8192, BULLET_PLAYER_357, 0, 0, args->fparam1, args->fparam2 );
}
//======================
// DEAGLE END
// ( .357 )
//======================
3.Откроем
файл hl_events.cpp на 29 строчке
и
пишем :
void EV_FireDeagle( struct event_args_s
*args );
А
на 81 строчке
пишем
так
gEngfuncs.pfnHookEvent(
"events/deagle.sc",
EV_FireDeagle );
4.hl_events.cpp - строка 58 добавляем :
CDeagle g_Deagle;
630 строчка :
HUD_PrepEntity(
&g_Deagle , &player );
725 строчка :
case WEAPON_DEAGLE:
pWeapon =
&g_Deagle;
break;
5.ev_hldm.h - 75:
enum deagle_e {
DEAGLE_IDLE1 = 0,
DEAGLE_IDLE2,
DEAGLE_IDLE3,
DEAGLE_IDLE4,
DEAGLE_IDLE5,
DEAGLE_SHOOT,
DEAGLE_SHOOT_EMPTY,
DEAGLE_RELOAD,
DEAGLE_RELOAD_EMPTY,
DEAGLE_DRAW,
DEAGLE_HOLSTER
};
Ну
вот
и
всё ! компилим !!!
Ну
и
на
последок - ресурсы
для
оружия :
У
вас
должен
быть HL OF - оттуда
скопируйте
модели , спрайты , звуки
и eagle.sc( переименуйте
на deagle.sc) в
папку valve
Теперь
в
папке valve\models *_desert_eagle.mdl на соответсвующие *_deagle.mdl
Всё - должно
работать !!!