Конференции   |   Вход   |   Участники   |   Календарь   |   Сообщения за день   |   Поиск   |   Правила

Вернуться   Global Half-Life | Форум > Конференция Panther Studios > Half-Life SDK: Кодинг > [ Кодинг ] Туториалы

Ответ
 
Опции темы
Kerard
User
Kerard вне форума
 
Регистрация: 23.11.2022
Сообщений: 16
Arrow Винтовка Генри

Небольшое руководство по созданию многозарядной винтовки.
Решил внести свой вклад в развитие этого сайта.
Код снайперской винтовки уже есть, но она с отъемным магазином. Поэтому я решил сделать руководство по созданию магазинной винтовки с заряжанием по одному патрону. Винтовка не снайперская, но переделать ее в снайперскую не составит труда. Всем фанатам Дикого Запада посвящается! Хотя при желании, если немного подправить код, она подойдет и для Второй Мировой.
Итак, я решил показать вам, как сделать магазинную винтовку с заряжанием по одному патрону. За образец возьму винтовку Генри образца 1860 года. Почему ее? Она мне просто нравится. Хотя, при желании этот код, как уже говорилось выше, подойдет для любой неавтоматической винтовки с заряжанием по одному патрону – надо просто изменить количество патронов. Поскольку винтовки со скобой Генри часто выпускались под револьверный патрон, а также, чтобы избавить вас от лишнего геморроя, мы не будем создавать новый тип боеприпасов, а сделаем ее на основе патронов 357 Magnum.
Итак, начали.
Для начала создаем на сервере файл henry.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.
*
****/
#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 henry_e 
{
    
HENRY_IDLE1 0,
    
HENRY_FIRE1,
    
HENRY_RELOAD,
    
HENRY_PUMP,
    
HENRY_START_RELOAD,
    
HENRY_DRAW,
    
HENRY_IDLE2,
    
HENRY_IDLE3
};

LINK_ENTITY_TO_CLASSweapon_henryCHenry );

int CHenry::GetItemInfo(ItemInfo *p)
{
    
p->pszName STRING(pev->classname);
    
p->pszAmmo1 "357";
    
p->iMaxAmmo1 HENRY_MAX_CARRY;
    
p->pszAmmo2 NULL;
    
p->iMaxAmmo2 = -1;
    
p->iMaxClip HENRY_MAX_CLIP;
    
p->iFlags 0;
    
p->iSlot 2;
    
p->iPosition 3;
    
p->iId m_iId WEAPON_HENRY;
    
p->iWeight PYTHON_WEIGHT;

    return 
1;
}

int CHenry::AddToPlayerCBasePlayer *pPlayer )
{
    if ( 
CBasePlayerWeapon::AddToPlayerpPlayer ) )
    {
        
MESSAGE_BEGINMSG_ONEgmsgWeapPickupNULLpPlayer->pev );
            
WRITE_BYTEm_iId );
        
MESSAGE_END();
        return 
TRUE;
    }
    return 
FALSE;
}

void CHenry::Spawn( )
{
    
pev->classname MAKE_STRING("weapon_henry"); // hack to allow for old names
    
Precache( );
    
m_iId WEAPON_HENRY;
    
SET_MODEL(ENT(pev), "models/w_henry.mdl");

    
m_iDefaultAmmo HENRY_DEFAULT_GIVE;

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


void CHenry::Precachevoid )
{
    
PRECACHE_MODEL("models/v_henry.mdl");
    
PRECACHE_MODEL("models/w_henry.mdl");
    
PRECACHE_MODEL("models/p_henry.mdl");

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

    
PRECACHE_SOUND ("weapons/357_cock1.wav");
    
PRECACHE_SOUND ("weapons/henry_shot1.WAV");
    
PRECACHE_SOUND ("weapons/henry_shot2.WAV");

    
m_usFireHenry PRECACHE_EVENT1"events/henry.sc" );
}

BOOL CHenry::Deploy( )
{
#ifdef CLIENT_DLL
    
if ( bIsMultiplayer() )
#else
    
if ( g_pGameRules->IsMultiplayer() )
#endif
    
{
        
// enable laser sight geometry.
        
pev->body 1;
    }
    else
    {
        
pev->body 0;
    }

    return 
DefaultDeploy"models/v_henry.mdl""models/p_henry.mdl"HENRY_DRAW"henry"UseDecrement(), pev->body );
}

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

    if (
m_iClip <= 0)
    {
        if (!
m_fFireOnEmpty)
            
Reload( );
        else
        {
            
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON"weapons/357_cock1.wav"0.8ATTN_NORM);
            
m_flNextPrimaryAttack 0.15;
        }

        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->SetAnimationPLAYER_ATTACK1 );


    
UTIL_MakeVectorsm_pPlayer->pev->v_angle m_pPlayer->pev->punchangle );

    
Vector vecSrc     m_pPlayer->GetGunPosition( );
    
Vector vecAiming m_pPlayer->GetAutoaimVectorAUTOAIM_10DEGREES );

    
Vector vecDir;
    
vecDir m_pPlayer->FireBulletsPlayer1vecSrcvecAimingVECTOR_CONE_1DEGREES8192BULLET_PLAYER_35700m_pPlayer->pevm_pPlayer->random_seed );

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

    
PLAYBACK_EVENT_FULLflagsm_pPlayer->edict(), m_usFireHenry0.0, (float *)&g_vecZero, (float *)&g_vecZerovecDir.xvecDir.y000);

    if (!
m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
        
// HEV suit - indicate out of ammo condition
        
m_pPlayer->SetSuitUpdate("!HEV_AMO0"FALSE0);

    if (
m_iClip != 0)
        
m_flPumpTime gpGlobals->time 0.5;

    
m_flNextPrimaryAttack UTIL_WeaponTimeBase() + 1.1;
    if (
m_iClip != 0)
        
m_flTimeWeaponIdle UTIL_WeaponTimeBase() + 5.0;
    else
        
m_flTimeWeaponIdle UTIL_WeaponTimeBase() + 0.75;
    
m_fInSpecialReload 0;
}




void CHenry::Reloadvoid )
{
    if (
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= || m_iClip == HENRY_MAX_CLIP)
        return;

    
// don't reload until recoil is done
    
if (m_flNextPrimaryAttack UTIL_WeaponTimeBase())
        return;

    
// check to see if we're ready to reload
    
if (m_fInSpecialReload == 0)
    {
        
SendWeaponAnimHENRY_START_RELOAD );
        
m_fInSpecialReload 1;
        
m_pPlayer->m_flNextAttack UTIL_WeaponTimeBase() + 0.6;
        
m_flTimeWeaponIdle UTIL_WeaponTimeBase() + 0.6;
        
m_flNextPrimaryAttack UTIL_WeaponTimeBase() + 1.0;
        return;
    }
    else if (
m_fInSpecialReload == 1)
    {
        if (
m_flTimeWeaponIdle UTIL_WeaponTimeBase())
            return;
        
// was waiting for gun to move to side
        
m_fInSpecialReload 2;

        
SendWeaponAnimHENRY_RELOAD );

        
m_flNextReload UTIL_WeaponTimeBase() + 0.8;
        
m_flTimeWeaponIdle UTIL_WeaponTimeBase() + 0.8;
    }
    else
    {
        
// Add them to the clip
        
m_iClip += 1;
        
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= 1;
        
m_fInSpecialReload 1;
    }
}


void CHenry::WeaponIdlevoid )
{
    
ResetEmptySound( );

    
m_pPlayer->GetAutoaimVectorAUTOAIM_5DEGREES );

    if ( 
m_flPumpTime && m_flPumpTime gpGlobals->time )
    {
        
m_flPumpTime 0;
    }

    if (
m_flTimeWeaponIdle <  UTIL_WeaponTimeBase() )
    {
        if (
m_iClip == && m_fInSpecialReload == && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
        {
            
Reload( );
        }
        else if (
m_fInSpecialReload != 0)
        {
            if (
m_iClip != 15 && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
            {
                
Reload( );
            }
            else
            {
                
// reload debounce has timed out
                
SendWeaponAnimHENRY_PUMP );
                
                
m_fInSpecialReload 0;
                
m_flTimeWeaponIdle UTIL_WeaponTimeBase() + 2.6;
            }
        }
        else
    {
    
int iAnim;
    
float flRand UTIL_SharedRandomFloatm_pPlayer->random_seed0);
    if (
flRand <= 0.5)
    {
        
iAnim HENRY_IDLE1;
        
m_flTimeWeaponIdle = (70.0/30.0);
    }
    else if (
flRand <= 0.7)
    {
        
iAnim HENRY_IDLE2;
        
m_flTimeWeaponIdle = (70.0/30.0);
    }
    else
    {
        
iAnim HENRY_IDLE3;
        
m_flTimeWeaponIdle = (88.0/30.0);
    }

    
int bUseScope FALSE;
#ifdef CLIENT_DLL
    
bUseScope bIsMultiplayer();
#else
    
bUseScope g_pGameRules->IsMultiplayer();
#endif
    
    
SendWeaponAnimiAnimUseDecrement() ? 0bUseScope );
        }
    }
}



class 
CHenryAmmo : public CBasePlayerAmmo
{
    
void Spawnvoid )
    { 
        
Precache( );
        
SET_MODEL(ENT(pev), "models/w_357ammobox.mdl");
        
CBasePlayerAmmo::Spawn( );
    }
    
void Precachevoid )
    {
        
PRECACHE_MODEL ("models/w_357ammobox.mdl");
        
PRECACHE_SOUND("items/9mmclip1.wav");
    }
    
BOOL AddAmmoCBaseEntity *pOther 
    { 
        if (
pOther->GiveAmmoAMMO_357BOX_GIVE"357"_357_MAX_CARRY ) != -1)
        {
            
EMIT_SOUND(ENT(pev), CHAN_ITEM"items/9mmclip1.wav"1ATTN_NORM);
            return 
TRUE;
        }
        return 
FALSE;
    }
};
LINK_ENTITY_TO_CLASSammo_henryCHenryAmmo );


#endif 
В этом коде все адаптировано под прилагаемую ниже модель, но при желании можно адаптировать его под нужную вам модель.

Последний раз редактировалось Kerard; 30.12.2022 в 13:56.
#1 Старый 18.12.2022, 17:59 Ответить с цитированием
Kerard
User
Kerard вне форума
 
Регистрация: 23.11.2022
Сообщений: 16
Red face

Теперь открываем файл weapons.h и пишем туда:

После:
С / С++:
#define M203_GRENADE_MAX_CARRY    10 
Пишем:
С / С++:
#define HENRY_MAX_CARRY            30 
После:
С / С++:
#define SNARK_MAX_CLIP            WEAPON_NOCLIP 
Пишем:
С / С++:
#define HENRY_MAX_CLIP            15 
После:
С / С++:
#define HIVEHAND_DEFAULT_GIVE        8 
Пишем:
С / С++:
#define HENRY_DEFAULT_GIVE            15 

После строчки:
С / С++:
#define WEAPON_SNARK        15 
Это:
С / С++:
#define WEAPON_HENRY            16 
Далее, в самом конце после снарков пишем:
С / С++:
class CHenry : public CBasePlayerWeapon
{
public:
    
void Spawnvoid );
    
void Precachevoid );
    
int iItemSlot( ) { return 3; }
    
int GetItemInfo(ItemInfo *p);
    
int AddToPlayerCBasePlayer *pPlayer );

    
void PrimaryAttackvoid );
    
BOOL Deploy( );
    
void Reloadvoid );
    
void WeaponIdlevoid );
    
int m_fInReload;
    
float m_flNextReload;
    
int m_iShell;

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

private:
    
unsigned short m_usFireHenry;
}; 
В weapons.cpp в разделе void W_Precache(void) пишем:
С / С++:
// henry
UTIL_PrecacheOtherWeapon"weapon_henry" ); 
Далее в player.cpp в разделе case101 пишем:
С / С++:
GiveNamedItem"weapon_henry" ); 
Переходим в клиент.

В файле hl_weapons.cpp после:
С / С++:
CSqueak g_Snark
Пишем:
С / С++:
CHenry g_Henry
Затем после:
С / С++:
    HUD_PrepEntity( &g_Snark    , &player ); 
Пишем:
С / С++:
HUD_PrepEntity( &g_Henry    , &player ); 
И наконец после:
С / С++:
case WEAPON_SNARK:
            
pWeapon = &g_Snark;
            break; 
Пишем:
С / С++:
        case WEAPON_HENRY:
            
pWeapon = &g_Henry;
            break; 
Добавлено через 31 секунду
Открываем теперь ev_hldm.cppи после:

С / С++:
void EV_SnarkFirestruct event_args_s *args  ); 
Пишем:
С / С++:
void EV_FireHenrystruct event_args_s *args  ); 
Спускаемся ниже. После:
С / С++:
//======================
//        PHYTON END 
//         ( .357 )
//====================== 
Пишем:
С / С++:
//======================
//       HENRY START 
//======================
void EV_FireHenryevent_args_t *args )
{
    
int idx;
    
vec3_t origin;
    
vec3_t angles;
    
vec3_t velocity;

    
vec3_t vecSrcvecAiming;
    
vec3_t uprightforward;
    
float flSpread 0.01;

    
idx args->entindex;
    
VectorCopyargs->originorigin );
    
VectorCopyargs->anglesangles );
    
VectorCopyargs->velocityvelocity );

    
AngleVectorsanglesforwardrightup );

    if ( 
EV_IsLocalidx ) )
    {
            
// Add muzzle flash to current weapon model
        
EV_MuzzleFlash();
        
gEngfuncs.pEventAPI->EV_WeaponAnimationHENRY_FIRE1);

        
V_PunchAxis0, -10.0 );
    }

    switch( 
gEngfuncs.pfnRandomLong0) )
    {
    case 
0:
        
gEngfuncs.pEventAPI->EV_PlaySoundidxoriginCHAN_WEAPON"weapons/henry_shot1.WAV"gEngfuncs.pfnRandomFloat(0.80.9), ATTN_NORM0PITCH_NORM );
        break;
    case 
1:
        
gEngfuncs.pEventAPI->EV_PlaySoundidxoriginCHAN_WEAPON"weapons/henry_shot2.WAV"gEngfuncs.pfnRandomFloat(0.80.9), ATTN_NORM0PITCH_NORM );
        break;
    }

    
EV_GetGunPositionargsvecSrcorigin );
    
    
VectorCopyforwardvecAiming );

    
EV_HLDM_FireBulletsidxforwardrightup1vecSrcvecAiming8192BULLET_PLAYER_35700args->fparam1args->fparam2 );
}
//======================
//       HENRY END 
//====================== 
Теперь открываем файл hl_events.cpp

После:
С / С++:
void EV_SnarkFirestruct event_args_s *args ); 
Пишем:
С / С++:
void EV_FireHenrystruct event_args_s *args  ); 
И в самом конце:
С / С++:
gEngfuncs.pfnHookEvent"events/henry.sc",    EV_FireHenry ); 
И наконец после:
С / С++:
enum gauss_e {
    
GAUSS_IDLE 0,
    
GAUSS_IDLE2,
    
GAUSS_FIDGET,
    
GAUSS_SPINUP,
    
GAUSS_SPIN,
    
GAUSS_FIRE,
    
GAUSS_FIRE2,
    
GAUSS_HOLSTER,
    
GAUSS_DRAW
}; 
Пишем:
С / С++:
enum henry_e {
    
HENRY_IDLE1 0,
    
HENRY_FIRE1,
    
HENRY_RELOAD,
    
HENRY_PUMP,
    
HENRY_START_RELOAD,
    
HENRY_DRAW,
    
HENRY_IDLE2,
    
HENRY_IDLE3
}; 
Компилируем.

Затем создаем файл henry.sc. Если влом, он есть в архиве ниже.
И наконец в halflife.fgd в разделе // weapons пишем:
Цитата:
@PointClass base(Weapon, Targetx) studio("models/w_henry.mdl") = weapon_henry : "Henry" []
Всё.

Архив со всем необходимым:
Вложения
Тип файла: rar HenryRifle.rar (765.6 Кб, 37942 просмотров)

Последний раз редактировалось Kerard; 30.03.2023 в 15:01.
#2 Старый 18.12.2022, 18:01 Ответить с цитированием
Shadow762
Быдлокодер
 
Аватар для Shadow762
Shadow762 вне форума
 
Регистрация: 22.11.2015
Проживает: Гиде-то
Сообщений: 50
Профиль Steam
По умолчанию

Цитата:
Обновленный архив, поскольку наш уважаемый админ отказался дать возможность удалять и редактировать сообщения.
Не сердись, возможность есть, просто ограниченная по времени
Все в порядке)
__________________
#3 Старый 19.12.2022, 20:02 Ответить с цитированием
sektant91
User
 
Аватар для sektant91
sektant91 вне форума
 
Регистрация: 03.12.2022
Проживает: Астана
Сообщений: 5
По умолчанию

Kerard
Цитата:
Небольшое руководство по созданию многозарядной винтовки.
Посмотрел модель - аж захотелось вестерн какой-нибудь начать делать в стиле Wanted!
Модель, кстати, сам делал?
Если да, то очень даже солидно. Выстрелы, перезарядка.
Цитата:
Решил внести свой вклад в развитие этого сайта
За это спасибо от меня лично. Знаю этот сайт еще с тех пор, когда он был hl-faction.ru, затем halflife.zone
И вот сейчас, глобальный Half-Life.

Я не силен в программировании, поверхностно знаю моделирование и немного картострой.
Но, как я вижу, туториал хороший.

Продолжай в том же духе!
А я попробую помочь создателям с пополнением коллекции модов

Добавлено через 3 минуты
Kerard, P.S, не обижай админа, благодаря ему у нас есть этот сайт, а главное - форум
P.S.S, вон что он сделал с сайтом своих обидчиков
__________________
DVD kolleksıoneri
#4 Старый 20.12.2022, 00:25 Ответить с цитированием
Kerard
User
Kerard вне форума
 
Регистрация: 23.11.2022
Сообщений: 16
По умолчанию

Цитата:
Модель, кстати, сам делал?
Сам.
Спасибо за добрые слова)
#5 Старый 20.12.2022, 11:59 Ответить с цитированием
Shadow762
Быдлокодер
 
Аватар для Shadow762
Shadow762 вне форума
 
Регистрация: 22.11.2015
Проживает: Гиде-то
Сообщений: 50
Профиль Steam
По умолчанию

Цитата:
Kerard, P.S, не обижай админа, благодаря ему у нас есть этот сайт, а главное - форум
P.S.S, вон что он сделал с сайтом своих обидчиков
какие ужасные вещи Вы говорите)
Там не обидчики никакие, просто тот "человек" получил по заслугам)

Цитата:
Модель, кстати, сам делал?
у Kerard'а все модели авторские.
__________________
#6 Старый 20.12.2022, 19:25 Ответить с цитированием
Kerard
User
Kerard вне форума
 
Регистрация: 23.11.2022
Сообщений: 16
По умолчанию

Чтобы переделать винтовку в снайперскую нужно вписать в файл henry.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.
*
****/
#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 henry_e 
{
    
HENRY_IDLE1 0,
    
HENRY_FIRE1,
    
HENRY_RELOAD,
    
HENRY_PUMP,
    
HENRY_START_RELOAD,
    
HENRY_DRAW,
    
HENRY_IDLE2,
    
HENRY_IDLE3
};

LINK_ENTITY_TO_CLASSweapon_henryCHenry );

int CHenry::GetItemInfo(ItemInfo *p)
{
    
p->pszName STRING(pev->classname);
    
p->pszAmmo1 "357";
    
p->iMaxAmmo1 HENRY_MAX_CARRY;
    
p->pszAmmo2 NULL;
    
p->iMaxAmmo2 = -1;
    
p->iMaxClip HENRY_MAX_CLIP;
    
p->iFlags 0;
    
p->iSlot 1;
    
p->iPosition 2;
    
p->iId m_iId WEAPON_HENRY;
    
p->iWeight PYTHON_WEIGHT;

    return 
1;
}

int CHenry::AddToPlayerCBasePlayer *pPlayer )
{
    if ( 
CBasePlayerWeapon::AddToPlayerpPlayer ) )
    {
        
MESSAGE_BEGINMSG_ONEgmsgWeapPickupNULLpPlayer->pev );
            
WRITE_BYTEm_iId );
        
MESSAGE_END();
        return 
TRUE;
    }
    return 
FALSE;
}

void CHenry::Spawn( )
{
    
pev->classname MAKE_STRING("weapon_henry"); // hack to allow for old names
    
Precache( );
    
m_iId WEAPON_HENRY;
    
SET_MODEL(ENT(pev), "models/w_henry.mdl");

    
m_iDefaultAmmo HENRY_DEFAULT_GIVE;

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


void CHenry::Precachevoid )
{
    
PRECACHE_MODEL("models/v_henry.mdl");
    
PRECACHE_MODEL("models/w_henry.mdl");
    
PRECACHE_MODEL("models/p_henry.mdl");

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

    
PRECACHE_SOUND ("weapons/357_reload1.wav");
    
PRECACHE_SOUND ("weapons/357_cock1.wav");
    
PRECACHE_SOUND ("weapons/henry_shot1.WAV");
    
PRECACHE_SOUND ("weapons/henry_shot2.WAV");

    
m_usFireHenry PRECACHE_EVENT1"events/henry.sc" );
}

BOOL CHenry::Deploy( )
{
#ifdef CLIENT_DLL
    
if ( bIsMultiplayer() )
#else
    
if ( g_pGameRules->IsMultiplayer() )
#endif
    
{
        
// enable laser sight geometry.
        
pev->body 1;
    }
    else
    {
        
pev->body 0;
    }

    return 
DefaultDeploy"models/v_henry.mdl""models/p_henry.mdl"HENRY_DRAW"henry"UseDecrement(), pev->body );
}


void CHenry::SecondaryAttackvoid )
{
    if ( 
m_pPlayer->pev->fov != )
    {
        
m_pPlayer->pev->fov m_pPlayer->m_iFOV 0// 0 means reset to default fov
        
m_fInZoom 0;
    }
    else if ( 
m_pPlayer->pev->fov != 10 )
    {
        
m_pPlayer->pev->fov m_pPlayer->m_iFOV 10;
        
m_fInZoom 1;
    }
    
    
pev->nextthink UTIL_WeaponTimeBase() + 0.1;
    
m_flNextSecondaryAttack UTIL_WeaponTimeBase() + 0.5;
}


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

    if (
m_iClip <= 0)
    {
        if (!
m_fFireOnEmpty)
            
Reload( );
        else
        {
            
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON"weapons/357_cock1.wav"0.8ATTN_NORM);
            
m_flNextPrimaryAttack 0.15;
        }

        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->SetAnimationPLAYER_ATTACK1 );


    
UTIL_MakeVectorsm_pPlayer->pev->v_angle m_pPlayer->pev->punchangle );

    
Vector vecSrc     m_pPlayer->GetGunPosition( );
    
Vector vecAiming m_pPlayer->GetAutoaimVectorAUTOAIM_10DEGREES );

    
Vector vecDir;
    
vecDir m_pPlayer->FireBulletsPlayer1vecSrcvecAimingVECTOR_CONE_1DEGREES8192BULLET_PLAYER_35700m_pPlayer->pevm_pPlayer->random_seed );

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

    
PLAYBACK_EVENT_FULLflagsm_pPlayer->edict(), m_usFireHenry0.0, (float *)&g_vecZero, (float *)&g_vecZerovecDir.xvecDir.y000);

    if (!
m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
        
// HEV suit - indicate out of ammo condition
        
m_pPlayer->SetSuitUpdate("!HEV_AMO0"FALSE0);

    if (
m_iClip != 0)
        
m_flPumpTime gpGlobals->time 0.5;

    
m_flNextPrimaryAttack UTIL_WeaponTimeBase() + 1.1;
    if (
m_iClip != 0)
        
m_flTimeWeaponIdle UTIL_WeaponTimeBase() + 5.0;
    else
        
m_flTimeWeaponIdle UTIL_WeaponTimeBase() + 0.75;
    
m_fInSpecialReload 0;
}




void CHenry::Reloadvoid )
{
    if (
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= || m_iClip == HENRY_MAX_CLIP)
        return;

    
// don't reload until recoil is done
    
if (m_flNextPrimaryAttack UTIL_WeaponTimeBase())
        return;

    if ( 
m_pPlayer->pev->fov != )
    {
        
SecondaryAttack();
    }

    
// check to see if we're ready to reload
    
if (m_fInSpecialReload == 0)
    {
        
SendWeaponAnimHENRY_START_RELOAD );
        
m_fInSpecialReload 1;
        
m_pPlayer->m_flNextAttack UTIL_WeaponTimeBase() + 0.6;
        
m_flTimeWeaponIdle UTIL_WeaponTimeBase() + 0.6;
        
m_flNextPrimaryAttack UTIL_WeaponTimeBase() + 1.0;
        return;
    }
        if ( 
m_pPlayer->pev->fov != )
    {
        
SecondaryAttack();
    }
    else if (
m_fInSpecialReload == 1)
    {
        if (
m_flTimeWeaponIdle UTIL_WeaponTimeBase())
            return;
        
// was waiting for gun to move to side
        
m_fInSpecialReload 2;

        
SendWeaponAnimHENRY_RELOAD );

        
m_flNextReload UTIL_WeaponTimeBase() + 0.8;
        
m_flTimeWeaponIdle UTIL_WeaponTimeBase() + 0.8;
    }
    else
    {
        
// Add them to the clip
        
m_iClip += 1;
        
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= 1;
        
m_fInSpecialReload 1;
    }
}


void CHenry::WeaponIdlevoid )
{
    
ResetEmptySound( );

    
m_pPlayer->GetAutoaimVectorAUTOAIM_5DEGREES );

    if ( 
m_flPumpTime && m_flPumpTime gpGlobals->time )
    {
        
m_flPumpTime 0;
    }

    if (
m_flTimeWeaponIdle <  UTIL_WeaponTimeBase() )
    {
        if (
m_iClip == && m_fInSpecialReload == && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
        {
            
Reload( );
        }
        else if (
m_fInSpecialReload != 0)
        {
            if (
m_iClip != 15 && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
            {
                
Reload( );
            }
            else
            {
                
// reload debounce has timed out
                
SendWeaponAnimHENRY_PUMP );
                
                
m_fInSpecialReload 0;
                
m_flTimeWeaponIdle UTIL_WeaponTimeBase() + 2.6;
            }
        }
    else
    {
    
int iAnim;
    
float flRand UTIL_SharedRandomFloatm_pPlayer->random_seed0);
    if (
flRand <= 0.5)
    {
        
iAnim HENRY_IDLE1;
        
m_flTimeWeaponIdle = (70.0/30.0);
    }
    else if (
flRand <= 0.7)
    {
        
iAnim HENRY_IDLE2;
        
m_flTimeWeaponIdle = (70.0/30.0);
    }
    else
    {
        
iAnim HENRY_IDLE3;
        
m_flTimeWeaponIdle = (88.0/30.0);
    }

    
int bUseScope FALSE;
#ifdef CLIENT_DLL
    
bUseScope bIsMultiplayer();
#else
    
bUseScope g_pGameRules->IsMultiplayer();
#endif
    
    
SendWeaponAnimiAnimUseDecrement() ? 0bUseScope );
        }
    }
}



class 
CHenryAmmo : public CBasePlayerAmmo
{
    
void Spawnvoid )
    { 
        
Precache( );
        
SET_MODEL(ENT(pev), "models/w_357ammobox.mdl");
        
CBasePlayerAmmo::Spawn( );
    }
    
void Precachevoid )
    {
        
PRECACHE_MODEL ("models/w_357ammobox.mdl");
        
PRECACHE_SOUND("items/9mmclip1.wav");
    }
    
BOOL AddAmmoCBaseEntity *pOther 
    { 
        if (
pOther->GiveAmmoAMMO_357BOX_GIVE"357"_357_MAX_CARRY ) != -1)
        {
            
EMIT_SOUND(ENT(pev), CHAN_ITEM"items/9mmclip1.wav"1ATTN_NORM);
            return 
TRUE;
        }
        return 
FALSE;
    }
};
LINK_ENTITY_TO_CLASSammo_henryCHenryAmmo );


#endif 

Добавлено через 4 минуты

А в файле weapons.h пишем указанный выше код, но после:
С / С++:
void PrimaryAttackvoid ); 
Пишем:
С / С++:
void SecondaryAttackvoid ); 
И все. Снайперская винтовка готова.

Последний раз редактировалось Kerard; 18.01.2023 в 12:37.
#7 Старый 30.12.2022, 13:50 Ответить с цитированием
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

На основе Vbulletin