Weapon Limits: Difference between revisions
(→Step 2: Restrict more weapon types: added more explaination) |
Thunder4ik (talk | contribs) m (clean up, added orphan tag) |
||
(4 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
{{Orphan|date=January 2024}} | |||
This tutorial is for restricting the weapons players can carry at once, a little like the Bioshock series. | This tutorial is for restricting the weapons players can carry at once, a little like the Bioshock series. | ||
=== Prerequisits === | === Prerequisits === | ||
This tutorial was made in | This tutorial was made in {{Src13sp|4}} branch. Different branches may require different coding. | ||
== Step 1: Enable built-in weapon limit == | == Step 1: Enable built-in weapon limit == | ||
In hl2_player.cpp, you should see this line of code around line 74: | In hl2_player.cpp, you should see this line of code around line 74: | ||
< | <source lang=cpp> | ||
// This switches between the single primary weapon, and multiple weapons with buckets approach (jdw) | // This switches between the single primary weapon, and multiple weapons with buckets approach (jdw) | ||
#define HL2_SINGLE_PRIMARY_WEAPON_MODE 0; | #define HL2_SINGLE_PRIMARY_WEAPON_MODE 0; | ||
</ | </source> | ||
Change the 0 to a 1 to enable this mode. | Change the 0 to a 1 to enable this mode. | ||
What this does is enable some code that restricts you to only being able to pick up one primary weapon. | What this does is enable some code that restricts you to only being able to pick up one primary weapon. | ||
This code includes: | This code includes: | ||
< | <source lang=cpp> | ||
void CHL2_Player::Weapon_Equip( CBaseCombatWeapon *pWeapon ) | void CHL2_Player::Weapon_Equip( CBaseCombatWeapon *pWeapon ) | ||
{ | { | ||
Line 19: | Line 22: | ||
Weapon_DropSlot(WEAPON_PRIMARY_SLOT); | Weapon_DropSlot(WEAPON_PRIMARY_SLOT); | ||
} | } | ||
</ | </source> | ||
< | <source lang=cpp> | ||
bool CHL2_Player::BumpWeapon( CBaseCombatWeapon *pWeapon ) | bool CHL2_Player::BumpWeapon( CBaseCombatWeapon *pWeapon ) | ||
{ | { | ||
CBaseCombatCharacter *pOwner = pWeapon->GetOwner(); | CBaseCombatCharacter *pOwner = pWeapon->GetOwner(); | ||
Line 90: | Line 92: | ||
return true; | return true; | ||
} | } | ||
</ | </source> | ||
bool CHL2_Player::ClientCommand( const CCommand &args ) | bool CHL2_Player::ClientCommand( const CCommand &args ) | ||
< | <source lang=cpp> | ||
//Drop primary weapon | //Drop primary weapon | ||
if ( !Q_stricmp( args[0], "DropPrimary" ) ) | if ( !Q_stricmp( args[0], "DropPrimary" ) ) | ||
Line 99: | Line 101: | ||
return true; | return true; | ||
} | } | ||
</ | </source> | ||
void CHL2_Player::PlayerUse ( void ) | void CHL2_Player::PlayerUse ( void ) | ||
< | <source lang=cpp> | ||
//Check for weapon pick-up | //Check for weapon pick-up | ||
if ( m_afButtonPressed & IN_USE ) | if ( m_afButtonPressed & IN_USE ) | ||
Line 123: | Line 125: | ||
} | } | ||
} | } | ||
</ | </source> | ||
== Step 2: Restrict more weapon types == | == Step 2: Restrict more weapon types == | ||
Weapon types are defined by the slot they are in, as shown in hl2_player.h around line 48: | Weapon types are defined by the slot they are in, as shown in hl2_player.h around line 48: | ||
< | <source lang=cpp> | ||
//---------------------------------------------------- | //---------------------------------------------------- | ||
// Definitions for weapon slots | // Definitions for weapon slots | ||
Line 135: | Line 137: | ||
#define WEAPON_EXPLOSIVE_SLOT 3 | #define WEAPON_EXPLOSIVE_SLOT 3 | ||
#define WEAPON_TOOL_SLOT 4 | #define WEAPON_TOOL_SLOT 4 | ||
</ | </source> | ||
This means that weapons not in the 2nd (shown in-game as the 3rd) slot will not be restricted. | This means that weapons not in the 2nd (shown in-game as the 3rd) slot will not be restricted. | ||
Let's change that. | Let's change that. | ||
Line 162: | Line 164: | ||
=== Second method: Add the weapon's slot to the... greylist. === | === Second method: Add the weapon's slot to the... greylist. === | ||
To do this, find this again in hl2_player.cpp: | To do this, find this again in hl2_player.cpp: | ||
< | <source lang=cpp> | ||
void CHL2_Player::Weapon_Equip( CBaseCombatWeapon *pWeapon ) | void CHL2_Player::Weapon_Equip( CBaseCombatWeapon *pWeapon ) | ||
{ | { | ||
Line 171: | Line 173: | ||
} | } | ||
#endif | #endif | ||
</ | </source> | ||
Now add this above or below the WEAPON_PRIMARY_SLOT statement: | Now add this above or below the WEAPON_PRIMARY_SLOT statement: | ||
< | <source lang=cpp> | ||
if ( pWeapon->GetSlot() == WEAPON_X_SLOT) | if ( pWeapon->GetSlot() == WEAPON_X_SLOT) | ||
{ | { | ||
Weapon_DropSlot(WEAPON_X_SLOT); | Weapon_DropSlot(WEAPON_X_SLOT); | ||
} | } | ||
</ | </source> | ||
Replace X with whatever slot you want: | Replace X with whatever slot you want: | ||
Line 192: | Line 194: | ||
Now you can only pick up one of the weapons in that slot. Trying to pick up another weapon in that slot will drop your current one and pick up the new one. | Now you can only pick up one of the weapons in that slot. Trying to pick up another weapon in that slot will drop your current one and pick up the new one. | ||
[[Category:Weapons programming]] | [[Category:Weapons programming]] | ||
[[Category:Tutorials]] | [[Category:Tutorials]] |
Latest revision as of 22:58, 21 January 2024

You can help by

January 2024
This tutorial is for restricting the weapons players can carry at once, a little like the Bioshock series.
Prerequisits
This tutorial was made in Source 2013 Singleplayer branch. Different branches may require different coding.
Step 1: Enable built-in weapon limit
In hl2_player.cpp, you should see this line of code around line 74:
// This switches between the single primary weapon, and multiple weapons with buckets approach (jdw)
#define HL2_SINGLE_PRIMARY_WEAPON_MODE 0;
Change the 0 to a 1 to enable this mode.
What this does is enable some code that restricts you to only being able to pick up one primary weapon. This code includes:
void CHL2_Player::Weapon_Equip( CBaseCombatWeapon *pWeapon )
{
if ( pWeapon->GetSlot() == WEAPON_PRIMARY_SLOT)
{
Weapon_DropSlot(WEAPON_PRIMARY_SLOT);
}
bool CHL2_Player::BumpWeapon( CBaseCombatWeapon *pWeapon )
{
CBaseCombatCharacter *pOwner = pWeapon->GetOwner();
// Can I have this weapon type?
if ( pOwner || !Weapon_CanUse( pWeapon ) || !g_pGameRules->CanHavePlayerItem( this, pWeapon ) )
{
if ( gEvilImpulse101 )
{
UTIL_Remove( pWeapon );
}
return false;
}
// ----------------------------------------
// If I already have it just take the ammo
// ----------------------------------------
if (Weapon_OwnsThisType( pWeapon->GetClassname(), pWeapon->GetSubType()))
{
//Only remove the weapon if we attained ammo from it
if ( Weapon_EquipAmmoOnly( pWeapon ) == false )
return false;
// Only remove me if I have no ammo left
// Can't just check HasAnyAmmo because if I don't use clips, I want to be removed,
if ( pWeapon->UsesClipsForAmmo1() && pWeapon->HasPrimaryAmmo() )
return false;
UTIL_Remove( pWeapon );
return false;
}
// -------------------------
// Otherwise take the weapon
// -------------------------
else
{
//Make sure we're not trying to take a new weapon type we already have
if ( Weapon_SlotOccupied( pWeapon ) )
{
CBaseCombatWeapon *pActiveWeapon = Weapon_GetSlot( WEAPON_PRIMARY_SLOT );
if ( pActiveWeapon != NULL && pActiveWeapon->HasAnyAmmo() == false && Weapon_CanSwitchTo( pWeapon ) )
{
Weapon_Equip( pWeapon );
return true;
}
//Attempt to take ammo if this is the gun we're holding already
if ( Weapon_OwnsThisType( pWeapon->GetClassname(), pWeapon->GetSubType() ) )
{
Weapon_EquipAmmoOnly( pWeapon );
}
return false;
}
pWeapon->CheckRespawn();
pWeapon->AddSolidFlags( FSOLID_NOT_SOLID );
pWeapon->AddEffects( EF_NODRAW );
Weapon_Equip( pWeapon );
EmitSound( "HL2Player.PickupWeapon" );
return true;
}
bool CHL2_Player::ClientCommand( const CCommand &args )
//Drop primary weapon
if ( !Q_stricmp( args[0], "DropPrimary" ) )
{
Weapon_DropSlot( WEAPON_PRIMARY_SLOT );
return true;
}
void CHL2_Player::PlayerUse ( void )
//Check for weapon pick-up
if ( m_afButtonPressed & IN_USE )
{
CBaseCombatWeapon *pWeapon = dynamic_cast<CBaseCombatWeapon *>(pUseEntity);
if ( ( pWeapon != NULL ) && ( Weapon_CanSwitchTo( pWeapon ) ) )
{
//Try to take ammo or swap the weapon
if ( Weapon_OwnsThisType( pWeapon->GetClassname(), pWeapon->GetSubType() ) )
{
Weapon_EquipAmmoOnly( pWeapon );
}
else
{
Weapon_DropSlot( pWeapon->GetSlot() );
Weapon_Equip( pWeapon );
}
usedSomething = true;
}
}
Step 2: Restrict more weapon types
Weapon types are defined by the slot they are in, as shown in hl2_player.h around line 48:
//----------------------------------------------------
// Definitions for weapon slots
//----------------------------------------------------
#define WEAPON_MELEE_SLOT 0
#define WEAPON_SECONDARY_SLOT 1
#define WEAPON_PRIMARY_SLOT 2
#define WEAPON_EXPLOSIVE_SLOT 3
#define WEAPON_TOOL_SLOT 4
This means that weapons not in the 2nd (shown in-game as the 3rd) slot will not be restricted. Let's change that.
First method: Change the weapons' slots
Go to your mod's script folder and scroll down until you see the weapon_X.txt files. For example, let's look in the weapon_shotgun.txt file:
// Shotgun WeaponData { // Weapon data is loaded by both the Game and Client DLLs. "printname" "#HL2_Shotgun" "viewmodel" "models/weapons/v_shotgun.mdl" "playermodel" "models/weapons/w_shotgun.mdl" "anim_prefix" "shotgun" "bucket" "3" "bucket_position" "0" "bucket_360" "1" "bucket_position_360" "1"
The "bucket" number is what we want. This is the slot on the X axis the gun is on the weapon selection UI and what determines what type of weapon it is. Change the "bucket" number to "2" to make it a "Primary" weapon. Now, when you try to pick up that weapon in-game, you'll have to drop your current primary weapon to pick up that one. It's also a good idea to change the "bucket_position" tag to 0 too so that there isn't any unnecessary space in the weapon selection UI.
Second method: Add the weapon's slot to the... greylist.
To do this, find this again in hl2_player.cpp:
void CHL2_Player::Weapon_Equip( CBaseCombatWeapon *pWeapon )
{
#if HL2_SINGLE_PRIMARY_WEAPON_MODE
if ( pWeapon->GetSlot() == WEAPON_PRIMARY_SLOT)
{
Weapon_DropSlot(WEAPON_PRIMARY_SLOT);
}
#endif
Now add this above or below the WEAPON_PRIMARY_SLOT statement:
if ( pWeapon->GetSlot() == WEAPON_X_SLOT)
{
Weapon_DropSlot(WEAPON_X_SLOT);
}
Replace X with whatever slot you want:
0 in-code/1 in-game = MELEE (crowbar)
1/2 = SECONDARY (pistol)
2/3 = PRIMARY (smg & pulse gun) [this is already included in the code so you don't have to include it again]
3/4 = EXPLOSIVE (grenades)
4/5 = TOOL (bugbait)
Now you can only pick up one of the weapons in that slot. Trying to pick up another weapon in that slot will drop your current one and pick up the new one.