This is a simple tutorial which is about modifying weapons in Counter Strike
It's not really complicated as it sounds, but requires some basic knowledge (Medium to intermediate)
There MAY be better ways or options, but this is just an average tutorial.
I have commented most of the lines, and possibly even used stupid terms, so please don't mind me for that. =@
This features:
Custom sound(s)
Custom model(s)
Custom secondary attack
Custom magazine/clip size
For sample purposes I've added these:
Explosion at the point where shooting
Delay between each shot (Could be used for making semi-automatic weapons)
Aug/Sg530 zooming style
50 bullets per mag
Basically I replaced Galil contents with H&K(Heckler & Koch AG36,sophisticated German AR) ones.
While there is a explosion, it won't do damage, and only specific weapons can be changed(For example if you're using a skin made for AK47, it won't work with other weapons)
I will try to expand this tutorial(or create new one) and overlap what I said above^ whenever I have free time...
Bugs may exist (I only know one. If you pick a dropped Hk/Galil it's mag size will be set to selected amount; WHICH by default is 50.)
#define MDL_VIEW "models/v_hk.mdl" // View model (What you see when holding the weapon) #define MDL_WORLD "models/w_hk.mdl" // World model (What you see when SOMEONE/YOU drop(s) the weapon)
new Float:WAIT_TIME = 0.2 // Delay between each gunshot new Float:WAIT_TIME_SCOPE = 0.25 // Scope delay
new bool:g_bCantShoot[33] // We will use this in order to check/delay every shoot new bool:g_bDidShoot[33] // We will use this in order to check/delay sounds
new bool:g_bCantScope[33] // We will use this in order to check/delay zooming
RegisterHam(Ham_Weapon_PrimaryAttack,"weapon_galil","hamShotPre",0) // Hooks shooting RegisterHam(Ham_Weapon_PrimaryAttack,"weapon_galil","hamShotPost",1) // Hooks shooting /* Both forwards above CANNOT be reigstered from "player"(s) Elsewise server MAY even crash or plugin might not work completely */ RegisterHam(Ham_Item_PostFrame,"weapon_galil","hamScopePre",0) // Hooks secondary attack RegisterHam(Ham_Weapon_Reload,"weapon_galil","hamReloadPre",0) // Hooks weapon reload RegisterHam(Ham_Item_PreFrame,"weapon_galil","hamGalilUsagePre",1) // Hooks clip size
public plugin_precache() { // Precaches models,sounds and sprites (If not did so, server will crash upon start) precache_model(MDL_VIEW) precache_model(MDL_WORLD) precache_sound(SOUND_SHOOT1) precache_sound(SOUND_SHOOT2)
public fwUpdateClientDataPost(id,sendweapons,cd_handle) // Special thanks to EFFx { if(!g_bCantShoot[id]) return PLUGIN_CONTINUE // Returns if player CAAAAN shoot set_cd(cd_handle,CD_flNextAttack,WAIT_TIME) // Blocks shooting for some time return FMRES_HANDLED }
public fwSetModelPost(entity,const model[]) { if(pev_valid(entity) && equal(model,"models/w_galil.mdl")) { new id = entity_get_edict(entity,EV_ENT_owner) // Gets entity(galil)'s owner index entity_set_model(entity,MDL_WORLD) g_bMagSet[id] = false return FMRES_SUPERCEDE } return -0 // Nothing }
public hamShotPre(galil) { if(WAIT_TIME<=0.1) return HAM_HANDLED // Returns if there's no delay new id = entity_get_edict(galil,EV_ENT_owner) // Gets entity(galil)'s owner index
if(!g_bCantShoot[id]) { g_bCantShoot[id] = true // Declare that player CAN'T shoot (Delay) g_bDidShoot[id] = true // Declare that player DID shoot set_task(WAIT_TIME,"tskSetShotAvailability",id) }else { g_bDidShoot[id]=false // Declare that player DIDN'T shoot return HAM_SUPERCEDE // If player can't shoot because of delay, returns and blocks shooting } return HAM_IGNORED // Returns once again in the end so compiler doesn't throw a warning (AFAIK 1.9+) }
public hamShotPost(galil) { new id = entity_get_edict(galil,EV_ENT_owner) // Gets index of player who is holding the gun
/* Code below CHECKS if player just shooted AND has bullets in clip If second check isn't performed, player(s) will still be able to hear gun shots
Variable "sound" is a random number from 1 to 2 It will be used to allocate random gunshot sound VIA switch statement
The third/fourth statement CHECKS if variable WAIT_TIME is less or equal to 0.1 It will be used to check if there is no delay If this is not performed, weapon(galil) will be bugged, as well as the game
*/
if(g_bDidShoot[id] && clip!=0 || WAIT_TIME<=0.1 && clip!=0) { new sound = random_num(1,2) // Random number for 1 to 2 switch(sound) { case 1: emit_sound(id,CHAN_AUTO,SOUND_SHOOT1,1.0,ATTN_NORM,0,PITCH_NORM) // First gunshot case 2: emit_sound(id,CHAN_AUTO,SOUND_SHOOT2,1.0,ATTN_NORM,0,PITCH_NORM) // Second gunshot }
new aim_position[3]; get_user_origin(id,aim_position,3) // Gets aiming position te_create_explosion(aim_position,explosion_sprite) // Makes an explosion effect at aiming position
} return HAM_SUPERCEDE // Probably unnecessary }
public hamScopePre(galil) { new id = entity_get_edict(galil,EV_ENT_owner) // Gets index of player who is holding the gun
public hamReloadPre(galil) { new id = entity_get_edict(galil,EV_ENT_owner) // Gets index of player who is holding the gun
static clip,ammo get_user_ammo(id,get_user_weapon(id),clip,ammo) // Gets clip and ammo number
if(clip == HK_MAXAMMO) return HAM_SUPERCEDE // Returns if weapon has as much bullets as prechanged value is
cs_set_user_zoom(id,CS_RESET_ZOOM,1) g_bCantScope[id] = false // Declares that player CAAAN scope set_task(2.7,"tskChangeAmmo",id) // Sets a task to reset availability for reloading
return HAM_HANDLED }
public hamGalilUsagePre(galil) { new id = entity_get_edict(galil,EV_ENT_owner) // Gets index of player who is holding the gun
public evWeaponChanged(id) { new weapon = read_data(2) // Gets weapon index (Could also be removed and replaced with read_data(2) ) if(weapon == CSW_HK) // Checks if changed weapon is Hk { entity_set_model(id,MDL_VIEW) // Sets players view model } }
public tskSetShotAvailability(id) { g_bCantShoot[id] = false // Declare that player CAAAN shoot }
public tskSetScopeAvailability(id) { g_bCantScope[id] = false // Declare that player CAAAN shoot }
public tskChangeAmmo(id) { g_bMagSet[id] = false }
The reason I had to also use engine is because some pev/set_pev functions don't work properly And what I found "crazy" is that I simply couldn't even change viewmodel using fakemeta
Seems that engine is far superior to fakemeta (?) */
Last edited by thEsp; 06-12-2019 at 12:51.
Reason: removed a useless line
Several days or weeks have passed since I uploaded the thread, I've collected some 'enough' information, and I'll probably do a totally new tutorial. I'll keep thinking what I need to add and/or fix.