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 CClientPedManager::RestreamWeapon ( unsigned short usModel ) { eWeaponSlot eSlot = (eWeaponSlot) GetWeaponSlotFromModel ( usModel ); // Store the affected vehicles CClientPed* pPed; std::vector < CClientPed* > ::const_iterator iter = IterBegin (); for ( ; iter != IterEnd (); iter++ ) { pPed = *iter; // Streamed in and same vehicle ID? if ( pPed->IsStreamedIn () && pPed->GetWeapon ( eSlot ) && pPed->GetWeapon ( eSlot )->GetInfo ( WEAPONSKILL_STD )->GetModel () == usModel ) { // Awesome hack skills + 1, change him to another model while we unload for the lulz // Translation: My hack level has increased to ninety nine and we need to wait a frame before reloading the model ID in question so that the custom model unloads properly. // To do this we take away the weapon and give it back in CPed::StreamedInPulse ergo reloading the model info pPed->StreamOutWeaponForABit ( eSlot ); } } }
void CWeaponRPCs::TakeWeaponAmmo ( NetBitStreamInterface& bitStream ) { ElementID ID; SWeaponTypeSync weaponType; if ( bitStream.ReadCompressed ( ID ) && bitStream.Read ( &weaponType ) ) { unsigned char ucWeaponID = weaponType.data.ucWeaponType; SWeaponAmmoSync ammo ( ucWeaponID, true, false ); if ( bitStream.Read ( &ammo ) ) { unsigned short usAmmo = ammo.data.usTotalAmmo; CClientPed * pPed = m_pPedManager->Get ( ID, true ); if ( pPed ) { // Valid weapon id? if ( !CClientPickupManager::IsValidWeaponID ( ucWeaponID ) ) return; // Do we have it? 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 ( ulWeaponAmmo - usAmmo < 0 ) ulWeaponAmmo = 0; else ulWeaponAmmo -= usAmmo; // Remove the weapon ammo pPlayerWeapon->SetAmmoTotal ( ulWeaponAmmo ); if ( pPlayerWeapon->GetAmmoTotal () > ucAmmoInClip ) pPlayerWeapon->SetAmmoInClip ( ucAmmoInClip ); else if ( pPlayerWeapon->GetAmmoTotal () <= ucAmmoInClip ) pPlayerWeapon->SetAmmoInClip ( pPlayerWeapon->GetAmmoTotal () ); } } } }
void CWeaponRPCs::SetWeaponAmmo ( CClientEntity* pSource, NetBitStreamInterface& bitStream ) { SWeaponTypeSync weaponType; if ( bitStream.Read ( &weaponType ) ) { unsigned char ucWeaponID = weaponType.data.ucWeaponType; SWeaponAmmoSync ammo ( ucWeaponID, true, true ); if ( bitStream.Read ( &ammo ) ) { unsigned short usAmmo = ammo.data.usTotalAmmo; unsigned short usAmmoInClip = ammo.data.usAmmoInClip; CClientPed * pPed = m_pPedManager->Get ( pSource->GetID (), true ); if ( pPed ) { // Valid weapon id? if ( !CClientPickupManager::IsValidWeaponID ( ucWeaponID ) ) return; // Do we have it? CWeapon* pPlayerWeapon = pPed->GetWeapon ( (eWeaponType) ucWeaponID ); if ( pPlayerWeapon == NULL ) return; unsigned char ucAmmoInClip = static_cast < unsigned char > ( pPlayerWeapon->GetAmmoInClip () ); pPlayerWeapon->SetAmmoInClip ( usAmmoInClip ); pPlayerWeapon->SetAmmoTotal ( usAmmo ); if ( !usAmmoInClip ) { if ( usAmmo > ucAmmoInClip ) pPlayerWeapon->SetAmmoInClip ( ucAmmoInClip ); else if ( usAmmo <= ucAmmoInClip ) pPlayerWeapon->SetAmmoInClip ( usAmmo ); } } } } }
void CWeaponRPCs::GiveWeaponAmmo ( NetBitStreamInterface& bitStream ) { ElementID ID; SWeaponTypeSync weaponType; if ( bitStream.ReadCompressed ( ID ) && bitStream.Read ( &weaponType ) ) { unsigned char ucWeaponID = weaponType.data.ucWeaponType; SWeaponAmmoSync ammo ( ucWeaponID, true, false ); if ( bitStream.Read ( &ammo ) ) { unsigned short usAmmo = ammo.data.usTotalAmmo; CClientPed * pPed = m_pPedManager->Get ( ID, true ); if ( pPed ) { // Valid weapon id? if ( !CClientPickupManager::IsValidWeaponID ( ucWeaponID ) ) return; // Do we have it? CWeapon* pPlayerWeapon = pPed->GetWeapon ( (eWeaponType) ucWeaponID ); if ( pPlayerWeapon == NULL ) return; unsigned long ulWeaponAmmo = pPlayerWeapon->GetAmmoTotal (); ulWeaponAmmo += usAmmo; // Adjust the ammo to 9999 if it's above if ( ulWeaponAmmo > 9999 ) { ulWeaponAmmo = 9999; } // Add the weapon ammo pPlayerWeapon->SetAmmoTotal ( ulWeaponAmmo ); } } } }
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 ); } } } } } } } }