partial void InitProjSpecific(XElement element, string parentDebugName) { particleEmitters = new List <ParticleEmitter>(); foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "particleemitter": particleEmitters.Add(new ParticleEmitter(subElement)); break; case "sound": var sound = Submarine.LoadRoundSound(subElement); if (sound != null) { loopSound = subElement.GetAttributeBool("loop", false); if (subElement.Attribute("selectionmode") != null) { if (Enum.TryParse(subElement.GetAttributeString("selectionmode", "Random"), out SoundSelectionMode selectionMode)) { soundSelectionMode = selectionMode; } } sounds.Add(sound); } break; } } }
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 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); } }
protected StatusEffect(XElement element, string parentDebugName) { requiredItems = new List <RelatedItem>(); spawnItems = new List <ItemSpawnInfo>(); Afflictions = new List <Affliction>(); ReduceAffliction = new List <Pair <string, float> >(); tags = new HashSet <string>(element.GetAttributeString("tags", "").Split(',')); Range = element.GetAttributeFloat("range", 0.0f); #if CLIENT particleEmitters = new List <ParticleEmitter>(); #endif IEnumerable <XAttribute> attributes = element.Attributes(); List <XAttribute> propertyAttributes = new List <XAttribute>(); propertyConditionals = new List <PropertyConditional>(); foreach (XAttribute attribute in attributes) { switch (attribute.Name.ToString()) { case "type": if (!Enum.TryParse(attribute.Value, true, out type)) { DebugConsole.ThrowError("Invalid action type \"" + attribute.Value + "\" in StatusEffect (" + parentDebugName + ")"); } break; case "target": string[] Flags = attribute.Value.Split(','); foreach (string s in Flags) { if (!Enum.TryParse(s, true, out TargetType targetType)) { DebugConsole.ThrowError("Invalid target type \"" + s + "\" in StatusEffect (" + parentDebugName + ")"); } else { targetTypes |= targetType; } } break; case "disabledeltatime": disableDeltaTime = attribute.GetAttributeBool(false); break; case "setvalue": setValue = attribute.GetAttributeBool(false); break; case "targetnames": DebugConsole.ThrowError("Error in StatusEffect config (" + parentDebugName + ") - use identifiers or tags to define the targets instead of names."); break; case "targetidentifiers": string[] identifiers = attribute.Value.Split(','); targetIdentifiers = new HashSet <string>(); for (int i = 0; i < identifiers.Length; i++) { targetIdentifiers.Add(identifiers[i].Trim().ToLowerInvariant()); } break; case "duration": duration = attribute.GetAttributeFloat(0.0f); break; case "stackable": Stackable = attribute.GetAttributeBool(true); break; case "checkconditionalalways": CheckConditionalAlways = attribute.GetAttributeBool(false); break; case "conditionalcomparison": case "comparison": if (!Enum.TryParse(attribute.Value, out conditionalComparison)) { DebugConsole.ThrowError("Invalid conditional comparison type \"" + attribute.Value + "\" in StatusEffect (" + parentDebugName + ")"); } break; case "sound": DebugConsole.ThrowError("Error in StatusEffect " + element.Parent.Name.ToString() + " - sounds should be defined as child elements of the StatusEffect, not as attributes."); break; default: propertyAttributes.Add(attribute); break; } } int count = propertyAttributes.Count; propertyNames = new string[count]; propertyEffects = new object[count]; int n = 0; foreach (XAttribute attribute in propertyAttributes) { propertyNames[n] = attribute.Name.ToString().ToLowerInvariant(); propertyEffects[n] = XMLExtensions.GetAttributeObject(attribute); n++; } foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "explosion": explosion = new Explosion(subElement, parentDebugName); break; case "fire": FireSize = subElement.GetAttributeFloat("size", 10.0f); break; case "use": case "useitem": useItemCount++; break; case "remove": case "removeitem": removeItem = true; break; case "requireditem": case "requireditems": RelatedItem newRequiredItem = RelatedItem.Load(subElement, parentDebugName); if (newRequiredItem == null) { DebugConsole.ThrowError("Error in StatusEffect config - requires an item with no identifiers."); continue; } requiredItems.Add(newRequiredItem); break; case "conditional": IEnumerable <XAttribute> conditionalAttributes = subElement.Attributes(); foreach (XAttribute attribute in conditionalAttributes) { if (attribute.Name.ToString().ToLowerInvariant() == "targetitemcomponent") { continue; } propertyConditionals.Add(new PropertyConditional(attribute)); } break; case "affliction": AfflictionPrefab afflictionPrefab; if (subElement.Attribute("name") != null) { DebugConsole.ThrowError("Error in StatusEffect (" + parentDebugName + ") - define afflictions using identifiers instead of names."); string afflictionName = subElement.GetAttributeString("name", "").ToLowerInvariant(); afflictionPrefab = AfflictionPrefab.List.Find(ap => ap.Name.ToLowerInvariant() == afflictionName); if (afflictionPrefab == null) { DebugConsole.ThrowError("Error in StatusEffect (" + parentDebugName + ") - Affliction prefab \"" + afflictionName + "\" not found."); continue; } } else { string afflictionIdentifier = subElement.GetAttributeString("identifier", "").ToLowerInvariant(); afflictionPrefab = AfflictionPrefab.List.Find(ap => ap.Identifier.ToLowerInvariant() == afflictionIdentifier); if (afflictionPrefab == null) { DebugConsole.ThrowError("Error in StatusEffect (" + parentDebugName + ") - Affliction prefab with the identifier \"" + afflictionIdentifier + "\" not found."); continue; } } float afflictionStrength = subElement.GetAttributeFloat(1.0f, "amount", "strength"); Afflictions.Add(afflictionPrefab.Instantiate(afflictionStrength)); break; case "reduceaffliction": if (subElement.Attribute("name") != null) { DebugConsole.ThrowError("Error in StatusEffect (" + parentDebugName + ") - define afflictions using identifiers or types instead of names."); ReduceAffliction.Add(new Pair <string, float>( subElement.GetAttributeString("name", "").ToLowerInvariant(), subElement.GetAttributeFloat(1.0f, "amount", "strength", "reduceamount"))); } else { string name = subElement.GetAttributeString("identifier", null) ?? subElement.GetAttributeString("type", null); name = name.ToLowerInvariant(); if (AfflictionPrefab.List.Any(ap => ap.Identifier == name || ap.AfflictionType == name)) { ReduceAffliction.Add(new Pair <string, float>( name, subElement.GetAttributeFloat(1.0f, "amount", "strength", "reduceamount"))); } else { DebugConsole.ThrowError("Error in StatusEffect (" + parentDebugName + ") - Affliction prefab with the identifier or type \"" + name + "\" not found."); } } break; case "spawnitem": var newSpawnItem = new ItemSpawnInfo(subElement, parentDebugName); if (newSpawnItem.ItemPrefab != null) { spawnItems.Add(newSpawnItem); } break; #if CLIENT case "particleemitter": particleEmitters.Add(new ParticleEmitter(subElement)); break; case "sound": var sound = Submarine.LoadRoundSound(subElement); if (sound != null) { loopSound = subElement.GetAttributeBool("loop", false); if (subElement.Attribute("selectionmode") != null) { if (Enum.TryParse(subElement.GetAttributeString("selectionmode", "Random"), out SoundSelectionMode selectionMode)) { soundSelectionMode = selectionMode; } } sounds.Add(sound); } break; #endif } } }
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); } }