//this function basically returns a smoothed movement vector, for better movement responsivness in small spaces const Vec3 &CPlayerInput::FilterMovement(const Vec3 &desired) { float frameTimeCap(min(gEnv->pTimer->GetFrameTime(),0.033f)); float inputAccel(g_pGameCVars->pl_inputAccel); Vec3 oldFilteredMovement = m_filteredDeltaMovement; if (desired.len2()<0.01f) { m_filteredDeltaMovement.zero(); } else if (inputAccel<=0.0f) { m_filteredDeltaMovement = desired; } else { Vec3 delta(desired - m_filteredDeltaMovement); float len(delta.len()); if (len<=1.0f) delta = delta * (1.0f - len*0.55f); m_filteredDeltaMovement += delta * min(frameTimeCap * inputAccel,1.0f); } if (oldFilteredMovement.GetDistance(m_filteredDeltaMovement) > 0.001f) m_pPlayer->GetGameObject()->ChangedNetworkState( INPUT_ASPECT ); return m_filteredDeltaMovement; }
bool CLaser::GetProbableHit(EntityId weaponId, const IFireMode* pFireMode, Vec3& hit) { if (!m_laserBeam.IsLaserActivated()) return false; if(gEnv->bMultiplayer) { CWeapon* pParentWeapon = GetWeapon(); if (pParentWeapon && pParentWeapon->IsZoomed()) { return false; } } CWeapon* pWeapon = GetWeapon(); int slot = pWeapon->IsOwnerFP() ? eIGS_FirstPerson : eIGS_ThirdPerson; Vec3 lastBeamHit = m_laserBeam.GetLastHit(); Vec3 currentBeamPosition = pWeapon->GetSlotHelperPos(slot, "weapon_term", true); Matrix33 rotation = pWeapon->GetSlotHelperRotation(slot, "weapon_term", true); Vec3 currentBeamDirection = rotation.GetColumn1(); const CFireMode* pCFireMode = static_cast<const CFireMode*>(pFireMode); const CSingle* pSingle = crygti_cast<const CSingle*>(pCFireMode); if (pSingle && pSingle->GetShared()->fireparams.laser_beam_uses_spread) { currentBeamDirection = pSingle->ApplySpread(currentBeamDirection, pSingle->GetSpread()); } float distanceToLastHit = lastBeamHit.GetDistance(currentBeamPosition); hit = currentBeamPosition + currentBeamDirection * distanceToLastHit; return true; }
float SearchGroup::CalculateScore(SearchSpot& searchSpot, EntityId entityID, SearchSpotQuery* query, Vec3& targetCurrentPos) const { assert(query); Agent agent(entityID); if (agent.IsValid()) { const Vec3 spotPosition = searchSpot.GetPos(); const Vec3 agentPosition = agent.GetPos(); const float agentToSpotDistance = agentPosition.GetDistance(spotPosition); if (agentToSpotDistance < query->minDistanceFromAgent) { return -100.0f; } float closenessToAgentScore = 0.0f; closenessToAgentScore = 1.0f - clamp_tpl(agentToSpotDistance, 1.0f, 50.0f) / 50.0f; const float closenessToTargetScore = 1.0f - clamp_tpl(spotPosition.GetDistance(m_targetPos), 1.0f, 50.0f) / 50.0f; float closenessToTargetCurrentPosScore = 0.0f; if (!targetCurrentPos.IsZeroFast()) { closenessToTargetCurrentPosScore = 1.0f - clamp_tpl(spotPosition.GetDistance(targetCurrentPos), 1.0f, 50.0f) / 50.0f; } return closenessToAgentScore * query->closenessToAgentWeight + closenessToTargetScore * query->closenessToTargetWeight + closenessToTargetCurrentPosScore * query->closenessToTargetCurrentPosWeight; } else { return -100.0f; } }
void CSpammer::UpdatePotentialTargets() { const float minLockOnDistance = m_fireParams->spammerParams.minLockOnDistance; const float maxLockOnDistance = m_fireParams->spammerParams.maxLockOnDistance; const float maxAngleCos = cry_cosf(DEG2RAD(m_fireParams->spammerParams.targetingTolerance)); const CAutoAimManager& autoAimManager = g_pGame->GetAutoAimManager(); const TAutoaimTargets& aaTargets = autoAimManager.GetAutoAimTargets(); const int targetCount = aaTargets.size(); const Vec3 probableHit = Vec3Constants<float>::fVec3_Zero; const Vec3 weaponPos = GetWeaponPosition(probableHit); const Vec3 weaponFwd = GetWeaponDirection(weaponPos, probableHit); m_potentialTargets.Clear(); CPlayerVisTable::SVisibilityParams queryTargetParams(0); const bool flat2DMode = m_fireParams->spammerParams.targetingFlatMode; for (int i = 0; i < targetCount; ++i) { const SAutoaimTarget& target = aaTargets[i]; CRY_ASSERT(target.entityId != m_pWeapon->GetOwnerId()); if (!target.HasFlagSet(eAATF_AIHostile)) continue; IEntity* pTargetEntity = gEnv->pEntitySystem->GetEntity(target.entityId); if (!pTargetEntity) continue; CActor* pActor = target.pActorWeak.lock().get(); AABB bounds; pTargetEntity->GetWorldBounds(bounds); Vec3 targetPos = bounds.GetCenter(); Vec3 targetDistVec = (targetPos - weaponPos).normalized(); float distance = targetPos.GetDistance(weaponPos); if (distance <= minLockOnDistance || distance >= maxLockOnDistance) continue; float alignment; if (!flat2DMode) { alignment = weaponFwd * targetDistVec; } else { const CCamera& viewCamera = gEnv->pSystem->GetViewCamera(); if (!viewCamera.IsPointVisible(targetPos)) continue; alignment = Vec3(weaponFwd.x, weaponFwd.y, 0.0f).GetNormalizedSafe() * Vec3(targetDistVec.x, targetDistVec.y, 0.0f).GetNormalizedSafe(); } if (alignment <= maxAngleCos) continue; const SpammerTarget finalTargetInfo = GetVisibilityTestTarget(pTargetEntity, target.entityId, pActor, bounds); const int kAutoaimVisibilityLatency = 0; queryTargetParams.targetEntityId = finalTargetInfo.targetId; if (!g_pGame->GetPlayerVisTable()->CanLocalPlayerSee(queryTargetParams, kAutoaimVisibilityLatency)) continue; float priority = 1.0f; priority *= finalTargetInfo.radius; priority /= m_targetsAssigned.GetNumLockOns(target.entityId)+1; const float m = 1.0f / (1.0f - maxAngleCos); priority *= m * alignment + (1.0f - m); priority *= 0.1f; priority = min(priority, 1.0f); m_potentialTargets.AddTarget(target.entityId, priority); } float n = 0.0f; size_t num = m_potentialTargets.m_potentialTargets.size(); for (size_t i = 0; i < num; ++i) { n = max(n, m_potentialTargets.m_potentialTargets[i].m_probability); } m_potentialTargets.m_totalProbability = 0.0f; for (size_t i = 0; num && i < m_potentialTargets.m_potentialTargets.size(); ++i) { m_potentialTargets.m_potentialTargets[i].m_probability /= n + FLT_EPSILON; m_potentialTargets.m_totalProbability += m_potentialTargets.m_potentialTargets[i].m_probability; } }
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; }