//------------------------------------------------------------------------ bool CC4::CanSelect() const { bool canSelect = (CWeapon::CanSelect() && !OutOfAmmo(false)); //Check for remaining projectiles to detonate if(!canSelect) { CActor *pOwner = GetOwnerActor(); if(!pOwner) return false; EntityId detonatorId = pOwner->GetInventory()?pOwner->GetInventory()->GetItemByClass(CItem::sDetonatorClass):0; //Do not re-select detonator again if(detonatorId && (detonatorId==pOwner->GetCurrentItemId())) return false; IFireMode *pFM = GetFireMode(GetCurrentFireMode()); if(pFM) { //CC4::Select will select the detonator in this case EntityId projectileId = pFM->GetProjectileId(); if(projectileId && g_pGame->GetWeaponSystem()->GetProjectile(projectileId)) return true; } } return canSelect; };
//------------------------------------------------------------------------ int CScriptBind_Weapon::SetAmmoCount(IFunctionHandler *pH) { CWeapon *pWeapon = GetWeapon(pH); if (!pWeapon) return pH->EndFunction(); IFireMode* pFireMode = GetRequestedFireMode(pWeapon, pH); if (pFireMode) { if (pH->GetParamType(2) != svtNumber) return pH->EndFunction(); const char *ammoName = 0; if (pH->GetParamType(1) == svtString) pH->GetParam(1, ammoName); IEntityClass* pAmmoType = pFireMode->GetAmmoType(); if (ammoName) pAmmoType = gEnv->pEntitySystem->GetClassRegistry()->FindClass(ammoName); int ammo = 0; pH->GetParam(2, ammo); pWeapon->SetAmmoCount(pAmmoType, ammo); } return pH->EndFunction(); }
//------------------------------------------------------------------------ void CDetonate::StartFire() { if (CanFire(false)) { CActor *pOwner=m_pWeapon->GetOwnerActor(); CCCPOINT(DetonateFireMode_StartFireOK); m_pWeapon->RequireUpdate(eIUS_FireMode); m_detonationTimer = 0.1f; m_pWeapon->PlayAction(GetFragmentIds().fire); m_pWeapon->RequestDetonate(); } else { #if !defined(_RELEASE) IFireMode* pFM = m_pWeapon->GetFireMode(m_pWeapon->GetCurrentFireMode()); EntityId projectileId = pFM ? pFM->GetProjectileId() : 0; IEntity * projectile = gEnv->pEntitySystem->GetEntity(projectileId); CryLog ("[Detonate] Failure to detonate %s '%s' (timer = %.4f, can detonate = %s, fire mode = '%s') projectile = %u (%s '%s')", m_pWeapon->GetEntity()->GetClass()->GetName(), m_pWeapon->GetEntity()->GetName(), m_detonationTimer, m_canDetonate ? "TRUE" : "FALSE", pFM ? pFM->GetName() : "NONE", projectileId, projectile ? projectile->GetClass()->GetName() : "NONE", projectile ? projectile->GetName() : "N/A"); #endif CCCPOINT_IF(m_detonationTimer > 0.0f, DetonateFireMode_CannotFire_TimerNotReachedZero); CCCPOINT(DetonateFireMode_CannotFire); } }
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 CHeavyMountedWeapon::SetUnMountedConfiguration() { SwitchToRippedOffFireMode(); IFireMode * pMountedFireMode = GetFireMode(0); assert(pMountedFireMode); pMountedFireMode->Enable(false); ExitZoom(true); //Second zoom mode is supposed to be unmounted if(GetZoomMode(1)) { EnableZoomMode(1, true); SetCurrentZoomMode(1); } //Just in case, it was not clear properly CActor* pOwner = GetOwnerActor(); if ((pOwner != NULL) && pOwner->IsClient()) { float defaultFov = 55.0f; gEnv->pRenderer->EF_Query(EFQ_SetDrawNearFov,defaultFov); } }
//------------------------------------------------------------------------ bool CDetonate::Detonate(bool net) { if (m_pWeapon->IsServer()) { CActor *pOwner=m_pWeapon->GetOwnerActor(); if (!pOwner) return false; if (CWeapon *pWeapon=static_cast<CWeapon*>(pOwner->GetItemByClass(CItem::sC4Class))) { IFireMode* pFM = pWeapon->GetFireMode(pWeapon->GetCurrentFireMode()); //assert(pFM && "Detonator has not fire mode! Can not detonate C4"); if(!pFM) return false; while(EntityId projectileId=pFM->RemoveProjectileId()) { if (CProjectile *pProjectile=g_pGame->GetWeaponSystem()->GetProjectile(projectileId)) { pProjectile->Explode(true, false); g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(pWeapon->GetOwner(), GameplayEvent(eGE_WeaponShot, pProjectile->GetEntity()->GetClass()->GetName(), 1, (void *)pWeapon->GetEntityId())); } } } } if (!net) m_pWeapon->RequestShoot(0, ZERO, ZERO, ZERO, ZERO, 1.0f, 0, false); return true; }
EStatus Update(float timePassed) { if (IsTransitioningOut()) { const float ROTATION_LERP_SPEED = 10.0f; //--- Blend body rotation to match current view Ang3 targetViewDir = m_player.GetAngles(); Quat targetRotation = Quat::CreateRotationZ(targetViewDir.z); Quat newRotation = Quat::CreateNlerp(m_player.GetEntity()->GetRotation(), targetRotation, timePassed*ROTATION_LERP_SPEED); m_player.GetEntity()->SetRotation(newRotation); } else { static uint32 leanParamCRC = gEnv->pSystem->GetCrc32Gen()->GetCRC32Lowercase("SlideFactor"); const Matrix34 &worldTM = m_player.GetEntity()->GetWorldTM(); const Vec3 baseRgt = worldTM.GetColumn0(); const Vec3 baseFwd = worldTM.GetColumn1(); const Vec3 lookFwd = m_player.GetViewQuatFinal().GetColumn1(); const float leanAngle = cry_acosf(baseFwd.Dot(lookFwd)); float targetLeanFactor = clamp(leanAngle / MAX_LEAN_ANGLE, 0.0f, 1.0f); if (baseRgt.Dot(lookFwd) < 0.0f) { targetLeanFactor *= -1.0f; } CWeapon *pWeapon = m_player.GetWeapon(m_player.GetCurrentItemId()); if (pWeapon) { IFireMode *pFiremode = pWeapon->GetFireMode(pWeapon->GetCurrentFireMode()); if (pFiremode && (pFiremode->GetNextShotTime() > 0.0f)) { targetLeanFactor = 0.0f; } } const float delta = targetLeanFactor - m_leanFactor; const float step = LEAN_RATE * timePassed; const float newLeanFactor = (float)__fsel(delta, min(m_leanFactor + step, targetLeanFactor), max(m_leanFactor - step, targetLeanFactor)); SWeightData weightData; weightData.weights[0] = newLeanFactor; SetParam(leanParamCRC, weightData); m_leanFactor = newLeanFactor; if (GetRootScope().IsDifferent(m_fragmentID, m_fragTags)) { SetFragment(m_fragmentID, m_fragTags); } } return TPlayerAction::Update(timePassed); }
//------------------------------------------------------------------------ int CScriptBind_Weapon::GetSpread(IFunctionHandler *pH) { CWeapon *pWeapon = GetWeapon(pH); if (!pWeapon) return pH->EndFunction(); IFireMode *pFireMode = pWeapon->GetFireMode(pWeapon->GetCurrentFireMode()); if (pFireMode) return pH->EndFunction(pFireMode->GetSpread()); return pH->EndFunction(); }
//------------------------------------------------------------------------ int CScriptBind_Weapon::GetCrosshair(IFunctionHandler *pH) { CWeapon *pWeapon = GetWeapon(pH); if (!pWeapon) return pH->EndFunction(); IFireMode* pFireMode = GetRequestedFireMode(pWeapon, pH); if (pFireMode) return pH->EndFunction(pFireMode->GetCrosshair()); return pH->EndFunction(); }
//------------------------------------------------------------------------ int CScriptBind_Weapon::GetAmmoType(IFunctionHandler *pH) { CWeapon *pWeapon = GetWeapon(pH); if (!pWeapon) return pH->EndFunction(); IFireMode* pFireMode = GetRequestedFireMode(pWeapon, pH); if (pFireMode) if (IEntityClass * pCls = pFireMode->GetAmmoType()) return pH->EndFunction(pCls->GetName()); return pH->EndFunction(); }
//------------------------------------------------------------------------ int CScriptBind_Weapon::GetFireMode(IFunctionHandler *pH, int idx) { CWeapon *pWeapon = GetWeapon(pH); if (!pWeapon) return pH->EndFunction(); IFireMode* pFireMode = pWeapon->GetFireMode(idx); if (pFireMode) { return pH->EndFunction(pFireMode->GetName()); } return pH->EndFunction(); }
//------------------------------------------------------------------------ void CWeapon::NetShootEx(const Vec3 &pos, const Vec3 &dir, const Vec3 &vel, const Vec3 &hit, float extra, int predictionHandle, int fireModeId) { IFireMode *pFM = GetFireMode(fireModeId); if (pFM) { pFM->NetShootEx(pos, dir, vel, hit, extra, predictionHandle); } else { #ifdef SERVER_CHECKS g_pGame->GetAntiCheatManager()->FlagActivity(eCT_ShootingWithoutFiremode, GetOwnerActor()->GetChannelId()); #endif } }
//------------------------------------------------------------------------ int CScriptBind_Weapon::EnableFireMode(IFunctionHandler *pH, const char* name, bool enable) { CWeapon *pWeapon = GetWeapon(pH); if (!pWeapon) return pH->EndFunction(); IFireMode* pFireMode = pWeapon->GetFireMode(name); if (pFireMode) { pFireMode->Enable(enable); } return pH->EndFunction(); }
void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { switch (event) { case (eFE_Activate): { if (!IsPortActive(pActInfo, 0)) return; IItemSystem* pItemSys = CCryAction::GetCryAction()->GetIItemSystem(); // get actor IActor* pActor = CCryAction::GetCryAction()->GetClientActor(); if (!pActor) return; IInventory *pInventory = pActor->GetInventory(); if (!pInventory) return; IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(GetPortString(pActInfo,1)); IItem* pItem = pItemSys->GetItem(pInventory->GetItemByClass(pClass)); if (!pItem || !pItem->GetIWeapon()) { pItem = pActor->GetCurrentItem(); if (!pItem || pItem->GetEntity()->GetClass() != pClass || !pItem->GetIWeapon()) { GameWarning("[flow] CFlowNode_WeaponAmmo: No item/weapon %s!", GetPortString(pActInfo,1).c_str()); return; } } IWeapon *pWeapon = pItem->GetIWeapon(); const string& ammoType = GetPortString(pActInfo,2); IEntityClass* pAmmoClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(ammoType.c_str()); CRY_ASSERT(pAmmoClass); IFireMode* pCurrentFireMode = pWeapon->GetFireMode(pWeapon->GetCurrentFireMode()); if (pCurrentFireMode) { int clipSize = pCurrentFireMode->GetClipSize(); int ammo = pWeapon->GetAmmoCount(pAmmoClass) + GetPortInt(pActInfo,3); ammo = CLAMP(ammo, 0, clipSize); pWeapon->SetAmmoCount(pAmmoClass, ammo); } ActivateOutput(pActInfo, 0, pWeapon->GetAmmoCount(pAmmoClass)); } break; } }
//------------------------------------------------------------------------ int CScriptBind_Weapon::IsFireModeEnabled(IFunctionHandler *pH, const char* name) { CWeapon *pWeapon = GetWeapon(pH); if (!pWeapon) return pH->EndFunction(); bool bIsEnabled = false; IFireMode* pFireMode = pWeapon->GetFireMode(name); if (pFireMode) { bIsEnabled = pFireMode->IsEnabled(); } return pH->EndFunction(bIsEnabled); }
//----------------------------------------------------------------------- bool CC4::OnActionSelectDetonator(EntityId actorId, const ActionId& actionId, int activationMode, float value) { if(activationMode == eAAM_OnPress) { bool projectile = false; IFireMode* pFM = GetFireMode(GetCurrentFireMode()); if(pFM) { EntityId projectileId = pFM->GetProjectileId(); if(projectileId && g_pGame->GetWeaponSystem()->GetProjectile(projectileId)) projectile = true; } //If there is some projectile we can switch if(projectile) SelectDetonator(); } return true; }
//------------------------------------------------------------------------ void CC4::Select(bool select) { if(select) { bool outOfAmmo = OutOfAmmo(false); bool projectile = false; IFireMode *pFM = GetFireMode(GetCurrentFireMode()); if(pFM) { EntityId projectileId = pFM->GetProjectileId(); if(projectileId && g_pGame->GetWeaponSystem()->GetProjectile(projectileId)) projectile = true; } if(outOfAmmo && projectile) { SelectDetonator(); return; } else if(outOfAmmo) { Select(false); CActor *pOwner=GetOwnerActor(); if(!pOwner) return; EntityId fistsId = pOwner->GetInventory()?pOwner->GetInventory()->GetItemByClass(CItem::sFistsClass):0; if(fistsId) pOwner->SelectItem(fistsId,true); return; } } CWeapon::Select(select); }
//------------------------------------------------------------------------ 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 CIronSight::OnZoomedOut() { m_zoomed = false; ClearDoF(); if(CActor *pActor = m_pWeapon->GetOwnerActor()) { if(CScreenEffects *pSFX = pActor->GetScreenEffects()) { pSFX->ResetBlendGroup(CScreenEffects::eSFX_GID_ZoomOut); pSFX->ResetBlendGroup(CScreenEffects::eSFX_GID_ZoomIn); pSFX->ResetBlendGroup(CScreenEffects::eSFX_GID_HitReaction); pSFX->EnableBlends(true, CScreenEffects::eSFX_GID_ZoomIn); pSFX->EnableBlends(true, CScreenEffects::eSFX_GID_ZoomOut); pSFX->EnableBlends(true, CScreenEffects::eSFX_GID_HitReaction); } if(pActor->IsClient()) { if(SPlayerStats *pStats = static_cast<SPlayerStats *>(pActor->GetActorStats())) pStats->FPWeaponSwayOn = false; } } //Reset spread and recoil modifications IFireMode *pFireMode = m_pWeapon->GetFireMode(m_pWeapon->GetCurrentFireMode()); if(pFireMode) { pFireMode->ResetSpreadMod(); pFireMode->ResetRecoilMod(); } if(m_pShared->zoomParams.scope_mode) ResetFovAndPosition(); m_pWeapon->OnZoomChanged(false, m_pWeapon->GetCurrentZoomMode()); }
//------------------------------------------------------------------------ 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 ReplenishAmmo( IWeapon* pWeapon ) { IFireMode *pFireMode = pWeapon->GetFireMode(pWeapon->GetCurrentFireMode()); if (pFireMode) pWeapon->SetAmmoCount(pFireMode->GetAmmoType(), pFireMode->GetClipSize()); }