Sidebar

USP Weapon codding.

Frest@mapper

New member
22.07.2007
81
29
USP Weapon codding.

Привет, всем!!
Каждый раз я вижу на одну из тем отвечают самые опытные коддеры.
Я думал что эти темы были похожими на мои ошибки,но все таки я на шел одну свою страшную ошибку...

Вот сегодня начал делать мод, решил создать там пистолет USP(стандартный пистолет в самом начале у копов).
----------------------------------------
Название - weapon_usp
----------------------------------------
Вот код:
Код:
//========= Copyright © 2007-2008, Frest, All rights reserved. ============//
//
// Purpose:        USP - hand gun
//
// $NoKeywords: $
//=============================================================================//

#include "cbase.h"
#include "NPCEvent.h"
#include "basehlcombatweapon.h"
#include "basecombatcharacter.h"
#include "AI_BaseNPC.h"
#include "player.h"
#include "gamerules.h"
#include "in_buttons.h"
#include "soundent.h"
#include "game.h"
#include "vstdlib/random.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

#define    USP_FASTEST_REFIRE_TIME        0.1f
#define    USP_FASTEST_DRY_REFIRE_TIME    0.2f

#define    USP_ACCURACY_SHOT_PENALTY_TIME        0.2f    // Applied amount of time each shot adds to the time we must recover from
#define    USP_ACCURACY_MAXIMUM_PENALTY_TIME    1.5f    // Maximum penalty to deal out

ConVar    usp_use_new_accuracy( "usp_use_new_accuracy", "1" );

//-----------------------------------------------------------------------------
// CWeaponUSP
//-----------------------------------------------------------------------------

class CWeaponUSP : public CBaseHLCombatWeapon
{
    DECLARE_DATADESC();

public:
    DECLARE_CLASS( CWeaponUSP, CBaseHLCombatWeapon );

    CWeaponUSP(void);

    DECLARE_SERVERCLASS();

    void    Precache( void );
    void    ItemPostFrame( void );
    void    ItemPreFrame( void );
    void    ItemBusyFrame( void );
    void    PrimaryAttack( void );
    void    AddViewKick( void );
    void    DryFire( void );
    void    Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );

    void    UpdatePenaltyTime( void );

    int        CapabilitiesGet( void ) { return bits_CAP_WEAPON_RANGE_ATTACK1; }
    Activity    GetPrimaryAttackActivity( void );

    virtual bool Reload( void );

    virtual const Vector& GetBulletSpread( void )
    {        
        // Handle NPCs first
        static Vector npcCone = VECTOR_CONE_5DEGREES;
        if ( GetOwner() && GetOwner()->IsNPC() )
            return npcCone;
            
        static Vector cone;

        if ( usp_use_new_accuracy.GetBool() )
        {
            float ramp = RemapValClamped(    m_flAccuracyPenalty, 
                                            0.0f, 
                                            USP_ACCURACY_MAXIMUM_PENALTY_TIME, 
                                            0.0f, 
                                            1.0f ); 

            // We lerp from very accurate to inaccurate over time
            VectorLerp( VECTOR_CONE_1DEGREES, VECTOR_CONE_6DEGREES, ramp, cone );
        }
        else
        {
            // Old value
            cone = VECTOR_CONE_4DEGREES;
        }

        return cone;
    }
    
    virtual int    GetMinBurst() 
    { 
        return 1; 
    }

    virtual int    GetMaxBurst() 
    { 
        return 3; 
    }

    virtual float GetFireRate( void ) 
    {
        return 0.5f; 
    }

    DECLARE_ACTTABLE();

private:
    float    m_flSoonestPrimaryAttack;
    float    m_flLastAttackTime;
    float    m_flAccuracyPenalty;
    int        m_nNumShotsFired;
};


IMPLEMENT_SERVERCLASS_ST(CWeaponUSP, DT_WeaponUSP)
END_SEND_TABLE()

LINK_ENTITY_TO_CLASS( weapon_USP, CWeaponUSP );
PRECACHE_WEAPON_REGISTER( weapon_USP );

BEGIN_DATADESC( CWeaponUSP )

    DEFINE_FIELD( m_flSoonestPrimaryAttack, FIELD_TIME ),
    DEFINE_FIELD( m_flLastAttackTime,        FIELD_TIME ),
    DEFINE_FIELD( m_flAccuracyPenalty,        FIELD_FLOAT ), //NOTENOTE: This is NOT tracking game time
    DEFINE_FIELD( m_nNumShotsFired,            FIELD_INTEGER ),

END_DATADESC()

acttable_t    CWeaponUSP::m_acttable[] = 
{
    { ACT_IDLE,                        ACT_IDLE_PISTOL,                true },
    { ACT_IDLE_ANGRY,                ACT_IDLE_ANGRY_PISTOL,            true },
    { ACT_RANGE_ATTACK1,            ACT_RANGE_ATTACK_PISTOL,        true },
    { ACT_RELOAD,                    ACT_RELOAD_PISTOL,                true },
    { ACT_WALK_AIM,                    ACT_WALK_AIM_PISTOL,            true },
    { ACT_RUN_AIM,                    ACT_RUN_AIM_PISTOL,                true },
    { ACT_GESTURE_RANGE_ATTACK1,    ACT_GESTURE_RANGE_ATTACK_PISTOL,true },
    { ACT_RELOAD_LOW,                ACT_RELOAD_PISTOL_LOW,            false },
    { ACT_RANGE_ATTACK1_LOW,        ACT_RANGE_ATTACK_PISTOL_LOW,    false },
    { ACT_COVER_LOW,                ACT_COVER_PISTOL_LOW,            false },
    { ACT_RANGE_AIM_LOW,            ACT_RANGE_AIM_PISTOL_LOW,        false },
    { ACT_GESTURE_RELOAD,            ACT_GESTURE_RELOAD_PISTOL,        false },
};


IMPLEMENT_ACTTABLE( CWeaponUSP );

//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CWeaponUSP::CWeaponUSP( void )
{
    m_flSoonestPrimaryAttack = gpGlobals->curtime;
    m_flAccuracyPenalty = 0.0f;

    m_fMinRange1        = 24;
    m_fMaxRange1        = 1500;
    m_fMinRange2        = 24;
    m_fMaxRange2        = 200;

    m_bFiresUnderwater    = true;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponUSP::Precache( void )
{
    BaseClass::Precache();
}

//-----------------------------------------------------------------------------
// Purpose:
// Input  :
// Output :
//-----------------------------------------------------------------------------
void CWeaponUSP::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
    switch( pEvent->event )
    {
        case EVENT_WEAPON_PISTOL_FIRE:
        {
            Vector vecShootOrigin, vecShootDir;
            vecShootOrigin = pOperator->Weapon_ShootPosition();

            CAI_BaseNPC *npc = pOperator->MyNPCPointer();
            ASSERT( npc != NULL );

            vecShootDir = npc->GetActualShootTrajectory( vecShootOrigin );

            CSoundEnt::InsertSound( SOUND_COMBAT|SOUND_CONTEXT_GUNFIRE, pOperator->GetAbsOrigin(), SOUNDENT_VOLUME_PISTOL, 0.2, pOperator, SOUNDENT_CHANNEL_WEAPON, pOperator->GetEnemy() );

            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:
            BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
            break;
    }
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponUSP::DryFire( void )
{
    WeaponSound( EMPTY );
    SendWeaponAnim( ACT_VM_DRYFIRE );
    
    m_flSoonestPrimaryAttack    = gpGlobals->curtime + USP_FASTEST_DRY_REFIRE_TIME;
    m_flNextPrimaryAttack        = gpGlobals->curtime + SequenceDuration();
}

//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponUSP::PrimaryAttack( void )
{
    if ( ( gpGlobals->curtime - m_flLastAttackTime ) > 0.5f )
    {
        m_nNumShotsFired = 0;
    }
    else
    {
        m_nNumShotsFired++;
    }

    m_flLastAttackTime = gpGlobals->curtime;
    m_flSoonestPrimaryAttack = gpGlobals->curtime + USP_FASTEST_REFIRE_TIME;
    CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), SOUNDENT_VOLUME_PISTOL, 0.2, GetOwner() );

    CBasePlayer *pOwner = ToBasePlayer( GetOwner() );

    if( pOwner )
    {
        // Each time the player fires the USP, reset the view punch. This prevents
        // the aim from 'drifting off' when the player fires very quickly. This may
        // not be the ideal way to achieve this, but it's cheap and it works, which is
        // great for a feature we're evaluating. (sjb)
        pOwner->ViewPunchReset();
    }

    BaseClass::PrimaryAttack();

    // Add an accuracy penalty which can move past our maximum penalty time if we're really spastic
    m_flAccuracyPenalty += USP_ACCURACY_SHOT_PENALTY_TIME;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponUSP::UpdatePenaltyTime( void )
{
    CBasePlayer *pOwner = ToBasePlayer( GetOwner() );

    if ( pOwner == NULL )
        return;

    // Check our penalty time decay
    if ( ( ( pOwner->m_nButtons & IN_ATTACK ) == false ) && ( m_flSoonestPrimaryAttack < gpGlobals->curtime ) )
    {
        m_flAccuracyPenalty -= gpGlobals->frametime;
        m_flAccuracyPenalty = clamp( m_flAccuracyPenalty, 0.0f, USP_ACCURACY_MAXIMUM_PENALTY_TIME );
    }
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponUSP::ItemPreFrame( void )
{
    UpdatePenaltyTime();

    BaseClass::ItemPreFrame();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponUSP::ItemBusyFrame( void )
{
    UpdatePenaltyTime();

    BaseClass::ItemBusyFrame();
}

//-----------------------------------------------------------------------------
// Purpose: Allows firing as fast as button is pressed
//-----------------------------------------------------------------------------
void CWeaponUSP::ItemPostFrame( void )
{
    BaseClass::ItemPostFrame();

    if ( m_bInReload )
        return;
    
    CBasePlayer *pOwner = ToBasePlayer( GetOwner() );

    if ( pOwner == NULL )
        return;

    //Allow a refire as fast as the player can click
    if ( ( ( pOwner->m_nButtons & IN_ATTACK ) == false ) && ( m_flSoonestPrimaryAttack < gpGlobals->curtime ) )
    {
        m_flNextPrimaryAttack = gpGlobals->curtime - 0.1f;
    }
    else if ( ( pOwner->m_nButtons & IN_ATTACK ) && ( m_flNextPrimaryAttack < gpGlobals->curtime ) && ( m_iClip1 <= 0 ) )
    {
        DryFire();
    }
}

//-----------------------------------------------------------------------------
// Purpose: 
// Output : int
//-----------------------------------------------------------------------------
Activity CWeaponUSP::GetPrimaryAttackActivity( void )
{
    if ( m_nNumShotsFired < 1 )
        return ACT_VM_PRIMARYATTACK;

    if ( m_nNumShotsFired < 2 )
        return ACT_VM_RECOIL1;

    if ( m_nNumShotsFired < 3 )
        return ACT_VM_RECOIL2;

    return ACT_VM_RECOIL3;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool CWeaponUSP::Reload( void )
{
    bool fRet = DefaultReload( GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD );
    if ( fRet )
    {
        WeaponSound( RELOAD );
        m_flAccuracyPenalty = 0.0f;
    }
    return fRet;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponUSP::AddViewKick( void )
{
    CBasePlayer *pPlayer  = ToBasePlayer( GetOwner() );
    
    if ( pPlayer == NULL )
        return;

    QAngle    viewPunch;

    viewPunch.x = random->RandomFloat( 0.25f, 0.5f );
    viewPunch.y = random->RandomFloat( -.6f, .6f );
    viewPunch.z = 0.0f;

    //Add it to the view punch
    pPlayer->ViewPunch( viewPunch );
}
-------------------------------------------
Вот скрипт weapon_usp:
Код:
// USP

WeaponData
{
    // Weapon data is loaded by both the Game and Client DLLs.
    "printname"    "USP"
    "viewmodel"            "models/weapons/v_pist_usp.mdl"
    "playermodel"        "models/weapons/w_pist_usp.mdl"
    "anim_prefix"        "pistol"
    "bucket"            "1"
    "bucket_position"    "1"

    "clip_size"            "12"
    "primary_ammo"        "Pistol"
    "secondary_ammo"    "None"

    "weight"            "2"
    "item_flags"        "0"

    // Sounds for the weapon. There is a max of 16 sounds per category (i.e. max 16 "single_shot" sounds)
    SoundData
    {

        "reload"        "Weapon_Pistol.Reload"
        "reload_npc"    "Weapon_Pistol.NPC_Reload"
        "empty"            "Weapon_Pistol.Empty"
        "single_shot"    "Weapon_USP.Single"
        "single_shot_npc"    "Weapon_Pistol.NPC_Single"
        "special1"        "Weapon_Pistol.Special1"
        "special2"        "Weapon_Pistol.Special2"
        "burst"            "Weapon_Pistol.Burst"
    }

    // Weapon Sprite data is loaded by the Client DLL.
    TextureData
    {
        "weapon"
        {
                "font"        "CSweaponsSmall"
                "character"    "A"
        }
        "weapon_s"
        {    
                "font"        "CSweapons"
                "character"    "A"
        }
        "ammo"
        {
                "font"        "CSTypeDeath"
                "character"        "M"
        }
        "crosshair"
        {
                "file"        "sprites/crosshairs"
                "x"            "0"
                "y"            "48"
                "width"        "24"
                "height"    "24"
        }
        "autoaim"
        {
                "file"        "sprites/crosshairs"
                "x"            "0"
                "y"            "48"
                "width"        "24"
                "height"    "24"
        }
    }
}
После этого я запустил игру.В игре я вводил give weapon_usp, оружие появилась.Оно работало и стреляло.Но было много ошибок:
1)Когда я стреляю,анимация выстрела пистолета работает,но когда я стреляю быстрее(в смысле кнопку мыши нажимаю быстрее) то анимация прекращается, и просто стоит пистолет, но стреляет =(.
2)MuzzleFlash появляется очень быстро и уходит,а когда быстрее стреляю то вообще не появляестя :mad:.
3)Пистолет на левой руке >_<!
4)Пистолет виден не полностью, показывает только ствол и все. X_x.

ПОЖАЛУЙСТА кто нить помогите исправить эти ошибки! T_T.
Заранее как всегда спасибо!
 
Последнее редактирование модератором:

realspaik

Member
30.08.2006
651
4
18
3) нужно разблокировать команду cl_righthand , что бы двиг отражал модель на правую сторону. Вообщем вот
http://developer.valvesoftware.com/wiki/Importing_CSS_Weapons_Into_HL2
4) в CSS и HL2 различается viewmodel_fov , поэкспериментируй с этим параметром, сейчас не могу точно сказать какие значения для обеих игр.

1,2 ) в код особо не вникал, но ты вроде просто скопировал и изменил халфовский weapon_pistol ? этого недостаточно для коректной работы оружия. Нужно еще перекомпилить саму модель оружия взятого из CSS , или как вариант глубже копать код и подгонять его к модели.
 

Frest@mapper

New member
22.07.2007
81
29
Senks!

Спасибо realspaik, за 3) совет.У меня получилось исправить ошибку левой руки.Но твой 4) совет че то я не понял :spy:.

Кстати я использовал код weapon_pistol, просто я там все ошибки исправил и поменял имя на USP.:D:D
 
Последнее редактирование:

Frag

New member
22.09.2007
6
0
0
Глюк с анимацией :
Смени
Код:
Activity CWeaponUSP::GetPrimaryAttackActivity( void )
{
if ( m_nNumShotsFired < 1 )
return ACT_VM_PRIMARYATTACK;

if ( m_nNumShotsFired < 2 )
return ACT_VM_RECOIL1;

if ( m_nNumShotsFired < 3 )
return ACT_VM_RECOIL2;

return ACT_VM_RECOIL3;
}
на
Код:
Activity CWeaponUSP::GetPrimaryAttackActivity( void )
{
return ACT_VM_PRIMARYATTACK;
}
Или вообще удали.
 
Последнее редактирование модератором:

realspaik

Member
30.08.2006
651
4
18
2 Frest@mapper:
FOV , это угол зрения камеры(игрока). На сорсе используется двойная система. Есть просто fov - угол зрения окружающего мира и viewmodel_fov, угол под которым игрок видит оружие. fov и viewmodel_fov это консольные переменные, для CSS и HL2 их значение различно. Если не ошибаюсь в халфе это 54, а для оружия контры нужно 70. То есть надо расширить угол зрения что бы большая часть оружия попадала в кадр. Как это сделать уже тебе решать) Если все оружие для своего мода ты собираешься использовать из CSS, то просто измени значение параметра viewmodel_fov , кажется это прописывается в файле view.cpp в клиентской части естественно. если оружие будет и новое и оригинальное, то придумай способ при активизации контровского оружия изменять значение viewmodel_fov, а потом возвращать его прежнее значение, как сделано в Garrys Mod.
Еще идея щас возникла, можно попробовать перекомпилировать модель оружие и параметром $origin отодвинуть его подальше от глаз игрока.
 

Frest@mapper

New member
22.07.2007
81
29
Frag сказал(а):
Глюк с анимацией :
Смени
Код:
 Activity CWeaponUSP::GetPrimaryAttackActivity( void )
 {
 if ( m_nNumShotsFired < 1 )
 return ACT_VM_PRIMARYATTACK;
 
 if ( m_nNumShotsFired < 2 )
 return ACT_VM_RECOIL1;
 
 if ( m_nNumShotsFired < 3 )
 return ACT_VM_RECOIL2;
 
 return ACT_VM_RECOIL3;
 }
на
Код:
 Activity CWeaponUSP::GetPrimaryAttackActivity( void )
 {
 return ACT_VM_PRIMARYATTACK;
 }
Или вообще удали.
Ураа!Спасибо за ответ на первый вопрос =)).
 

Game Server

Доноры Красавчики

Пользователи онлайн