Waffen fallen lassen
Dieses Tutorial erklärt, wie man Waffen fallen lassen kann. Die gleiche Funktion kann man auch in Counter-Strike und Day of Defeat sehen.
Inhaltsverzeichnis |
Anleitung
server/hl2/hl2_player.cpp
Suche nach
ConVar xc_use_crouch_limiter( "xc_use_crouch_limiter", "0", FCVAR_ARCHIVE, "Use the crouch limiting logic on the controller" );
und füge danach folgenden Code ein
void CC_Player_Drop( void )
{
CBasePlayer *pPlayer = NULL;
pPlayer = ToBasePlayer( UTIL_GetCommandClient() );
if( !pPlayer )
return;
CBaseCombatWeapon *pPlayerItem = NULL;
pPlayerItem = pPlayer->GetActiveWeapon();
if( pPlayerItem )
pPlayer->Weapon_Drop( pPlayerItem, NULL, NULL);
}
static ConCommand drop("drop", CC_Player_Drop, "Drop Player Item.");
Dadurch fügen wir der Modifikation einen neuen Konsolenbefehl hinzu, der die Funktion weapon_drop aufruft.
server/player.cpp
Suche nach
if ( !IsAllowedToPickupWeapons() ) return false;
und füge danach folgenden Code ein
for ( int i = 0; i < WeaponCount(); i++ )
{
CBaseCombatWeapon *pSearch = GetWeapon( i );
if ( pSearch && pSearch->GetSlot() == pWeapon->GetSlot() && pSearch->GetPosition() == pWeapon->GetPosition() )
{
if( Weapon_EquipAmmoOnly( pWeapon ) )
{
if ( pWeapon->HasPrimaryAmmo() )
return false;
return true;
}
else
{
return false;
}
}
}
Sobald man über eine, am Boden liegende, Waffe läuft, wird geprüft ob der entsprechende Waffenslot frei ist.
Suche nach
if ( pWeapon->UsesClipsForAmmo1() )
{
pWeapon->m_iClip1 = pWeapon->GetMaxClip1();
}
und kommentiere es aus.
server/basecombatcharacter.cpp
Suche nach
if (pWeapon->GetMaxClip1() == -1)
{
#ifdef HL2_DLL
if( FStrEq(STRING(gpGlobals->mapname), "d3_c17_09") && FClassnameIs(pWeapon, "weapon_rpg") && pWeapon->NameMatches("player_spawn_items") )
{
// !!!HACK - Don't give any ammo with the spawn equipment RPG in d3_c17_09. This is a chapter
// start and the map is way to easy if you start with 3 RPG rounds. It's fine if a player conserves
// them and uses them here, but it's not OK to start with enough ammo to bypass the snipers completely.
GiveAmmo( 0, pWeapon->m_iPrimaryAmmoType);
}
else
#endif // HL2_DLL
GiveAmmo(pWeapon->GetDefaultClip1(), pWeapon->m_iPrimaryAmmoType);
}
// If default ammo given is greater than clip
// size, fill clips and give extra ammo
else if (pWeapon->GetDefaultClip1() > pWeapon->GetMaxClip1() )
{
pWeapon->m_iClip1 = pWeapon->GetMaxClip1();
GiveAmmo( (pWeapon->GetDefaultClip1() - pWeapon->GetMaxClip1()), pWeapon->m_iPrimaryAmmoType);
}
und
if (pWeapon->GetMaxClip2() == -1)
{
GiveAmmo(pWeapon->GetDefaultClip2(), pWeapon->m_iSecondaryAmmoType);
}
// If default ammo given is greater than clip
// size, fill clips and give extra ammo
else if ( pWeapon->GetDefaultClip2() > pWeapon->GetMaxClip2() )
{
pWeapon->m_iClip2 = pWeapon->GetMaxClip2();
GiveAmmo( (pWeapon->GetDefaultClip2() - pWeapon->GetMaxClip2()), pWeapon->m_iSecondaryAmmoType);
}
und kommentiere beides aus.
Suche nach
if ( pWeapon->UsesClipsForAmmo1() )
{
pWeapon->m_iClip1 = pWeapon->GetDefaultClip1();
if( FClassnameIs( pWeapon, "weapon_smg1" ) )
{
// Drop enough ammo to kill 2 of me.
// Figure out how much damage one piece of this type of ammo does to this type of enemy.
float flAmmoDamage = g_pGameRules->GetAmmoDamage( UTIL_PlayerByIndex(1), this, pWeapon->GetPrimaryAmmoType() );
pWeapon->m_iClip1 = (GetMaxHealth() / flAmmoDamage) * 2;
}
}
if ( pWeapon->UsesClipsForAmmo2() )
{
pWeapon->m_iClip2 = pWeapon->GetDefaultClip2();
}
und kommentiere es ebenfalls aus.
Erklärung
Im ersten Teil erstellen wir einen neuen Konsolenbefehl, der die Funktion Weapon_Drop aufruft. Diese Funktion bewirtk, dass die aktuelle Waffe aus dem Inventar des Spieler entfernt und in ein Entity umgewandelt wird.
Danach müssen wir sicherstellen, dass keine Waffen aufgenommen werden können, die an Slots gehören, die bereits besetzt sind.
Als letztes verhindern wir noch, dass die Waffe beim Aufheben, mit der Standardmunition geladen wird. D.h. wenn man eine leere Waffe wegwirft und wieder aufhebt, wird sie wieder voll geladen. Mit den hier gezeigten Änderungen bleibt sie hingegen leer.