예제 #1
0
파일: C4.cpp 프로젝트: super-nova/NovaRepo
//------------------------------------------------------------------------
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;
};
예제 #2
0
//------------------------------------------------------------------------
void CVehicleWeapon::StartUse(EntityId userId)
{
	if (m_ownerId && userId != m_ownerId)
		return; 

  if (GetEntity()->GetParent())
  { 
    m_pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(GetEntity()->GetParent()->GetId());
    assert(m_pVehicle && "Using VehicleWeapons on non-vehicles may lead to unexpected behavior.");

    if (m_pVehicle)
    {   
      m_pPart = m_pVehicle->GetWeaponParentPart(GetEntityId()); 
      m_pOwnerSeat = m_pVehicle->GetWeaponParentSeat(GetEntityId());
      m_pSeatUser = m_pVehicle->GetSeatForPassenger(userId);
    }
  }
  
	SetOwnerId(userId);
  Select(true);	
	m_stats.used = true;

	EnableUpdate(true, eIUS_General);
	RequireUpdate(eIUS_General);

  if (OutOfAmmo(false))
    Reload(false);

  UseManualBlending(true);

	LowerWeapon(false);

	SendMusicLogicEvent(eMUSICLOGICEVENT_WEAPON_MOUNT);

}
예제 #3
0
파일: Plant.cpp 프로젝트: Xydrel/Infected
//------------------------------------------------------------------------
void CPlant::CheckAmmo()
{
	if(m_pWeapon->GetOwnerActor())
	{
		bool noAmmo = OutOfAmmo();
		m_pWeapon->HideItem(noAmmo);
	}
}
예제 #4
0
//------------------------------------------------------------------------
void CBurst::EndBurst()
{
	m_pWeapon->EndBurst();

	//Generally handled by Single::Shoot for most weapons - but bursts dont go through there for clients
	if(!gEnv->bServer && OutOfAmmo())
	{
		OnOutOfAmmo(m_pWeapon->GetOwnerActor(), m_fireParams->fireparams.autoReload);
	}
}
//------------------------------------------------------------------------
void CRapid::UpdateSound(float frameTime)
{
	if (m_speed >= 0.00001f)
	{
		if (m_soundId == INVALID_SOUNDID)
		{
			m_soundId = m_pWeapon->PlayAction(m_pShared->rapidactions.rapid_fire, 0, true, CItem::eIPAF_Default & (~CItem::eIPAF_Animation));
		}

		if (m_soundId != INVALID_SOUNDID)
		{
			float rpm_scale = m_speed / m_pShared->rapidparams.min_speed;
			float ammo = 0;

			if (!OutOfAmmo())
			{
				ammo = 1.0f;
			}

			ISound *pSound = m_pWeapon->GetISound(m_soundId);

			if (pSound)
			{
				if (g_pGameCVars->i_debug_sounds)
				{
					float color[] = {1, 1, 1, 0.5};
					gEnv->pRenderer->Draw2dLabel(150, 500, 1.3f, color, false, "%s rpm_scale: %.2f", m_pWeapon->GetEntity()->GetName(), rpm_scale);
				}

				pSound->SetParam("rpm_scale", rpm_scale, false);
				pSound->SetParam("ammo", ammo, false);

				//Sound variations for FY71 (AI most common weapon)
				if(m_pShared->fireparams.sound_variation && !m_pWeapon->IsOwnerFP())
				{
					pSound->SetParam("variations", m_soundVariationParam, true);
				}
			}

			if (m_speed >= m_pShared->rapidparams.min_speed)
			{
				m_spinUpSoundId = INVALID_SOUNDID;
			}
		}
	}
	else if (m_soundId != INVALID_SOUNDID)
	{
		m_pWeapon->StopSound(m_soundId);
		m_soundId = INVALID_SOUNDID;
	}
}
예제 #6
0
//------------------------------------------------------------------------
void CVehicleWeapon::StartUse(EntityId userId)
{
	if (m_owner.GetId() && userId != m_owner.GetId())
		return; 

  if (GetEntity()->GetParent())
  { 
		const EntityId vehicleId = GetEntity()->GetParent()->GetId();
		m_vehicleId = vehicleId;
    IVehicle* pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(vehicleId);
    assert(pVehicle && "Using VehicleWeapons on non-vehicles may lead to unexpected behavior.");

    if (pVehicle)
    {
      IVehicleSeat* pOwnerSeat = pVehicle->GetWeaponParentSeat(GetEntityId());
      IVehicleSeat* pSeatUser = pVehicle->GetSeatForPassenger(userId);
			m_bOwnerInSeat = (pOwnerSeat == pSeatUser);

			if(userId == g_pGame->GetIGameFramework()->GetClientActorId())
			{
				pVehicle->RegisterVehicleEventListener(this, "CVehicleWeapon");
			}
    }
  }
  
	SetOwnerId(userId);
  Select(true);	
	m_stats.used = true;

	EnableUpdate(true, eIUS_General);
	RequireUpdate(eIUS_General);

  if (OutOfAmmo(false))
    Reload(false);

  m_shootCounter = 0;
	
	if(userId == g_pGame->GetIGameFramework()->GetClientActorId())
	{
		SHUDEvent	event;

		event.eventType			= eHUDEvent_OnItemSelected;
		event.eventIntData	= CItem::GetEntityId();

		CHUDEventDispatcher::CallEvent(event);

		SHUDEventWrapper::FireModeChanged(this, m_firemode);
	}
}
예제 #7
0
파일: C4.cpp 프로젝트: super-nova/NovaRepo
//------------------------------------------------------------------------
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);
}
예제 #8
0
bool CShotgun::Shoot(bool resetAnimation, bool autoreload/* =true */, bool noSound /* =false */)
{
	IEntityClass *ammo = m_pShared->fireparams.ammo_type_class;
	int ammoCount = m_pWeapon->GetAmmoCount(ammo);

	if(m_pShared->fireparams.clip_size==0)
		ammoCount = m_pWeapon->GetInventoryAmmoCount(ammo);

	CActor *pActor = m_pWeapon->GetOwnerActor();
	bool playerIsShooter = pActor?pActor->IsPlayer():false;

	if(!CanFire(true))
	{
		if((ammoCount <= 0) && (!m_reloading))
		{
			m_pWeapon->PlayAction(m_pShared->actions.empty_clip);
			//Auto reload
			m_pWeapon->Reload();
		}

		return false;
	}
	else if(m_pWeapon->IsWeaponLowered())
	{
		m_pWeapon->PlayAction(m_pShared->actions.null_fire);
		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();
		}

		return false;
	}

	// Aim assistance
	m_pWeapon->AssistAiming();

	const char *action = m_pShared->actions.fire_cock.c_str();

	if(ammoCount == 1 || (m_pShared->fireparams.no_cock && m_pWeapon->IsZoomed()))
		action = m_pShared->actions.fire.c_str();

	m_pWeapon->PlayAction(action, 0, false, CItem::eIPAF_Default|CItem::eIPAF_RestartAnimation|CItem::eIPAF_CleanBlending);

	Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE);
	Vec3 pos = GetFiringPos(hit);
	Vec3 fdir = ApplySpread(GetFiringDir(hit, pos), GetSpread());
	Vec3 vel = GetFiringVelocity(fdir);
	Vec3 dir;

	CheckNearMisses(hit, pos, fdir, WEAPON_HIT_RANGE, m_pShared->shotgunparams.spread);

	bool serverSpawn = m_pWeapon->IsServerSpawn(ammo);

	// SHOT HERE
	for(int i = 0; i < m_pShared->shotgunparams.pellets; i++)
	{
		CProjectile *pAmmo = m_pWeapon->SpawnAmmo(ammo, false);

		if(pAmmo)
		{
			dir = ApplySpread(fdir, 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->Launch(pos, dir, vel);

			if((!m_pShared->tracerparams.geometry.empty() || !m_pShared->tracerparams.effect.empty()) && (ammoCount==GetClipSize() || (ammoCount%m_pShared->tracerparams.frequency==0)))
			{
				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 += m_next_shot_dt;
	m_zoomtimeout = m_next_shot + 0.5f;
	ammoCount--;

	if(playerIsShooter)
	{
		if(pActor->InZeroG())
		{
			IEntityPhysicalProxy *pPhysicsProxy = (IEntityPhysicalProxy *)pActor->GetEntity()->GetProxy(ENTITY_PROXY_PHYSICS);
			SMovementState ms;
			pActor->GetMovementController()->GetMovementState(ms);
			CPlayer *plr = (CPlayer *)pActor;

			if(m_recoilparams.back_impulse > 0.0f)
			{
				Vec3 impulseDir = ms.aimDirection * -1.0f;
				Vec3 impulsePos = ms.pos;
				float impulse = m_recoilparams.back_impulse;
				pPhysicsProxy->AddImpulse(-1, impulsePos, impulseDir * impulse * 100.0f, true, 1.0f);
			}

			if(m_recoilparams.angular_impulse > 0.0f)
			{
				float impulse = m_recoilparams.angular_impulse;
				pActor->AddAngularImpulse(Ang3(0,impulse,0), 1.0f);
			}
		}

		if(pActor->IsClient())
			if(gEnv->pInput)
				gEnv->pInput->ForceFeedbackEvent(SFFOutputEvent(eDI_XI, eFF_Rumble_Basic, 0.15f, 0.0f, fabsf(m_recoilparams.back_impulse)*3.0f));
	}

	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);
	}

	if(OutOfAmmo())
	{
		m_pWeapon->OnOutOfAmmo(ammo);

		if(autoreload)
		{
			m_pWeapon->GetScheduler()->TimerAction(m_pWeapon->GetCurrentAnimationTime(eIGS_FirstPerson), CSchedulerAction<ScheduleReload>::Create(m_pWeapon), false);
		}
	}

	m_pWeapon->RequestShoot(ammo, pos, dir, vel, hit, 1.0f, 0, false);

	return true;
}
예제 #9
0
bool CShotgun::CanFire(bool considerAmmo) const
{
	return (m_next_shot<=0.0f) && (m_spinUpTime<=0.0f) &&
		   !m_pWeapon->IsBusy() && !m_pWeapon->IsSwitchingFireMode() && (!considerAmmo || !OutOfAmmo() || !m_pShared->fireparams.ammo_type_class || m_pShared->fireparams.clip_size == -1)
		   && (!m_reloading || m_pShared->shotgunparams.partial_reload);
}
예제 #10
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);
	}
}
예제 #11
0
파일: Plant.cpp 프로젝트: kitnet/project-o
//------------------------------------------------------------------------
void CPlant::CheckAmmo()
{
	m_pWeapon->HideItem(OutOfAmmo());
}
예제 #12
0
파일: Plant.cpp 프로젝트: kitnet/project-o
//------------------------------------------------------------------------
bool CPlant::CanFire(bool considerAmmo/* =true */) const
{
	return !m_planting && !m_pressing && !m_pWeapon->IsBusy() && (!considerAmmo || !OutOfAmmo()) && PlayerStanceOK();
}
//------------------------------------------------------------------------
void CRapid::Update(float frameTime, uint32 frameId)
{
	FUNCTION_PROFILER( GetISystem(), PROFILE_GAME );

	PlayStopRapidFireIfNeeded();

	BaseClass::Update(frameTime, frameId);

	if (m_speed <= 0.0f && m_acceleration < 0.0001f)
	{
		FinishDeceleration();
		return;
	}

	CActor* pOwnerActor = m_pWeapon->GetOwnerActor();
	const bool isOwnerClient = pOwnerActor ? pOwnerActor->IsClient() : false;
	const bool isOwnerPlayer = pOwnerActor ? pOwnerActor->IsPlayer() : false;

	m_pWeapon->RequireUpdate(eIUS_FireMode);

	m_speed = m_speed + m_acceleration*frameTime;

	if (m_speed > m_fireParams->rapidparams.max_speed)
	{
		m_speed = m_fireParams->rapidparams.max_speed;
		m_rapidFlags &= ~eRapidFlag_accelerating;
	}

	if ((m_speed >= m_fireParams->rapidparams.min_speed) && !(m_rapidFlags & eRapidFlag_decelerating))
	{
		float dt = 1.0f;
		if (cry_fabsf(m_speed)>0.001f && cry_fabsf(m_fireParams->rapidparams.max_speed)>0.001f)
		{
			dt = m_speed * (float)__fres(m_fireParams->rapidparams.max_speed);
		}
		CRY_ASSERT(m_fireParams->fireparams.rate > 0);
		
		m_next_shot_dt = 60.0f* (float)__fres((m_fireParams->fireparams.rate*dt));

		if (CanFire(false))
		{
			if (!OutOfAmmo())
			{
				const bool firing = (m_rapidFlags & eRapidFlag_netShooting) || Shoot(true, m_fireParams->fireparams.autoReload);
				Firing(firing);
			}
			else
			{
				StopFire();
			}
		}
	}
	else if (m_firing)
	{
		StopFire();
		if (OutOfAmmo() && isOwnerPlayer)
		{
			m_pWeapon->Reload();
		}
	}

	if ((m_speed < m_fireParams->rapidparams.min_speed) && (m_acceleration < 0.0f) && !(m_rapidFlags & eRapidFlag_decelerating))
		Accelerate(m_fireParams->rapidparams.deceleration);

	UpdateRotation(frameTime);
	UpdateFiring(pOwnerActor, isOwnerClient, isOwnerPlayer, frameTime);
}
예제 #14
0
//-------------------------------------------------
bool CHandGrenades::CanSelect() const
{
	return (inherited::CanSelect() && !OutOfAmmo(false));
}
예제 #15
0
//------------------------------------------------------------------------
bool CThrowableWeapon::CanSelect() const
{
    return CWeapon::CanSelect() && !OutOfAmmo(false);
}
예제 #16
0
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;
}
예제 #17
0
//--------------------------------------------------------------------
bool CWeapon::OnActionAttack(EntityId actorId, const ActionId& actionId, int activationMode, float value)
{
	if(!m_modifying)
	{
		if(IsTwoHand())
		{
			COffHand * offHandWeapon = NULL;
			bool isOffHandSelected = false;
			GetOffHandInfo(this,isOffHandSelected,&offHandWeapon);

			if(offHandWeapon && 
				(offHandWeapon->GetOffHandState()&(eOHS_HOLDING_GRENADE|eOHS_SWITCHING_GRENADE|eOHS_PICKING_ITEM)))
				return false;
		}

		if (activationMode == eAAM_OnPress)
		{

			if(PreActionAttack(true))
				return true;

			bool isDualWield = false;
			CWeapon *dualWield = NULL;
			GetDualWieldInfo(this,isDualWield,&dualWield);

			if (isDualWield)
			{
				m_fire_alternation = !m_fire_alternation;
				m_requestedFire = true;

				if (m_fire_alternation || !dualWield->CanFire())
				{
					if(!IsWeaponRaised() && CanFire())
						StartFire();
					else if(!dualWield->IsWeaponRaised())
						dualWield->StartFire();
				}
				else if (dualWield->CanFire())
				{
					if(!dualWield->IsWeaponRaised() && dualWield->CanFire())
						dualWield->StartFire();
					else if(!IsWeaponRaised())
						StartFire();
				}
				else if(OutOfAmmo(false))
				{
					Reload();
					dualWield->Reload();
				}
			}
			else
			{
				if(!m_weaponRaised)
					StartFire();

				m_requestedFire = true;
			}
		}
		else if (activationMode == eAAM_OnRelease)
		{
			PreActionAttack(false);

			StopFire();
			m_requestedFire = false;
		}
	}

	return true;
}
예제 #18
0
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);
}
예제 #19
0
파일: Rapid.cpp 프로젝트: Arnm7890/CryGame
//------------------------------------------------------------------------
void CRapid::Update(float frameTime, uint32 frameId)
{
  FUNCTION_PROFILER( GetISystem(), PROFILE_GAME );

  CSingle::Update(frameTime, frameId);

	if (m_speed <= 0.0f && m_acceleration < 0.0001f)
	{
		FinishDeceleration();
		return;
	}

	m_pWeapon->RequireUpdate(eIUS_FireMode);

	m_speed = m_speed + m_acceleration*frameTime;

	if (m_speed > m_pShared->rapidparams.max_speed)
	{
		m_speed = m_pShared->rapidparams.max_speed;
		m_accelerating = false;
	}

	if ((m_speed >= m_pShared->rapidparams.min_speed) && (!m_decelerating))
	{
		float dt = 1.0f;
		if (cry_fabsf(m_speed)>0.001f && cry_fabsf(m_pShared->rapidparams.max_speed>0.001f))
			dt=m_speed/m_pShared->rapidparams.max_speed;
		m_next_shot_dt = 60.0f/(m_pShared->fireparams.rate*dt);

		bool canShoot = CanFire(false);

		if (canShoot)
		{
			if (!OutOfAmmo())
			{
				if (m_netshooting)
					Firing(true);
				else
					Firing(Shoot(true, false));

				if (m_firing && !(m_pShared->rapidparams.camshake_rotate.IsZero() && m_pShared->rapidparams.camshake_shift.IsZero()))
				{
					CActor *act = m_pWeapon->GetOwnerActor();
					if (act && act->IsClient())
					{
						IView *pView = g_pGame->GetIGameFramework()->GetIViewSystem()->GetActiveView();
						if (pView)            
							pView->SetViewShake(Ang3(m_pShared->rapidparams.camshake_rotate), m_pShared->rapidparams.camshake_shift, m_next_shot_dt/m_pShared->rapidparams.camshake_perShot, m_next_shot_dt/m_pShared->rapidparams.camshake_perShot, 0, 1);            
					}
				}
			}
			else
			{
				Firing(false);
				Accelerate(m_pShared->rapidparams.deceleration);
				if (m_pWeapon->GetOwnerActor() && m_pWeapon->GetOwnerActor()->IsPlayer())
				{
					SmokeEffect();
					m_pWeapon->Reload();
				}
			}
		}
	}
	else if (m_firing)
	{
		Firing(false);
		if (OutOfAmmo() && m_pWeapon->GetOwnerActor() && m_pWeapon->GetOwnerActor()->IsPlayer())
		{
			SmokeEffect();
			m_pWeapon->Reload();
		}
	}

	if ((m_speed < m_pShared->rapidparams.min_speed) && (m_acceleration < 0.0f) && (!m_decelerating))
		Accelerate(m_pShared->rapidparams.deceleration);

	UpdateRotation(frameTime);
	UpdateSound(frameTime);
}
예제 #20
0
파일: JAW.cpp 프로젝트: amrhead/eaascode
bool CJaw::CanSelect() const
{
	return (BaseClass::CanSelect() && !OutOfAmmo(false));
}
예제 #21
0
bool ASFireWeapon::CanBeUsed()
{
	return ASWeapon::CanBeUsed() && !Reloading() && !OutOfAmmo();
}