void CWeaponRPCs::TakeWeapon ( NetBitStreamInterface& bitStream ) { // Read out weapon id and ammo amount ElementID ID; SWeaponTypeSync weaponType; if ( bitStream.ReadCompressed ( ID ) && bitStream.Read ( &weaponType ) ) { unsigned char ucWeaponID = weaponType.data.ucWeaponType; CClientPed * pPed = m_pPedManager->Get ( ID, true ); if ( pPed ) { // Don't change remote players weapons (affects sync) if ( pPed->GetType () == CCLIENTPED || ( CClientPlayer * ) pPed == m_pPlayerManager->GetLocalPlayer () ) { // Is the weapon id valid? (may not be neccessary, just being safe) if ( CClientPickupManager::IsValidWeaponID ( ucWeaponID ) ) { // Remove the weapon pPed->RemoveWeapon ( static_cast < eWeaponType > ( ucWeaponID ) ); } } } } }
void CWeaponRPCs::TakeWeapon ( CClientEntity* pSource, NetBitStreamInterface& bitStream ) { // Read out weapon id and ammo amount SWeaponTypeSync weaponType; if ( bitStream.Read ( &weaponType ) ) { unsigned char ucWeaponID = weaponType.data.ucWeaponType; CClientPed * pPed = m_pPedManager->Get ( pSource->GetID (), true ); if ( pPed ) { // Is the weapon id valid? (may not be neccessary, just being safe) if ( CClientPickupManager::IsValidWeaponID ( ucWeaponID ) ) { // Have we ammo in packet? If so, we need to take the ammo, not weapon SWeaponAmmoSync ammo ( ucWeaponID, true, false ); if ( bitStream.Read ( &ammo ) ) { unsigned short usAmmo = ammo.data.usTotalAmmo; // Do we have the weapon? CWeapon* pPlayerWeapon = pPed->GetWeapon ( (eWeaponType) ucWeaponID ); if ( pPlayerWeapon == NULL ) return; unsigned char ucAmmoInClip = static_cast < unsigned char > ( pPlayerWeapon->GetAmmoInClip () ); pPlayerWeapon->SetAmmoInClip ( 0 ); unsigned long ulWeaponAmmo = pPlayerWeapon->GetAmmoTotal (); if ( usAmmo > ulWeaponAmmo ) ulWeaponAmmo = 0; else ulWeaponAmmo -= usAmmo; // Update the ammo pPlayerWeapon->SetAmmoTotal ( ulWeaponAmmo ); if ( pPlayerWeapon->GetAmmoTotal () > ucAmmoInClip ) pPlayerWeapon->SetAmmoInClip ( ucAmmoInClip ); else if ( pPlayerWeapon->GetAmmoTotal () <= ucAmmoInClip ) pPlayerWeapon->SetAmmoInClip ( pPlayerWeapon->GetAmmoTotal () ); } else { // Don't change remote players weapons (affects sync) if ( pPed->IsLocalPlayer () ) { // Remove the weapon pPed->RemoveWeapon ( static_cast < eWeaponType > ( ucWeaponID ) ); } } } } } }
void CWeaponRPCs::GiveWeapon ( NetBitStreamInterface& bitStream ) { // Read out weapon id and ammo amount ElementID ID; SWeaponTypeSync weaponType; if ( bitStream.ReadCompressed ( ID ) && bitStream.Read ( &weaponType ) ) { SWeaponAmmoSync ammo ( weaponType.data.ucWeaponType, true, false ); if ( bitStream.Read ( &ammo ) ) { bool bGiveWeapon = bitStream.ReadBit (); unsigned char ucWeaponID = weaponType.data.ucWeaponType; unsigned short usAmmo = ammo.data.usTotalAmmo; CClientPed * pPed = m_pPedManager->Get ( ID, true ); if ( pPed ) { // Don't change remote players weapons (affects sync) if ( pPed->GetType () == CCLIENTPED || pPed->GetType () == CCLIENTPLAYER ) { // Valid weapon id? if ( ucWeaponID == 0 || CClientPickupManager::IsValidWeaponID ( ucWeaponID ) ) { // Adjust the ammo to 9999 if it's above if ( usAmmo > 9999 ) usAmmo = 9999; // Give the local player the weapon CWeapon* pPlayerWeapon = NULL; if ( ucWeaponID != 0 ) { pPlayerWeapon = pPed->GiveWeapon ( static_cast < eWeaponType > ( ucWeaponID ), usAmmo ); if ( pPlayerWeapon && bGiveWeapon ) pPlayerWeapon->SetAsCurrentWeapon (); } else { // This could be entered into a hack of the year competition. Its about as hacky as it gets. // For some stupid reason, going from brassknuckles to unarmed causes the knuckles to remain // on display but unusable. So, what we do is switch to a MELEE weapon (creating one if necessary) // then switch back to unarmed from there, which works fine. CWeapon* oldWeapon = pPed->GetWeapon (WEAPONSLOT_TYPE_UNARMED); if ( oldWeapon ) { eWeaponType unarmedWeapon = oldWeapon->GetType(); pPed->RemoveWeapon ( unarmedWeapon ); if ( bGiveWeapon || pPed->GetCurrentWeaponSlot() == WEAPONSLOT_TYPE_UNARMED ) { oldWeapon = NULL; if ( unarmedWeapon == WEAPONTYPE_BRASSKNUCKLE ) { oldWeapon = pPed->GetWeapon(WEAPONSLOT_TYPE_MELEE); if ( oldWeapon && oldWeapon->GetType() == WEAPONTYPE_UNARMED ) { oldWeapon = pPed->GiveWeapon(WEAPONTYPE_GOLFCLUB, 100); } else { oldWeapon = NULL; } pPed->SetCurrentWeaponSlot ( WEAPONSLOT_TYPE_MELEE ); } // switch to the unarmed slot pPed->SetCurrentWeaponSlot ( WEAPONSLOT_TYPE_UNARMED ); // if we created a special MELEE weapon just for this, remove it now if ( oldWeapon ) { oldWeapon->Remove(); } } } else { // Probably the ped is streamed out pPed->GiveWeapon ( WEAPONTYPE_UNARMED, 1 ); if ( bGiveWeapon ) pPed->SetCurrentWeaponSlot ( WEAPONSLOT_TYPE_UNARMED ); } } } } } } } }