//------------------------------------------------------------------------ void CWeapon::OnPickedUp(EntityId actorId, bool destroyed) { BROADCAST_WEAPON_EVENT(OnPickedUp, (this, actorId, destroyed)); CItem::OnPickedUp(actorId, destroyed); GetEntity()->SetFlags(GetEntity()->GetFlags() | ENTITY_FLAG_NO_PROXIMITY); GetEntity()->SetFlags(GetEntity()->GetFlags() & ~ENTITY_FLAG_ON_RADAR); if(GetISystem()->IsSerializingFile() == 1) return; CActor *pActor=GetActor(actorId); if (!pActor) return; if (!IsServer()) return; // bonus ammo is always put in the actor's inv if (!m_bonusammo.empty()) { for (TAmmoMap::iterator it=m_bonusammo.begin(); it!=m_bonusammo.end(); ++it) { int count=it->second; SetInventoryAmmoCount(it->first, GetInventoryAmmoCount(it->first)+count); } m_bonusammo.clear(); } // current ammo is only added to actor's inv, if we already have this weapon if (destroyed && m_params.unique) { for (TAmmoMap::iterator it=m_ammo.begin(); it!=m_ammo.end(); ++it) { //Only add ammo to inventory, if not accessory ammo (accessories give ammo already) if(m_accessoryAmmo.find(it->first)==m_accessoryAmmo.end()) { int count=it->second; SetInventoryAmmoCount(it->first, GetInventoryAmmoCount(it->first)+count); } } } if(!gEnv->bMultiplayer && !m_initialSetup.empty() && pActor->IsClient()) { for (TAccessoryMap::iterator it=m_accessories.begin(); it!=m_accessories.end(); ++it) FixAccessories(GetAccessoryParams(it->first), true); } }
//------------------------------------------------------------------------ void CWeapon::OnDroppedByPlayer(IInventory* pPlayerInventory) { CRY_ASSERT(pPlayerInventory); TFireModeVector::const_iterator firemodesEndIt = m_firemodes.end(); for (TFireModeVector::const_iterator firemodeCit = m_firemodes.begin(); firemodeCit != firemodesEndIt ; ++firemodeCit) { const CFireMode* pFiremode = *firemodeCit; if (pFiremode) { IEntityClass* pFiremodeAmmo = pFiremode->GetAmmoType(); if (pFiremodeAmmo) { // Exchange also ammo pool from inventory to bonus ammo map, for next user who picks it up int ammoCount = pPlayerInventory->GetAmmoCount(pFiremodeAmmo); if (ammoCount > 0) { if(gEnv->bMultiplayer) { int currentClipAmount = GetAmmoCount(pFiremodeAmmo); int clipSize = pFiremode->GetClipSize(); int numForClip = clamp_tpl(clipSize - currentClipAmount, 0, ammoCount); SetAmmoCount(pFiremodeAmmo, currentClipAmount + numForClip); ammoCount -= numForClip; } SetInventoryAmmoCount(pFiremodeAmmo, 0); SWeaponAmmoUtils::SetAmmo(m_bonusammo, pFiremodeAmmo, ammoCount); } } } } }
void CWeapon::TestClipAmmoCountIsValid() { TFireModeVector::iterator itEnd = m_firemodes.end(); for (TFireModeVector::iterator it = m_firemodes.begin(); it != itEnd; ++it) { IFireMode* pFM = *it; if (pFM && pFM->IsEnabled()) { IEntityClass* pAmmoType = pFM->GetAmmoType(); if(pAmmoType) { int clipSize = pFM->GetClipSize(); const SFireModeParams* pFireModeParams = ((CFireMode*)pFM)->GetShared(); if (pFireModeParams) { clipSize += pFireModeParams->fireparams.bullet_chamber; } const int ammoCount = GetAmmoCount(pAmmoType); if (ammoCount > clipSize) { SetAmmoCount(pAmmoType, clipSize); const int excessAmmo = ammoCount - clipSize; SetInventoryAmmoCount(pAmmoType, GetInventoryAmmoCount(pAmmoType) + excessAmmo); } } } } }
//------------------------------------------------------------------------ void CAmmoPickup::PickUp(EntityId pickerId, bool sound, bool select, bool keepHistory) { if(!CheckAmmoRestrictions(pickerId)) return; SetOwnerId(pickerId); CActor *pActor=GetActor(pickerId); if (!pActor) return; IInventory *pInventory = GetActorInventory(pActor); if (!pInventory) return; if (IsServer()) { // bonus ammo is always put in the actor's inv if (!m_bonusammo.empty()) { for (TAmmoMap::iterator it=m_bonusammo.begin(); it!=m_bonusammo.end(); ++it) { int count=it->second; SetInventoryAmmoCount(it->first, GetInventoryAmmoCount(it->first)+count); if(pActor->IsPlayer()) { ShouldSwitchGrenade(it->first); OnIncendiaryAmmoPickedUp(it->first,count); } } m_bonusammo.clear(); } for (TAmmoMap::iterator it=m_ammo.begin(); it!=m_ammo.end(); ++it) { int count=it->second; SetInventoryAmmoCount(it->first, GetInventoryAmmoCount(it->first)+count); if(pActor->IsPlayer()) { ShouldSwitchGrenade(it->first); OnIncendiaryAmmoPickedUp(it->first,count); } } if (!m_ammoName.empty() && m_ammoCount) { IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(m_ammoName.c_str()); SetInventoryAmmoCount(pClass, GetInventoryAmmoCount(pClass)+m_ammoCount); if(pActor->IsPlayer()) { ShouldSwitchGrenade(pClass); OnIncendiaryAmmoPickedUp(pClass,m_ammoCount); } } TriggerRespawn(); } //Play sound if(!m_pickup_sound.empty()) { IEntity *pPicker = m_pEntitySystem->GetEntity(pickerId); if(pPicker) { IEntitySoundProxy* pSoundProxy = (IEntitySoundProxy*)pPicker->GetProxy(ENTITY_PROXY_SOUND); if(pSoundProxy) { //Execute sound at picker position pSoundProxy->PlaySound(m_pickup_sound, pPicker->GetWorldPos(),FORWARD_DIRECTION, FLAG_SOUND_DEFAULT_3D, eSoundSemantic_Weapon); } } } RemoveEntity(); }
//------------------------------------------------------------------------ void CWeapon::OnDroppedByAI(IInventory* pAIInventory) { CRY_ASSERT(pAIInventory); const TAmmoVector& minDroppedAmmoMap = m_weaponsharedparams->ammoParams.minDroppedAmmo; const bool checkForMinAmmoDrops = m_minDropAmmoAvailable && !minDroppedAmmoMap.empty(); TFireModeVector::const_iterator firemodesEndIt = m_firemodes.end(); for (TFireModeVector::const_iterator firemodeCit = m_firemodes.begin(); firemodeCit != firemodesEndIt ; ++firemodeCit) { const CFireMode* pFiremode = *firemodeCit; if (pFiremode) { IEntityClass* pFiremodeAmmo = pFiremode->GetAmmoType(); if (pFiremodeAmmo) { // Additional ammo which always goes to the magazine, when ai drops a weapon int minAmmoDrop = 0; if (checkForMinAmmoDrops) { const SWeaponAmmo* pMinDroppedAmmo = SWeaponAmmoUtils::FindAmmoConst(minDroppedAmmoMap, pFiremodeAmmo); if (pMinDroppedAmmo != NULL) { minAmmoDrop = pMinDroppedAmmo->count; SWeaponAmmo* pCurrentAmmo = SWeaponAmmoUtils::FindAmmo(m_ammo, pFiremodeAmmo); if (pCurrentAmmo) { pCurrentAmmo->count = min(minAmmoDrop + pCurrentAmmo->count, pFiremode->GetClipSize()); } else { m_ammo.push_back(SWeaponAmmo(pFiremodeAmmo, min(minAmmoDrop, pFiremode->GetClipSize()))); } } } // Exchange also ammo pool from inventory to bonus ammo map, for next user who picks it up { const int ammoCount = pAIInventory->GetAmmoCount(pFiremodeAmmo); if (ammoCount > 0) { SetInventoryAmmoCount(pFiremodeAmmo, 0); SWeaponAmmoUtils::SetAmmo(m_bonusammo, pFiremodeAmmo, ammoCount); } else { //Put always some extra rounds when dropped by AI const SWeaponAmmo* pDefaultBonusAmmo = SWeaponAmmoUtils::FindAmmoConst(m_weaponsharedparams->ammoParams.bonusAmmo, pFiremodeAmmo); if (pDefaultBonusAmmo) { SetInventoryAmmoCount(pFiremodeAmmo, 0); SWeaponAmmoUtils::SetAmmo(m_bonusammo, pFiremodeAmmo, max(minAmmoDrop, (int)Random(pDefaultBonusAmmo->count))); } } } } } } m_minDropAmmoAvailable = false; }
//------------------------------------------------------------------------ void CWeapon::OnPickedUp(EntityId actorId, bool destroyed) { BROADCAST_WEAPON_EVENT(OnPickedUp, (this, actorId, destroyed)); BaseClass::OnPickedUp(actorId, destroyed); GetEntity()->SetFlags(GetEntity()->GetFlags() | ENTITY_FLAG_NO_PROXIMITY); // bonus ammo is always put in the actor's inv if (!m_bonusammo.empty()) { for (TAmmoVector::iterator it = m_bonusammo.begin(); it != m_bonusammo.end(); ++it) { const SWeaponAmmo& currentBonusAmmo = *it; SetInventoryAmmoCount(currentBonusAmmo.pAmmoClass, GetInventoryAmmoCount(currentBonusAmmo.pAmmoClass)+currentBonusAmmo.count); } m_bonusammo.clear(); } if(GetISystem()->IsSerializingFile() == 1) return; CActor *pActor = GetActor(actorId); if (!pActor) return; // current ammo is only added to actor's inv, if we already have this weapon if (destroyed && m_sharedparams->params.unique) { for (TAmmoVector::iterator it = m_ammo.begin(); it!=m_ammo.end(); ++it) { //Only add ammo to inventory, if not accessory ammo (accessories give ammo already) const SWeaponAmmo& currentAmmo = *it; const SWeaponAmmo* pAccessoryAmmo = SWeaponAmmoUtils::FindAmmo(m_weaponsharedparams->ammoParams.accessoryAmmo, currentAmmo.pAmmoClass); if(pAccessoryAmmo != NULL) { SetInventoryAmmoCount(currentAmmo.pAmmoClass, GetInventoryAmmoCount(currentAmmo.pAmmoClass)+currentAmmo.count); } } } TestClipAmmoCountIsValid(); if (!gEnv->bServer && pActor->IsPlayer()) { IEntityClass* pCurrentAmmoClass = m_fm ? m_fm->GetAmmoType() : NULL; if (pCurrentAmmoClass) { //server has serialised the inventory count already if(IInventory* pInventory = GetActorInventory(GetOwnerActor())) { if(m_lastRecvInventoryAmmo > pInventory->GetAmmoCapacity(pCurrentAmmoClass)) { pInventory->SetAmmoCapacity(pCurrentAmmoClass, m_lastRecvInventoryAmmo); } SetInventoryAmmoCountInternal(pInventory, pCurrentAmmoClass, m_lastRecvInventoryAmmo); } } } if(gEnv->bMultiplayer) { HighlightWeapon(false); } m_expended_ammo = 0; }