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++内访问。
汉化翻译By：OKcf，可以补充内容，修改错误
== 脚本参数/键值 ==
These are the keyvalues that will be read by . All weapons support them. Script keys are on the left, C++ variables on the right.
=== Viewmodel and UI/V模和UI界面 ===
; printname / szPrintName
: 向玩家展示的名字，最多80个字符。
: Can use a key, as well as a definite string; however, localization keys are case-insensitive, while defined strings are not.
; viewmodel / szViewModel
: 的路径，需要包括model\文件夹开头。若不提供V模路径，选取武器时可能导致崩溃！
 
; bucket / iSlot
: 武器槽位置。0默认为近战。原文：The HUD weapon selection in the X axis. 0 being the melee weapons by default.请酌情参考。
 待考究，仅为翻译者发现的参数规律，请亲自实验，求生之路2中，0=主武器，1=近战/手枪（其中用"bucket_position"这个参数来区分，0代表手枪，1代表近战），2=投掷物，3为医疗包所在位置（升级弹药包也是3），4为药丸所在位置，5则表示拿在手上。
; bucket_position / iPosition
: 武器位置。原文：The HUD weapon selection in the Y axis. 0 Being the pistol in the (1) X axis by default.请酌情参考。
 
; weight / iWeight
: 游戏中自动切换武器的时的优先权。
: 此重量非彼重量，指优先权。
: 比如当某把武器子弹耗尽或某物品被消耗殆尽后，自动切换到另一把武器/物品的优先权，每把武器都可以设置独立的优先权，但是一般同类武器设置同一个优先权（比如主武器设置100，副武器设置50等等）。
 以求生之路2为例，主武器=25，副武器=5，投掷物=2，包/弹药升级/电击器=2，药丸=2，油桶类物品=2}}
; autoswitchto / bAutoSwitchTo
: 是否在用尽弹药后切换到本武器。默认为true（开启），所以一般不写入武器脚本内，如果你要关闭改成false，就得写这个值进去。
:可以根据weight的值进行优先级排序。
: An example of this is the initial appearance of the in the map 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.请酌情参考。
 
== ==
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
: 在4个不同的界面的选取系统，看边上的图片，支持的值0~3。原文: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 设置项来给你的武器进行填写。
==== Rumble 设置项 ====
; rumble -1 / RUMBLE_INVALID
: 如果Rumble无效，则回退。原文：The fallback if a rumble isn't valid.
; rumble 0 / RUMBLE_STOP_ALL
: 停止当前Rumble效果。原文：Cease all current rumbling effects.
; rumble 1 / RUMBLE_PISTOL
: 用于 /手枪。
: When used, firing too quickly will prevent the rumble from activating at all.
; rumble 2 / RUMBLE_357
: 用于 /马格南手枪。
: Similar to the previous, but firing speed has no ability to stop the rumble from activating.
; rumble 3 / RUMBLE_SMG1
: 用于 /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
: 用于 /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
: 用于 /霰弹枪。
: 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
: 用于 /AR2的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
: 用于/火箭筒。求生之路的榴弹发射器用的是"5"。
; rumble 9 / RUMBLE_CROWBAR_SWING
: 用于挥舞的 /撬棍，无论是否击中东西。 
; rumble 10 / RUMBLE_AIRBOAT_GUN
: 用于 /汽艇发射高斯炮。
; rumble 11 / RUMBLE_JEEP_ENGINE_LOOP
: 用于 /吉普引擎熄火。
; rumble 12 / RUMBLE_FLAT_LEFT
: 用于吉普。
; rumble 13 / RUMBLE_FLAT_RIGHT
: 有定义， 但在 代码中未使用。
; rumble 14 / RUMBLE_FLAT_BOTH
: 用于 /起重机使用时。
; 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 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 ; 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
: clip_size=主弹匣容量，clip2_size=副弹匣容量。
: Putting -1 for either of these values will disregard the size of the magazine.应该是-1忽略子弹大小？或者无限子弹？
; default_clip / iDefaultClip1
; default_clip2 / iDefaultClip2
:描述：default_clip每开一次枪默认减少的子弹数量1，clip2每开一次枪默认减少的子弹数量2。感觉不明所以。
: 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
: primary_ammo：武器的主要子弹类型，secondary_ammo：武器的次要子弹类型。类似于半条命中的带榴弹的SMG,没有次要子弹则填写None。
; MeleeWeapon / m_bMeleeWeapon
: 武器是近战武器，类似于蝴蝶刀，撬棍，刺刀等。默认为false。
一个实例，来自于半条命2的weapon_smg1.txt （smg冲锋枪）：
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[NPC的单次使用/单发]
* double_shot[次要子弹类型的使用]
* double_shot_npc[NPC的次要子弹类型的使用]
* burst[爆（？）]
* reload[重新装弹]
* reload_npc[NPC的重新装弹]
* melee_miss[近战武器没有击中]
* melee_hit[使用者听到的近战武器击中]
* melee_hit_world[地图上/其他玩家听到的近战武器击中]
* special1[特殊1]
* special2[特殊2]
* special3{特殊3}
* taunt[嘲讽]
* deploy[部署]
An example from the default HL2 weapon_smg1.txt file:半条命2smg的实例
sounddata
{
	// When the player reloads[当玩家重新装填子弹]
	reload weapon_smg1.reload
	
	// When an NPC reloads[当NPC重新装填子弹]
	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[当NPC进行单发子弹]
	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/材质信息 ==
若想要定义武器的图标，准心和弹药图标，你必须编辑texturedata 相关参数。
这儿有两种主要方式来编辑图标：自定义字体和传统位图。 更多信息请参阅： 。
=== Arguments/参数 ===
默认情况下，TextureData定义的一些值，你可以使用它们。
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
: 使用这个武器的时候，屏幕中心的准星设置。
 默认参数格式是[其实这些格式在下面有提到。。。才发现，懒得修改了]：
 "file" "文件路径"
 "x" "0"
 "y" "48"
 "width" "24"
 "height" "24"
; autoaim / iconAutoaim
: 当准星在一个目标身上时候的样式
 默认参数格式是：
 "file" "文件路径"
 "x" "0"
 "y" "48"
 "width" "24"
 "height" "24"
: Falls back to crosshair if not defined.
; zoom / iconZoomedCrosshair
: Used while zoomed in with the scope on the ; 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.
 装备武器后武器在武器槽显示的图标，但是并没有选取该武器。
 默认参数格式是：
 "file" ""//武器的图标文件目录
 "x" "坐标数字"//武器图标文件图片的X坐标
 "y" "坐标数字"//武器图标文件图片的Y坐标
 "width" "坐标数字"//图标宽度
 "height" "坐标数字"//图标高度
; 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.一个提供额外图标的参数，覆盖于武器图标顶部，选择时的发光特效。
 默认参数格式是：
 "font" "名字"
 "character" ""
; weapon_small / iconSmall
: Used for a variant of the standard weapon font class that is half the size of the original.百度翻译：用于标准武器字体类的变体，其大小是原始字体的一半。
; ammo / iconAmmo
: 主要弹药的图标，一般是在子弹数量前或者后。（一般是一枚子弹的图片作为图标）
 可用参数格式是：
 "file" ""//武器的图标文件目录
 "x" "坐标数字"//武器图标文件图片的X坐标
 "y" "坐标数字"//武器图标文件图片的Y坐标
 "width" "坐标数字"//图标宽度
 "height" "坐标数字"//图标高度
; ammo2 / iconAmmo2
: 次要弹药的图标，例如半条命2的smg冲锋枪的悬挂榴弹炮。
 可用参数格式同上ammo。
=== 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>
 存在于 clientscheme.res 文件内。
: The name of a font class defined in the clientscheme.res file. In Half-Life 2, they are usually a variation of the name WeaponIcons for weapon glyphs.
: The font class name entry in clientsceheme.res is case-insensitive, and as such, using WeaponIcons or weaponicons 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.图片的X坐标。
; y <integer>
: The longitudinal (Y-axis) position of the desired glyph on the sprite sheet.图片的Y坐标。PS：通过图片的XY坐标作为顶点。
; width <integer>
: How wide to render the selected area of the sheet, in pixels.然后以图片XY坐标作为顶点向右延伸的宽度
; 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:半条命2的SMG冲锋枪的武器脚本的texturedata参数。
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 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 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 use):
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 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 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.
Category:Weapons programming