private float GetSoundVolume(ItemSound sound) { if (sound == null) { return(0.0f); } if (sound.VolumeProperty == "") { return(1.0f); } ObjectProperty op = null; if (properties.TryGetValue(sound.VolumeProperty.ToLowerInvariant(), out op)) { float newVolume = 0.0f; try { newVolume = (float)op.GetValue(); } catch { return(0.0f); } newVolume *= sound.VolumeMultiplier; return(MathHelper.Clamp(newVolume, 0.0f, 1.0f)); } return(0.0f); }
private void PlaySound(ItemSound itemSound, Vector2 position) { if (Vector2.DistanceSquared(new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y), position) > itemSound.Range * itemSound.Range) { return; } if (itemSound.Loop) { if (loopingSoundChannel != null && loopingSoundChannel.Sound != itemSound.RoundSound.Sound) { loopingSoundChannel.FadeOutAndDispose(); loopingSoundChannel = null; } if (loopingSoundChannel == null || !loopingSoundChannel.IsPlaying) { float volume = GetSoundVolume(itemSound); if (volume <= 0.0001f) { return; } loopingSound = itemSound; loopingSoundChannel = loopingSound.RoundSound.Sound.Play( new Vector3(position.X, position.Y, 0.0f), 0.01f, muffle: SoundPlayer.ShouldMuffleSound(Character.Controlled, position, loopingSound.Range, Character.Controlled?.CurrentHull)); loopingSoundChannel.Looping = true; //TODO: tweak loopingSoundChannel.Near = loopingSound.Range * 0.4f; loopingSoundChannel.Far = loopingSound.Range; } } else { float volume = GetSoundVolume(itemSound); if (volume <= 0.0001f) { return; } var channel = SoundPlayer.PlaySound(itemSound.RoundSound.Sound, position, volume, itemSound.Range, item.CurrentHull); if (channel != null) { playingOneshotSoundChannels.Add(channel); } } }
public void PlaySound(ActionType type, Vector2 position) { if (loopingSound != null) { loopingSoundIndex = loopingSound.Sound.Loop(loopingSoundIndex, GetSoundVolume(loopingSound), position, loopingSound.Range); return; } List <ItemSound> matchingSounds; if (!sounds.TryGetValue(type, out matchingSounds)) { return; } ItemSound itemSound = null; if (!Sounds.SoundManager.IsPlaying(loopingSoundIndex)) { int index = Rand.Int(matchingSounds.Count); itemSound = matchingSounds[index]; } if (itemSound == null) { return; } if (itemSound.Loop) { loopingSound = itemSound; loopingSoundIndex = loopingSound.Sound.Loop(loopingSoundIndex, GetSoundVolume(loopingSound), position, loopingSound.Range); } else { float volume = GetSoundVolume(itemSound); if (volume == 0.0f) { return; } itemSound.Sound.Play(volume, itemSound.Range, position); } }
public void StopSounds(ActionType type) { if (loopingSound == null) { return; } if (loopingSound.Type != type) { return; } if (loopingSoundChannel != null) { loopingSoundChannel.FadeOutAndDispose(); loopingSoundChannel = null; loopingSound = null; } }
private float GetSoundVolume(ItemSound sound) { if (sound == null) { return(0.0f); } if (sound.VolumeProperty == "") { return(sound.VolumeMultiplier); } if (SerializableProperties.TryGetValue(sound.VolumeProperty, out SerializableProperty property)) { float newVolume = 0.0f; try { newVolume = (float)property.GetValue(this); } catch { return(0.0f); } newVolume *= sound.VolumeMultiplier; if (!MathUtils.IsValid(newVolume)) { DebugConsole.Log("Invalid sound volume (item " + item.Name + ", " + GetType().ToString() + "): " + newVolume); GameAnalyticsManager.AddErrorEventOnce( "ItemComponent.PlaySound:" + item.Name + GetType().ToString(), GameAnalyticsSDK.Net.EGAErrorSeverity.Error, "Invalid sound volume (item " + item.Name + ", " + GetType().ToString() + "): " + newVolume); return(0.0f); } return(MathHelper.Clamp(newVolume, 0.0f, 1.0f)); } return(0.0f); }
private void PlaySound(ItemSound itemSound, Vector2 position, Character user = null) { if (Vector3.DistanceSquared(GameMain.SoundManager.ListenerPosition, new Vector3(position.X, position.Y, 0.0f)) > itemSound.Range * itemSound.Range) { return; } if (itemSound.Loop) { loopingSound = itemSound; if (loopingSoundChannel != null && loopingSoundChannel.Sound != loopingSound.RoundSound.Sound) { loopingSoundChannel.Dispose(); loopingSoundChannel = null; } if (loopingSoundChannel == null || !loopingSoundChannel.IsPlaying) { loopingSoundChannel = loopingSound.RoundSound.Sound.Play( new Vector3(position.X, position.Y, 0.0f), GetSoundVolume(loopingSound), muffle: SoundPlayer.ShouldMuffleSound(Character.Controlled, position, loopingSound.Range, Character.Controlled?.CurrentHull)); loopingSoundChannel.Looping = true; //TODO: tweak loopingSoundChannel.Near = loopingSound.Range * 0.4f; loopingSoundChannel.Far = loopingSound.Range; } } else { float volume = GetSoundVolume(itemSound); if (volume <= 0.0f) { return; } SoundPlayer.PlaySound(itemSound.RoundSound.Sound, volume, itemSound.Range, position, item.CurrentHull); } }
public void StopSounds(ActionType type) { if (loopingSoundIndex <= 0) { return; } if (loopingSound == null) { return; } if (loopingSound.Type != type) { return; } if (Sounds.SoundManager.IsPlaying(loopingSoundIndex)) { Sounds.SoundManager.Stop(loopingSoundIndex); loopingSound = null; loopingSoundIndex = -1; } }
private bool LoadElemProjSpecific(XElement subElement) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "guiframe": if (subElement.Attribute("rect") != null) { DebugConsole.ThrowError("Error in item config \"" + item.ConfigFile + "\" - GUIFrame defined as rect, use RectTransform instead."); break; } Color?color = null; if (subElement.Attribute("color") != null) { color = subElement.GetAttributeColor("color", Color.White); } string style = subElement.Attribute("style") == null ? null : subElement.GetAttributeString("style", ""); GuiFrame = new GUIFrame(RectTransform.Load(subElement, GUI.Canvas), style, color); DefaultLayout = GUILayoutSettings.Load(subElement); break; case "alternativelayout": AlternativeLayout = GUILayoutSettings.Load(subElement); break; case "itemsound": case "sound": string filePath = subElement.GetAttributeString("file", ""); if (filePath == "") { filePath = subElement.GetAttributeString("sound", ""); } if (filePath == "") { DebugConsole.ThrowError("Error when instantiating item \"" + item.Name + "\" - sound with no file path set"); break; } if (!filePath.Contains("/") && !filePath.Contains("\\") && !filePath.Contains(Path.DirectorySeparatorChar)) { filePath = Path.Combine(Path.GetDirectoryName(item.Prefab.ConfigFile), filePath); } ActionType type; try { type = (ActionType)Enum.Parse(typeof(ActionType), subElement.GetAttributeString("type", ""), true); } catch (Exception e) { DebugConsole.ThrowError("Invalid sound type in " + subElement + "!", e); break; } RoundSound sound = Submarine.LoadRoundSound(subElement); if (sound == null) { break; } ItemSound itemSound = new ItemSound(sound, type, subElement.GetAttributeBool("loop", false)) { VolumeProperty = subElement.GetAttributeString("volumeproperty", "").ToLowerInvariant() }; if (soundSelectionModes == null) { soundSelectionModes = new Dictionary <ActionType, SoundSelectionMode>(); } if (!soundSelectionModes.ContainsKey(type) || soundSelectionModes[type] == SoundSelectionMode.Random) { SoundSelectionMode selectionMode = SoundSelectionMode.Random; Enum.TryParse(subElement.GetAttributeString("selectionmode", "Random"), out selectionMode); soundSelectionModes[type] = selectionMode; } List <ItemSound> soundList = null; if (!sounds.TryGetValue(itemSound.Type, out soundList)) { soundList = new List <ItemSound>(); sounds.Add(itemSound.Type, soundList); } soundList.Add(itemSound); break; default: return(false); //unknown element } return(true); //element processed }
public void PlaySound(ActionType type, Vector2 position, Character user = null) { if (loopingSound != null) { if (Vector3.DistanceSquared(GameMain.SoundManager.ListenerPosition, new Vector3(position.X, position.Y, 0.0f)) > loopingSound.Range * loopingSound.Range) { if (loopingSoundChannel != null) { loopingSoundChannel.FadeOutAndDispose(); loopingSoundChannel = null; } return; } if (loopingSoundChannel != null && loopingSoundChannel.Sound != loopingSound.RoundSound.Sound) { loopingSoundChannel.FadeOutAndDispose(); loopingSoundChannel = null; } if (loopingSoundChannel == null || !loopingSoundChannel.IsPlaying) { loopingSoundChannel = loopingSound.RoundSound.Sound.Play( new Vector3(position.X, position.Y, 0.0f), 0.01f, SoundPlayer.ShouldMuffleSound(Character.Controlled, position, loopingSound.Range, Character.Controlled?.CurrentHull)); loopingSoundChannel.Looping = true; //TODO: tweak loopingSoundChannel.Near = loopingSound.Range * 0.4f; loopingSoundChannel.Far = loopingSound.Range; } if (loopingSoundChannel != null) { if (Timing.TotalTime > lastMuffleCheckTime + 0.2f) { shouldMuffleLooping = SoundPlayer.ShouldMuffleSound(Character.Controlled, position, loopingSound.Range, Character.Controlled?.CurrentHull); lastMuffleCheckTime = (float)Timing.TotalTime; } loopingSoundChannel.Muffled = shouldMuffleLooping; float targetGain = GetSoundVolume(loopingSound); float gainDiff = targetGain - loopingSoundChannel.Gain; loopingSoundChannel.Gain += Math.Abs(gainDiff) < 0.1f ? gainDiff : Math.Sign(gainDiff) * 0.1f; loopingSoundChannel.Position = new Vector3(position.X, position.Y, 0.0f); } return; } if (!sounds.TryGetValue(type, out List <ItemSound> matchingSounds)) { return; } ItemSound itemSound = null; if (loopingSoundChannel == null || !loopingSoundChannel.IsPlaying) { SoundSelectionMode soundSelectionMode = soundSelectionModes[type]; int index; if (soundSelectionMode == SoundSelectionMode.CharacterSpecific && user != null) { index = user.ID % matchingSounds.Count; } else if (soundSelectionMode == SoundSelectionMode.ItemSpecific) { index = item.ID % matchingSounds.Count; } else if (soundSelectionMode == SoundSelectionMode.All) { foreach (ItemSound sound in matchingSounds) { PlaySound(sound, position, user); } return; } else { index = Rand.Int(matchingSounds.Count); } itemSound = matchingSounds[index]; PlaySound(matchingSounds[index], position, user); } }
public ItemComponent(Item item, XElement element) { this.item = item; properties = ObjectProperty.GetProperties(this); //canBePicked = ToolBox.GetAttributeBool(element, "canbepicked", false); //canBeSelected = ToolBox.GetAttributeBool(element, "canbeselected", false); //msg = ToolBox.GetAttributeString(element, "msg", ""); requiredItems = new List <RelatedItem>(); requiredSkills = new List <Skill>(); sounds = new Dictionary <ActionType, List <ItemSound> >(); SelectKey = InputType.Select; try { string selectKeyStr = ToolBox.GetAttributeString(element, "selectkey", "Select"); selectKeyStr = ToolBox.ConvertInputType(selectKeyStr); SelectKey = (InputType)Enum.Parse(typeof(InputType), selectKeyStr, true); } catch (Exception e) { DebugConsole.ThrowError("Invalid select key in " + element + "!", e); } PickKey = InputType.Select; try { string pickKeyStr = ToolBox.GetAttributeString(element, "selectkey", "Select"); pickKeyStr = ToolBox.ConvertInputType(pickKeyStr); PickKey = (InputType)Enum.Parse(typeof(InputType), pickKeyStr, true); } catch (Exception e) { DebugConsole.ThrowError("Invalid pick key in " + element + "!", e); } properties = ObjectProperty.InitProperties(this, element); foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "requireditem": case "requireditems": RelatedItem ri = RelatedItem.Load(subElement); if (ri != null) { requiredItems.Add(ri); } break; case "requiredskill": case "requiredskills": string skillName = ToolBox.GetAttributeString(subElement, "name", ""); requiredSkills.Add(new Skill(skillName, ToolBox.GetAttributeInt(subElement, "level", 0))); break; case "statuseffect": var statusEffect = StatusEffect.Load(subElement); if (statusEffectLists == null) { statusEffectLists = new Dictionary <ActionType, List <StatusEffect> >(); } List <StatusEffect> effectList; if (!statusEffectLists.TryGetValue(statusEffect.type, out effectList)) { effectList = new List <StatusEffect>(); statusEffectLists.Add(statusEffect.type, effectList); } effectList.Add(statusEffect); break; case "guiframe": string rectStr = ToolBox.GetAttributeString(subElement, "rect", "0.0,0.0,0.5,0.5"); string[] components = rectStr.Split(','); if (components.Length < 4) { continue; } Vector4 rect = ToolBox.GetAttributeVector4(subElement, "rect", Vector4.One); if (components[0].Contains(".")) { rect.X *= GameMain.GraphicsWidth; } if (components[1].Contains(".")) { rect.Y *= GameMain.GraphicsHeight; } if (components[2].Contains(".")) { rect.Z *= GameMain.GraphicsWidth; } if (components[3].Contains(".")) { rect.W *= GameMain.GraphicsHeight; } string style = ToolBox.GetAttributeString(subElement, "style", ""); Vector4 color = ToolBox.GetAttributeVector4(subElement, "color", Vector4.One); Alignment alignment = Alignment.Center; try { alignment = (Alignment)Enum.Parse(typeof(Alignment), ToolBox.GetAttributeString(subElement, "alignment", "Center"), true); } catch { DebugConsole.ThrowError("Error in " + element + "! \"" + element.Attribute("type").Value + "\" is not a valid alignment"); } guiFrame = new GUIFrame( new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Z, (int)rect.W), new Color(color.X, color.Y, color.Z) * color.W, alignment, style); break; case "sound": string filePath = ToolBox.GetAttributeString(subElement, "file", ""); if (filePath == "") { filePath = ToolBox.GetAttributeString(subElement, "sound", ""); } if (filePath == "") { DebugConsole.ThrowError("Error when instantiating item \"" + item.Name + "\" - sound with no file path set"); continue; } if (!filePath.Contains("/") && !filePath.Contains("\\") && !filePath.Contains(Path.DirectorySeparatorChar)) { filePath = Path.Combine(Path.GetDirectoryName(item.Prefab.ConfigFile), filePath); } ActionType type; try { type = (ActionType)Enum.Parse(typeof(ActionType), ToolBox.GetAttributeString(subElement, "type", ""), true); } catch (Exception e) { DebugConsole.ThrowError("Invalid sound type in " + subElement + "!", e); break; } Sound sound = Sound.Load(filePath); float range = ToolBox.GetAttributeFloat(subElement, "range", 800.0f); bool loop = ToolBox.GetAttributeBool(subElement, "loop", false); ItemSound itemSound = new ItemSound(sound, type, range, loop); itemSound.VolumeProperty = ToolBox.GetAttributeString(subElement, "volume", ""); itemSound.VolumeMultiplier = ToolBox.GetAttributeFloat(subElement, "volumemultiplier", 1.0f); List <ItemSound> soundList = null; if (!sounds.TryGetValue(itemSound.Type, out soundList)) { soundList = new List <ItemSound>(); sounds.Add(itemSound.Type, soundList); } soundList.Add(itemSound); break; default: ItemComponent ic = Load(subElement, item, item.ConfigFile, false); if (ic == null) { break; } ic.Parent = this; item.components.Add(ic); break; } } }
public void PlaySound(ActionType type, Character user = null) { if (!hasSoundsOfType[(int)type]) { return; } if (loopingSound != null) { if (Vector3.DistanceSquared(GameMain.SoundManager.ListenerPosition, new Vector3(item.WorldPosition, 0.0f)) > loopingSound.Range * loopingSound.Range || (GetSoundVolume(loopingSound)) <= 0.0001f) { if (loopingSoundChannel != null) { loopingSoundChannel.FadeOutAndDispose(); loopingSoundChannel = null; loopingSound = null; } return; } if (loopingSoundChannel != null && loopingSoundChannel.Sound != loopingSound.RoundSound.Sound) { loopingSoundChannel.FadeOutAndDispose(); loopingSoundChannel = null; loopingSound = null; } if (loopingSoundChannel == null || !loopingSoundChannel.IsPlaying) { loopingSoundChannel = loopingSound.RoundSound.Sound.Play( new Vector3(item.WorldPosition, 0.0f), 0.01f, SoundPlayer.ShouldMuffleSound(Character.Controlled, item.WorldPosition, loopingSound.Range, Character.Controlled?.CurrentHull)); loopingSoundChannel.Looping = true; //TODO: tweak loopingSoundChannel.Near = loopingSound.Range * 0.4f; loopingSoundChannel.Far = loopingSound.Range; } return; } var matchingSounds = sounds[type]; if (loopingSoundChannel == null || !loopingSoundChannel.IsPlaying) { SoundSelectionMode soundSelectionMode = soundSelectionModes[type]; int index; if (soundSelectionMode == SoundSelectionMode.CharacterSpecific && user != null) { index = user.ID % matchingSounds.Count; } else if (soundSelectionMode == SoundSelectionMode.ItemSpecific) { index = item.ID % matchingSounds.Count; } else if (soundSelectionMode == SoundSelectionMode.All) { foreach (ItemSound sound in matchingSounds) { PlaySound(sound, item.WorldPosition); } return; } else { index = Rand.Int(matchingSounds.Count); } PlaySound(matchingSounds[index], item.WorldPosition); } }
private bool LoadElemProjSpecific(XElement subElement) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "guiframe": string rectStr = ToolBox.GetAttributeString(subElement, "rect", "0.0,0.0,0.5,0.5"); string[] components = rectStr.Split(','); if (components.Length < 4) { break; } Vector4 rect = ToolBox.GetAttributeVector4(subElement, "rect", Vector4.One); if (components[0].Contains(".")) { rect.X *= GameMain.GraphicsWidth; } if (components[1].Contains(".")) { rect.Y *= GameMain.GraphicsHeight; } if (components[2].Contains(".")) { rect.Z *= GameMain.GraphicsWidth; } if (components[3].Contains(".")) { rect.W *= GameMain.GraphicsHeight; } string style = ToolBox.GetAttributeString(subElement, "style", ""); Vector4 color = ToolBox.GetAttributeVector4(subElement, "color", Vector4.One); Alignment alignment = Alignment.Center; try { alignment = (Alignment)Enum.Parse(typeof(Alignment), ToolBox.GetAttributeString(subElement, "alignment", "Center"), true); } catch { DebugConsole.ThrowError("Error in " + subElement.Parent + "! \"" + subElement.Parent.Attribute("type").Value + "\" is not a valid alignment"); } guiFrame = new GUIFrame( new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Z, (int)rect.W), new Color(color.X, color.Y, color.Z) * color.W, alignment, style); break; case "sound": string filePath = ToolBox.GetAttributeString(subElement, "file", ""); if (filePath == "") { filePath = ToolBox.GetAttributeString(subElement, "sound", ""); } if (filePath == "") { DebugConsole.ThrowError("Error when instantiating item \"" + item.Name + "\" - sound with no file path set"); break; } if (!filePath.Contains("/") && !filePath.Contains("\\") && !filePath.Contains(Path.DirectorySeparatorChar)) { filePath = Path.Combine(Path.GetDirectoryName(item.Prefab.ConfigFile), filePath); } ActionType type; try { type = (ActionType)Enum.Parse(typeof(ActionType), ToolBox.GetAttributeString(subElement, "type", ""), true); } catch (Exception e) { DebugConsole.ThrowError("Invalid sound type in " + subElement + "!", e); break; } Sound sound = Sound.Load(filePath); float range = ToolBox.GetAttributeFloat(subElement, "range", 800.0f); bool loop = ToolBox.GetAttributeBool(subElement, "loop", false); ItemSound itemSound = new ItemSound(sound, type, range, loop); itemSound.VolumeProperty = ToolBox.GetAttributeString(subElement, "volume", ""); itemSound.VolumeMultiplier = ToolBox.GetAttributeFloat(subElement, "volumemultiplier", 1.0f); List <ItemSound> soundList = null; if (!sounds.TryGetValue(itemSound.Type, out soundList)) { soundList = new List <ItemSound>(); sounds.Add(itemSound.Type, soundList); } soundList.Add(itemSound); break; default: return(false); //unknown element } return(true); //element processed }
public void PlaySound(ActionType type, Character user = null) { if (!hasSoundsOfType[(int)type]) { return; } if (GameMain.Client?.MidRoundSyncing ?? false) { return; } if (loopingSound != null) { if (Vector3.DistanceSquared(GameMain.SoundManager.ListenerPosition, new Vector3(item.WorldPosition, 0.0f)) > loopingSound.Range * loopingSound.Range || (GetSoundVolume(loopingSound)) <= 0.0001f) { if (loopingSoundChannel != null) { loopingSoundChannel.FadeOutAndDispose(); loopingSoundChannel = null; loopingSound = null; } return; } if (loopingSoundChannel != null && loopingSoundChannel.Sound != loopingSound.RoundSound.Sound) { loopingSoundChannel.FadeOutAndDispose(); loopingSoundChannel = null; loopingSound = null; } if (loopingSoundChannel == null || !loopingSoundChannel.IsPlaying) { loopingSoundChannel = loopingSound.RoundSound.Sound.Play( new Vector3(item.WorldPosition, 0.0f), 0.01f, loopingSound.RoundSound.GetRandomFrequencyMultiplier(), SoundPlayer.ShouldMuffleSound(Character.Controlled, item.WorldPosition, loopingSound.Range, Character.Controlled?.CurrentHull)); loopingSoundChannel.Looping = true; //TODO: tweak loopingSoundChannel.Near = loopingSound.Range * 0.4f; loopingSoundChannel.Far = loopingSound.Range; } // Looping sound with manual selection mode should be changed if value of ManuallySelectedSound has changed // Otherwise the sound won't change until the sound condition (such as being active) is disabled and re-enabled if (loopingSoundChannel != null && loopingSoundChannel.IsPlaying && soundSelectionModes[type] == SoundSelectionMode.Manual) { var playingIndex = sounds[type].IndexOf(loopingSound); var shouldBePlayingIndex = Math.Clamp(ManuallySelectedSound, 0, sounds[type].Count); if (playingIndex != shouldBePlayingIndex) { loopingSoundChannel.FadeOutAndDispose(); loopingSoundChannel = null; loopingSound = null; } } return; } var matchingSounds = sounds[type]; if (loopingSoundChannel == null || !loopingSoundChannel.IsPlaying) { SoundSelectionMode soundSelectionMode = soundSelectionModes[type]; int index; if (soundSelectionMode == SoundSelectionMode.CharacterSpecific && user != null) { index = user.ID % matchingSounds.Count; } else if (soundSelectionMode == SoundSelectionMode.ItemSpecific) { index = item.ID % matchingSounds.Count; } else if (soundSelectionMode == SoundSelectionMode.All) { foreach (ItemSound sound in matchingSounds) { PlaySound(sound, item.WorldPosition); } return; } else if (soundSelectionMode == SoundSelectionMode.Manual) { index = Math.Clamp(ManuallySelectedSound, 0, matchingSounds.Count); } else { index = Rand.Int(matchingSounds.Count); } PlaySound(matchingSounds[index], item.WorldPosition); } }