Difference between revisions of "Magazine style reloads:zh-cn"

From Valve Developer Community
Jump to: navigation, search
(Created page with "This will be a short and simple one! Say you want to make each shot and each reload count? In CS you can reload anytime you feel like. Some bullets will be deducted and that i...")
 
(The Actual Code)
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
This will be a short and simple one!
+
{{otherlang2
Say you want to make each shot and each reload count? In CS you can reload anytime you feel like. Some bullets will be deducted and that is all. However, in real life, you will not start to load the half-empty mag, you pull out a new one, and toss the used one. This system can be found in BF2, and some other games.
+
|title=弹夹装填风格
 +
|en=Magazine_style_reloads
 +
}}
 +
这个教程将会很短且很简单
 +
假设你想每次发射子弹后重新装填都要重新计数? 在反恐精英中你可以随时重新装填你的弹夹.只是从备弹中减去你使用的子弹数量仅此而已。然而在现实生活中你一般不会在弹夹打了一半的情况下换弹,你会把旧的弹夹扔掉换上一个新的,这种装填系统在战地2或其他类似游戏中都能看到。
  
== Creating a Boolean Variable ==
+
== 创建布尔类型变量 ==
  
So now to the code; look up the '''basecombatweapon_shared.h''' and search for "m_bFiresUnderwater" (line 115) to find this code:
+
现在我们看一下代码,打开 '''basecombatweapon_shared.h''' 搜索 "m_bFiresUnderwater" (115行) 找到这行代码:
 
  CNetworkVar( int, m_iClip2 ); // number of shots left in the secondary weapon clip, -1 it not used
 
  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
 
  bool m_bFiresUnderwater; // true if this weapon can fire underwater
  
In-between these two lines you create a variable:
+
在这两行代码之间添加一个布尔类型变量 m_bMagazineStyleReloads:
 
  CNetworkVar( int, m_iClip2 ); // number of shots left in the secondary weapon clip, -1 it not used
 
  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_bMagazineStyleReloads; // true if this weapon reloads by removing magazines (remaining bullets)'''
Line 14: Line 18:
  
  
Now go to '''basecombatweapon_shared.cpp''' and search to "m_bFiresUnderwater" (lines 2253 and 2300):
+
现在打开 '''basecombatweapon_shared.cpp''' 搜索 "m_bFiresUnderwater" (在2253行和2300行):
 
  DEFINE_FIELD( m_bFiresUnderwater, FIELD_BOOLEAN ),
 
  DEFINE_FIELD( m_bFiresUnderwater, FIELD_BOOLEAN ),
  
Once again you need to define it like so:
+
需要像下面这样定义它:
 
  '''DEFINE_FIELD( m_bMagazineStyleReloads, FIELD_BOOLEAN ),'''
 
  '''DEFINE_FIELD( m_bMagazineStyleReloads, FIELD_BOOLEAN ),'''
 
  DEFINE_FIELD( m_bFiresUnderwater, FIELD_BOOLEAN ),
 
  DEFINE_FIELD( m_bFiresUnderwater, FIELD_BOOLEAN ),
  
  
Now that you have the variable set up, look into the CBaseCombatWeapon constructor (line 54) where:
+
变量设置好了,找到构造函数CBaseCombatWeapon (54行)如下代码:
 
  m_bReloadsSingly = false;
 
  m_bReloadsSingly = false;
  
And depending on what you want, you either default magazine style reloads to be on or off:
+
根据你的需要, 你可以设置默认弹夹装填方式是否启用:
 
  m_bReloadsSingly = false;
 
  m_bReloadsSingly = false;
 
  '''m_bMagazineStyleReloads = false;'''
 
  '''m_bMagazineStyleReloads = false;'''
  
== The Actual Code ==
+
== 主体代码 ==
  
Now here's the main part of the code. Look at the ''FinishReload'' procedure (line 1986) and you will find:
+
我们来看主体代码.找到 ''FinishReload'' 函数(1986行)
 
  if ( UsesClipsForAmmo1() )
 
  if ( UsesClipsForAmmo1() )
 
  {
 
  {
Line 39: Line 43:
 
  }
 
  }
  
Change the last two lines to look like this:
+
像这样更改最后两行:
 
  if ( UsesClipsForAmmo1() )
 
  if ( UsesClipsForAmmo1() )
 
  {
 
  {
Line 47: Line 51:
 
  }
 
  }
  
All that has happened is that if the flag is turned on: you make the clip full again, and remove a whole clip out from the total ammo count.
+
如果开启了这种弹夹装填方式整个流程会像这样:你把弹夹装填完成,然后在子弹总数上减去了整个弹夹子弹的数量。
To display the amount of magazines you just have to divide the total amount of ammo by a full clip size and round up.
+
要显示弹匣的数量,您只需要将弹药的总量除以完整的弹夹大小并四舍五入即可。
  
 
''Note: this technique "hacks" a magazine style reload instead of creating a native implementation, thus the player can still receive individual bullets.''
 
''Note: this technique "hacks" a magazine style reload instead of creating a native implementation, thus the player can still receive individual bullets.''

Latest revision as of 03:02, 13 October 2019

English

这个教程将会很短且很简单 假设你想每次发射子弹后重新装填都要重新计数? 在反恐精英中你可以随时重新装填你的弹夹.只是从备弹中减去你使用的子弹数量仅此而已。然而在现实生活中你一般不会在弹夹打了一半的情况下换弹,你会把旧的弹夹扔掉换上一个新的,这种装填系统在战地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);
	}
}