//------------------------------------------------------------------------ void CShotgun::NetShootEx(const Vec3 &pos, const Vec3 &dir, const Vec3 &vel, const Vec3 &hit, float extra, int ph) { assert(0 == ph); IEntityClass *ammo = m_pShared->fireparams.ammo_type_class; const char *action = m_pShared->actions.fire_cock.c_str(); CActor *pActor = m_pWeapon->GetOwnerActor(); bool playerIsShooter = pActor?pActor->IsPlayer():false; int ammoCount = m_pWeapon->GetAmmoCount(ammo); if(m_pShared->fireparams.clip_size==0) ammoCount = m_pWeapon->GetInventoryAmmoCount(ammo); if(ammoCount == 1) action = m_pShared->actions.fire.c_str(); m_pWeapon->ResetAnimation(); m_pWeapon->PlayAction(action, 0, false, CItem::eIPAF_Default|CItem::eIPAF_NoBlend); Vec3 pdir; // SHOT HERE for(int i = 0; i < m_pShared->shotgunparams.pellets; i++) { CProjectile *pAmmo = m_pWeapon->SpawnAmmo(ammo, true); if(pAmmo) { pdir = ApplySpread(dir, m_pShared->shotgunparams.spread); int hitTypeId = g_pGame->GetGameRules()->GetHitTypeId(m_pShared->fireparams.hit_type.c_str()); pAmmo->SetParams(m_pWeapon->GetOwnerId(), m_pWeapon->GetHostId(), m_pWeapon->GetEntityId(), m_pShared->shotgunparams.pelletdamage, hitTypeId, playerIsShooter?m_pShared->fireparams.damage_drop_per_meter:0.0f, m_pShared->fireparams.damage_drop_min_distance); pAmmo->SetDestination(m_pWeapon->GetDestination()); pAmmo->SetRemote(true); pAmmo->Launch(pos, pdir, vel); bool emit = false; if(m_pWeapon->GetStats().fp) emit = (!m_pShared->tracerparams.geometryFP.empty() || !m_pShared->tracerparams.effectFP.empty()) && (ammoCount==GetClipSize() || (ammoCount%m_pShared->tracerparams.frequency==0)); else emit = (!m_pShared->tracerparams.geometry.empty() || !m_pShared->tracerparams.effect.empty()) && (ammoCount==GetClipSize() || (ammoCount%m_pShared->tracerparams.frequency==0)); if(emit) EmitTracer(pos,hit,false); m_projectileId = pAmmo->GetEntity()->GetId(); } } m_pWeapon->OnShoot(m_pWeapon->GetOwnerId(), 0, ammo, pos, dir, vel); 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_pShared->shotgunparams.pellets, (void *)m_pWeapon->GetEntityId())); } MuzzleFlashEffect(true); RejectEffect(); m_fired = true; m_next_shot = 0.0f; ammoCount--; if(m_pWeapon->IsServer()) { if(m_pShared->fireparams.clip_size != -1) { if(m_pShared->fireparams.clip_size!=0) m_pWeapon->SetAmmoCount(ammo, ammoCount); else m_pWeapon->SetInventoryAmmoCount(ammo, ammoCount); } } if((ammoCount<1) && !m_pShared->fireparams.slider_layer.empty()) { const char *slider_back_layer = m_pShared->fireparams.slider_layer.c_str(); m_pWeapon->PlayLayer(slider_back_layer, CItem::eIPAF_Default|CItem::eIPAF_NoBlend); } m_pWeapon->RequireUpdate(eIUS_FireMode); }
//------------------------------------------------------------------------ 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); }