Tutorial: Add a new simple weapon (straightforward way) Last edited 2 years ago2022-09-29 09:59:33 UTC

You are viewing an older revision of this wiki page. The current revision may be more detailed and up-to-date. Click here to see the current revision of this page.
Disclaimer
This is not a proper way of adding new weapons because it does not use client side network prediction and stuff, but it is still reliable for single player only mods. For a more complete guide, refer to Weapons Programming - Standard Weapons.
Are you programming for a single-player Half-Life mod and looking for an easy way to add new, normal hitscan, shooting weapons? You are at the right place. In this tutorial, we will look into a way to add AK-47 from CS 1.6 to Half-Life.

Before we start

This tutorial requires you to use:

Get the files

Get the models, sound and sprites from CS 1.6 and put in the respective folders in your mod folder. Assets to be taken:

Files to edit

As a bare minimum, these are the files needed to be edited to get a working weapon (minus client side prediction). They are: As a matter of fact, ak47.cpp needs to be manually created by right clicking dlls folder in hldll/Source Files, click Add, New Item, and type in ak47. This file needs to be updated to hl_cdll as well by finding its location (alongside other weapons, search for mp5.cpp for example). Right click on the folder, click Add and click Existing Items and find the ak47.cpp.

weapons.h

Scroll down and paste this code
enum ak47_e
{
    AK47_IDLE,
    AK47_RELOAD,
    AK47_DRAW,
    AK47_SHOOT1,
    AK47_SHOOT2,
    AK47_SHOOT3,
};

class CAK47 : public CBasePlayerWeapon
{
    void Spawn();
    void Precache();
    int iItemSlot() { return 2; }
    bool GetItemInfo(ItemInfo* p);
    void PrimaryAttack();
    void Reload();
    bool Deploy();
    void WeaponIdle();
    bool UseDecrement()
    {
#if defined(CLIENT_WEAPONS)
        return true;
#else
        return false;
#endif
    }

    int m_iShell;
};

ak47.cpp

Paste this code
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "monsters.h"
#include "weapons.h"
#include "player.h"
#include "soundent.h"
#include "gamerules.h"
#include "UserMessages.h"

LINK_ENTITY_TO_CLASS(weapon_ak47, CAK47);

void CAK47::Spawn()
{
    Precache();
    SET_MODEL(ENT(pev), "models/w_ak47.mdl");
    m_iId = WEAPON_AK47;
    m_iDefaultAmmo = 30;
    FallInit(); // get ready to fall down.
}

void CAK47::Precache()
{
    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_SOUND("weapons/ak47-1.wav");
}

bool CAK47::GetItemInfo(ItemInfo* p)
{
    p->pszName = STRING(pev->classname);
    p->pszAmmo1 = "762";
    p->iMaxAmmo1 = 90;
    p->pszAmmo2 = NULL;
    p->iMaxAmmo2 = NULL;
    p->iMaxClip = 30;
    p->iSlot = 2;
    p->iPosition = 3;
    p->iFlags = 0;
    p->iId = m_iId = WEAPON_AK47;
    p->iWeight = MP5_WEIGHT;

    return true;
}

bool CAK47::Deploy()
{
    return DefaultDeploy("models/v_ak47.mdl", "models/p_ak47.mdl", AK47_DRAW, "mp5");
}

void CAK47::PrimaryAttack()
{
    // don't fire underwater
    if (m_pPlayer->pev->waterlevel == 3)
    {
        PlayEmptySound();
        m_flNextPrimaryAttack = 0.15;
        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_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 = m_pPlayer->FireBulletsPlayer(1, vecSrc, vecAiming, VECTOR_CONE_3DEGREES, 8192, BULLET_PLAYER_MP5,
        1, 30, m_pPlayer->pev, m_pPlayer->random_seed);

    SendWeaponAnim(AK47_SHOOT1 + RANDOM_LONG(0, 2));
    EMIT_SOUND(edict(), CHAN_AUTO, "weapons/ak47-1.wav", 1, ATTN_NORM);

    Vector vecShellVelocity = m_pPlayer->pev->velocity + gpGlobals->v_right * RANDOM_FLOAT(100, 200) +
        gpGlobals->v_up * RANDOM_FLOAT(100, 150) + gpGlobals->v_forward * 25;
    EjectBrass(pev->origin + m_pPlayer->pev->view_ofs + gpGlobals->v_up * -12 + gpGlobals->v_forward * 20 +
        gpGlobals->v_right * -8, vecShellVelocity, pev->angles.y, m_iShell, TE_BOUNCE_SHELL);

    m_pPlayer->pev->punchangle.x -= 2;
    m_iClip--;
    m_flNextPrimaryAttack = 0.1;
    m_flTimeWeaponIdle = 0.85;
}

void CAK47::Reload()
{
    DefaultReload(30, AK47_RELOAD, 2.5);
}


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

    if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
        return;

    SendWeaponAnim(AK47_IDLE);
}

cdll_dll.h

Add WEAPON_AK47 in the same WeaponID enum.

hl_weapons.cpp

case WEAPON_SNARK:
        pWeapon = &g_Snark;
        break;
and paste
case WEAPON_AK47:
    pWeapon = &g_AK47;
    break;
below it.

weapons.cpp

Find UTIL_PrecacheOtherWeapon("weapon_hornetgun"); and paste UTIL_PrecacheOtherWeapon("weapon_ak47"); below it.

player.cpp (Optional)

This is to add ak47 to the impulse 101 cheat command. Find GiveNamedItem("weapon_hornetgun"); and paste GiveNamedItem("weapon_ak47"); below it.

Finale

Save and compile your codes. It should give you a working AK-47 under the Crossbow slot.

Edits

If you want to edit some of the attributes, you can do as below.

Enjoy!

You now have a working AK-47!

5 Comments

Commented 1 year ago2023-06-25 12:29:38 UTC Comment #105376
Works 100%. Thx. but my I ask you question, how can I use desert eagle sprites? I already have code for it but I can't bcz of sprites
Commented 1 year ago2023-07-16 04:08:33 UTC Comment #105403
@Draxler: What sprites? Do you mean the laser?
Commented 4 months ago2024-07-19 14:43:44 UTC Comment #106258
Great Tutorial.
I can get the gun in game, but it wont pick up any ammo so only get 30 shots.
says p->pszAmmo1 = "762"; I tried changing that to 9mm but the gun does not appear.
Commented 2 months ago2024-08-26 16:26:22 UTC Comment #106335
i got the gun in the game, but seems like the fire and reload animations don't work. the weapon just stays idle while it fires or reloads. i've checked the animation order in a model viewer and they're the same as in the animation enum. is this something to do with the half-life updated sdk?
Commented 2 months ago2024-08-28 14:20:56 UTC Comment #106341
im getting this error Host_Error: PF_precache_model_I: 'models/v_ak47.mdl' Precache can only be done in spawn functions
i copied all needed files and checked the sourcecode several times
any idea?

You must log in to post a comment. You can login or register a new account.