Beispiel #1
0
void WeaponBase::Fire(glm::vec3 fireOrigin, glm::vec3 fireDirection)
{
    fireAttempt = true;
    if (CanFire())
    {
        storedAmmo -= GetRequiredAmmoToFire();
        firingTime = fireRateInSeconds;
        coolingTime = cooldownInSeconds;
        FireInternal(fireOrigin, fireDirection);
    }
    else if (continualFire && firingTime > 0.0f)
    {
        // Continue fire weapons we can fire until firing time == 0, at which point we have to wait for the cooldown.
        FireInternal(fireOrigin, fireDirection);
    }
}
void CBeamLaser::Update(void)
{
	if(targetType!=Target_None){
		weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
		if(!onlyForward){
			wantedDir=targetPos-weaponPos;
			wantedDir.Normalize();
		}
		predict=salvoSize/2;
	}
	CWeapon::Update();

	if(lastFireFrame > gs->frameNum - 18 && lastFireFrame != gs->frameNum  && weaponDef->sweepFire)
	{
		if (gs->Team(owner->team)->metal>=metalFireCost && gs->Team(owner->team)->energy>=energyFireCost)
		{
			owner->UseEnergy(energyFireCost / salvoSize);
			owner->UseMetal(metalFireCost / salvoSize);

			std::vector<int> args;
			args.push_back(0);
			owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
			CMatrix44f weaponMat = owner->localmodel->GetPieceMatrix(args[0]);

			float3 relWeaponPos = weaponMat.GetPos();
			weaponPos=owner->pos+owner->frontdir*-relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*-relWeaponPos.x;

			float3 dir = owner->frontdir * weaponMat[10] + owner->updir * weaponMat[6] + -owner->rightdir * weaponMat[2];
			FireInternal(dir, true);
		}
	}
}
void CBeamLaser::Fire(void)
{
	float3 dir;
	if (onlyForward && dynamic_cast<CAirMoveType*>(owner->moveType)) {
		// the taairmovetype can't align itself properly, change back when that is fixed
		dir = owner->frontdir;
	} else {
		if (salvoLeft == salvoSize - 1) {
			if (fireSoundId)
				sound->PlaySample(fireSoundId, owner, fireSoundVolume);

			dir = targetPos - weaponMuzzlePos;
			dir.Normalize();
			oldDir = dir;
		} else if (weaponDef->beamburst) {
			if (fireSoundId && !weaponDef->soundTrigger)
				sound->PlaySample(fireSoundId, owner, fireSoundVolume);

			dir = targetPos-weaponMuzzlePos;
			dir.Normalize();
		} else {
			dir = oldDir;
		}
	}

	dir += (salvoError) * (1 - owner->limExperience * 0.7f);
	dir.Normalize();

	FireInternal(dir, false);
}
Beispiel #4
0
void CBeamLaser::FireImpl(bool scriptCall)
{
	// sweepfire must exclude regular fire (!)
	if (sweepFireState.IsSweepFiring())
		return;

	FireInternal(GetFireDir(false, scriptCall));
}
void CBeamLaser::Update(void)
{
	if (targetType != Target_None) {
		weaponPos =
			owner->pos +
			owner->frontdir * relWeaponPos.z +
			owner->updir    * relWeaponPos.y +
			owner->rightdir * relWeaponPos.x;
		weaponMuzzlePos =
			owner->pos +
			owner->frontdir * relWeaponMuzzlePos.z +
			owner->updir    * relWeaponMuzzlePos.y +
			owner->rightdir * relWeaponMuzzlePos.x;

		if (!onlyForward) {
			wantedDir = targetPos - weaponPos;
			wantedDir.ANormalize();
		}

		if (!weaponDef->beamburst) {
			predict = salvoSize / 2;
		} else {
 			// beamburst tracks the target during the burst so there's no need to lead
			predict = 0;
		}
	}
	CWeapon::Update();

	if (lastFireFrame > gs->frameNum - 18 && lastFireFrame != gs->frameNum  && weaponDef->sweepFire) {
		if (teamHandler->Team(owner->team)->metal >= metalFireCost &&
			teamHandler->Team(owner->team)->energy >= energyFireCost) {

			owner->UseEnergy(energyFireCost / salvoSize);
			owner->UseMetal(metalFireCost / salvoSize);

			std::vector<int> args;
			args.push_back(0);
			owner->cob->Call(COBFN_QueryPrimary + weaponNum, args);
			CMatrix44f weaponMat = owner->cob->GetPieceMatrix(args[0]);

			const float3 relWeaponPos = weaponMat.GetPos();
			const float3 dir =
				owner->frontdir *  weaponMat[10] +
				owner->updir    *  weaponMat[ 6] +
				owner->rightdir * -weaponMat[ 2];

			weaponPos =
				owner->pos +
				owner->frontdir * -relWeaponPos.z +
				owner->updir    *  relWeaponPos.y +
				owner->rightdir * -relWeaponPos.x;

			FireInternal(dir, true);
		}
	}
}
Beispiel #6
0
void CBeamLaser::UpdateSweep()
{
	// sweeping always happens between targets
	if (targetType == Target_None) {
		sweepFireState.SetSweepFiring(false);
		return;
	}
	if (!weaponDef->sweepFire)
		return;

	#if (!SWEEPFIRE_ENABLED)
	return;
	#endif

	// if current target position changed, start sweeping through a new arc
	if (sweepFireState.StartSweep(targetPos))
		sweepFireState.Init(targetPos, weaponMuzzlePos);

	if (sweepFireState.IsSweepFiring())
		sweepFireState.Update(GetFireDir(true, false));

	// TODO:
	//   also stop sweep if angle no longer changes, spawn
	//   more intermediate beams for large angle and range?
	if (sweepFireState.StopSweep())
		sweepFireState.SetSweepFiring(false);

	if (!sweepFireState.IsSweepFiring())
		return;
	if (reloadStatus > gs->frameNum)
		return;

	if (teamHandler->Team(owner->team)->metal < metalFireCost) { return; }
	if (teamHandler->Team(owner->team)->energy < energyFireCost) { return; }

	owner->UseEnergy(energyFireCost / salvoSize);
	owner->UseMetal(metalFireCost / salvoSize);

	FireInternal(sweepFireState.GetSweepCurrDir());

	// FIXME:
	//   reloadStatus is normally only set in UpdateFire and only if CanFire
	//   (which is not true during sweeping, the integration should be better)
	reloadStatus = gs->frameNum + int(reloadTime / owner->reloadSpeed);
}
Beispiel #7
0
void CBeamLaser::FireImpl(void)
{
	float3 dir;
	if (onlyForward && dynamic_cast<CStrafeAirMoveType*>(owner->moveType)) {
		// HoverAirMoveType cannot align itself properly, change back when that is fixed
		dir = owner->frontdir;
	} else {
		if (salvoLeft == salvoSize - 1) {
			dir = targetPos - weaponMuzzlePos;
			dir.SafeNormalize();
			oldDir = dir;
		} else if (weaponDef->beamburst) {
			dir = targetPos - weaponMuzzlePos;
			dir.SafeNormalize();
		} else {
			dir = oldDir;
		}
	}

	dir += ((salvoError) * (1.0f - owner->limExperience * weaponDef->ownerExpAccWeight));
	dir.SafeNormalize();

	FireInternal(dir, false);
}