FragmentID CHeavyWeapon::GetSelectAction() const { if (AreAnyItemFlagsSet(eIF_Unholstering)) return GetFragmentIds().unholster_select; else return GetFragmentIds().Select; }
void CSpammer::UpdateLoadIn(float frameTime) { const int currentAmmoCount = GetAmmoCount(); const bool infiniteAmmo = (GetClipSize() < 0); if ((!infiniteAmmo) && (m_numLoadedRockets >= currentAmmoCount)) { GetWeapon()->PlayAction(GetFragmentIds().empty_clip); StopFire(); return; } const SSpammerParams& params = GetShared()->spammerParams; const float loadInTime = 1.0f / (params.loadInRate / 60.0f); m_timer -= frameTime; while (m_timer < 0.0f && m_numLoadedRockets < params.maxNumRockets) { m_timer += loadInTime; AddTarget(); GetWeapon()->PlayAction(GetFragmentIds().c**k); } if (m_numLoadedRockets != m_targetsAssigned.GetNumLockOns()) { EntityId nextTarget = GetNextLockOnTarget(); if (nextTarget != 0) m_targetsAssigned.LockOn(nextTarget); } }
void CShotgun::ReloadShell(int zoomed) { if(m_reload_was_broken) return; CActor* pOwner = m_pWeapon->GetOwnerActor(); bool isAI = pOwner && (pOwner->IsPlayer() == false); int ammoCount = m_pWeapon->GetAmmoCount(m_fireParams->fireparams.ammo_type_class); if ((ammoCount < GetClipSize()) && (m_max_shells>0) && (isAI || (m_pWeapon->GetInventoryAmmoCount(m_fireParams->fireparams.ammo_type_class) > (m_load_shell_on_end ? 1 : 0))) ) // AI has unlimited ammo { m_max_shells --; const float speedOverride = GetReloadSpeedMultiplier(pOwner); // reload a shell m_pWeapon->PlayAction(GetFragmentIds().reload_shell, 0, false, CItem::eIPAF_Default,speedOverride); uint32 animTime = m_pWeapon->GetCurrentAnimationTime(eIGS_Owner); if(animTime==0) animTime = 530; //For DS m_pWeapon->GetScheduler()->TimerAction(animTime, CSchedulerAction<PartialReloadAction>::Create(PartialReloadAction(m_pWeapon, zoomed)), false); // call this again } else { EndReload(zoomed); } }
//------------------------------------------------------------------------ void CPlant::StartFire() { CActor* pOwner = m_pWeapon->GetOwnerActor(); if (pOwner && pOwner->IsClient() && !CanFire(true)) { return; } CPlayer *ownerPlayer = m_pWeapon->GetOwnerPlayer(); if (ownerPlayer) { ownerPlayer->StateMachineHandleEventMovement( PLAYER_EVENT_FORCEEXITSLIDE ); } m_pWeapon->RequireUpdate(eIUS_FireMode); m_planting = true; m_pWeapon->SetBusy(true); m_pWeapon->PlayAction(GetFragmentIds().intoPlant, 0,false,CItem::eIPAF_Default); m_pWeapon->GetScheduler()->TimerAction(m_pWeapon->GetCurrentAnimationTime(eIGS_Owner), CSchedulerAction<StartPlantAction>::Create(this), false); m_pWeapon->RequestStartFire(); }
void CShotgun::StartReload(int zoomed) { //If reload was broken to shoot, do not start a reload before shooting if(m_break_reload) return; int clipSize = GetClipSize(); int ammoCount = m_pWeapon->GetAmmoCount(m_fireParams->fireparams.ammo_type_class); if ((ammoCount >= clipSize) || m_reloading) return; CActor* pActor = m_pWeapon->GetOwnerActor(); m_max_shells = clipSize - ammoCount; m_reload_was_broken = false; m_reloading = true; if (zoomed) m_pWeapon->ExitZoom(true); IEntityClass* ammo = m_fireParams->fireparams.ammo_type_class; m_pWeapon->OnStartReload(m_pWeapon->GetOwnerId(), ammo); m_pWeapon->PlayAction(GetFragmentIds().begin_reload, 0, false, CItem::eIPAF_Default, -1); m_reload_pump = ammoCount > 0 ? false : true; uint32 animTime = m_pWeapon->GetCurrentAnimationTime(eIGS_Owner); if(animTime==0) animTime = 500; //For DS m_pWeapon->GetScheduler()->TimerAction(animTime, CSchedulerAction<BeginReloadLoop>::Create(BeginReloadLoop(this, zoomed)), false); }
//------------------------------------------------------------------------ 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); } }
bool CLTagSingle::NextGrenadeType() { uint32 grenadeType = (m_grenadeType + 1) % ELTAGGrenadeType_LAST; while (grenadeType != m_grenadeType) { assert(grenadeType < ELTAGGrenadeType_LAST); if (m_fireParams->lTagGrenades.grenades[grenadeType].c_str()[0] != '\0') { m_grenadeType = static_cast<ELTAGGrenadeType>(grenadeType); m_pWeapon->PlayAction(GetFragmentIds().change_firemode); SwitchGrenades(); //m_pWeapon->GetGameObject()->ChangedNetworkState(eEA_GameClientStatic); return true; } if (++grenadeType >= ELTAGGrenadeType_LAST) { grenadeType = static_cast<ELTAGGrenadeType>(0); } } return false; }
//------------------------------------------------------------------------ void CAutomatic::StartFire() { BaseClass::StartFire(); if (m_firing) m_pWeapon->PlayAction(GetFragmentIds().spin_down_tail); m_pWeapon->RequestStartFire(); }
void CBurst::NetStartFire() { IEntityClass* ammo = GetShared()->fireparams.ammo_type_class; int ammoCount = m_pWeapon->GetAmmoCount(ammo); m_pWeapon->PlayAction( GetFragmentIds().burst_fire, 0, false, CItem::eIPAF_Default, -1.0f, GetFireAnimationWeight(), GetFireFFeedbackWeight()); }
void CRapid::PlayStopRapidFireIfNeeded() { if (m_queueRapidFireAction) { // Workaround to try not have a stop_rapid_fire being queued the same frame than a start_rapid_fire, since we're skipping some sounds getting started. // TODO: Remove once the action resolve in mannequin handles the case differently. m_pWeapon->PlayAction( GetFragmentIds().stop_rapid_fire, 0, false, CItem::eIPAF_Default, -1.0f, GetFireAnimationWeight(), GetFireFFeedbackWeight()); m_queueRapidFireAction = false; } }
//------------------------------------------------------------------------ void CRapid::Accelerate(float acc) { m_acceleration = acc; if (acc > 0.0f) { if (!IsFiring()) { SpinUpEffect(true); } m_rapidFlags |= eRapidFlag_accelerating; m_rapidFlags &= ~eRapidFlag_decelerating; int flags = CItem::eIPAF_Default; m_pWeapon->PlayAction(GetFragmentIds().spin_up, 0, false, flags); } else { m_rapidFlags |= eRapidFlag_decelerating; m_rapidFlags &= ~eRapidFlag_accelerating; if(m_speed>0.0f) { m_pWeapon->PlayAction(GetFragmentIds().spin_down); if(m_firing) { m_pWeapon->PlayAction(GetFragmentIds().spin_down_tail); } } if (IsFiring()) { SpinUpEffect(false); } } }
//------------------------------------------------------------------------ void CCharge::StopFire() { if (m_fireParams->chargeparams.shoot_on_stop) { if (m_charged > 0) { ChargedShoot(); } m_pWeapon->PlayAction(GetFragmentIds().uncharge); m_charged = 0; m_charging = false; m_chargeTimer = 0.0f; } CAutomatic::StopFire(); }
//------------------------------------------------------------------------ void CDetonate::OutOfAmmoExplode() { CActor *pOwner = m_pWeapon->GetOwnerActor(); if (!pOwner) return; if (gEnv->bMultiplayer) { pOwner->SelectLastItem(true, true); } else { m_pWeapon->PlayAction(GetFragmentIds().deselect); m_pWeapon->GetScheduler()->TimerAction(uint32(m_pWeapon->GetCurrentAnimationTime(eIGS_Owner)), CSchedulerAction<DropRemoveAction>::Create(this), false); } }
//------------------------------------------------------------------------ bool CCharge::Shoot(bool resetAnimation, bool autoreload /* =true */, bool isRemote) { m_autoreload = autoreload; if (!m_charged) { m_charging = true; m_chargeTimer = m_fireParams->chargeparams.time; m_pWeapon->PlayAction(GetFragmentIds().charge, 0, false, CItem::eIPAF_Default); ChargeEffect(true); } else if (!m_charging && m_firing) ChargedShoot(); m_pWeapon->RequireUpdate(eIUS_FireMode); return true; }
//------------------------------------------------------------------------ void CRapid::StartFire() { if (m_pWeapon->IsBusy() || !CanFire(true)) { //Clip empty sound if(!CanFire(true) && !m_reloading) { int ammoCount = m_pWeapon->GetAmmoCount(m_fireParams->fireparams.ammo_type_class); if (GetClipSize()==0) ammoCount = m_pWeapon->GetInventoryAmmoCount(m_fireParams->fireparams.ammo_type_class); if(ammoCount<=0) { m_pWeapon->PlayAction(GetFragmentIds().empty_clip); m_pWeapon->OnFireWhenOutOfAmmo(); } } return; } m_rapidFlags &= ~eRapidFlag_netShooting; if ((m_rapidFlags & (eRapidFlag_decelerating | eRapidFlag_accelerating)) == 0) { m_pWeapon->EnableUpdate(true, eIUS_FireMode); } //SpinUpEffect(true); Accelerate(m_fireParams->rapidparams.acceleration); m_rapidFlags |= eRapidFlag_startedFiring; m_firstFire = true; m_startFiringTime = gEnv->pTimer->GetAsyncTime(); m_muzzleEffect.StartFire(this); m_pWeapon->RequestStartFire(); }
//------------------------------------------------------------------------ void CBurst::Update(float frameTime, uint32 frameId) { BaseClass::Update(frameTime, frameId); if (m_bursting) { if (m_next_shot <= 0.0f) { float saved_next_burst=m_next_burst; m_next_burst=0.0f; m_burst_shot = m_burst_shot+1; Shoot(true, m_fireParams->fireparams.autoReload); if (!m_firing || (m_burst_shot >= m_fireParams->burstparams.nshots-1)) { EndBurst(); m_firing = false; m_bursting = false; m_burst_shot = 0; SmokeEffect(); m_pWeapon->PlayAction(GetFragmentIds().spin_down_tail); m_pWeapon->SetItemFlag(CItem::eIF_BlockActions, false); } m_next_burst=saved_next_burst; } } if (m_fireTriggerDown || m_bursting) m_pWeapon->RequireUpdate(eIUS_FireMode); m_next_burst -= frameTime; if (m_next_burst <= 0.0f) m_next_burst = 0.0f; }
//------------------------------------------------------------------------ void CRapid::Activate(bool activate) { BaseClass::Activate(activate); if (m_pBarrelSpinAction) { m_pBarrelSpinAction->Stop(); m_pBarrelSpinAction = 0; } if (activate) { m_pBarrelSpinAction = GetWeapon()->PlayAction(GetFragmentIds().barrel_spin); } m_rotation_angle = 0.0f; m_speed = 0.0f; m_rapidFlags &= ~(eRapidFlag_accelerating|eRapidFlag_decelerating|eRapidFlag_startedFiring); m_acceleration = 0.0f; // initialize rotation xforms UpdateRotation(0.0f); Firing(false); }
void CJaw::DoAutoDrop() { if(!m_playedDropAction && m_fm) { m_firedRockets--; CActor* pOwner = GetOwnerActor(); // no need to auto-drop for AI if(pOwner && !pOwner->IsPlayer()) return; if((GetAmmoCount(m_fm->GetAmmoType())<=0)&&(m_firedRockets<=0)) { if( pOwner ) { uint8 uniqueId = m_pItemSystem->GetItemUniqueId(GetEntity()->GetClass()->GetName()); bool selectNext = pOwner->GetInventory()->GetCountOfUniqueId(uniqueId) <= 1; PlayAction(GetFragmentIds().drop); m_playedDropAction = true; } } } }
bool CShotgun::Shoot(bool resetAnimation, bool autoreload/* =true */, bool isRemote) { CCCPOINT(Shotgun_TryShoot); m_firePending = false; m_shotIndex++; IEntityClass* ammo = m_fireParams->fireparams.ammo_type_class; int ammoCount = m_pWeapon->GetAmmoCount(ammo); int clipSize = GetClipSize(); if (clipSize == 0) ammoCount = m_pWeapon->GetInventoryAmmoCount(ammo); CActor *pActor = m_pWeapon->GetOwnerActor(); bool playerIsShooter = pActor ? pActor->IsPlayer() : false; bool shooterIsClient = pActor ? pActor->IsClient() : false; if (!CanFire(true)) { if ((ammoCount <= 0) && (!m_reloading)) { m_pWeapon->PlayAction(GetFragmentIds().empty_clip); m_pWeapon->OnFireWhenOutOfAmmo(); CCCPOINT(Shotgun_TryShootWhileOutOfAmmo); } else { CCCPOINT(Shotgun_TryShootWhileCannotBeFired); } return false; } if (m_reloading) { if(m_pWeapon->IsBusy()) m_pWeapon->SetBusy(false); if(CanFire(true) && !m_break_reload) { m_break_reload = true; m_pWeapon->RequestCancelReload(); } CCCPOINT(Shotgun_TryShootWhileReloading); return false; } uint32 flags = CItem::eIPAF_Default; if (IsProceduralRecoilEnabled() && pActor) { pActor->ProceduralRecoil(m_fireParams->proceduralRecoilParams.duration, m_fireParams->proceduralRecoilParams.strength, m_fireParams->proceduralRecoilParams.kickIn, m_fireParams->proceduralRecoilParams.arms); } float speedOverride = -1.f; m_pWeapon->PlayAction(GetFragmentIds().fire, 0, false, flags, speedOverride); Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE); Vec3 pos = GetFiringPos(hit); Vec3 fdir = GetFiringDir(hit, pos); Vec3 vel = GetFiringVelocity(fdir); Vec3 dir; const float hitDist = hit.GetDistance(pos); CheckNearMisses(hit, pos, fdir, WEAPON_HIT_RANGE, m_fireParams->shotgunparams.spread); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId, string().Format("Invalid hit type '%s' in fire params for '%s'", m_fireParams->fireparams.hit_type.c_str(), m_pWeapon->GetEntity()->GetName())); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId == g_pGame->GetGameRules()->GetHitTypeId(m_fireParams->fireparams.hit_type.c_str()), "Sanity Check Failed: Stored hit type id does not match the type string, possibly CacheResources wasn't called on this weapon type"); int quad = cry_random(0, 3); const int numPellets = m_fireParams->shotgunparams.pellets; std::vector<CProjectile*> projList; projList.reserve(numPellets); int ammoCost = (m_fireParams->fireparams.fake_fire_rate && playerIsShooter) ? m_fireParams->fireparams.fake_fire_rate : 1; ammoCost = min(ammoCost, ammoCount); EntityId firstAmmoId = 0; // SHOT HERE for (int i = 0; i < numPellets; i++) { CProjectile *pAmmo = m_pWeapon->SpawnAmmo(m_fireParams->fireparams.spawn_ammo_class, false); if (pAmmo) { if(!firstAmmoId) { firstAmmoId = pAmmo->GetEntityId(); } projList.push_back(pAmmo); dir = ApplySpread(fdir, m_fireParams->shotgunparams.spread, quad); quad = (quad+1)%4; int pelletDamage = m_fireParams->shotgunparams.pelletdamage; if (!playerIsShooter) pelletDamage += m_fireParams->shotgunparams.npc_additional_damage; const bool canOvercharge = m_pWeapon->GetSharedItemParams()->params.can_overcharge; const float overchargeModifier = pActor ? pActor->GetOverchargeDamageScale() : 1.0f; if (canOvercharge) { pelletDamage = int(pelletDamage * overchargeModifier); } CProjectile::SProjectileDesc projectileDesc( m_pWeapon->GetOwnerId(), m_pWeapon->GetHostId(), m_pWeapon->GetEntityId(), pelletDamage, m_fireParams->fireparams.damage_drop_min_distance, m_fireParams->fireparams.damage_drop_per_meter, m_fireParams->fireparams.damage_drop_min_damage, m_fireParams->fireparams.hitTypeId, m_fireParams->fireparams.bullet_pierceability_modifier, m_pWeapon->IsZoomed()); projectileDesc.pointBlankAmount = m_fireParams->fireparams.point_blank_amount; projectileDesc.pointBlankDistance = m_fireParams->fireparams.point_blank_distance; projectileDesc.pointBlankFalloffDistance = m_fireParams->fireparams.point_blank_falloff_distance; if (m_fireParams->fireparams.ignore_damage_falloff) projectileDesc.damageFallOffAmount = 0.0f; const Vec3 pelletDestination = pos + (dir * hitDist); pAmmo->SetParams(projectileDesc); pAmmo->SetDestination(m_pWeapon->GetDestination()); pAmmo->Launch(pos, dir, vel); pAmmo->CreateBulletTrail( pelletDestination ); pAmmo->SetKnocksTargetInfo( GetShared() ); if ((!m_fireParams->tracerparams.geometry.empty() || !m_fireParams->tracerparams.effect.empty()) && ((ammoCount == clipSize) || (ammoCount%m_fireParams->tracerparams.frequency==0))) { EmitTracer(pos, pelletDestination, &m_fireParams->tracerparams, pAmmo); } if(shooterIsClient) { pAmmo->RegisterLinkedProjectile(m_shotIndex); if(gEnv->bMultiplayer) { float damageCap = g_pGameCVars->pl_shotgunDamageCap; pAmmo->SetDamageCap(damageCap); } } m_projectileId = pAmmo->GetEntity()->GetId(); pAmmo->SetAmmoCost(ammoCost); } } if (m_pWeapon->IsServer()) { const char *ammoName = ammo != NULL ? ammo->GetName() : NULL; g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(m_pWeapon->GetOwner(), GameplayEvent(eGE_WeaponShot, ammoName, m_fireParams->shotgunparams.pellets, (void *)(EXPAND_PTR)m_pWeapon->GetEntityId())); } m_muzzleEffect.Shoot(this, hit, m_barrelId); m_fired = true; SetNextShotTime(m_next_shot + m_next_shot_dt); ammoCount -= ammoCost; if (ammoCount < m_fireParams->fireparams.minimum_ammo_count) ammoCount = 0; if (clipSize != -1) { if (clipSize != 0) m_pWeapon->SetAmmoCount(ammo, ammoCount); else m_pWeapon->SetInventoryAmmoCount(ammo, ammoCount); } OnShoot(m_pWeapon->GetOwnerId(), firstAmmoId, ammo, pos, dir, vel); const SThermalVisionParams& thermalParams = m_fireParams->thermalVisionParams; m_pWeapon->AddShootHeatPulse(pActor, thermalParams.weapon_shootHeatPulse, thermalParams.weapon_shootHeatPulseTime, thermalParams.owner_shootHeatPulse, thermalParams.owner_shootHeatPulseTime); if (OutOfAmmo()) { m_pWeapon->OnOutOfAmmo(ammo); if (autoreload) { uint32 scheduleTime = max(m_pWeapon->GetCurrentAnimationTime(eIGS_Owner), (uint)(m_next_shot*1000)); m_pWeapon->GetScheduler()->TimerAction(scheduleTime, CSchedulerAction<ScheduleReload>::Create(ScheduleReload(this, m_pWeapon)), false); m_autoReloading = true; } } m_pWeapon->RequestShoot(ammo, pos, dir, vel, hit, 1.0f, 0, false); #if defined(ANTI_CHEAT) const int numProjectiles = projList.size(); uint32 shotId = m_pWeapon->GetLastShotId(); for(int i = 0; i < numProjectiles; i++) { CProjectile * pAmmo = projList[i]; pAmmo->SetShotId(shotId); shotId -= (1 << CWeapon::GetShotIdCountOffset()); } #endif CCCPOINT(Shotgun_Fired); return true; }
bool CSpammer::ShootRocket(EntityId target) { IEntityClass* pAmmoClass = m_fireParams->fireparams.ammo_type_class; int ammoCount = m_pWeapon->GetAmmoCount(pAmmoClass); CActor *pOwnerActor = m_pWeapon->GetOwnerActor(); const bool playerIsShooter = pOwnerActor ? pOwnerActor->IsPlayer() : false; const bool clientIsShooter = pOwnerActor ? pOwnerActor->IsClient() : false; bool bHit = false; ray_hit rayhit; rayhit.pCollider = 0; Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE, &bHit, &rayhit); Vec3 pos = GetFiringPos(hit); Vec3 dir = GetFiringDir(hit, pos); Vec3 vel = GetFiringVelocity(dir); int flags = CItem::eIPAF_Default; if (IsProceduralRecoilEnabled() && pOwnerActor) { pOwnerActor->ProceduralRecoil(m_fireParams->proceduralRecoilParams.duration, m_fireParams->proceduralRecoilParams.strength, m_fireParams->proceduralRecoilParams.kickIn, m_fireParams->proceduralRecoilParams.arms); } float speedOverride = -1.f; GetWeapon()->PlayAction(GetFragmentIds().fire, 0, false, flags, speedOverride); CheckNearMisses(hit, pos, dir, (hit-pos).len(), 1.0f); CProjectile* pAmmo = m_pWeapon->SpawnAmmo(m_fireParams->fireparams.spawn_ammo_class, false); const EntityId weaponOwnerId = m_pWeapon->GetOwnerId(); EntityId ammoId = 0; if (pAmmo) { ammoId = pAmmo->GetEntityId(); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId, string().Format("Invalid hit type '%s' in fire params for '%s'", m_fireParams->fireparams.hit_type.c_str(), m_pWeapon->GetEntity()->GetName())); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId == g_pGame->GetGameRules()->GetHitTypeId(m_fireParams->fireparams.hit_type.c_str()), "Sanity Check Failed: Stored hit type id does not match the type string, possibly CacheResources wasn't called on this weapon type"); pAmmo->SetParams(CProjectile::SProjectileDesc( weaponOwnerId, m_pWeapon->GetHostId(), m_pWeapon->GetEntityId(), m_fireParams->fireparams.damage, m_fireParams->fireparams.damage_drop_min_distance, m_fireParams->fireparams.damage_drop_per_meter, m_fireParams->fireparams.damage_drop_min_damage, m_fireParams->fireparams.hitTypeId, m_fireParams->fireparams.bullet_pierceability_modifier, m_pWeapon->IsZoomed())); // this must be done after owner is set pAmmo->InitWithAI(); pAmmo->SetDestination(target); pAmmo->Launch(pos, dir, vel, m_speed_scale); m_projectileId = ammoId; if (clientIsShooter && pAmmo->IsPredicted() && gEnv->IsClient() && gEnv->bServer) { pAmmo->GetGameObject()->BindToNetwork(); } } if (m_pWeapon->IsServer()) { const char *ammoName = pAmmoClass != NULL ? pAmmoClass->GetName() : NULL; g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(m_pWeapon->GetOwner(), GameplayEvent(eGE_WeaponShot, ammoName, 1, (void *)(EXPAND_PTR)m_pWeapon->GetEntityId())); } OnShoot(weaponOwnerId, ammoId, pAmmoClass, pos, dir, vel); if(playerIsShooter) { const SThermalVisionParams& thermalParams = m_fireParams->thermalVisionParams; m_pWeapon->AddShootHeatPulse(pOwnerActor, thermalParams.weapon_shootHeatPulse, thermalParams.weapon_shootHeatPulseTime, thermalParams.owner_shootHeatPulse, thermalParams.owner_shootHeatPulseTime); } m_muzzleEffect.Shoot(this, hit, m_barrelId); RecoilImpulse(pos, dir); m_fired = true; m_next_shot += m_next_shot_dt; if (++m_barrelId == m_fireParams->fireparams.barrel_count) m_barrelId = 0; ammoCount--; int clipSize = GetClipSize(); if (clipSize != -1) { if (clipSize!=0) m_pWeapon->SetAmmoCount(pAmmoClass, ammoCount); else m_pWeapon->SetInventoryAmmoCount(pAmmoClass, ammoCount); } m_pWeapon->RequestShoot(pAmmoClass, pos, dir, vel, hit, m_speed_scale, pAmmo? pAmmo->GetGameObject()->GetPredictionHandle() : 0, false); return true; }
//------------------------------------------------------------------------ void CShotgun::NetShootEx(const Vec3 &pos, const Vec3 &dir, const Vec3 &vel, const Vec3 &hit, float extra, int ph) { CCCPOINT(Shotgun_NetShoot); assert(0 == ph); IEntityClass* ammo = m_fireParams->fireparams.ammo_type_class; FragmentID action = m_fireParams->fireparams.no_cock ? GetFragmentIds().fire : GetFragmentIds().fire_cock; CActor *pActor = m_pWeapon->GetOwnerActor(); bool playerIsShooter = pActor?pActor->IsPlayer():false; int ammoCount = m_pWeapon->GetAmmoCount(ammo); int clipSize = GetClipSize(); if (clipSize == 0) ammoCount = m_pWeapon->GetInventoryAmmoCount(ammo); if (ammoCount == 1) action = GetFragmentIds().fire; if (IsProceduralRecoilEnabled() && pActor) { pActor->ProceduralRecoil(m_fireParams->proceduralRecoilParams.duration, m_fireParams->proceduralRecoilParams.strength, m_fireParams->proceduralRecoilParams.kickIn,m_fireParams->proceduralRecoilParams.arms); } m_pWeapon->PlayAction(action, 0, false, CItem::eIPAF_Default); Vec3 pdir; int quad = cry_random(0, 3); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId, string().Format("Invalid hit type '%s' in fire params for '%s'", m_fireParams->fireparams.hit_type.c_str(), m_pWeapon->GetEntity()->GetName())); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId == g_pGame->GetGameRules()->GetHitTypeId(m_fireParams->fireparams.hit_type.c_str()), "Sanity Check Failed: Stored hit type id does not match the type string, possibly CacheResources wasn't called on this weapon type"); int ammoCost = m_fireParams->fireparams.fake_fire_rate ? m_fireParams->fireparams.fake_fire_rate : 1; ammoCost = min(ammoCost, ammoCount); // SHOT HERE for (int i = 0; i < m_fireParams->shotgunparams.pellets; i++) { CProjectile *pAmmo = m_pWeapon->SpawnAmmo(m_fireParams->fireparams.spawn_ammo_class, true); if (pAmmo) { pdir = ApplySpread(dir, m_fireParams->shotgunparams.spread, quad); quad = (quad+1)%4; CProjectile::SProjectileDesc projectileDesc( m_pWeapon->GetOwnerId(), m_pWeapon->GetHostId(), m_pWeapon->GetEntityId(), m_fireParams->shotgunparams.pelletdamage, m_fireParams->fireparams.damage_drop_min_distance, m_fireParams->fireparams.damage_drop_min_damage, m_fireParams->fireparams.damage_drop_per_meter, m_fireParams->fireparams.hitTypeId, m_fireParams->fireparams.bullet_pierceability_modifier, m_pWeapon->IsZoomed()); projectileDesc.pointBlankAmount = m_fireParams->fireparams.point_blank_amount; projectileDesc.pointBlankDistance = m_fireParams->fireparams.point_blank_distance; projectileDesc.pointBlankFalloffDistance = m_fireParams->fireparams.point_blank_falloff_distance; if (m_fireParams->fireparams.ignore_damage_falloff) projectileDesc.damageFallOffAmount = 0.0f; pAmmo->SetParams(projectileDesc); pAmmo->SetDestination(m_pWeapon->GetDestination()); pAmmo->SetRemote(true); pAmmo->Launch(pos, pdir, vel); bool emit = false; if(m_pWeapon->GetStats().fp) emit = (!m_fireParams->tracerparams.geometryFP.empty() || !m_fireParams->tracerparams.effectFP.empty()) && ((ammoCount == clipSize) || (ammoCount%m_fireParams->tracerparams.frequency==0)); else emit = (!m_fireParams->tracerparams.geometry.empty() || !m_fireParams->tracerparams.effect.empty()) && ((ammoCount == clipSize) || (ammoCount%m_fireParams->tracerparams.frequency==0)); if (emit) { EmitTracer(pos, hit, &m_fireParams->tracerparams, pAmmo); } m_projectileId = pAmmo->GetEntity()->GetId(); pAmmo->SetAmmoCost(ammoCost); } } if (m_pWeapon->IsServer()) { const char *ammoName = ammo != NULL ? ammo->GetName() : NULL; g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(m_pWeapon->GetOwner(), GameplayEvent(eGE_WeaponShot, ammoName, m_fireParams->shotgunparams.pellets, (void *)(EXPAND_PTR)m_pWeapon->GetEntityId())); } m_muzzleEffect.Shoot(this, hit, m_barrelId); m_fired = true; m_next_shot = 0.0f; ammoCount -= ammoCost; if (m_pWeapon->IsServer()) { if (clipSize != -1) { if (clipSize != 0) m_pWeapon->SetAmmoCount(ammo, ammoCount); else m_pWeapon->SetInventoryAmmoCount(ammo, ammoCount); } } OnShoot(m_pWeapon->GetOwnerId(), 0, ammo, pos, dir, vel); m_pWeapon->RequireUpdate(eIUS_FireMode); }
void CHeavyMountedWeapon::PerformRipOff(CActor* pOwner) { ExitZoom(true); UnlinkMountedGun(); SetUnMountedConfiguration(); // This needs to come after the call to UnlinkMountedGun otherwise killcam doesn't work properly AttachToHand(true); StopFire(); Physicalize(false, false); if (pOwner) { HandleHeavyWeaponPro(*pOwner); float speedOverride = 1.0f; if(pOwner->IsPlayer()) { CPlayer* pOwnerPlayer = static_cast<CPlayer*>(pOwner); speedOverride = pOwnerPlayer->GetModifiableValues().GetValue(kPMV_HeavyWeaponRipOffSpeedOverride); } PlayAction(GetFragmentIds().rip_off, 0, false, eIPAF_Default, speedOverride); m_rippingOff = true; m_stats.dropped = false; DoRipOffPrompt(GetOwnerId(), false); int timeDelay = GetCurrentAnimationTime(eIGS_Owner); timeDelay = (timeDelay > 0) ? timeDelay : 2000; int removeViewLimitDelay = int(timeDelay * 0.65f); GetScheduler()->TimerAction(timeDelay, CSchedulerAction<EndRippingOff>::Create(EndRippingOff(this)), false); GetScheduler()->TimerAction(removeViewLimitDelay, CSchedulerAction<RemoveViewLimitsAction>::Create(RemoveViewLimitsAction(this)), false); if(!pOwner->IsThirdPerson() && !(m_stats.viewmode&eIVM_FirstPerson)) { SetViewMode(eIVM_FirstPerson); } //Lock view in place during rip off SActorParams ¶ms = pOwner->GetActorParams(); Vec3 limitDir(ZERO); bool bUseMovementState = true; if (pOwner->IsClient() && (g_pGame->GetHostMigrationState() != CGame::eHMS_NotMigrating)) { // If this happens during a host migration, our aim direction may not have made it into the movement // controller yet, get it from the saved migration params instead const CGameRules::SHostMigrationClientControlledParams *pHostMigrationParams = g_pGame->GetGameRules()->GetHostMigrationClientParams(); if (pHostMigrationParams) { limitDir = pHostMigrationParams->m_aimDirection; bUseMovementState = false; } } if (bUseMovementState) { IMovementController *pMovementController = pOwner->GetMovementController(); SMovementState state; pMovementController->GetMovementState(state); limitDir = state.aimDirection; } params.viewLimits.SetViewLimit(limitDir, 0.01f, 0.01f, 0.01f, 0.01f, SViewLimitParams::eVLS_Item); pOwner->SetSpeedMultipler(SActorParams::eSMR_Item, 0.0f); if(!gEnv->bMultiplayer) pOwner->LockInteractor(GetEntityId(), false); } TriggerRespawn(); if (pOwner) { if (CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem()) { pRecordingSystem->OnWeaponRippedOff(this); } BATTLECHATTER(BC_Ripoff, GetOwnerId()); if(pOwner->IsClient()) { g_pGame->GetPersistantStats()->IncrementClientStats(EIPS_RipOffMountedWeapon); ClearInputFlag(eWeaponAction_Zoom); } } else { //--- If ripped off without an actor we should finish instantly m_rippingOff = false; m_rippedOff = true; } }
//------------------------------------------------------------------------ IMPLEMENT_RMI(CItem, ClEnterModify) { PlayAction(GetFragmentIds().enter_modify, 0, false, eIPAF_Default ); return true; }
void CLTagSingle::NetShootEx(const Vec3 &pos, const Vec3 &dir, const Vec3 &vel, const Vec3 &hit, float extra, int predictionHandle) { IEntityClass* ammo = m_fireParams->fireparams.ammo_type_class; int weaponAmmoCount = m_pWeapon->GetAmmoCount(ammo); int ammoCount = weaponAmmoCount; CActor* pOwnerActor = m_pWeapon->GetOwnerActor(); bool playerIsShooter = pOwnerActor ? pOwnerActor->IsPlayer() : false; if (IsProceduralRecoilEnabled() && pOwnerActor) { pOwnerActor->ProceduralRecoil(m_fireParams->proceduralRecoilParams.duration, m_fireParams->proceduralRecoilParams.strength, m_fireParams->proceduralRecoilParams.kickIn, m_fireParams->proceduralRecoilParams.arms); } m_pWeapon->PlayAction(GetFragmentIds().fire, 0, false, CItem::eIPAF_Default); CProjectile *pAmmo = m_pWeapon->SpawnAmmo(m_fireParams->fireparams.spawn_ammo_class, true); CLTAGGrenade* pGrenade = static_cast<CLTAGGrenade*>(pAmmo); if (pGrenade) { CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId, string().Format("Invalid hit type '%s' in fire params for '%s'", m_fireParams->fireparams.hit_type.c_str(), m_pWeapon->GetEntity()->GetName())); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId == g_pGame->GetGameRules()->GetHitTypeId(m_fireParams->fireparams.hit_type.c_str()), "Sanity Check Failed: Stored hit type id does not match the type string, possibly CacheResources wasn't called on this weapon type"); pGrenade->SetParams(CProjectile::SProjectileDesc( m_pWeapon->GetOwnerId(), m_pWeapon->GetHostId(), m_pWeapon->GetEntityId(), m_fireParams->fireparams.damage, 0.f, 0.f, 0.f, m_fireParams->fireparams.hitTypeId, m_fireParams->fireparams.bullet_pierceability_modifier, m_pWeapon->IsZoomed())); // this must be done after owner is set pGrenade->InitWithAI(); pGrenade->SetDestination(m_pWeapon->GetDestination()); pGrenade->SetGrenadeType(m_grenadeType); pGrenade->Launch(pos, dir, vel, m_speed_scale); m_projectileId = pGrenade->GetEntity()->GetId(); } if (m_pWeapon->IsServer()) { const char *ammoName = ammo != NULL ? ammo->GetName() : NULL; g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(m_pWeapon->GetOwner(), GameplayEvent(eGE_WeaponShot, ammoName, 1, (void *)(EXPAND_PTR)m_pWeapon->GetEntityId())); #ifdef SERVER_CHECKS if (pOwnerActor && m_pWeapon->IsServerSpawn(ammo)) { int inventoryAmmoCount = m_pWeapon->GetInventoryAmmoCount(ammo); int totalAmmoCount=weaponAmmoCount+inventoryAmmoCount; // this needed seeing as how this seems to use weaponAmmo or inventoryAmmo but NOT both? if (totalAmmoCount <= 0) { g_pGame->GetAntiCheatManager()->FlagActivity(eCT_ServerSpawnedAmmoUsed, pOwnerActor->GetChannelId()); } } #endif } m_muzzleEffect.Shoot(this, hit, m_barrelId); RecoilImpulse(pos, dir); m_fired = true; m_next_shot = 0.0f; ammoCount--; if(ammoCount<0) ammoCount = 0; if (m_pWeapon->IsServer()) { int clipSize = GetClipSize(); if (clipSize != -1) { if (clipSize != 0) m_pWeapon->SetAmmoCount(ammo, ammoCount); else m_pWeapon->SetInventoryAmmoCount(ammo, ammoCount); } } OnShoot(m_pWeapon->GetOwnerId(), pAmmo?pAmmo->GetEntity()->GetId():0, ammo, pos, dir, vel); if(playerIsShooter) { const SThermalVisionParams& thermalParams = m_fireParams->thermalVisionParams; m_pWeapon->AddShootHeatPulse(pOwnerActor, thermalParams.weapon_shootHeatPulse, thermalParams.weapon_shootHeatPulseTime, thermalParams.owner_shootHeatPulse, thermalParams.owner_shootHeatPulseTime); } if (OutOfAmmo()) m_pWeapon->OnOutOfAmmo(ammo); if (pAmmo && predictionHandle && pOwnerActor) { pAmmo->GetGameObject()->RegisterAsValidated(pOwnerActor->GetGameObject(), predictionHandle); pAmmo->GetGameObject()->BindToNetwork(); } else if (pAmmo && pAmmo->IsPredicted() && gEnv->IsClient() && gEnv->bServer && pOwnerActor && pOwnerActor->IsClient()) { pAmmo->GetGameObject()->BindToNetwork(); } m_pWeapon->RequireUpdate(eIUS_FireMode); }
//------------------------------------------------------------------------ IMPLEMENT_RMI(CItem, ClLeaveModify) { PlayAction(GetFragmentIds().leave_modify, 0); return true; }
void CAccessory::PickUp(EntityId pickerId, bool sound, bool select/* =true */, bool keepHistory/* =true */, const char *setup /*= NULL*/) { CActor *pActor=GetActor(pickerId); if (!pActor) return; TriggerRespawn(); GetEntity()->EnablePhysics(false); Physicalize(false, false); bool soundEnabled = IsSoundEnabled(); EnableSound(sound); SetViewMode(0); SetOwnerId(pickerId); CopyRenderFlags(GetOwner()); Hide(true); m_stats.dropped = false; m_stats.detached = false; m_stats.brandnew = false; IInventory *pInventory = pActor->GetInventory(); if (!pInventory) { GameWarning("Actor '%s' has no inventory, when trying to pickup '%s'!",pActor->GetEntity()->GetName(),GetEntity()->GetName()); return; } if (!pActor->IsPlayer() || pActor->IsClient() || gEnv->bMultiplayer) { bool hasAccessory = pInventory->HasAccessory(GetEntity()->GetClass()); bool hasAccessoryForThisWeapon = pInventory->HasAccessory(GetEntity()->GetClass()); if (!hasAccessoryForThisWeapon) pInventory->AddAccessory(GetEntity()->GetClass()); if (!hasAccessory) ProcessAccessoryAmmoCapacities(pInventory, true); if (!hasAccessoryForThisWeapon) ProcessAccessoryAmmo(pInventory); } OnPickedUp(pickerId, m_sharedparams->params.unique); if (select) { PlayAction(GetFragmentIds().pickedup); } EnableSound(soundEnabled); bool isLocalEntity = GetEntity()->GetFlags()&(ENTITY_FLAG_CLIENT_ONLY|ENTITY_FLAG_SERVER_ONLY) ? true : false; if (IsServer() && !IsDemoPlayback()) { if(!gEnv->bMultiplayer || isLocalEntity) RemoveEntity(); else if(g_pGame->GetGameRules()) g_pGame->GetGameRules()->ScheduleEntityRemoval(GetEntityId(),10.0f,false); //Give some time to the clients to pick the msg } if (IsServer()) { GetGameObject()->SetNetworkParent(pickerId); if (!isLocalEntity) { pActor->GetGameObject()->InvokeRMIWithDependentObject(CActor::ClPickUp(), CActor::PickItemParams(GetEntityId(), m_stats.selected, sound), eRMI_ToAllClients|eRMI_NoLocalCalls, GetEntityId()); } } }
//------------------------------------------------------------------------- bool CWeapon::OnActionModify(EntityId actorId, const ActionId& actionId, int activationMode, float value) { if (IsZoomed() || IsZoomingInOrOut()) return false; if (CanModify() && ((!IsReloading() && !IsBusy()) || AreAnyItemFlagsSet(eIF_Modifying))) { if (m_fm) m_fm->StopFire(); if (AreAnyItemFlagsSet(eIF_Modifying)) { m_enterModifyAction = 0; PlayAction(GetFragmentIds().leave_modify, 0); s_dofSpeed = fres(-g_pGameCVars->i_weapon_customisation_transition_time); s_dofValue = 1.0f; s_focusValue = -1.0f; GetScheduler()->TimerAction(g_pGameCVars->i_weapon_customisation_transition_time, CSchedulerAction<ScheduleLayer_Leave>::Create(this), false); SetItemFlags( eIF_Transitioning ); ClearItemFlags( eIF_Modifying ); GetGameObject()->InvokeRMI(CItem::SvRequestLeaveModify(), CItem::EmptyParams(), eRMI_ToServer); } else { gEnv->p3DEngine->SetPostEffectParam("Dof_Active", 1.0f); gEnv->p3DEngine->SetPostEffectParam("Dof_UseMask", 0.f); gEnv->p3DEngine->SetPostEffectParam("Dof_FocusRange", -1.f); gEnv->p3DEngine->SetPostEffectParam("Dof_FocusMin", 0.5f); gEnv->p3DEngine->SetPostEffectParam("Dof_FocusMax", 1.0f); gEnv->p3DEngine->SetPostEffectParam("Dof_FocusLimit", 1.5f); gEnv->p3DEngine->SetPostEffectParam("Dof_FocusMinZ", 0.0f); gEnv->p3DEngine->SetPostEffectParam("Dof_FocusMinZScale", 0.0f); m_itemLowerMode = eILM_Raised; TagState tagState = TAG_STATE_EMPTY; m_enterModifyAction = new CItemAction(PP_PlayerAction, GetFragmentIds().enter_modify, tagState); PlayFragment(m_enterModifyAction); s_dofSpeed = fres(g_pGameCVars->i_weapon_customisation_transition_time); s_dofValue = 0.0f; SetItemFlags(eIF_Transitioning); GetScheduler()->TimerAction(g_pGameCVars->i_weapon_customisation_transition_time, CSchedulerAction<ScheduleLayer_Enter>::Create(this), false); SetItemFlags(eIF_Modifying); CPlayer *pPlayer = static_cast<CPlayer*>(GetOwnerActor()); if (pPlayer) { SPlayerStats *pStats = static_cast<SPlayerStats*>(pPlayer->GetActorStats()); assert(pStats); pStats->bIgnoreSprinting = true; } GetGameObject()->InvokeRMI(CItem::SvRequestEnterModify(), CItem::EmptyParams(), eRMI_ToServer); } } return true; }