Zh/Magazine style reloads

这个教程将会很短且很简单
假设你想每次发射子弹后重新装填都要重新计数? 在反恐精英中你可以随时重新装填你的弹夹.只是从备弹中减去你使用的子弹数量仅此而已。然而在现实生活中你一般不会在弹夹打了一半的情况下换弹，你会把旧的弹夹扔掉换上一个新的，这种装填系统在战地2或其他类似游戏中都能看到。
== 创建布尔类型变量 ==
现在我们看一下代码，打开 basecombatweapon_shared.h 搜索 "m_bFiresUnderwater" (115行) 找到这行代码：
 CNetworkVar( int, m_iClip2 );	// number of shots left in the secondary weapon clip, -1 it not used
 bool	m_bFiresUnderwater;	// true if this weapon can fire underwater
在这两行代码之间添加一个布尔类型变量 m_bMagazineStyleReloads：
 CNetworkVar( int, m_iClip2 );		// number of shots left in the secondary weapon clip, -1 it not used
 bool	m_bMagazineStyleReloads;	// true if this weapon reloads by removing magazines (remaining bullets)
 bool	m_bFiresUnderwater;		// true if this weapon can fire underwater
现在打开 basecombatweapon_shared.cpp 搜索 "m_bFiresUnderwater" (在2253行和2300行):
 DEFINE_FIELD( m_bFiresUnderwater, FIELD_BOOLEAN ),
需要像下面这样定义它：
 DEFINE_FIELD( m_bMagazineStyleReloads, FIELD_BOOLEAN ),
 DEFINE_FIELD( m_bFiresUnderwater, FIELD_BOOLEAN ),
变量设置好了，找到构造函数CBaseCombatWeapon (54行)如下代码:
 m_bReloadsSingly	= false;
根据你的需要, 你可以设置默认弹夹装填方式是否启用:
 m_bReloadsSingly		= false;
 m_bMagazineStyleReloads	= false;
== 主体代码 ==
我们来看主体代码.找到 FinishReload 函数(1986行)：
 if ( UsesClipsForAmmo1() )
 {
 	int primary = min( GetMaxClip1() - m_iClip1, pOwner->GetAmmoCount(m_iPrimaryAmmoType));	
 	m_iClip1 += primary;
 	pOwner->RemoveAmmo( primary, m_iPrimaryAmmoType);
 }
像这样更改最后两行:
 if ( UsesClipsForAmmo1() )
 {
 	int primary = min( GetMaxClip1() - m_iClip1, pOwner->GetAmmoCount(m_iPrimaryAmmoType));	
 	m_iClip1 += primary;
 pOwner->RemoveAmmo( m_bMagazineStyleReloads ? min(pOwner->GetAmmoCount(m_iPrimaryAmmoType,GetMaxClip1()) : primary, m_iPrimaryAmmoType);
 }
如果开启了这种弹夹装填方式整个流程会像这样：你把弹夹装填完成，然后在子弹总数上减去了整个弹夹子弹的数量。
要显示弹匣的数量，您只需要将弹药的总量除以完整的弹夹大小并四舍五入即可。
Note: this technique "hacks" a magazine style reload instead of creating a native implementation, thus the player can still receive individual bullets.
== Covering Your Ass ==
Ever noticed, that the game auto-reloads your gun if you holster it? This is not good, especially the way this code is implemented; to remove this go to weapon_hl2mpbasehlmpcombatweapon.cpp or basehlcombatweapon_shared.cpp and find the ItemHolsterFrame procedure. Comment out the 
 		FinishReload();
== An Example ==
Now an example to turn on magazine style reloads for any weapon:
 CWeaponPistol::CWeaponPistol( void )
 {
 	m_flSoonestPrimaryAttack = gpGlobals->curtime;
 	m_flAccuracyPenalty = 0.0f;
 
 	m_fMinRange1		= 24;
 	m_fMaxRange1		= 1500;
 	m_fMinRange2		= 24;
 	m_fMaxRange2		= 200;
 
 	m_bMagazineStyleReloads = true; // Magazine style reloads
 	m_bFiresUnderwater	= true;
 }
== Extension ==
If you want to only lose 1 of your total ammo instead of the real amount, change:
 m_iClip1 = m_bMagazineStyleReloads ? GetMaxClip1() : m_iClip1 + primary;
 pOwner->RemoveAmmo( m_bMagazineStyleReloads ? GetMaxClip1() : primary, m_iPrimaryAmmoType);
to:
 m_iClip1 = m_bMagazineStyleReloads ? GetMaxClip1() : m_iClip1 + primary;
 pOwner->RemoveAmmo( m_bMagazineStyleReloads ? 1 : primary, m_iPrimaryAmmoType);
== The Actual Code (FIX) ==
If you use the code above then it will work perfectly except...
If you have a full clip that looks like this (12:6)
And then you shoot to (3:6)
And then you reload it becomes (12:0)
It gives you a full clip back instead of the partially full clip you found.
 if ( UsesClipsForAmmo1() )
 {
 	int primary = min( GetMaxClip1() - m_iClip1, pOwner->GetAmmoCount(m_iPrimaryAmmoType));	
 	if( pOwner->GetAmmoCount(m_iPrimaryAmmoType) >= GetMaxClip1() ){
 		m_iClip1 = m_bMagazineStyleReloads ? GetMaxClip1() : m_iClip1 + primary;
 		pOwner->RemoveAmmo( m_bMagazineStyleReloads ? GetMaxClip1() : primary, m_iPrimaryAmmoType);
 	}else{
 		m_iClip1 = pOwner->GetAmmoCount(m_iPrimaryAmmoType);
 		pOwner->RemoveAmmo( GetMaxClip1(), m_iPrimaryAmmoType);
 	}
 }