/// <summary> /// Triggers a new 3D sound. /// </summary> public Cue Play3DCue(string cueName, IAudioEmitter emitter) { if (FrameworkCore.gameState != GameState.Play || FrameworkCore.soundbank == null) { return(null); } Cue3D cue3D; if (cuePool.Count > 0) { // If possible, reuse an existing Cue3D instance. cue3D = cuePool.Pop(); } else { // Otherwise we have to allocate a new one. cue3D = new Cue3D(); } // Fill in the cue and emitter fields. try { cue3D.Cue = FrameworkCore.soundbank.GetCue(cueName); } catch { } cue3D.Emitter = emitter; // Set the 3D position of this cue, and then play it. Apply3D(cue3D); try { cue3D.Cue.Play(); } catch { } // Remember that this cue is now active. activeCues.Add(cue3D); return(cue3D.Cue); }
//targeting brain. public void Update(GameTime gameTime, List <Collideable> ships) { turretWeapon.Update(gameTime); BeamDamageCheck(gameTime); UpdateBeamSound(); if (updateTimer > 0) { updateTimer -= (int)gameTime.ElapsedGameTime.TotalMilliseconds; if (lastSelectedShip != null && !lastSelectedShip.IsDestroyed) { UpdateRotation(gameTime, lastSelectedShip.Position); } else { ResetTurretOrientation(); } return; } else { updateTimer = 300; } if (parentShip.targetShip != null && parentShip.targetShip.IsDestroyed) { //priority ship is dead. Clear this ship's priority target. parentShip.SetTargetShip(null); } //if we can't fire, then reset all turrets to default orientations. if (parentShip.OrderEffect != null && !parentShip.OrderEffect.canFire) { ResetTurretOrientation(); return; } //limit how often the think update happens, limit to the turret weapon's refire rate. if (turretWeapon.lastFireTime > 0 && turretWeapon.firetype == Weapon.fireType.Projectile) { return; } SpaceShip targetShip = null; float nearestDistance = float.MaxValue; Vector3 finalPredictedPosition = Vector3.Zero; Matrix orientation = Matrix.CreateFromQuaternion(parentShip.Rotation); //ship orientation Matrix turretOrientation = Matrix.CreateFromQuaternion(rotateQuat); //turret orientation //does the ship have a priority target? check if target is in firing arc. if (parentShip.targetShip != null && !parentShip.targetShip.IsDestroyed) { Vector3 muzzleVec = GetMuzzleVec(0); SpaceShip enemyShip = (SpaceShip)parentShip.targetShip; Vector3 predictedPosition = GetPredictedPosition(gameTime, muzzleVec, enemyShip); //now check if the predictedPosition is within the valid firing arc. Vector3 aimFacing = GetOrientationMatrix(upAimVector, orientation); float frontDot = Helpers.GetDot(muzzleVec, predictedPosition, aimFacing); if (frontDot > 0) { targetShip = enemyShip; finalPredictedPosition = predictedPosition; } } //we do not have a priority target. so, let's evaluate every ship. if (targetShip == null) { for (int i = 0; i < ships.Count; i++) { //only target spaceships. if (!Helpers.IsSpaceship(ships[i])) { continue; } SpaceShip enemy = ships[i] as SpaceShip; //don't target dead ships. if (enemy.IsDestroyed) { continue; } //don't target owner. if (enemy == parentShip) { continue; } //don't target friendlies. if (enemy.owner == parentShip.owner) { continue; } //same faction. don't target this ship. if (enemy.owner.factionName == parentShip.owner.factionName) { continue; } Vector3 aimFacing = GetOrientationMatrix(upAimVector, orientation); float frontDot = Helpers.GetDot(this.position, enemy.Position, aimFacing); if (frontDot < 0) { continue; } //ok, we now have a LIVE ENEMY ship that is in FRONT of us. //Now get the predicted firing Vector IF the ship is moving. // if the ship isn't moving, then we don't predict anything - we just directly target the ship. SpaceShip enemyShip = (SpaceShip)enemy; Vector3 muzzleVec = GetMuzzleVec(0); //for simplicity sake we only check the first muzzle barrel. Vector3 predictedPosition = Vector3.Zero; //if the weapon is not ready to be fired, don't bother calculating the predictedPosition if (turretWeapon.CurBurstReloadTime <= 0 && turretWeapon.lastFireTime <= 0) { predictedPosition = GetPredictedPosition(gameTime, muzzleVec, enemyShip); } else { predictedPosition = enemy.Position; } //now check if the predictedPosition is within the valid firing arc. frontDot = Helpers.GetDot(muzzleVec, predictedPosition, aimFacing); if (frontDot < 0) { continue; } //keep track of the closest predictedPosition. //enemy ship. float distanceToEnemyShip = Vector3.Distance(predictedPosition, this.position); if (distanceToEnemyShip < nearestDistance) { nearestDistance = distanceToEnemyShip; targetShip = (SpaceShip)enemy; finalPredictedPosition = predictedPosition; } } } if (targetShip == null) { //no valid target found. //I have no target: so reset turret orientation to default aim position. ResetTurretOrientation(); return; } //now fire the turret. for (int i = 0; i < muzzleOffsets.Length; i++) { Vector3 muzzleVec = position; muzzleVec += (turretOrientation.Right * muzzleOffsets[i].X) + (turretOrientation.Up * muzzleOffsets[i].Y) + (turretOrientation.Forward * -muzzleOffsets[i].Z); if (turretWeapon.Fire(parentShip, finalPredictedPosition, muzzleVec)) { IAudioEmitter audioEmit = new IAudioEmitter(); audioEmit.Position = this.position; if (turretWeapon.firetype == Weapon.fireType.Projectile) { FrameworkCore.audiomanager.Play3DCue(sounds.Weapon.rifle, audioEmit); } PlayBeamSound(); //bolt was created. now create the muzzleflash. parentShip.Particles.CreateMuzzleFlash(muzzleVec, (finalPredictedPosition - muzzleVec)); if (i >= muzzleOffsets.Length - 1) { //and reset the weapon's refire timer. float fireRateModifier = 1f; if (parentShip.OrderEffect != null) { if (parentShip.OrderEffect.fireRateModifier > 0) { fireRateModifier = parentShip.OrderEffect.fireRateModifier; } } turretWeapon.lastFireTime = (int)(turretWeapon.refireTime / fireRateModifier); //fire rate modifier controls time between shots. turretWeapon.lastFireTime = Helpers.ApplyFireRateModifier(parentShip, turretWeapon.lastFireTime); } } } lastSelectedShip = targetShip; //Handle turret rotation. UpdateRotation(gameTime, finalPredictedPosition); }