Weapon script

From Valve Developer Community
Revision as of 03:08, 23 March 2018 by ReverendV92 (talk | contribs) (Viewmodel and UI: Added details about the Xbox 360 / controller-specific features, such as the controller inventory and the rumble settings found here: https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/game/shared/rumble_shared.h#L2)

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 localization 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. Not providing a viewmodel and selecting the weapon will cause the game to crash.
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 auto-selects one.
The "weight" used in the name is often erroneously misunderstood to mean weight as a mass, but is actually the weight as a priority.
Higher priority weapons will be selected before others when a weapon runs out of ammo, and a replacement is auto-selected by the game based on this value.
autoswitchto / bAutoSwitchTo
Whether to switch to this gun on running out of ammo for another. Defaults true.
Combined with the previous weight command can set the order of precedent for auto-selection.
An example of this is the initial appearance of the Magnum in the map d1_canals_08 in Half-Life 2; when the player walks within pickup range of the .357, the weight value of the Magnum (being the highest in HL2 at 7) combined with this boolean ensures it is automatically selected for the scripted sequence that follows.
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. Used in Counter-Strike: Source to differentiate weapon models that are modeled as such from the rest.
AllowFlipping / m_bAllowFlipping
Allow the viewmodel to be mirrored if the user wants left handed weapons. Defaults true.

Console/Controller Mode-Specific Variables (New with Half-Life 2: Episode Two / Source 2007)

Support for some controller features were added with the release of The Orange Box for the Xbox 360, which aimed to take advantage of the force feedback (rumble) system of modern controllers; as well as slightly modified weapon bucket commands, due to the console version using a modified HUD and weapon selection system, via the directional pad (d-pad).

A visual reference on the bucket layout for the controller-style inventory.
bucket_360
The HUD weapon selection on one of the four directional pad buttons. Only supports integers from 0 to 3 (See image).
bucket_position_360
The HUD weapon selection priority in the four buckets themselves. Weapons shown in the image start at 0, and increment by one each.
rumble / iRumbleEffect
Which rumble effect to use when fired when playing with a controller. Works on consoles, as well as when using Xbox controllers on PC.
The table below includes an overview of some of the default rumble settings. Of note is that only three rumble effects may be active at any given time (unless changed in the compiled code).

Rumble Settings

rumble -1 / RUMBLE_INVALID
The fallback if a rumble isn't valid.
rumble 0 / RUMBLE_STOP_ALL
Cease all current rumbling effects.
rumble 1 / RUMBLE_PISTOL
Used on the Pistol.
When used, firing too quickly will prevent the rumble from activating at all.
rumble 2 / RUMBLE_357
Used on the Magnum.
Similar to the previous, but firing speed has no ability to stop the rumble from activating.
rumble 3 / RUMBLE_SMG1
Used on the SMG.
An initial shake, followed by a rapid fall-off of feedback after a few rounds are fired. Using on a weapon like the Pistol will prevent the rumble from activating if fired too quickly.
rumble 4 / RUMBLE_AR2
Used on the AR2.
An initial shake, followed by a slight fall-off of feedback but maintains most of the "punch" of the first shot.
rumble 5 / RUMBLE_SHOTGUN_SINGLE
Used on the Shotgun for single-shot.
A fairly large feedback pulse, that consistently maintains the force with every subsequent follow-up shot, even in automatic.
rumble 6 / RUMBLE_SHOTGUN_DOUBLE
Used on the Shotgun for double-shot.
Feels identical to the normal shotgun rumble effect.
rumble 7 / RUMBLE_AR2_ALT_FIRE
Used on the AR2 for the energy ball alt-fire.
Over the course of the AR2 alt-fire animation, quickly builds a rumble, and then releases at the point of firing the ball.
rumble 8 / RUMBLE_RPG_MISSILE
Used when firing an RPG rocket.
rumble 9 / RUMBLE_CROWBAR_SWING
Used when swinging the Crowbar, regardless of if it hit anything.
rumble 10 / RUMBLE_AIRBOAT_GUN
Used when firing the Airboat gauss cannon.
rumble 11 / RUMBLE_JEEP_ENGINE_LOOP
Used for the Jeep engine idle.
rumble 12 / RUMBLE_FLAT_LEFT
Used for the Jeep.
rumble 13 / RUMBLE_FLAT_RIGHT
Defined, but unused in the Source SDK 2013 code.
rumble 14 / RUMBLE_FLAT_BOTH
Used for the rumble effects when using the Crane.
rumble 15 / RUMBLE_DMG_LOW
When taking light damage; defined/unused.
rumble 16 / RUMBLE_DMG_MED
When taking medium damage; defined/unused.
rumble 17 / RUMBLE_DMG_HIGH
When taking high damage; defined/unused.
rumble 18 / RUMBLE_FALL_LONG
When taking a lethal amount of fall damage.
rumble 19 / RUMBLE_FALL_SHORT
When taking a non-lethal amount of fall damage.
rumble 20 / RUMBLE_PHYSCANNON_OPEN
When the Gravity Gun claws open.
rumble 21 / RUMBLE_PHYSCANNON_PUNT
In speculation: when punting something with the Gravity Gun
In implementation: defined/unused.
rumble 22 / RUMBLE_PHYSCANNON_LOW
In speculation: when using a low amount of force on an object.
In use: when punting something with the Gravity Gun.
rumble 23 / RUMBLE_PHYSCANNON_MEDIUM
In speculation: when using a medium amount of force on an object; defined/unused.
rumble 24 / RUMBLE_PHYSCANNON_HIGH
In speculation: when using a high amount of force on an object; defined/unused.
rumble 25 / RUMBLE_PORTALGUN_LEFT
When firing the blue portal with the Portal Gun; defined/unused.
rumble 26 / RUMBLE_PORTALGUN_RIGHT
When firing the orange portal with the Portal Gun; defined/unused.
rumble 27 / RUMBLE_PORTAL_PLACEMENT_FAILURE
When the Portal Gun fails to place down a portal; defined/unused.

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_SELECTONEMPTY
If a player runs out of ammo in their current weapon, and the ITEM_FLAG_NOAUTOSWITCHEMPTY is not assigned to that weapon, select a weapon that has this flag. Note: the 'weight' value assigned to the weapons with this flag affect switch priority.
2 / ITEM_FLAG_NOAUTORELOAD
Weapon does not automatically reload.
4 / ITEM_FLAG_NOAUTOSWITCHEMPTY
Weapon does not automatically switch to another weapon when empty.
8 / ITEM_FLAG_LIMITINWORLD
Weapon is limited in world.
16 / ITEM_FLAG_EXHAUSTIBLE
A player can totally exhaust their ammo supply and lose this weapon. The Frag Grenade has this flag.
32 / ITEM_FLAG_DOHITLOCATIONDMG
This weapon takes hit location into account when applying damage.
64 / ITEM_FLAG_NOAMMOPICKUPS
Don't draw ammo pickup sprites/sounds when ammo is received.
128 / 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.