목요일, 10월 19, 2006

Purpose: AK46 weapon 만들기

-= CS(카스)의 AK47 weapon 만들기 =-

Purpose: AK46 weapon 만들기
Author: godmode2k (godmode2k@hotmail.com | MSN IM)
Date: October. 12. 2004
Destination: 모드나라 (http://mod.zoa.to)
Source:
http://www.planethalflife.com/hlprogramming/tutorial.asp?i=233


SDK: HL1 SDK 2.3
Code: Multyplayer Source
Tested: Steam based

(*)Special thanks to:
- Adrien Shepard (adrien_shepard@hotmail.com)


Description:
지난번 제가 작성한 tutorials:
0. "자신이 만든 MOD를 STEAM 으로 돌려보기 입니다."
1. 외국 Tutorial 번역 "Creating a New VGUI Menu - Part 1"
2. "게임내에서 wave 파일을 재생하자!"
3. "Radio Command Menu 만들기(CS 처럼)"
4. "MOD 게임 바탕화면 Logo 바꾸기"
5. "HLDS로 나의 MOD Server 구성하기"
6. "Counter-Strike 처럼 Team System 만들기(수정된 Radio Command Menu 포함)"
7. "기존 M16에서 CS(카스)의 M4A1 weapon 만들기"

주소는: 0. http://cocowest.javasarang.net/mod/bbs/view.php?&bbs_id=hlsdk&page=&doc_num=39
1. http://cocowest.javasarang.net/mod/vgui_p1/VGUIMenuPart1.htm
2. http://cocowest.javasarang.net/mod/bbs/view.php?&bbs_id=hlsdk&page=&doc_num=49
3. http://cocowest.javasarang.net/mod/bbs/view.php?&bbs_id=hlsdk&page=&doc_num=51
4. http://cocowest.javasarang.net/mod/bbs/view.php?&bbs_id=hlsdk&page=&doc_num=53
5. http://cocowest.javasarang.net/mod/bbs/view.php?&bbs_id=hlsdk&page=&doc_num=59
6. http://cocowest.javasarang.net/mod/bbs/view.php?&bbs_id=hlsdk&page=&doc_num=74
7. http://cocowest.javasarang.net/mod/bbs/view.php?&bbs_id=hlsdk&page=&doc_num=99

[ 추가사항 ]
* 원본 ak47.cpp 파일만으로는 동작하지 않습니다.
* 따라서 기존 M4A1의 코드와 흐름을 같이 했으며, 원본 ak47.cpp 자체 코드의 수정이 있었습니다.
*
*


[ 주의 ]
code를 추가해 줄 때,

// 018killer: ... [
// 018killer: ... ]

사이 부분의 code를 추가해 주시면 됩니다


*** 분량이 조금 많습니다. 커피나 시원한 음료수 하나 놓고 시작하시기 바랍니다.
*** 중간에 키보드를 던지는 ,,, ㅎㅎ; 그런일이 발생하지 않았으면 하는 바람입니다.

그럼, 준비가 되셨다면 시작해 볼까요?



--------------------------------------------------------------
파일명: mp files/ak47.cpp , cl_dll files/ak47.cpp
작업위치: top
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "monsters.h"
#include "weapons.h"
#include "nodes.h"
#include "player.h"
#include "soundent.h"
#include "gamerules.h"
#include "shake.h"


enum ak47_e
{
AK47_IDLE1,
AK47_RELOAD,
AK47_DRAW,
AK47_SHOOT1,
AK47_SHOOT2,
AK47_SHOOT3
};


//
// enum ak47_e 부분의 코드는 v_*.mdl 파일의 sequence 정의입니다. 확인하는 부분은
// v_*.mdl 파일을 MilkShape 3D 로 decomplie 하면 v_*.qc 라는 파일이 나옵니다.
// 그 파일을 열면 제일 아래 부분에 sequence 정의 부분이 나옵니다.
// 그 부분을 순서대로 enumeration 하시면 됩니다.
//


// This is where you can change the animations,
// so if you have a model with diff anmations and you want to use it,
// you would also need to define the new animations in some of the classes like
// reload, idle, primary attack etc.

LINK_ENTITY_TO_CLASS( weapon_ak47, CAK47 );


//=========================================================
//=========================================================
void CAK47::Spawn( )
{
pev->classname = MAKE_STRING("weapon_ak47"); // hack to allow for old names
Precache( );
SET_MODEL(ENT(pev), "models/w_ak47.mdl");
m_iId = WEAPON_AK47;

m_iDefaultAmmo = AK47_DEFAULT_GIVE;

FallInit();// get ready to fall down.
}


void CAK47::Precache( void )
{
PRECACHE_MODEL("models/v_ak47.mdl");
PRECACHE_MODEL("models/w_ak47.mdl");
PRECACHE_MODEL("models/p_ak47.mdl");

m_iShell = PRECACHE_MODEL ("models/shell.mdl");// brass shellTE_MODEL

PRECACHE_MODEL("models/w_9mmARclip.mdl");
PRECACHE_SOUND("items/9mmclip1.wav");

PRECACHE_MODEL("models/player/sas/sas.mdl");

// Counter-Strike에 있는 AK47 sound files [
PRECACHE_SOUND ("weapons/ak47_clipout.wav");
PRECACHE_SOUND ("weapons/ak47_clipin.wav");

PRECACHE_SOUND ("weapons/ak47_boltpull.wav");

PRECACHE_SOUND ("weapons/ak47-1.wav");
PRECACHE_SOUND ("weapons/ak47-2.wav");
// Counter-Strike에 있는 AK47 sound files ]

m_usAK47 = PRECACHE_EVENT( 1, "events/ak47.sc" );
m_usAK472 = PRECACHE_EVENT( 1, "events/ak472.sc" );
}


int CAK47::GetItemInfo(ItemInfo *p)
{
p->pszName = STRING(pev->classname);
p->pszAmmo1 = "357";
// p->pszAmmo1 = "9mm";
p->iMaxAmmo1 = _357_MAX_CARRY;
// p->iMaxAmmo1 = _9MM_MAX_CARRY;
p->pszAmmo2 = NULL;
p->iMaxAmmo2 = -1;
p->iMaxClip = AK47_MAX_CLIP;
p->iSlot = 1;
p->iPosition = 4;
p->iFlags = 0;
p->iId = m_iId = WEAPON_AK47;
p->iWeight = AK47_WEIGHT;

return 1;
}


int CAK47::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;
}


BOOL CAK47::Deploy( )
{
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/ak47_deploy.wav", 1, ATTN_NORM, 0, 94 + RANDOM_LONG(0,0xf));
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/ak47_boltpull.wav", 1, ATTN_NORM, 0, 94 + RANDOM_LONG(0,0xf));

// AK47 총기를 다시 draw
// 대부분 'q'를 누를 때 AK47이 다시 그려지는 모습을 보게됨
return DefaultDeploy( "models/v_ak47.mdl", "models/p_ak47.mdl", AK47_DRAW, "mp5" ); // "mp5" -> "ak47"로 해도 무관
}


void CAK47::PrimaryAttack()
{
// don''t fire underwater
if (m_pPlayer->pev->waterlevel == 3)
{
PlayEmptySound( );
m_flNextPrimaryAttack = 0.15;
return;
}

// I have it set to where the ak can fire underwater right above just remove parts
// where I commented it out from "//PlayEmptySound( );" to "//return;"
if (m_iClip <= 0)
{
PlayEmptySound();
m_flNextPrimaryAttack = 0.15;
return;
}

m_pPlayer->m_iWeaponVolume = NORMAL_GUN_VOLUME;
m_pPlayer->m_iWeaponFlash = NORMAL_GUN_FLASH;

m_iClip--;


m_pPlayer->pev->effects = (int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH;

// player "shoot" animation
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );

Vector vecSrc = m_pPlayer->GetGunPosition( );
Vector vecAiming = m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
Vector vecDir;

// #ifdef CLIENT_DLL
// if ( !bIsMultiplayer() )
// #else
// if ( !g_pGameRules->IsMultiplayer() )
// #endif
// {
// optimized multiplayer. Widened to make it easier to hit a moving player
vecDir = m_pPlayer->FireBulletsPlayer( 1, vecSrc, vecAiming, VECTOR_CONE_1DEGREES, 8192, BULLET_PLAYER_AK47, 2, 0, m_pPlayer->pev, m_pPlayer->random_seed );
// }
// else
// {
// single player spread
// vecDir = m_pPlayer->FireBulletsPlayer( 1, vecSrc, vecAiming, VECTOR_CONE_3DEGREES, 8192, BULLET_PLAYER_357, 2, 0, m_pPlayer->pev, m_pPlayer->random_seed );
// }

int flags;
#if defined( CLIENT_WEAPONS )
flags = FEV_NOTHOST;
#else
flags = 0;
#endif

PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usAK47, 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_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1;

if ( m_flNextPrimaryAttack < UTIL_WeaponTimeBase() )
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1;

m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
}


void CAK47::SecondaryAttack( void )
{
return;
}


void CAK47::Reload( void )
{
if ( m_pPlayer->ammo_357 <= 0 )
// if ( m_pPlayer->ammo_9mm <= 0 )
return;

DefaultReload( AK47_MAX_CLIP, AK47_RELOAD, 2.3 );
//DefaultReload( AK47_MAX_CLIP, AK47_RELOAD, 2.75 );

EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/ak47_clipout.wav", 1, ATTN_NORM, 0, 94 + RANDOM_LONG(0,0xf));
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/ak47_clipin.wav", 1, ATTN_NORM, 0, 94 + RANDOM_LONG(0,0xf));
}


void CAK47::WeaponIdle( void )
{
ResetEmptySound( );

m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );

// if ( m_flTimeWeaponIdle > UTIL_WeaponTimeBase() )
// return;

int iAnim;
// switch ( RANDOM_LONG( 0, 1 ) )
// {
// default:
// case 1:
iAnim = AK47_IDLE1;
// break;
// }

SendWeaponAnim( iAnim );

// m_flTimeWeaponIdle = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 ); // how long till we do this again.
}


class CAK47AmmoClip : public CBasePlayerAmmo
{
void Spawn( void )
{
Precache( );
SET_MODEL(ENT(pev), "models/w_9mmARclip.mdl");
CBasePlayerAmmo::Spawn( );
}
void Precache( void )
{
PRECACHE_MODEL ("models/w_9mmARclip.mdl");
PRECACHE_SOUND("items/9mmclip1.wav");
}
BOOL AddAmmo( CBaseEntity *pOther )
{
int bResult = (pOther->GiveAmmo( AMMO_AK47CLIP_GIVE, "357", _357_MAX_CARRY) != -1);
if (bResult)
{
EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM);
}
return bResult;
}
};


LINK_ENTITY_TO_CLASS( ammo_ak47clip, CAK47AmmoClip );

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: mp files/weapons.h
작업위치:
// The amount of ammo given to a player by an ammo item.
#define AMMO_URANIUMBOX_GIVE 20
...
#define AMMO_CROSSBOWCLIP_GIVE CROSSBOW_MAX_CLIP
#define AMMO_RPGCLIP_GIVE RPG_MAX_CLIP
#define AMMO_URANIUMBOX_GIVE 20
#define AMMO_SNARKBOX_GIVE 5

바로 아래 부분
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

#define WEAPON_AK47 17 // 무기에 대한 번호: 이것은 매우 중요함! 무기가 추가되는 대로 거기에 맞춰 번호를 sequence 대로 맞춰야 함
#define AK47_WEIGHT 20 // 무기중 우선권
#define AK47_MAX_CARRY 250 // 최대총알수
#define AK47_MAX_CLIP 30 // 한탄창 최대총알수
#define AK47_DEFAULT_GIVE 250 // 디폴트로 주어지는 총알수
#define AMMO_AK47CLIP_GIVE 30 // 주운탄창 총알수

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: mp files/weapons.h
작업위치:
class CPython : public CBasePlayerWeapon
{
public:
...
private:
unsigned short m_usFirePython;
};

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

class CAK47 : public CBasePlayerWeapon
{
public:
void Spawn( void );
void Precache( void );
int iItemSlot( void ) { return 3; }
int GetItemInfo(ItemInfo *p);
int AddToPlayer( CBasePlayer *pPlayer );

void PrimaryAttack( void );
void SecondaryAttack( void );
BOOL Deploy( void );
void Reload( void );
void WeaponIdle( void );
float m_flNextAnimTime;
int m_iShell;
bool m_bSilenced;

virtual BOOL UseDecrement( void )
{
#if defined( CLIENT_WEAPONS )
return TRUE;
#else
return FALSE;
#endif
}

private:
unsigned short m_usAK47;
unsigned short m_usAK472;
};

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: mp files/weapons.cpp
작업위치:
// called by worldspawn
void W_Precache(void)
{
...
// mp5
UTIL_PrecacheOtherWeapon( "weapon_9mmAR" );
UTIL_PrecacheOther( "ammo_9mmAR" );
UTIL_PrecacheOther( "ammo_ARgrenades" );

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

// 하프라이프에 ak47 화기와 탄약을 precache 합니다.
UTIL_PrecacheOtherWeapon( "weapon_ak47" );
UTIL_PrecacheOther( "ammo_ak47clip" );

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: mp files/weapons.h
작업위치:
// bullet types
typedef enum
{
...
BULLET_PLAYER_BUCKSHOT, // shotgun
BULLET_PLAYER_CROWBAR, // crowbar swipe

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

BULLET_PLAYER_AK47, // ak47

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: mp files/combat.cpp
작업위치:
Vector CBaseEntity::FireBulletsPlayer ( ... )
{
...
...
case BULLET_PLAYER_357:
...
< 추가 할 곳 >
case BULLET_NONE: // FIX
...

에서 case BULLET_PLAYER_357: 와 case BULLET_NONE: // FIX 사이에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

case BULLET_PLAYER_AK47: // 총알이 발사될 때 호출
pEntity->TraceAttack(pevAttacker, gSkillData.plrDmgAK47, vecDir, &tr, DMG_BULLET);
break;

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: mp files/multiplay_gamerules.cpp
작업위치:
void CHalfLifeMultiplay::RefreshSkillData( void )
{
...

// hornet
gSkillData.plrDmgHornet = 10;

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

// ak47
gSkillData.plrDmgAK47 = 20; // 맞았을 때 damage

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: mp files/skill.h
작업위치:
struct skilldata_t
{
...
// Player Weapons
float plrDmgCrowbar;
float plrDmg9MM;
...
float plrDmgSatchel;
float plrDmgTripmine;

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

float plrDmgAK47;

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: mp files/weapons.cpp
작업위치:
void DecalGunshot( TraceResult *pTrace, int iBulletType )
{
...
switch( iBulletType )
{
case BULLET_PLAYER_9MM:
case BULLET_MONSTER_9MM:
...
case BULLET_PLAYER_357:

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

case BULLET_PLAYER_AK47:

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: mp files/multiplay_gamerules.cpp
작업위치:
void CHalfLifeMultiplay :: PlayerSpawn( CBasePlayer *pPlayer )
{
...
if ( addDefault )
{
pPlayer->GiveNamedItem( "weapon_crowbar" );
pPlayer->GiveNamedItem( "weapon_9mmhandgun" );

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

pPlayer->GiveNamedItem( "weapon_ak47" ); // 플레이어가 스폰될 때 ak47이 주어집니다.

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: cl_dll files/hl/hl_events.cpp
작업위치:
extern "C"
{
// HLDM
void EV_FireGlock1( struct event_args_s *args );
...
void EV_TripmineFire( struct event_args_s *args );
void EV_SnarkFire( struct event_args_s *args );

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

void EV_FireAK47( struct event_args_s *args );
void EV_FireAK472( struct event_args_s *args );

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: cl_dll files/hl/hl_events.cpp
작업위치:
void Game_HookEvents( void )
{
gEngfuncs.pfnHookEvent( "events/glock1.sc", EV_FireGlock1 );
...
gEngfuncs.pfnHookEvent( "events/snarkfire.sc", EV_SnarkFire );

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

gEngfuncs.pfnHookEvent( "events/ak47.sc", EV_FireAK47 );
gEngfuncs.pfnHookEvent( "events/ak472.sc", EV_FireAK472 );

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: cl_dll files/hl/hl_weapons.cpp
작업위치: 전역변수
// HLDM Weapon placeholder entities.
CGlock g_Glock;
...
CTripmine g_Tripmine;
CSqueak g_Snark;

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

CAK47 g_AK47;

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: cl_dll files/hl/hl_weapons.cpp
작업위치:
void HUD_InitClientWeapons( void )
{
...
HUD_PrepEntity( &g_Tripmine , &player );
HUD_PrepEntity( &g_Snark , &player );

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

HUD_PrepEntity( &g_AK47 , &player );

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: cl_dll files/hl/hl_weapons.cpp
작업위치:
void HUD_WeaponsPostThink( ... )
{
...
case WEAPON_MP5:
pWeapon = &g_Mp5;
break;

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

case WEAPON_AK47:
pWeapon = &g_AK47;
break;

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: cl_dll files/hl/ev_hldm.cpp
작업위치:
//======================
// SQUEAK END
//======================

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

//======================
// AK47 START
//======================
enum ak47_e
{
AK47_IDLE1,
AK47_RELOAD,
AK47_DRAW,
AK47_SHOOT1,
AK47_SHOOT2,
AK47_SHOOT3,
};

// Normal Fire
void EV_FireAK47( event_args_t *args )
{
int idx;
vec3_t origin;
vec3_t angles;
vec3_t velocity;

vec3_t ShellVelocity;
vec3_t ShellOrigin;
int shell;
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 );

shell = gEngfuncs.pEventAPI->EV_FindModelIndex ("models/shell.mdl");

if ( EV_IsLocal( idx ) )
{
// Add muzzle flash to current weapon model
EV_MuzzleFlash();
gEngfuncs.pEventAPI->EV_WeaponAnimation( AK47_SHOOT1 + gEngfuncs.pfnRandomLong(0,2), 2 );

V_PunchAxis( 0, gEngfuncs.pfnRandomFloat( -2, 2 ) );
}

EV_GetDefaultShellInfo( args, origin, velocity, ShellVelocity, ShellOrigin, forward, right, up, 20, -12, 4 );

EV_EjectBrass ( ShellOrigin, ShellVelocity, angles[ YAW ], shell, TE_BOUNCE_SHELL );

// fire #1 sound
switch( gEngfuncs.pfnRandomLong( 0, 1 ) )
{
case 0:
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/ak47-1.wav", 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ) );
break;
case 1:
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/ak47-2.wav", 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ) );
break;
}

EV_GetGunPosition( args, vecSrc, origin );
VectorCopy( forward, vecAiming );

if ( gEngfuncs.GetMaxClients() > 1 )
{
EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_AK47, 2, &tracerCount[idx-1], args->fparam1, args->fparam2 );
}
else
{
EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_AK47, 2, &tracerCount[idx-1], args->fparam1, args->fparam2 );
}
}

// Secondary
void EV_FireAK472( event_args_t *args )
{
int idx;
vec3_t origin;
vec3_t angles;
vec3_t velocity;

vec3_t ShellVelocity;
vec3_t ShellOrigin;
int shell;
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 );

shell = gEngfuncs.pEventAPI->EV_FindModelIndex ("models/shell.mdl");

if ( EV_IsLocal( idx ) )
{
// Add muzzle flash to current weapon model
EV_MuzzleFlash();
gEngfuncs.pEventAPI->EV_WeaponAnimation( AK47_SHOOT1 + gEngfuncs.pfnRandomLong(0,2), 2 );

V_PunchAxis( 0, gEngfuncs.pfnRandomFloat( -2, 2 ) );
}

EV_GetDefaultShellInfo( args, origin, velocity, ShellVelocity, ShellOrigin, forward, right, up, 20, -12, 4 );

EV_EjectBrass ( ShellOrigin, ShellVelocity, angles[ YAW ], shell, TE_BOUNCE_SHELL );

// fire #2 sound
switch( gEngfuncs.pfnRandomLong( 0, 1 ) )
{
case 0:
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/ak47-1.wav", 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ) );
break;
case 1:
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/ak47-2.wav", 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ) );
break;
}

EV_GetGunPosition( args, vecSrc, origin );
VectorCopy( forward, vecAiming );

if ( gEngfuncs.GetMaxClients() > 1 )
{
EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_AK47, 2, &tracerCount[idx-1], args->fparam1, args->fparam2 );
}
else
{
EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_AK47, 2, &tracerCount[idx-1], args->fparam1, args->fparam2 );
}
}
//======================
// AK47 END
//======================

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: cl_dll files/hl/ev_hldm.cpp
작업위치:
extern "C"
{

// HLDM
void EV_FireGlock1( struct event_args_s *args );
...
void EV_TripmineFire( struct event_args_s *args );
void EV_SnarkFire( struct event_args_s *args );

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

void EV_FireAK47( struct event_args_s *args );
void EV_FireAK472( struct event_args_s *args );

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: cl_dll files/hl/ev_hldm.cpp
작업위치:
void EV_HLDM_DecalGunshot( pmtrace_t *pTrace, int iBulletType )
{
...
switch( iBulletType )
{
case BULLET_PLAYER_357:

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

case BULLET_PLAYER_AK47:

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: cl_dll files/hl/ev_hldm.cpp
작업위치:
int EV_HLDM_CheckTracer( ... )
{
...
switch( iBulletType )
{
case BULLET_MONSTER_12MM:

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

case BULLET_PLAYER_AK47:

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: cl_dll files/hl/ev_hldm.cpp
작업위치:
void EV_HLDM_FireBullets( ... )
{
...
switch(iBulletType)
{
default:
case BULLET_PLAYER_9MM:
...
case BULLET_PLAYER_357:

EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType );
EV_HLDM_DecalGunshot( &tr, iBulletType );

break;

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

case BULLET_PLAYER_AK47:
if ( !tracer )
{
EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType );
EV_HLDM_DecalGunshot( &tr, iBulletType );
}
break;

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: cl_dll files/ev_hldm.h
작업위치:
// bullet types
typedef enum
{
BULLET_NONE = 0,
...
BULLET_PLAYER_CROWBAR, // crowbar swipe

바로 아래 부분에 작성
--------------------------------------------------------------
// 018killer: AddWeapons [
// Purpose: ak47

BULLET_PLAYER_AK47,

// 018killer: AddWeapons ]
==============================================================



--------------------------------------------------------------
파일명: ak47.sc, ak472.sc
작업위치:
모드의 events 폴더
Steam/SteamApps/내 계정/half-life/My_MOD/events

--------------------------------------------------------------
모드의 events 폴더에 ak47.sc, ak472.sc 을 만듭니다.
(이름만 같게해서 내용없는 파일을 만든다.)
==============================================================



--------------------------------------------------------------
파일명: p_ak47.mdl, v_ak47.mdl, w_ak47.mdl
작업위치:
Steam/SteamApps/내 계정/half-life/My_MOD/models

--------------------------------------------------------------
모드의 models 디렉토리에 ak47 관련 modeling file 들을 넣어 줍니다.
ak47 관련 model 파일들은 Counter-Strike 안에 있는 AK47 model 들을 사용하시면 됩니다.
==============================================================



--------------------------------------------------------------
파일명: ak47-1.wav, ak47-2.wav, ak47_boltpull.wav, ak47_clipin.wav, ak47_clipout.wav
작업위치:
Steam/SteamApps/내 계정/half-life/My_MOD/sound/weapons

--------------------------------------------------------------
모드의 sound/weapons 디렉토리에 ak47 관련 sound file 들을 넣어 줍니다.
ak47 관련 sound 파일들은 Counter-Strike 안에 있는 sound/weapons/AK47 관련 .wav 파일 들을 사용하시면 됩니다.
==============================================================



--------------------------------------------------------------
파일명: weapon_ak47.txt
작업위치:
Steam/SteamApps/내 계정/half-life/My_MOD/sprites

--------------------------------------------------------------
weapon_ak47.txt 파일은 HUD에서 사용되는 AIM 입니다.
이 파일이 없으면 HUD상에 해당 무기의 AIM이 보이질 않습니다.
CS에서 사용되는 무기들은 counter-strike.gcf 파일안에 sprites 디렉토리에 있습니다.
==============================================================


------------------------
파일명: weapon_ak47.txt
------------------------
10
weapon 320 320hud1 160 80 80 20
weapon_s 320 320hud1 160 100 80 20
ammo 320 640hud7 72 72 24 24
crosshair 320 crosshairs 24 0 24 24
autoaim 320 crosshairs 0 72 24 24
weapon 640 640hud10 0 0 170 45
weapon_s 640 640hud11 0 0 170 45
ammo 640 640hud7 72 72 24 24
crosshair 640 crosshairs 24 0 24 24
autoaim 640 crosshairs 0 72 24 24



이상입니다.
질문이나 fix 되어야 할 점이 있을시엔 godmode2k@hotmail.com 으로 메일을 보내주시기 바랍니다.

댓글 없음:

댓글 쓰기