Weapon script

From Valve Developer Community
Jump to: navigation, search

While it is perfectly possible to define a weapon's properties entirely in C++, Valve tend to use weapon scripts instead. These allow changes to be applied by a server restart, with no need to shut the game down and recompile its code.

Weapons scripts should be located at game\scripts\<classname>.txt, and everything inside should be a child of a single WeaponData key.

A weapon's scripted values are accessed from its GetWpnData() function.

Standard keys

These are the keyvalues that will be read by CBaseCombatWeapon. All weapons support them. Script keys are on the left, C++ variables on the right.

Note:Boolean values are represented as 1/0. Wrap any values that include whitespace in "quote marks".

Viewmodel and UI

printname / szPrintName
The friendly name shown to players in the UI. Max 80 characters (but can be a localisation key).
viewmodel / szViewModel
Path to the viewmodel seen by the player holding the weapon. Relative to the game root, so be sure to include the models\ folder. Max 80 characters.
bucket / iSlot
The HUD weapon selection in the X axis. 0 being the melee weapons by default.
bucket_position / iPosition
The HUD weapon selection in the Y axis. 0 Being the pistol in the (1) X axis by default.
weight / iWeight
Used to determine the weapon's importance when the game autoselects one. Nothing to do with physical weight!
autoswitchto / bAutoSwitchTo
Whether to switch to this gun on running out of ammo for another. Defaults true.
autoswitchfrom / bAutoSwitchFrom
Whether to switch away from this weapon when picking up another weapon or ammo. Defaults true.
showusagehint / bShowUsageHint
Show on-screen hints about how to use the weapon. Defaults false.
BuiltRightHanded / m_bBuiltRightHanded
Weapon viewmodel is right-handed. Defaults true.
AllowFlipping / m_bAllowFlipping
Allow the viewmodel to be mirrored if the user wants left handed weapons. Defaults true.
rumble / iRumbleEffect (New with Source 2007)
Which rumble effect to use when fired. To do: Only on Xbox, or on PC with a supported gamepad too?

Worldmodel

playermodel / szWorldModel
Path to the weapon's regular model that is seen in the world. Relative to the game root, so be sure to include the \models folder. Max 80 characters.
anim_prefix / szAnimationPrefix
Prefix of the animations that should be played by characters wielding this weapon (e.g. prefix_idle, prefix_reload). Max 16 characters.

Ammunition

clip_size / iMaxClip1
clip2_size / iMaxClip2
Bullets in each clip. -1 means clips are not used.
default_clip / iDefaultClip1
default_clip2 / iDefaultClip2
Amount of ammo in the weapon when it spawns.
primary_ammo / szAmmo1
secondary_ammo / szAmmo2
The AmmoDef name of the hitscan ammunitions this weapon fires. Both default to "none". Max 32 characters each.
MeleeWeapon / m_bMeleeWeapon
Weapon is a crowbar, knife, fists, etc. Defaults false.

SoundData

The SoundData subkey defines the sounds that should play when the weapon fires a bullet, fires dry, reloads, and so on. CBaseCombatWeapon will understand (but not necessarily use) the following:

  • empty
  • single_shot
  • single_shot_npc
  • double_shot
  • double_shot_npc
  • burst
  • reload
  • reload_npc
  • melee_miss
  • melee_hit
  • melee_hit_world
  • special1
  • special2
  • special3
  • taunt

TextureData

To do: The various glyphs and sprites used on the HUD.

Flags

1 / ITEM_FLAG_NOAUTORELOAD
Weapon does not automatically reload.
2 / ITEM_FLAG_NOAUTOSWITCHEMPTY
Weapon does not automatically switch to another weapon when empty.
3 / ITEM_FLAG_LIMITINWORLD
Weapon is limited in world.
4 / ITEM_FLAG_EXHAUSTIBLE
A player can totally exhaust their ammo supply and lose this weapon. The Frag Grenade has this flag.
5 / ITEM_FLAG_DOHITLOCATIONDMG
This weapon takes hit location into account when applying damage.
6 / ITEM_FLAG_NOAMMOPICKUPS
Don't draw ammo pickup sprites/sounds when ammo is received.
6 / ITEM_FLAG_NOITEMPICKUP
Don't draw weapon pickup when this weapon is picked up by the player.

Parsing new keys

You will at some point probably want to parse additional keys from a weapon script. You may want to simply because important values like cycle time (how long between each bullet) and bullets per shot are not read from scripts by Valve's code.

Doing it is incredibly easy:

#include "cbase.h"
#include "weapon_parse.h"
#include "KeyValues.h"
 
class MyWeaponParse : public FileWeaponInfo_t
{
public:
	DECLARE_CLASS_GAMEROOT( MyWeaponParse, FileWeaponInfo_t );
 
	void Parse( ::KeyValues* pKeyValuesData, const char* szWeaponName )
	{
		BaseClass::Parse( pKeyValuesData, szWeaponName );
 
		m_flCycleTime	= pKeyValuesData->GetFloat( "CycleTime", 0.15 );
		m_iBullets	= pKeyValuesData->GetInt( "Bullets", 1 );
	}
 
	float	m_flCycleTime;
	int	m_iBullets;
};
 
// This function probably exists somewhere in your mod already.
FileWeaponInfo_t* CreateWeaponInfo()
{
	return new MyWeaponParse;
}

From outside the weapon

To load weapon script keys from outside the weapon class (e.g. for VGUI use):

Tip:See KeyValues for other ways to access data from a FileWeaponInfo_t object.

Client:

const FileWeaponInfo_t &weaponInfo = C_BasePlayer::GetLocalPlayer()->GetActiveWeapon()->GetWpnData();
wchar_t* wepname = g_pVGuiLocalize->Find(weaponInfo.szPrintName); // Loading a localised string

Server:

// TODO

Encryption

To prevent server operators from changing the behaviour of your weapons, you can ICE encrypt them. This isn't totally secure as your ICE key can be extracted from your mod's binaries by anyone with enough knowledge, but it will head off most tampering.

To implement encryption, choose a secret eight-character alphanumeric key and run your weapon scripts through VICE with it. Then create const unsigned char* GetEncryptionKey() in your GameRules class and have it return the key.

Once your mod starts loading ICE-encrypted files (.ctx) it will not load normal .txt files, even if a CTX is missing.