public static Sound PlayCue(Main main, string cue, float volume = 1.0f, float minimumTimeBetweenSounds = 0.25f) { float lastSoundPlayedTime = minimumTimeBetweenSounds * -2.0f; Sound.lastSoundPlayedTimes.TryGetValue(cue, out lastSoundPlayedTime); float time = main.TotalTime; if (time > lastSoundPlayedTime + minimumTimeBetweenSounds) { Sound.lastSoundPlayedTimes[cue] = time; Sound sound = new Sound(); sound.Cue.Value = cue; sound.Is3D.Value = false; if (volume != 1.0f) sound.GetProperty("Volume").Value = volume; sound.DeleteWhenDone.Value = true; sound.DeleteStopOption.Value = AudioStopOptions.AsAuthored; main.AddComponent(sound); sound.Play.Execute(); return sound; } return null; }
public override void Bind(Entity result, Main main, bool creating = false) { Factory.Get<DynamicMapFactory>().Bind(result, main, creating); Transform transform = result.Get<Transform>(); DynamicMap map = result.Get<DynamicMap>(); Sound zombieSound = new Sound(); zombieSound.Serialize = false; zombieSound.Cue.Value = "Zombie"; result.Add("ZombieSound", zombieSound); Property<bool> playerVisible = new Property<bool> { Value = false, Editable = false, Serialize = false }; result.Add("PlayerVisible", playerVisible); zombieSound.Add(new Binding<Vector3>(zombieSound.Position, transform.Position)); zombieSound.Add(new Binding<Vector3>(zombieSound.Velocity, map.LinearVelocity)); Property<float> damage = result.GetProperty<float>("Damage"); map.Add(new CommandBinding<Collidable, ContactCollection>(map.Collided, delegate(Collidable collidable, ContactCollection contact) { if (result.Active && collidable is EntityCollidable) { if (((EntityCollidable)collidable).Entity.Tag is Player) { Player player = (Player)((EntityCollidable)collidable).Entity.Tag; player.Health.Value -= damage; } } })); Property<float> zombieSoundPitch = zombieSound.GetProperty("Pitch"); Property<float> visibilityCheckInterval = result.GetProperty<float>("VisibilityCheckInterval"); Property<float> torqueMultiplier = result.GetProperty<float>("TorqueMultiplier"); Property<float> maxSpeed = result.GetProperty<float>("MaxSpeed"); Property<float> playerPositionMemoryTime = result.GetProperty<float>("PlayerPositionMemoryTime"); float timeSinceLastSpottedPlayer = playerPositionMemoryTime; float timeSinceLastVisibilityCheck = 0.0f; result.Add(new Updater { delegate(float dt) { if (!result.Active) return; Entity player = PlayerFactory.Instance; if (player != null) { Vector3 playerPosition = player.Get<Transform>().Position.Value; Vector3 rayDirection = playerPosition - transform.Position; float playerDistance = rayDirection.Length(); rayDirection /= playerDistance; timeSinceLastVisibilityCheck += dt; if (timeSinceLastVisibilityCheck > visibilityCheckInterval) { Map.GlobalRaycastResult hit = Map.GlobalRaycast(playerPosition + (rayDirection * -3.0f), -rayDirection, playerDistance); if (hit.Map == map) { timeSinceLastSpottedPlayer = 0.0f; playerVisible.Value = true; } timeSinceLastVisibilityCheck = 0.0f; } timeSinceLastSpottedPlayer += dt; if (timeSinceLastSpottedPlayer < playerPositionMemoryTime) { float torque = torqueMultiplier * map.PhysicsEntity.Mass * dt; Vector3 impulse = new Vector3(torque * rayDirection.Z, 0.0f, -torque * rayDirection.X); map.PhysicsEntity.ApplyAngularImpulse(ref impulse); Vector3 velocity = map.PhysicsEntity.AngularVelocity; float speed = velocity.Length(); if (speed > maxSpeed) map.PhysicsEntity.AngularVelocity = velocity * (maxSpeed / speed); map.PhysicsEntity.ActivityInformation.Activate(); zombieSoundPitch.Value = ((speed / maxSpeed) / torque) - 1.0f; } else if (playerVisible) playerVisible.Value = false; } if (timeSinceLastSpottedPlayer > playerPositionMemoryTime && zombieSound.IsPlaying) zombieSound.Stop.Execute(Microsoft.Xna.Framework.Audio.AudioStopOptions.AsAuthored); else if (timeSinceLastSpottedPlayer < playerPositionMemoryTime && !zombieSound.IsPlaying) zombieSound.Play.Execute(); } }); }