//------------------------------------------------------------------------ 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::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 CRocketLauncher::AutoDrop() { if(m_zm && m_zm->IsZoomed()) { GetScheduler()->TimerAction(GetCurrentAnimationTime(eIGS_FirstPerson), CSchedulerAction<EndZoomOutAction>::Create(EndZoomOutAction(this)), true); } else if(m_fm) { m_firedRockets--; CActor* pOwner = GetOwnerActor(); // no need to auto-drop for AI if(pOwner && !pOwner->IsPlayer()) return; if((GetAmmoCount(m_fm->GetAmmoType()) + GetInventoryAmmoCount(m_fm->GetAmmoType()) <= 0)&&(m_firedRockets<=0)) { PlayAction(g_pItemStrings->deselect); GetScheduler()->TimerAction(GetCurrentAnimationTime(eIGS_FirstPerson), CSchedulerAction<EndDropAction>::Create(EndDropAction(this)), true); } } }
//------------------------------------------------------------------------ void CWeapon::OnStartReload(EntityId shooterId, IEntityClass* pAmmoType) { BROADCAST_WEAPON_EVENT(OnStartReload, (this, shooterId, pAmmoType)); if (CActor *pActor = GetOwnerActor()) { if (IAIObject *pAIObject=pActor->GetEntity()->GetAI()) if (gEnv->pAISystem) gEnv->pAISystem->SendSignal( SIGNALFILTER_SENDER, 1, "OnReload", pAIObject); if(pActor->IsClient()) { if (gEnv->bMultiplayer && pActor->IsCloaked()) { CPersistantStats::GetInstance()->IncrementClientStats(EIPS_CloakedReloads); } if(m_weaponsharedparams->bulletBeltParams.numBullets > 0) { const uint32 refillTime = (uint32)(GetCurrentAnimationTime(eIGS_Owner) * m_weaponsharedparams->bulletBeltParams.beltRefillReloadFraction); GetScheduler()->TimerAction(refillTime, CSchedulerAction<RefillBeltAction>::Create(RefillBeltAction(this)), false); } } } IFireMode *pFireMode = GetFireMode(GetCurrentFireMode()); if (pFireMode) { if(GetInventoryAmmoCount(pAmmoType) < pFireMode->GetClipSize()) { BATTLECHATTER(BC_LowAmmo, shooterId); } else { BATTLECHATTER(BC_Reloading, shooterId); } } }
//------------------------------------------------------------------------ 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(); }
//------------------------------------------------------------------------ IMPLEMENT_RMI(CWeapon, SvRequestShootEx) { CHECK_OWNER_REQUEST(); bool ok=true; CActor *pActor=GetActorByNetChannel(pNetChannel); if (!pActor || pActor->IsDead()) { ok=false; } #ifdef SERVER_CHECKS CAntiCheatManager * pAntiCheatManager = static_cast<CAntiCheatManager*>(g_pGame->GetAntiCheatManager()); bool validatePrediction = pAntiCheatManager ? pAntiCheatManager->GetAntiCheatVar(eAV_IP_UseTest_ValidatePredicatedSpawn, 1) != 0 : false; if(ok && validatePrediction && params.predictionHandle) { CFireMode *pFireMode = (CFireMode*)GetFireMode(params.fireModeId); if (pFireMode) { const SFireModeParams *pFireModeParams = pFireMode->GetShared(); if(pFireModeParams) { IEntityClass *pAmmoClass = pFireModeParams->fireparams.ammo_type_class; if(pAmmoClass) { int totalAmmoCount = GetAmmoCount(pAmmoClass) + GetInventoryAmmoCount(pAmmoClass); if(totalAmmoCount <= 0) { CryLog("actor %s does not have enough ammo for predicted spawn of %s, not spawning...", pActor->GetEntity()->GetName(), pAmmoClass->GetName()); ok = false; } } } } } #endif if (ok) { m_fireCounter++; m_expended_ammo++; IActor *pLocalActor=m_pGameFramework->GetClientActor(); bool isLocal = pLocalActor && (pLocalActor->GetChannelId() == pActor->GetChannelId()); if (!isLocal) { NetShootEx(params.pos, params.dir, params.vel, params.hit, params.extra, params.predictionHandle, params.fireModeId); } CHANGED_NETWORK_STATE(this, ASPECT_STREAM); } else { if(params.predictionHandle) { CGameRules::SPredictionParams predictionParams(params.predictionHandle); g_pGame->GetGameRules()->GetGameObject()->InvokeRMI(CGameRules::ClPredictionFailed(), predictionParams, eRMI_ToClientChannel, m_pGameFramework->GetGameChannelId(pNetChannel)); } } return true; }
//------------------------------------------------------------------------ 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; }