Zh/Weapon script
武器可以通过C++编程的方式实现自定义,当然Valve更喜欢简单轻便的武器脚本. 这种方式可以通过重启游戏房间/服务器来进行套用更改,相对于编程的方式,它不需要进行编译其二进制代码。 这为终端用户(个人计算机的使用者End-User)和开发人员提供了以下便利:
- By having code in the public realm, end-users can modify certain aspects to their liking. If you wish to support mods via this method in your own mod, giving the user more options will likely be welcomed.(使用代码的公共领域,终端用户可以通过这种方式在自己的mod中支援这种mod,提供更多选项)(?)
- It allows the developer to edit the code, and merely reboot the server or game to see the changes; this speeds up iteration time, as the binaries do not need to be recompiled to test minor changes.
它允许开发人员编辑代码,并且通过重启房间/服务器的方式立刻套用更改,可以更良好的支持更新,加快更迭的时间。因为这种脚本无需进行二进制代码的编译。
武器脚本位于此目录下:game\scripts\<classname>.txt
, 并且皆以weapondata
作为Table Key(开头?)。
一个武器脚本的键值可以通过 GetWpnData()
函数在C++内访问。
脚本参数/键值
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.
Template:注意 Template:注意 Template:注意
Viewmodel and UI/V模和UI界面
printname / szPrintName
- 向玩家展示的名字,最多80个字符。
- Can use a localization key, as well as a definite string; however, localization keys are case-insensitive, while defined strings are not.
viewmodel / szViewModel
- viewmodel的路径,需要包括model\文件夹开头。若不提供V模路径,选取武器时可能导致崩溃!
Template:注意
bucket / iSlot
- 武器槽位置。0默认为近战。原文:The HUD weapon selection in the X axis. 0 being the melee weapons by default.请酌情参考。
Template:注意
bucket_position / iPosition
- 武器位置。原文:The HUD weapon selection in the Y axis. 0 Being the pistol in the (1) X axis by default.请酌情参考。
Template:注意
weight / iWeight
- 游戏中自动切换武器的时的优先权。
- 此重量非彼重量,指优先权。
- 比如当某把武器子弹耗尽或某物品被消耗殆尽后,自动切换到另一把武器/物品的优先权,每把武器都可以设置独立的优先权,但是一般同类武器设置同一个优先权(比如主武器设置100,副武器设置50等等)。
Template:注意
autoswitchto / bAutoSwitchTo
- 是否在用尽弹药后切换到本武器。默认为true(开启),所以一般不写入武器脚本内,如果你要关闭改成false,就得写这个值进去。
- 可以根据
weight
的值进行优先级排序。 - 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
- 在拿起另一个武器/弹药时,是否丢弃本武器。默认为开启true。原文Whether to switch away from this weapon when picking up another weapon or ammo. Defaults true.请酌情参考。
showusagehint / bShowUsageHint
- 有关如何使用本武器的屏幕提示。默认为关闭false。
BuiltRightHanded / m_bBuiltRightHanded
- 右手持枪。这个值默认为true(1),即右手。
AllowFlipping / m_bAllowFlipping
- 当玩家修改为左手持枪时,则镜像武器模型。默认为true开启(1)。
Worldmodel/W模/世界模型
playermodel / szWorldModel
- 武器在地图上显示的模型(即没有被玩家拾取,分布在地图上的模型)路径,以
\models
文件夹开头,最多80个字符。 anim_prefix / szAnimationPrefix
- 挥舞(?)该武器的时候播放的动画,如prefix_idle, prefix_reload,最多16个字符。似乎在半条命2中不起作用。原文Prefix of the animations that should be played by characters wielding this weapon (e.g. prefix_idle, prefix_reload). Max 16 characters. Does not appear to have any effect when changed in Half-Life 2, however.请酌情参考。
Template:注意
Template:EP2 add
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). To enable this mode, the following console command must be set: hud_fastswitch 2
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 implementation: 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.
Ammunition
clip_size / iMaxClip1
clip2_size / iMaxClip2
- Magazine size for primary and secondary magazines, respectively.
- Putting -1 for either of these values will disregard the size of the magazine.
default_clip / iDefaultClip1
default_clip2 / iDefaultClip2
- Amount of ammo in the weapon when it spawns. When set to 0, the gun will spawn with no additional ammo, and will be unloaded.
primary_ammo / szAmmo1
secondary_ammo / szAmmo2
- The AmmoDef name of the hitscan ammunition this weapon fires for the primary and secondary/alt-fire modes, respectively. Both default to "None". Max 32 characters each.
MeleeWeapon / m_bMeleeWeapon
- Weapon is a melee-style weapon, such as a crowbar, knife, fists, etc. Defaults false.
An example of the previous from the default weapon_smg1.txt
in HL2:
clip_size 45 default_clip 45 primary_ammo smg1 clip2_size -1 default_clip2 -1 secondary_ammo smg1_grenade
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
deploy

Weapon_SMG1.Single
or weapon_smg1.single
will return the same result. Keep this in mind when writing sound scripts that case is not solely used to differentiate sounds.An example from the default HL2 weapon_smg1.txt
file:
sounddata { // When the player reloads reload weapon_smg1.reload // When an NPC reloads reload_npc weapon_smg1.npc_reload // Dry-fire empty weapon_smg1.empty // When the player fires single_shot weapon_smg1.single // When an NPC fires single_shot_npc weapon_smg1.npc_single // When a player fire both barrels / alt-fire double_shot weapon_smg1.double // Single-shot fire mode selection; unused special1 weapon_smg1.special1 // Burst fire mode selection; unused special2 weapon_smg1.special2 // Burst fire sound; unused burst weapon_smg1.burst }
TextureData
To define the HUD bucket icons, crosshairs, and ammo icons used by a weapon, you must edit the texturedata
table.
There are primarily two main ways of editing HUD icons: custom fonts, and traditional bitmap images. For more information, see the related article.
Arguments
Within the texturedata
table, as defined in weapon_resource.cpp
by default there are several values. The values used in the scripts are first, followed by the values as represented in C++ after the slash:
crosshair / iconCrosshair
- Used for the main crosshair that appears on the screen while using this weapon.
autoaim / iconAutoaim
- Used when the crosshair is on a target class, to change the crosshair style and colours.
- Falls back to
crosshair
if not defined. zoom / iconZoomedCrosshair
- Used while zoomed in with the scope on the Crossbow; falls back to
crosshair
if not defined. zoom_autoaim / iconZoomedAutoaim
- Used for the crosshair while zoomed in; falls back to
zoom
if not defined. weapon / iconInactive
- The weapon icon that appears when the HUD is drawn, but the weapon is not selected.
weapon_s / iconActive
- An additional icon that is overlaid on top of the
weapon
icon, to provide a glow effect when the weapon is selected, hence the_s
suffix. This is also reflected in the C++ class names for it and the former. weapon_small / iconSmall
- Used for a variant of the standard weapon font class that is half the size of the original.
ammo / iconAmmo
- An icon used when picking up primary ammo that appears on the side of the screen.
ammo2 / iconAmmo2
- An icon used when picking up secondary/alt-fire ammo that appears on the side of the screen. Examples of this are AR2 balls and SMG grenades.
Defining Glyphs
For each of these definitions, there are two ways to define a glyph for use by default.
The first involves the use of fonts, as defined in the resource/clientscheme.res
file included with every stand-alone Source game. The article linked abouve dictates how to use this.
The second method, is to use bitmap images, such as sprites to define the glyphs.
Font-Specific Method
- font <string>
- The name of a font class defined in the
clientscheme.res
file. In Half-Life 2, they are usually a variation of the nameWeaponIcons
for weapon glyphs. - The font class name entry in
clientsceheme.res
is case-insensitive, and as such, usingWeaponIcons
orweaponicons
will return the same result. Keep this in mind when writing font classes that case is not solely used to differentiate them. - character <string>
- The specific font character to use on the sheet itself. For example, in HL2, on the
WeaponIcons
font,a
is the character used for the SMG. - The character specified is case-sensitive, as using
A
in place of the former changes the glyph to a Lambda symbol used in the Half-Life 2 branding. This allows font sheets to have not just 26 different glyphs across the alphabet, but doubles it for lowercase and uppercase.
Bitmap-Specific Method
- file <path/to/image>
- The path to the image, relative to
materials/
, so the initial root folder name is not needed. - x <integer>
- The lateral (X-axis) position of the desired glyph on the sprite sheet.
- y <integer>
- The longitudinal (Y-axis) position of the desired glyph on the sprite sheet.
- width <integer>
- How wide to render the selected area of the sheet, in pixels.
- height <integer>
- How tall to render the selected area of the sheet, in pixels.
Example
An example from the default scripts/weapon_smg1.txt
found in Half-Life 2:
texturedata { weapon { font weaponicons character a } weapon_s { font weaponiconsselected character a } ammo { font weaponicons character r } ammo2 { font weaponicons character t } crosshair { font crosshairs character Q } autoaim { file sprites/crosshairs x 0 y 48 width 24 height 24 } }
Flags
The following base-2 keyvalue flags are used to imbue the weapon with any combination of the following effects. To combine multiple effects, add the integer assigned to the effects you wish to use together in the weapon script.
For example:
item_flags 38
Would give the weapon the ITEM_FLAG_DOHITLOCATIONDMG
, ITEM_FLAG_NOAUTOSWITCHEMPTY
, and ITEM_FLAG_NOAUTORELOAD
flags (32 + 4 + 2, respectively).
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):

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.