Need to start some were in modding right? Why not try the Half-Life modding Kit. This Kit is designed to have all the tools you need to start your own Half-Life mod, simple mods can be made or advance ones like Base Defense with this small set of tools. If you want to start modding Half-Life you should try this.

Post tutorial Report RSS Coding Custom Weapons Part 2 Of 3 Client Side

Lets finish up the coding process of our Colt M1911, in this tutorial we will be finishing the Colt we have started in the previous tutorial for server side, after this tutorial and the first one you will have a perfectly working gun

Posted by on - Advanced Client Side Coding

Ready to do the ever so exciting client side coding? As most of you have realized Half-Life's engine (Gold Source) is very very messed up in the coding process (not buggy just hard to code in a way) well in this tutorial we will be jumping around from I think 6 different files 1 of witch you do not actually need but can do in another file but lets not bore you any longer I know you want to get some custom weapons into your mod. To be honest this part is really not that hard, I just marked it advance because if you miss 1 thing the game will not work right. First just open up your client.dsp (NOT TO BE CONFUSED WITH CLIENT.H OR CLIENT.CPP)


Now the server side does read and operate some stuff coded on client side and vice versa but for some reason the server side or client side will not pick up the weapon file if it is on one or the other, so we are going to add it. There are 2 ways we can do this, the way I recommend is you just drag the one from your server side folder to the client.dsp window you have opened, this is better because you will always have the same file in the client and server side version which is what you need. Or you can copy and paste the file into the client side folder and drag the file into you client.dsp, I would not do the second one because it will not stay updated like the first one.

Now lets get on to the coding section, first look open up hl_events.cpp, you might not see this file on your dsp but there should be what looks like a folder labeled hl in the dsp when you click it it will drop down, I think these are all the files on server side that the client side needs. You should see void EV_SnarkFire( struct event_args_s *args ); under that add


void EV_FireColt1( struct event_args_s *args );
void EV_FireColt2( struct event_args_s *args );

This is adding in the part of the fire event for when you shoot the weapon, this allows it to trigger animations. I do not think I used the EV_FireColt2 in the code but I added it just in case I did. scroll down a little more and you should see gEngfuncs.pfnHookEvent( "events/snarkfire.sc", EV_SnarkFire ); under that add

gEngfuncs.pfnHookEvent( "events/colt.sc", EV_FireColt1 );
gEngfuncs.pfnHookEvent( "events/colt2.sc", EV_FireColt2 );

This is basically a precache for your event like we did in the server side, Now open up hl_weapons.cpp and scroll down till you see CSqueak g_Snark; under that we will add

CColt g_Colt;

This is basically linking the CColt, the name we gave the weapon in the colt.cpp to the g_Colt which is what the client side will have pieces of code linked with, it is very important you rember g_Colt we will use it later, now you want to search HUD_PrepEntity( &g_Snark , &player ); because it is a couple hundred lines down, and under that we will add

HUD_PrepEntity( &g_Colt , &player );

According to the code this is Allocate slot(s) for each weapon that we are going to be predicting, basically it is getting the HUD ready for the new weapon so the HUD knows to add it. Now search WEAPON_GLOCK and under that entry add

case WEAPON_COLT:
pWeapon = &g_Colt;
break;

This just tells the code that WEAPON_COLT is also g_Colt, Now open up ev_hldm.cpp and search for EV_SnarkFire under that line of code add this

void EV_FireColt1( struct event_args_s *args );
void EV_FireColt2( struct event_args_s *args );

This is registering the fire event we made in hl_events.cpp to the ev_hldm.cpp file, now right under that you will see #define VECTOR_CONE_20DEGREES Vector( 0.17365, 0.17365, 0.17365 ) remember we made a custom Vector in the previous tutorial now we need to add it to the client side so under that add this

#define VECTOR_CONE_COLT Vector( 0.00273, 0.00273, 0.00273 )

It does have to be the same as the one in the server side, I don't know what will happen if it is not you might have bullets shooting behind you, that would be pretty cool though :) Now search for GLOCK END and under that entry add


//======================
// Colt START
//======================
void EV_FireColt1( event_args_t *args )
{
int idx;
vec3_t origin;
vec3_t angles;
vec3_t velocity;
int empty;

vec3_t ShellVelocity;
vec3_t ShellOrigin;
int shell;
vec3_t vecSrc, vecAiming;
vec3_t up, right, forward;

idx = args->entindex;
VectorCopy( args->origin, origin );
VectorCopy( args->angles, angles );
VectorCopy( args->velocity, velocity );

empty = args->bparam1;
AngleVectors( angles, forward, right, up );

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

if ( EV_IsLocal( idx ) )
{
EV_MuzzleFlash();
gEngfuncs.pEventAPI->EV_WeaponAnimation( empty ? COLT_SHOOT_EMPTY : COLT_SHOOT1, 2 );

V_PunchAxis( 0, -2.0 );
}

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

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

gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/pl_gun3.wav", gEngfuncs.pfnRandomFloat(0.92, 1.0), ATTN_NORM, 0, 98 + gEngfuncs.pfnRandomLong( 0, 3 ) );

EV_GetGunPosition( args, vecSrc, origin );

VectorCopy( forward, vecAiming );

EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_9MM, 0, 0, args->fparam1, args->fparam2 );
}

void EV_FireColt2( 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 vecSpread;
vec3_t up, right, forward;

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");// brass shell

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

V_PunchAxis( 0, -2.0 );
}

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

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

gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/pl_gun3.wav", gEngfuncs.pfnRandomFloat(0.92, 1.0), ATTN_NORM, 0, 98 + gEngfuncs.pfnRandomLong( 0, 3 ) );

EV_GetGunPosition( args, vecSrc, origin );

VectorCopy( forward, vecAiming );

EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_9MM, 0, &tracerCount[idx-1], args->fparam1, args->fparam2 );

}
//======================
// Colt END
//======================

I am not going to break this piece down since it is pointless of me, I do not understand most of it and I feel it will take up to much time to do it so lets move on, But before we do remember at the start of the tutorial when I said 1 file would not actually be needed, well ev_hldm.h is not actually needed, you could add the animations which we will be adding next to the top of this code entry, a couple of Half-Life's vanilla weapons do this like the crossbow and the gauss, I do not know why though. Now open up ev_hldm.h and lets finish up, you should see animations just add the animations the same way we had them in the colt.cpp

enum colt_e {
COLT_IDLE,
COLT_SHOOT1,
COLT_SHOOT2,
COLT_RELOAD,
COLT_RELOAD_NOSHOOT,
COLT_DRAW,
COLT_SHOOT_EMPTY,
COLT_EMPTY_IDLE
};

Oops I did forget 1 thing, we made a custom ammo remember, so we need to add it in open back up hl_weapons.cpp and search ammo_9mm under that line you want to add

player.ammo_45 = (int)from->client.vuser1[3];

Now you should be all done compile it and it should work, well after you finish the first piece of the 3rd part of this tutorial for finishing the gun (not coding). I hoped this helped you if it did not work though just message me

Post comment Comments
Red_Fire_Gaming
Red_Fire_Gaming - - 35 comments

Whenever i try to build the cl_dll, i get this error, and it all happens inside the hl_weapons.cpp file, here's the build log, my custom weapon is named shotguntwo


1>------ Rebuild All started: Project: cl_dll, Configuration: Debug Win32 ------
1>Deleting intermediate and output files for project 'cl_dll', configuration 'Debug|Win32'
1>Compiling...
1>ammo.cpp
1>ammo_secondary.cpp
1>ammohistory.cpp
1>battery.cpp
1>cdll_int.cpp
1>com_weapons.cpp
1>death.cpp
1>demo.cpp
1>entity.cpp
1>ev_common.cpp
1>events.cpp
1>flashlight.cpp
1>GameStudioModelRenderer.cpp
1>geiger.cpp
1>health.cpp
1>hud.cpp
1>hud_msg.cpp
1>hud_redraw.cpp
1>hud_servers.cpp
1>hud_spectator.cpp
1>Generating Code...
1>Compiling...
1>hud_update.cpp
1>in_camera.cpp
1>input.cpp
1>inputw32.cpp
1>menu.cpp
1>message.cpp
1>parsemsg.cpp
1>saytext.cpp
1>status_icons.cpp
1>statusbar.cpp
1>studio_util.cpp
1>StudioModelRenderer.cpp
1>text_message.cpp
1>train.cpp
1>tri.cpp
1>util.cpp
1>vgui_checkbutton2.cpp
1>vgui_ClassMenu.cpp
1>vgui_ConsolePanel.cpp
1>vgui_ControlConfigPanel.cpp
1>Generating Code...
1>Compiling...
1>vgui_CustomObjects.cpp
1>vgui_grid.cpp
1>vgui_helpers.cpp
1>vgui_int.cpp
1>vgui_listbox.cpp
1>vgui_loadtga.cpp
1>vgui_MOTDWindow.cpp
1>vgui_SchemeManager.cpp
1>vgui_ScorePanel.cpp
1>vgui_ServerBrowser.cpp
1>vgui_SpectatorPanel.cpp
1>vgui_TeamFortressViewport.cpp
1>vgui_teammenu.cpp
1>view.cpp
1>crossbow.cpp
1>crowbar.cpp
1>egon.cpp
1>ev_hldm.cpp
1>gauss.cpp
1>handgrenade.cpp
1>Generating Code...
1>Compiling...
1>hl_baseentity.cpp
1>hl_events.cpp
1>hl_objects.cpp
1>hl_weapons.cpp
1>c:\users\halfwaylambda\downloads\hl_code_vc_2008\src_dll\testmod_cl_dll\hl\hl_weapons.cpp(69) : error C2146: syntax error : missing ';' before identifier 'g_ShotgunTwo'
1>c:\users\halfwaylambda\downloads\hl_code_vc_2008\src_dll\testmod_cl_dll\hl\hl_weapons.cpp(69) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\halfwaylambda\downloads\hl_code_vc_2008\src_dll\testmod_cl_dll\hl\hl_weapons.cpp(69) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\halfwaylambda\downloads\hl_code_vc_2008\src_dll\testmod_cl_dll\hl\hl_weapons.cpp(640) : error C2664: 'HUD_PrepEntity' : cannot convert parameter 1 from 'int *' to 'CBaseEntity *'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>c:\users\halfwaylambda\downloads\hl_code_vc_2008\src_dll\testmod_cl_dll\hl\hl_weapons.cpp(764) : error C2065: 'WEAPON_SHOTGUNTWO' : undeclared identifier
1>c:\users\halfwaylambda\downloads\hl_code_vc_2008\src_dll\testmod_cl_dll\hl\hl_weapons.cpp(764) : error C2051: case expression not constant
1>c:\users\halfwaylambda\downloads\hl_code_vc_2008\src_dll\testmod_cl_dll\hl\hl_weapons.cpp(765) : error C2440: '=' : cannot convert from 'int *' to 'CBasePlayerWeapon *'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>hl_wpn_glock.cpp
1>hornetgun.cpp
1>interface.cpp
1>mp5.cpp
1>python.cpp
1>rpg.cpp
1>satchel.cpp
1>shotgun.cpp
1>shotguntwo.cpp
1>Generating Code...
1>Creating browse information file...
1>Microsoft Browse Information Maintenance Utility Version 9.00.30729
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>BSCMAKE: error BK1506 : cannot open file '.\Debug\pm_debug.sbr': No such file or directory
1>Build log was saved at "file://c:\Users\Halfwaylambda\Downloads\HL_code_VC_2008\src_dll\testmod_cl_dll\Debug\BuildLog.htm"
1>cl_dll - 8 error(s), 0 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

I literally have no idea what's causing this issue, everything i added is just like the other weapons. I would highly appreciate it if you could help me fix this issue...

Reply Good karma Bad karma+1 vote
shepard62fr
shepard62fr - - 491 comments

Half_Way_Lambda read the compile log again

1>c:\users\halfwaylambda\downloads\hl_code_vc_2008\src_dll\testmod_cl_dll\hl\hl_weapons.cpp(69) : error C2146: syntax error : missing ';' before identifier 'g_ShotgunTwo'

Maybe a semicolon is missing, double check that.

1>c:\users\halfwaylambda\downloads\hl_code_vc_2008\src_dll\testmod_cl_dll\hl\hl_weapons.cpp(69) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\halfwaylambda\downloads\hl_code_vc_2008\src_dll\testmod_cl_dll\hl\hl_weapons.cpp(69) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

You likely forgot a character or something else, same as above.

1>c:\users\halfwaylambda\downloads\hl_code_vc_2008\src_dll\testmod_cl_dll\hl\hl_weapons.cpp(640) : error C2664: 'HUD_PrepEntity' : cannot convert parameter 1 from 'int *' to 'CBaseEntity *'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>c:\users\halfwaylambda\downloads\hl_code_vc_2008\src_dll\testmod_cl_dll\hl\hl_weapons.cpp(764) : error C2065: 'WEAPON_SHOTGUNTWO' : undeclared identifier

Looks like you have a typo error.

1>c:\users\halfwaylambda\downloads\hl_code_vc_2008\src_dll\testmod_cl_dll\hl\hl_weapons.cpp(764) : error C2051: case expression not constant
1>c:\users\halfwaylambda\downloads\hl_code_vc_2008\src_dll\testmod_cl_dll\hl\hl_weapons.cpp(765) : error C2440: '=' : cannot convert from 'int *' to 'CBasePlayerWeapon *'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

Caused by the typo error above.

Reply Good karma Bad karma+1 vote
Red_Fire_Gaming
Red_Fire_Gaming - - 35 comments

So i tried this again, this time i didn't get any typo errors, but now i get others, my weapon has the same name, ShotgunTwo, here's the log:


1>------ Rebuild All started: Project: cl_dll, Configuration: Debug Win32 ------
1>Deleting intermediate and output files for project 'cl_dll', configuration 'Debug|Win32'
1>Compiling...
1>ammo.cpp
1>ammo_secondary.cpp
1>ammohistory.cpp
1>battery.cpp
1>cdll_int.cpp
1>com_weapons.cpp
1>death.cpp
1>demo.cpp
1>entity.cpp
1>ev_common.cpp
1>events.cpp
1>flashlight.cpp
1>GameStudioModelRenderer.cpp
1>geiger.cpp
1>health.cpp
1>hud.cpp
1>hud_msg.cpp
1>hud_redraw.cpp
1>hud_servers.cpp
1>hud_spectator.cpp
1>Generating Code...
1>Compiling...
1>hud_update.cpp
1>in_camera.cpp
1>input.cpp
1>inputw32.cpp
1>menu.cpp
1>message.cpp
1>parsemsg.cpp
1>saytext.cpp
1>status_icons.cpp
1>statusbar.cpp
1>studio_util.cpp
1>StudioModelRenderer.cpp
1>text_message.cpp
1>train.cpp
1>tri.cpp
1>util.cpp
1>vgui_checkbutton2.cpp
1>vgui_ClassMenu.cpp
1>vgui_ConsolePanel.cpp
1>vgui_ControlConfigPanel.cpp
1>Generating Code...
1>Compiling...
1>vgui_CustomObjects.cpp
1>vgui_grid.cpp
1>vgui_helpers.cpp
1>vgui_int.cpp
1>vgui_listbox.cpp
1>vgui_loadtga.cpp
1>vgui_MOTDWindow.cpp
1>vgui_SchemeManager.cpp
1>vgui_ScorePanel.cpp
1>vgui_ServerBrowser.cpp
1>vgui_SpectatorPanel.cpp
1>vgui_TeamFortressViewport.cpp
1>vgui_teammenu.cpp
1>view.cpp
1>crossbow.cpp
1>crowbar.cpp
1>egon.cpp
1>ev_hldm.cpp
1>gauss.cpp
1>handgrenade.cpp
1>Generating Code...
1>Compiling...
1>hl_baseentity.cpp
1>hl_events.cpp
1>hl_objects.cpp
1>hl_weapons.cpp
1>hl_wpn_glock.cpp
1>hornetgun.cpp
1>interface.cpp
1>mp5.cpp
1>python.cpp
1>rpg.cpp
1>satchel.cpp
1>shotgun.cpp
1>squeakgrenade.cpp
1>tripmine.cpp
1>vgui_scrollbar2.cpp
1>vgui_slider2.cpp
1>voice_banmgr.cpp
1>voice_status.cpp
1>Generating Code...
1>Compiling...
1>pm_debug.c
1>pm_math.c
1>pm_shared.c
1>Generating Code...
1>Compiling manifest to resources...
1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>Linking...
1> Creating library .\Debug/client.lib and object .\Debug/client.exp
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CShotgunTwo::Spawn(void)" (?Spawn@CShotgunTwo@@UAEXXZ)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CShotgunTwo::Precache(void)" (?Precache@CShotgunTwo@@UAEXXZ)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall CShotgunTwo::AddToPlayer(class CBasePlayer *)" (?AddToPlayer@CShotgunTwo@@UAEHPAVCBasePlayer@@@Z)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall CShotgunTwo::GetItemInfo(struct ItemInfo *)" (?GetItemInfo@CShotgunTwo@@UAEHPAUItemInfo@@@Z)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall CShotgunTwo::Deploy(void)" (?Deploy@CShotgunTwo@@UAEHXZ)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CShotgunTwo::PrimaryAttack(void)" (?PrimaryAttack@CShotgunTwo@@UAEXXZ)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CShotgunTwo::SecondaryAttack(void)" (?SecondaryAttack@CShotgunTwo@@UAEXXZ)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CShotgunTwo::Reload(void)" (?Reload@CShotgunTwo@@UAEXXZ)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CShotgunTwo::WeaponIdle(void)" (?WeaponIdle@CShotgunTwo@@UAEXXZ)
1>.\Debug\client.dll : fatal error LNK1120: 9 unresolved externals
1>Creating browse information file...
1>Microsoft Browse Information Maintenance Utility Version 9.00.30729
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>Build log was saved at "file://c:\Users\Half Way Lambda\Documents\Half-Life 1 Mod Coding\coding_test2\cl_dll\Debug\BuildLog.htm"
1>cl_dll - 10 error(s), 0 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

Reply Good karma Bad karma+1 vote
Red_Fire_Gaming
Red_Fire_Gaming - - 35 comments

Nevermind, i fixed it.

Reply Good karma Bad karma+1 vote
MrPixel92
MrPixel92 - - 2 comments

How did you fix it?

Reply Good karma Bad karma+1 vote
Vaguila
Vaguila - - 13 comments

how did you fix it tell us lol

Reply Good karma Bad karma+1 vote
MrPixel92
MrPixel92 - - 2 comments

Hello. I tried, to create AK47 in my mod. I wrote both server and client side code for new gun. But when I try to build hl_cdll (client.dll), it gives me those errors:

1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CAK47::Spawn(void)" (?Spawn@CAK47@@UAEXXZ)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CAK47::Precache(void)" (?Precache@CAK47@@UAEXXZ)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall CAK47::GetItemInfo(struct ItemInfo *)" (?GetItemInfo@CAK47@@UAEHPAUItemInfo@@@Z)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall CAK47::AddToPlayer(class CBasePlayer *)" (?AddToPlayer@CAK47@@UAEHPAVCBasePlayer@@@Z)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CAK47::PrimaryAttack(void)" (?PrimaryAttack@CAK47@@UAEXXZ)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CAK47::SecondaryAttack(void)" (?SecondaryAttack@CAK47@@UAEXXZ)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall CAK47::Deploy(void)" (?Deploy@CAK47@@UAEHXZ)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CAK47::Reload(void)" (?Reload@CAK47@@UAEXXZ)
1>hl_weapons.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CAK47::WeaponIdle(void)" (?WeaponIdle@CAK47@@UAEXXZ)
1>..\..\..\cl_dlls\client.dll : fatal error LNK1120: 9 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

It seems like it doesn't see the weapon i created. How can i fix that?

Reply Good karma Bad karma+1 vote
SalsaSteam
SalsaSteam - - 1 comments

im getting the same error as yours, did you fix it?

Reply Good karma Bad karma+1 vote
Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: