Beispiel #1
0
        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;
                }
            }
        }
Beispiel #2
0
        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
        }
Beispiel #3
0
        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);
            }
        }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
        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);
            }
        }