//------------------------------------------------------------------------ void CWeapon::OnFireModeChanged(int currentFireMode) { // Update weapon stats since depends on firemode if (m_pWeaponStats) { bool hasFireModeStats = false; if (m_fm) { CFireMode* pFireMode = (CFireMode*)m_fm; if (pFireMode != NULL) { const SFireModeParams* pFireModeParams = pFireMode->GetShared(); if (pFireModeParams != NULL) { hasFireModeStats = true; m_pWeaponStats->SetStatsFromFiremode(&pFireModeParams->weaponStatChangesParams); } } } if (!hasFireModeStats) { m_pWeaponStats->SetStatsFromFiremode(NULL); } } BROADCAST_WEAPON_EVENT(OnFireModeChanged, (this, currentFireMode)); }
//------------------------------------------------------------------------ void CWeapon::OnShoot(EntityId shooterId, EntityId ammoId, IEntityClass* pAmmoType, const Vec3 &pos, const Vec3 &dir, const Vec3&vel) { BROADCAST_WEAPON_EVENT(OnShoot, (this, shooterId, ammoId, pAmmoType, pos, dir, vel)); //FIXME:quick temporary solution IActor *pClientActor = m_pGameFramework->GetClientActor(); CActor *pActor = static_cast<CActor*> (g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(shooterId)); if (pActor) { pActor->HandleEvent(SGameObjectEvent(eCGE_OnShoot,eGOEF_ToExtensions)); if(!gEnv->bMultiplayer && (pActor == pClientActor)) { if (IAIObject *pAIObject = pActor->GetEntity()->GetAI()) { gEnv->pAISystem->SendSignal(SIGNALFILTER_LEADER, 1, "OnEnableFire", pAIObject, 0); } gEnv->pAISystem->DisableGlobalPerceptionScaling(); } } const bool sendHUDEvent = (shooterId != 0) && ShouldSendOnShootHUDEvent(); if (sendHUDEvent) { SHUDEvent event(eHUDEvent_OnShoot); event.AddData(SHUDEventData((int)shooterId)); CHUDEventDispatcher::CallEvent(event); } }
//------------------------------------------------------------------------ void CWeapon::OnDropped(EntityId actorId) { BROADCAST_WEAPON_EVENT(OnDropped, (this, actorId)); CItem::OnDropped(actorId); GetEntity()->SetFlags(GetEntity()->GetFlags() & ~ENTITY_FLAG_NO_PROXIMITY); GetEntity()->SetFlags(GetEntity()->GetFlags() | ENTITY_FLAG_ON_RADAR); }
//------------------------------------------------------------------------ void CWeapon::OnEndReload(EntityId shooterId, IEntityClass *pAmmoType) { BROADCAST_WEAPON_EVENT(OnEndReload, (this, shooterId, pAmmoType)); if(CActor *pActor = GetOwnerActor()) { if(IAIObject *pAIObject=pActor->GetEntity()->GetAI()) gEnv->pAISystem->SendSignal(SIGNALFILTER_SENDER, 1, "OnReloadDone", pAIObject); } }
//------------------------------------------------------------------------ void CWeapon::OnOutOfAmmo(IEntityClass *pAmmoType) { BROADCAST_WEAPON_EVENT(OnOutOfAmmo, (this, pAmmoType)); /* - no need to send signal here - puppet will check ammo when fires if (CActor *pActor = GetOwnerActor()) { if (IAIObject *pAIObject=Actor->GetEntity()->GetAI()) gEnv->pAISystem->SendSignal( SIGNALFILTER_SENDER, 1, "OnOutOfAmmo", pAIObject); } */ }
//------------------------------------------------------------------------ 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::OnMelee(EntityId shooterId) { BROADCAST_WEAPON_EVENT(OnMelee, (this, shooterId)); if(CActor *pOwner = static_cast<CActor *>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(shooterId))) { if(pOwner->GetActorClass()==CPlayer::GetActorClassType()) { CPlayer *pPlayer = static_cast<CPlayer *>(pOwner); pPlayer->PlaySound(CPlayer::ESound_Melee); } } }
//------------------------------------------------------------------------ void CWeapon::OnEndReload(EntityId shooterId, IEntityClass* pAmmoType) { BROADCAST_WEAPON_EVENT(OnEndReload, (this, shooterId, pAmmoType)); if (CActor *pActor = GetOwnerActor()) { if (IAIObject *pAIObject=pActor->GetEntity()->GetAI()) if (gEnv->pAISystem) gEnv->pAISystem->SendSignal( SIGNALFILTER_SENDER, 1, "OnReloadDone", pAIObject); } if (m_doingMagazineSwap) { const char* magazineAttachment = m_weaponsharedparams->reloadMagazineParams.magazineAttachment.c_str(); HideCharacterAttachment(eIGS_FirstPerson, magazineAttachment, false); HideCharacterAttachment(eIGS_ThirdPerson, magazineAttachment, false); m_doingMagazineSwap = false; } }
//------------------------------------------------------------------------ void CWeapon::OnShoot(EntityId shooterId, EntityId ammoId, IEntityClass *pAmmoType, const Vec3 &pos, const Vec3 &dir, const Vec3 &vel) { BROADCAST_WEAPON_EVENT(OnShoot, (this, shooterId, ammoId, pAmmoType, pos, dir, vel)); //FIXME:quick temporary solution CActor *pActor = static_cast<CActor *>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(shooterId)); if(pActor) pActor->HandleEvent(SGameObjectEvent(eCGE_OnShoot,eGOEF_ToExtensions)); IActor *pClientActor=m_pGameFramework->GetClientActor(); if(pActor && pActor->GetActorClass() == CPlayer::GetActorClassType() && IsServer()) { if(pActor == pClientActor) { if(IAIObject *pAIObject=pActor->GetEntity()->GetAI()) gEnv->pAISystem->SendSignal(SIGNALFILTER_LEADER, 1, "OnEnableFire", pAIObject, 0); } } if(pClientActor && m_fm && strcmp(m_fm->GetType(), "Thrown")) { // inform the HUDRadar about the sound event Vec3 vPlayerPos=pClientActor->GetEntity()->GetWorldPos(); float fDist2=(vPlayerPos-pos).len2(); if(fDist2<250.0f*250.0f) { //if (pClientActor->GetEntityId() != shooterId) // pHUD->ShowSoundOnRadar(pos); if(gEnv->bMultiplayer) { CGameRules *pGameRules = g_pGame->GetGameRules(); } if((!IsSilencerAttached()) && fDist2<sqr(SAFE_GAMEAUDIO_BATTLESTATUS_FUNC_RET(GetBattleRange()))) SAFE_GAMEAUDIO_BATTLESTATUS_FUNC(TickBattleStatus(1.0f)); } } }
//------------------------------------------------------------------------ void CWeapon::OnMelee(EntityId shooterId) { BROADCAST_WEAPON_EVENT(OnMelee, (this, shooterId)); if(CActor* pOwner = static_cast<CActor *>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(shooterId))) { if (pOwner->GetActorClass()==CPlayer::GetActorClassType()) { CPlayer *pPlayer = static_cast<CPlayer *>(pOwner); if(CNanoSuit *pSuit = pPlayer->GetNanoSuit()) { ENanoMode curMode = pSuit->GetMode(); if (curMode == NANOMODE_SPEED) { if (gEnv->bServer) pSuit->SetSuitEnergy(pSuit->GetSuitEnergy()-15.0f); } else if (curMode == NANOMODE_STRENGTH) { if (gEnv->bServer) { if(gEnv->bMultiplayer) pSuit->SetSuitEnergy(pSuit->GetSuitEnergy()-40.0f); else pSuit->SetSuitEnergy(pSuit->GetSuitEnergy()-20.0f); } pSuit->PlaySound(STRENGTH_MELEE_SOUND, (pSuit->GetSlotValue(NANOSLOT_STRENGTH))*0.01f); } else if (curMode == NANOMODE_CLOAK) { if (gEnv->bServer) pSuit->SetSuitEnergy(0.0f); } if (gEnv->bServer && pSuit->IsInvulnerable()) pSuit->SetInvulnerability(false); } pPlayer->PlaySound(CPlayer::ESound_Melee); } } }
//------------------------------------------------------------------------ void CWeapon::OnStartFire(EntityId shooterId) { BROADCAST_WEAPON_EVENT(OnStartFire, (this, shooterId)); if (gEnv->bServer) { if(CActor* pOwner = static_cast<CActor *>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(shooterId))) { if (pOwner->GetActorClass()==CPlayer::GetActorClassType()) { CPlayer *pPlayer = static_cast<CPlayer *>(pOwner); if(CNanoSuit *pSuit = pPlayer->GetNanoSuit()) { if (pSuit->IsInvulnerable()) pSuit->SetInvulnerability(false); } } } } }
//------------------------------------------------------------------------ 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 CWeapon::OnStopFire(EntityId shooterId) { BROADCAST_WEAPON_EVENT(OnStopFire, (this, shooterId)); }
void CWeapon::OnZoomChanged(bool zoomed, int idx) { BROADCAST_WEAPON_EVENT(OnZoomChanged,(this, zoomed, idx)); }
//------------------------------------------------------------------------ void CWeapon::OnFireModeChanged(int currentFireMode) { BROADCAST_WEAPON_EVENT(OnFireModeChanged,(this, currentFireMode)); }
//------------------------------------------------------------------------ void CWeapon::OnSelected(bool selected) { BROADCAST_WEAPON_EVENT(OnSelected,(this, selected)); }
//------------------------------------------------------------------------ void CWeapon::OnStopTargetting(IWeapon *pWeapon) { BROADCAST_WEAPON_EVENT(OnStopTargetting,(this)); }
void CWeapon::OnSetAmmoCount(EntityId shooterId) { BROADCAST_WEAPON_EVENT(OnSetAmmoCount, (this, shooterId)); }
//------------------------------------------------------------------------ void CWeapon::OnReadyToFire() { BROADCAST_WEAPON_EVENT(OnReadyToFire, (this)); }
//------------------------------------------------------------------------ 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; }
//------------------------------------------------------------------------ void CWeapon::OnDropped(EntityId actorId, bool ownerWasAI) { BROADCAST_WEAPON_EVENT(OnDropped, (this, actorId)); BaseClass::OnDropped(actorId, ownerWasAI); IEntity * pEntity = GetEntity(); if(gEnv->bServer) { bool removeWeapon = true; if(gEnv->bMultiplayer && GetParams().check_clip_size_after_drop) { TFireModeVector::const_iterator firemodesEndIt = m_firemodes.end(); for (TFireModeVector::const_iterator firemodeCit = m_firemodes.begin(); firemodeCit != firemodesEndIt && removeWeapon; ++firemodeCit) { const CFireMode* pFiremode = *firemodeCit; if (pFiremode) { IEntityClass* pFiremodeAmmo = pFiremode->GetAmmoType(); if (pFiremodeAmmo) { //only check the main ammo type given with the weapon if(SWeaponAmmoUtils::FindAmmoConst(m_weaponsharedparams->ammoParams.ammo, pFiremodeAmmo)) { int currentClipAmount = GetAmmoCount(pFiremodeAmmo); int clipSize = pFiremode->GetClipSize(); if(currentClipAmount > 0 && currentClipAmount >= clipSize) { removeWeapon = false; } } } } } } else { const bool outOfAmmo = OutOfAmmo(true) && !ownerWasAI; const bool removeOnDrop = GetSharedItemParams()->params.remove_on_drop; removeWeapon = !gEnv->pSystem->IsSerializingFile() && (outOfAmmo && removeOnDrop); } if(removeWeapon && GetParams().check_bonus_ammo_after_drop) { for(unsigned int i = 0; i < m_bonusammo.size(); ++i) { if(m_bonusammo[i].count > 0) { removeWeapon = false; break; } } } if(removeWeapon) { if(gEnv->IsEditor()) { pEntity->Hide(true); } else { gEnv->pEntitySystem->RemoveEntity(pEntity->GetId()); } } } uint32 flags = pEntity->GetFlags(); flags &= ~ENTITY_FLAG_NO_PROXIMITY; pEntity->SetFlags(flags); m_expended_ammo = 0; if(gEnv->bMultiplayer && (g_pGameCVars->i_highlight_dropped_weapons == 2) || (IsHeavyWeapon() && g_pGameCVars->i_highlight_dropped_weapons == 1)) { HighlightWeapon(true, true); } }
//------------------------------------------------------------------------ void CWeapon::OnShoot(EntityId shooterId, EntityId ammoId, IEntityClass* pAmmoType, const Vec3 &pos, const Vec3 &dir, const Vec3&vel) { BROADCAST_WEAPON_EVENT(OnShoot, (this, shooterId, ammoId, pAmmoType, pos, dir, vel)); //FIXME:quick temporary solution CActor *pActor = static_cast<CActor*> (g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(shooterId)); if (pActor) pActor->HandleEvent(SGameObjectEvent(eCGE_OnShoot,eGOEF_ToExtensions)); IActor *pClientActor=m_pGameFramework->GetClientActor(); if (pActor && pActor->GetActorClass() == CPlayer::GetActorClassType() && IsServer()) { if (pActor == pClientActor) { if (IAIObject *pAIObject=pActor->GetEntity()->GetAI()) gEnv->pAISystem->SendSignal(SIGNALFILTER_LEADER, 1, "OnEnableFire", pAIObject, 0); } CPlayer *pPlayer=static_cast<CPlayer *>(pActor); CNanoSuit *pSuit=pPlayer->GetNanoSuit(); if(m_fm && strcmp(m_fm->GetType(), "Repair")) { if(pSuit) { if (pSuit->GetMode() == NANOMODE_STRENGTH && !IsMounted()) pSuit->SetSuitEnergy(pSuit->GetSuitEnergy()-g_pGameCVars->g_suitRecoilEnergyCost); else if(pSuit->GetMode() == NANOMODE_CLOAK) pSuit->SetSuitEnergy(0.0f); } } if (gEnv->bServer && pSuit && pSuit->IsInvulnerable()) pSuit->SetInvulnerability(false); } if (pClientActor && m_fm && strcmp(m_fm->GetType(), "Thrown")) { // inform the HUDRadar about the sound event Vec3 vPlayerPos=pClientActor->GetEntity()->GetWorldPos(); float fDist2=(vPlayerPos-pos).len2(); if (fDist2<250.0f*250.0f) { //if (pClientActor->GetEntityId() != shooterId) // pHUD->ShowSoundOnRadar(pos); if(gEnv->bMultiplayer) { CGameRules *pGameRules = g_pGame->GetGameRules(); if(pGameRules->GetTeamCount() < 2 || (pGameRules->GetTeam(shooterId) != pGameRules->GetTeam(pClientActor->GetEntityId()))) { //Small workaround for patch2... IFireMode* pFM = GetFireMode(GetCurrentFireMode()); bool grenade = pFM?(pFM->GetAmmoType()==CItem::sScarGrenadeClass):false; //~... if (!IsSilencerAttached() || grenade) { SAFE_HUD_FUNC(GetRadar()->AddEntityTemporarily(shooterId, 5.0f)); } else if(fDist2<5.0f*5.0f) { //Silencer attached SAFE_HUD_FUNC(GetRadar()->AddEntityTemporarily(shooterId, 5.0f)); } } } if ((!IsSilencerAttached()) && fDist2<sqr(SAFE_HUD_FUNC_RET(GetBattleRange()))) SAFE_HUD_FUNC(TickBattleStatus(1.0f)); } } }
void CWeapon::EndBurst() { BROADCAST_WEAPON_EVENT(OnEndBurst, (this, GetOwnerId())); }