示例#1
0
        /// <summary>
        /// Instantiates level data using the properties of the connection (seed, size, difficulty)
        /// </summary>
        public LevelData(LocationConnection locationConnection)
        {
            Seed             = locationConnection.Locations[0].BaseName + locationConnection.Locations[1].BaseName;
            Biome            = locationConnection.Biome;
            Type             = LevelType.LocationConnection;
            GenerationParams = LevelGenerationParams.GetRandom(Seed, LevelType.LocationConnection, Biome);
            Difficulty       = locationConnection.Difficulty;

            float sizeFactor = MathUtils.InverseLerp(
                MapGenerationParams.Instance.SmallLevelConnectionLength,
                MapGenerationParams.Instance.LargeLevelConnectionLength,
                locationConnection.Length);
            int width = (int)MathHelper.Lerp(GenerationParams.MinWidth, GenerationParams.MaxWidth, sizeFactor);

            Size = new Point(
                (int)MathUtils.Round(width, Level.GridCellSize),
                (int)MathUtils.Round(GenerationParams.Height, Level.GridCellSize));

            var rand = new MTRandom(ToolBox.StringToInt(Seed));

            InitialDepth = (int)MathHelper.Lerp(GenerationParams.InitialDepthMin, GenerationParams.InitialDepthMax, (float)rand.NextDouble());

            //minimum difficulty of the level before hunting grounds can appear
            float huntingGroundsDifficultyThreshold = 25;
            //probability of hunting grounds appearing in 100% difficulty levels
            float maxHuntingGroundsProbability = 0.3f;

            HasHuntingGrounds = OriginallyHadHuntingGrounds = rand.NextDouble() < MathUtils.InverseLerp(huntingGroundsDifficultyThreshold, 100.0f, Difficulty) * maxHuntingGroundsProbability;

            HasBeaconStation = !HasHuntingGrounds && rand.NextDouble() < locationConnection.Locations.Select(l => l.Type.BeaconStationChance).Max();
            IsBeaconActive   = false;
        }
示例#2
0
        public override void AddExtraMissions(LevelData levelData)
        {
            extraMissions.Clear();

            var currentLocation = Map.CurrentLocation;

            if (levelData.Type == LevelData.LevelType.Outpost)
            {
                //if there's an available mission that takes place in the outpost, select it
                var availableMissionsInLocation = currentLocation.AvailableMissions.Where(m => m.Locations[0] == currentLocation && m.Locations[1] == currentLocation);
                if (availableMissionsInLocation.Any())
                {
                    currentLocation.SelectedMission = availableMissionsInLocation.FirstOrDefault();
                }
                else
                {
                    currentLocation.SelectedMission = null;
                }
            }
            else
            {
                //if we had selected a mission that takes place in the outpost, deselect it when leaving the outpost
                if (currentLocation.SelectedMission?.Locations[0] == currentLocation &&
                    currentLocation.SelectedMission?.Locations[1] == currentLocation)
                {
                    currentLocation.SelectedMission = null;
                }

                if (levelData.HasBeaconStation && !levelData.IsBeaconActive)
                {
                    var beaconMissionPrefabs = MissionPrefab.List.FindAll(m => m.Tags.Any(t => t.Equals("beaconnoreward", StringComparison.OrdinalIgnoreCase)));
                    if (beaconMissionPrefabs.Any())
                    {
                        Random rand = new MTRandom(ToolBox.StringToInt(levelData.Seed));
                        var    beaconMissionPrefab = beaconMissionPrefabs.GetRandom(rand);
                        if (!Missions.Any(m => m.Prefab.Type == beaconMissionPrefab.Type))
                        {
                            extraMissions.Add(beaconMissionPrefab.Instantiate(Map.SelectedConnection.Locations));
                        }
                    }
                }
                if (levelData.HasHuntingGrounds)
                {
                    var huntingGroundsMissionPrefabs = MissionPrefab.List.FindAll(m => m.Tags.Any(t => t.Equals("huntinggroundsnoreward", StringComparison.OrdinalIgnoreCase)));
                    if (!huntingGroundsMissionPrefabs.Any())
                    {
                        DebugConsole.AddWarning("Could not find a hunting grounds mission for the level. No mission with the tag \"huntinggroundsnoreward\" found.");
                    }
                    else
                    {
                        Random rand = new MTRandom(ToolBox.StringToInt(levelData.Seed));
                        var    huntingGroundsMissionPrefab = huntingGroundsMissionPrefabs.GetRandom(rand);
                        if (!Missions.Any(m => m.Prefab.Tags.Any(t => t.Equals("huntinggrounds", StringComparison.OrdinalIgnoreCase))))
                        {
                            extraMissions.Add(huntingGroundsMissionPrefab.Instantiate(Map.SelectedConnection.Locations));
                        }
                    }
                }
            }
        }
示例#3
0
        private EventSet SelectRandomEvents(List <EventSet> eventSets)
        {
            if (level == null)
            {
                return(null);
            }
            MTRandom rand = new MTRandom(ToolBox.StringToInt(level.Seed));

            var allowedEventSets =
                eventSets.Where(es => level.Difficulty >= es.MinLevelDifficulty && level.Difficulty <= es.MaxLevelDifficulty && level.LevelData.Type == es.LevelType);

            if (GameMain.GameSession?.GameMode is CampaignMode campaign && campaign.Map?.CurrentLocation?.Type != null)
            {
                allowedEventSets = allowedEventSets.Where(set => set.LocationTypeIdentifiers == null || set.LocationTypeIdentifiers.Any(identifier => string.Equals(identifier, campaign.Map.CurrentLocation.Type.Identifier, StringComparison.OrdinalIgnoreCase)));
            }

            float totalCommonness = allowedEventSets.Sum(e => e.GetCommonness(level));
            float randomNumber    = (float)rand.NextDouble() * totalCommonness;

            foreach (EventSet eventSet in allowedEventSets)
            {
                float commonness = eventSet.GetCommonness(level);
                if (randomNumber <= commonness)
                {
                    return(eventSet);
                }
                randomNumber -= commonness;
            }

            return(null);
        }
示例#4
0
        /// <summary>
        /// Instantiates level data using the properties of the connection (seed, size, difficulty)
        /// </summary>
        public LevelData(LocationConnection locationConnection)
        {
            Seed             = locationConnection.Locations[0].BaseName + locationConnection.Locations[1].BaseName;
            Biome            = locationConnection.Biome;
            Type             = LevelType.LocationConnection;
            GenerationParams = LevelGenerationParams.GetRandom(Seed, LevelType.LocationConnection, Biome);
            Difficulty       = locationConnection.Difficulty;

            float sizeFactor = MathUtils.InverseLerp(
                MapGenerationParams.Instance.SmallLevelConnectionLength,
                MapGenerationParams.Instance.LargeLevelConnectionLength,
                locationConnection.Length);
            int width = (int)MathHelper.Lerp(GenerationParams.MinWidth, GenerationParams.MaxWidth, sizeFactor);

            Size = new Point(
                (int)MathUtils.Round(width, Level.GridCellSize),
                (int)MathUtils.Round(GenerationParams.Height, Level.GridCellSize));

            var rand = new MTRandom(ToolBox.StringToInt(Seed));

            InitialDepth = (int)MathHelper.Lerp(GenerationParams.InitialDepthMin, GenerationParams.InitialDepthMax, (float)rand.NextDouble());

            HasBeaconStation = rand.NextDouble() < locationConnection.Locations.Select(l => l.Type.BeaconStationChance).Max();
            IsBeaconActive   = false;
        }
示例#5
0
        public MissionMode(GameModePreset preset, object param)
            : base(preset, param)
        {
            Location[] locations = { GameMain.GameSession.StartLocation, GameMain.GameSession.EndLocation };

            MTRandom rand = new MTRandom(ToolBox.StringToInt(GameMain.NetLobbyScreen.LevelSeed));

            mission = Mission.LoadRandom(locations, rand, param as string);
        }
示例#6
0
        private void CreateScriptedEvents(Level level)
        {
            System.Diagnostics.Debug.Assert(events.Count == 0);

            MTRandom rand = new MTRandom(ToolBox.StringToInt(level.Seed));

            if (GameSettings.VerboseLogging)
            {
                DebugConsole.NewMessage("Generating events (seed: " + level.Seed + ")", Color.White);
            }

            events.AddRange(ScriptedEvent.GenerateLevelEvents(rand, level));
        }
示例#7
0
        public static Mission LoadRandom(Location[] locations, MTRandom rand, string missionType = "", bool isSinglePlayer = false)
        {
            //todo: use something else than strings to define the mission type
            missionType = missionType.ToLowerInvariant();

            List <MissionPrefab> allowedMissions = new List <MissionPrefab>();

            if (missionType == "random")
            {
                allowedMissions.AddRange(MissionPrefab.List);
                if (GameMain.Server != null)
                {
                    allowedMissions.RemoveAll(mission => !GameMain.Server.AllowedRandomMissionTypes.Any(a => mission.TypeMatches(a)));
                }
            }
            else if (missionType == "none")
            {
                return(null);
            }
            else if (string.IsNullOrWhiteSpace(missionType))
            {
                allowedMissions.AddRange(MissionPrefab.List);
            }
            else
            {
                allowedMissions = MissionPrefab.List.FindAll(m => m.TypeMatches(missionType));
            }

            if (isSinglePlayer)
            {
                allowedMissions.RemoveAll(m => m.MultiplayerOnly);
            }
            else
            {
                allowedMissions.RemoveAll(m => m.SingleplayerOnly);
            }

            float probabilitySum = allowedMissions.Sum(m => m.Commonness);
            float randomNumber   = (float)rand.NextDouble() * probabilitySum;

            foreach (MissionPrefab missionPrefab in allowedMissions)
            {
                if (randomNumber <= missionPrefab.Commonness)
                {
                    return(missionPrefab.Instantiate(locations));
                }
                randomNumber -= missionPrefab.Commonness;
            }

            return(null);
        }
示例#8
0
        /// <summary>
        /// Instantiates level data using the properties of the location
        /// </summary>
        public LevelData(Location location)
        {
            Seed             = location.BaseName;
            Biome            = location.Biome;
            Type             = LevelType.Outpost;
            GenerationParams = LevelGenerationParams.GetRandom(Seed, LevelType.Outpost, Biome);
            Difficulty       = 0.0f;

            var rand  = new MTRandom(ToolBox.StringToInt(Seed));
            int width = (int)MathHelper.Lerp(GenerationParams.MinWidth, GenerationParams.MaxWidth, (float)rand.NextDouble());

            Size = new Point(
                (int)MathUtils.Round(width, Level.GridCellSize),
                (int)MathUtils.Round(GenerationParams.Height, Level.GridCellSize));
        }
示例#9
0
        public static Mission LoadRandom(Location[] locations, MTRandom rand, bool requireCorrectLocationType, MissionType missionType, bool isSinglePlayer = false)
        {
            List <MissionPrefab> allowedMissions = new List <MissionPrefab>();

            if (missionType == MissionType.Random)
            {
                allowedMissions.AddRange(MissionPrefab.List);
            }
            else if (missionType == MissionType.None)
            {
                return(null);
            }
            else
            {
                allowedMissions = MissionPrefab.List.FindAll(m => m.type == missionType);
            }

            allowedMissions.RemoveAll(m => isSinglePlayer ? m.MultiplayerOnly : m.SingleplayerOnly);
            if (requireCorrectLocationType)
            {
                allowedMissions.RemoveAll(m => !m.IsAllowed(locations[0], locations[1]));
            }

            if (allowedMissions.Count == 0)
            {
                return(null);
            }

            int probabilitySum = allowedMissions.Sum(m => m.Commonness);
            int randomNumber   = rand.NextInt32() % probabilitySum;

            foreach (MissionPrefab missionPrefab in allowedMissions)
            {
                if (randomNumber <= missionPrefab.Commonness)
                {
                    return(missionPrefab.Instantiate(locations));
                }
                randomNumber -= missionPrefab.Commonness;
            }

            return(null);
        }
示例#10
0
        private ScriptedEventSet SelectRandomEvents(List <ScriptedEventSet> eventSets)
        {
            MTRandom rand = new MTRandom(ToolBox.StringToInt(level.Seed));

            var allowedEventSets =
                eventSets.Where(es => level.Difficulty >= es.MinLevelDifficulty && level.Difficulty <= es.MaxLevelDifficulty);

            float totalCommonness = allowedEventSets.Sum(e => e.GetCommonness(level));
            float randomNumber    = (float)rand.NextDouble() * totalCommonness;

            foreach (ScriptedEventSet eventSet in allowedEventSets)
            {
                float commonness = eventSet.GetCommonness(level);
                if (randomNumber <= commonness)
                {
                    return(eventSet);
                }
                randomNumber -= commonness;
            }

            return(null);
        }
示例#11
0
        private void CreateDummyLocations()
        {
            dummyLocations = new Location[2];

            string seed = "";

            if (GameMain.GameSession != null && GameMain.GameSession.Level != null)
            {
                seed = GameMain.GameSession.Level.Seed;
            }
            else if (GameMain.NetLobbyScreen != null)
            {
                seed = GameMain.NetLobbyScreen.LevelSeed;
            }

            MTRandom rand = new MTRandom(ToolBox.StringToInt(seed));

            for (int i = 0; i < 2; i++)
            {
                dummyLocations[i] = Location.CreateRandom(new Vector2((float)rand.NextDouble() * 10000.0f, (float)rand.NextDouble() * 10000.0f));
            }
        }
示例#12
0
        private void CreateScriptedEvents(Level level)
        {
            MTRandom rand = new MTRandom(ToolBox.StringToInt(level.Seed));

            float totalDifficulty = level.Difficulty;

            int tries = 0;

            while (tries < 5)
            {
                ScriptedEvent scriptedEvent = ScriptedEvent.LoadRandom(rand);
                if (scriptedEvent == null || scriptedEvent.Difficulty > totalDifficulty)
                {
                    tries++;
                    continue;
                }
                DebugConsole.Log("Created scripted event " + scriptedEvent.ToString());

                AddTask(new ScriptedTask(scriptedEvent));
                totalDifficulty -= scriptedEvent.Difficulty;
                tries            = 0;
            }
        }
示例#13
0
        private void CreateEvents(EventSet eventSet)
        {
            if (level == null)
            {
                return;
            }
            int applyCount = 1;

            if (eventSet.PerRuin)
            {
                applyCount = Level.Loaded.Ruins.Count();
            }
            else if (eventSet.PerWreck)
            {
                applyCount = Submarine.Loaded.Count(s => s.Info.IsWreck && (s.WreckAI == null || !s.WreckAI.IsAlive));
            }
            for (int i = 0; i < applyCount; i++)
            {
                if (eventSet.ChooseRandom)
                {
                    if (eventSet.EventPrefabs.Count > 0)
                    {
                        int seed = ToolBox.StringToInt(level.Seed);
                        foreach (var previousEvent in level.LevelData.EventHistory)
                        {
                            seed |= ToolBox.StringToInt(previousEvent.Identifier);
                        }

                        MTRandom rand = new MTRandom(seed);
                        List <Pair <EventPrefab, float> > unusedEvents = new List <Pair <EventPrefab, float> >(eventSet.EventPrefabs);
                        for (int j = 0; j < eventSet.EventCount; j++)
                        {
                            var eventPrefab = ToolBox.SelectWeightedRandom(unusedEvents, unusedEvents.Select(e => CalculateCommonness(e)).ToList(), rand);
                            if (eventPrefab != null)
                            {
                                var newEvent = eventPrefab.First.CreateInstance();
                                newEvent.Init(true);
                                DebugConsole.Log("Initialized event " + newEvent.ToString());
                                if (!selectedEvents.ContainsKey(eventSet))
                                {
                                    selectedEvents.Add(eventSet, new List <Event>());
                                }
                                selectedEvents[eventSet].Add(newEvent);
                                unusedEvents.Remove(eventPrefab);
                            }
                        }
                    }
                    if (eventSet.ChildSets.Count > 0)
                    {
                        var newEventSet = SelectRandomEvents(eventSet.ChildSets);
                        if (newEventSet != null)
                        {
                            CreateEvents(newEventSet);
                        }
                    }
                }
                else
                {
                    foreach (Pair <EventPrefab, float> eventPrefab in eventSet.EventPrefabs)
                    {
                        var newEvent = eventPrefab.First.CreateInstance();
                        newEvent.Init(true);
                        DebugConsole.Log("Initialized event " + newEvent.ToString());
                        if (!selectedEvents.ContainsKey(eventSet))
                        {
                            selectedEvents.Add(eventSet, new List <Event>());
                        }
                        selectedEvents[eventSet].Add(newEvent);
                    }

                    foreach (EventSet childEventSet in eventSet.ChildSets)
                    {
                        CreateEvents(childEventSet);
                    }
                }
            }
        }
        public void StartRound(Level level)
        {
            if (isClient)
            {
                return;
            }

            pendingEventSets.Clear();
            selectedEvents.Clear();
            activeEvents.Clear();

            pathFinder      = new PathFinder(WayPoint.WayPointList, indoorsSteering: false);
            totalPathLength = 0.0f;
            if (level != null)
            {
                var steeringPath = pathFinder.FindPath(ConvertUnits.ToSimUnits(Level.Loaded.StartPosition), ConvertUnits.ToSimUnits(Level.Loaded.EndPosition));
                totalPathLength = steeringPath.TotalLength;
            }

            this.level = level;
            SelectSettings();

            var initialEventSet = SelectRandomEvents(EventSet.List);

            if (initialEventSet != null)
            {
                pendingEventSets.Add(initialEventSet);
                int seed = ToolBox.StringToInt(level.Seed);
                foreach (var previousEvent in level.LevelData.EventHistory)
                {
                    seed ^= ToolBox.StringToInt(previousEvent.Identifier);
                }
                MTRandom rand = new MTRandom(seed);
                CreateEvents(initialEventSet, rand);
            }

            if (level?.LevelData?.Type == LevelData.LevelType.Outpost)
            {
                level.LevelData.EventHistory.AddRange(selectedEvents.Values.SelectMany(v => v).Select(e => e.Prefab).Where(e => !level.LevelData.EventHistory.Contains(e)));
                if (level.LevelData.EventHistory.Count > MaxEventHistory)
                {
                    level.LevelData.EventHistory.RemoveRange(0, level.LevelData.EventHistory.Count - MaxEventHistory);
                }
                AddChildEvents(initialEventSet);
                void AddChildEvents(EventSet eventSet)
                {
                    if (eventSet == null)
                    {
                        return;
                    }
                    foreach (EventPrefab ep in eventSet.EventPrefabs.Select(e => e.First))
                    {
                        if (!level.LevelData.NonRepeatableEvents.Contains(ep))
                        {
                            level.LevelData.NonRepeatableEvents.Add(ep);
                        }
                    }
                    foreach (EventSet childSet in eventSet.ChildSets)
                    {
                        AddChildEvents(childSet);
                    }
                }
            }

            PreloadContent(GetFilesToPreload());

            roundDuration        = 0.0f;
            isCrewAway           = false;
            crewAwayDuration     = 0.0f;
            crewAwayResetTimer   = 0.0f;
            intensityUpdateTimer = 0.0f;
            CalculateCurrentIntensity(0.0f);
            currentIntensity = targetIntensity;
            eventCoolDown    = 0.0f;
        }
示例#15
0
        private void CreateEvents(ScriptedEventSet eventSet)
        {
            int applyCount = 1;

            if (eventSet.PerRuin)
            {
                applyCount = Level.Loaded.Ruins.Count();
            }
            else if (eventSet.PerWreck)
            {
                applyCount = Submarine.Loaded.Count(s => s.Info.IsWreck && (s.WreckAI == null || !s.WreckAI.IsAlive));
            }
            for (int i = 0; i < applyCount; i++)
            {
                if (eventSet.ChooseRandom)
                {
                    if (eventSet.EventPrefabs.Count > 0)
                    {
                        MTRandom rand        = new MTRandom(ToolBox.StringToInt(level.Seed));
                        var      eventPrefab = ToolBox.SelectWeightedRandom(eventSet.EventPrefabs, eventSet.EventPrefabs.Select(e => e.Commonness).ToList(), rand);
                        if (eventPrefab != null)
                        {
                            var newEvent = eventPrefab.CreateInstance();
                            newEvent.Init(true);
                            DebugConsole.Log("Initialized event " + newEvent.ToString());
                            if (!selectedEvents.ContainsKey(eventSet))
                            {
                                selectedEvents.Add(eventSet, new List <ScriptedEvent>());
                            }
                            selectedEvents[eventSet].Add(newEvent);
                        }
                    }
                    if (eventSet.ChildSets.Count > 0)
                    {
                        var newEventSet = SelectRandomEvents(eventSet.ChildSets);
                        if (newEventSet != null)
                        {
                            CreateEvents(newEventSet);
                        }
                    }
                }
                else
                {
                    foreach (ScriptedEventPrefab eventPrefab in eventSet.EventPrefabs)
                    {
                        var newEvent = eventPrefab.CreateInstance();
                        newEvent.Init(true);
                        DebugConsole.Log("Initialized event " + newEvent.ToString());
                        if (!selectedEvents.ContainsKey(eventSet))
                        {
                            selectedEvents.Add(eventSet, new List <ScriptedEvent>());
                        }
                        selectedEvents[eventSet].Add(newEvent);
                    }

                    foreach (ScriptedEventSet childEventSet in eventSet.ChildSets)
                    {
                        CreateEvents(childEventSet);
                    }
                }
            }
        }
示例#16
0
        public override void AddExtraMissions(LevelData levelData)
        {
            extraMissions.Clear();

            var currentLocation = Map.CurrentLocation;

            if (levelData.Type == LevelData.LevelType.Outpost)
            {
                //if there's an available mission that takes place in the outpost, select it
                foreach (var availableMission in currentLocation.AvailableMissions)
                {
                    if (availableMission.Locations[0] == currentLocation && availableMission.Locations[1] == currentLocation)
                    {
                        currentLocation.SelectMission(availableMission);
                    }
                }
            }
            else
            {
                foreach (Mission mission in currentLocation.SelectedMissions.ToList())
                {
                    //if we had selected a mission that takes place in the outpost, deselect it when leaving the outpost
                    if (mission.Locations[0] == currentLocation &&
                        mission.Locations[1] == currentLocation)
                    {
                        currentLocation.DeselectMission(mission);
                    }
                }

                if (levelData.HasBeaconStation && !levelData.IsBeaconActive)
                {
                    var beaconMissionPrefabs = MissionPrefab.List.FindAll(m => m.Tags.Any(t => t.Equals("beaconnoreward", StringComparison.OrdinalIgnoreCase)));
                    if (beaconMissionPrefabs.Any())
                    {
                        Random rand = new MTRandom(ToolBox.StringToInt(levelData.Seed));
                        var    beaconMissionPrefab = ToolBox.SelectWeightedRandom(beaconMissionPrefabs, beaconMissionPrefabs.Select(p => (float)p.Commonness).ToList(), rand);
                        if (!Missions.Any(m => m.Prefab.Type == beaconMissionPrefab.Type))
                        {
                            extraMissions.Add(beaconMissionPrefab.Instantiate(Map.SelectedConnection.Locations, Submarine.MainSub));
                        }
                    }
                }
                if (levelData.HasHuntingGrounds)
                {
                    var huntingGroundsMissionPrefabs = MissionPrefab.List.FindAll(m => m.Tags.Any(t => t.Equals("huntinggroundsnoreward", StringComparison.OrdinalIgnoreCase)));
                    if (!huntingGroundsMissionPrefabs.Any())
                    {
                        DebugConsole.AddWarning("Could not find a hunting grounds mission for the level. No mission with the tag \"huntinggroundsnoreward\" found.");
                    }
                    else
                    {
                        Random rand = new MTRandom(ToolBox.StringToInt(levelData.Seed));
                        var    huntingGroundsMissionPrefab = ToolBox.SelectWeightedRandom(huntingGroundsMissionPrefabs, huntingGroundsMissionPrefabs.Select(p => (float)Math.Max(p.Commonness, 0.1f)).ToList(), rand);
                        if (!Missions.Any(m => m.Prefab.Tags.Any(t => t.Equals("huntinggrounds", StringComparison.OrdinalIgnoreCase))))
                        {
                            extraMissions.Add(huntingGroundsMissionPrefab.Instantiate(Map.SelectedConnection.Locations, Submarine.MainSub));
                        }
                    }
                }
            }
        }
示例#17
0
        public static NPCPersonalityTrait GetRandom(string seed)
        {
            var rand = new MTRandom(ToolBox.StringToInt(seed));

            return(ToolBox.SelectWeightedRandom(list, list.Select(t => t.commonness).ToList(), rand));
        }
示例#18
0
        private void CreateEvents()
        {
            //don't create new events if docked to the start oupost
            if (Level.Loaded?.StartOutpost != null &&
                Submarine.MainSub.DockedTo.Contains(Level.Loaded.StartOutpost))
            {
                return;
            }

            for (int i = selectedEventSets.Count - 1; i >= 0; i--)
            {
                ScriptedEventSet eventSet = selectedEventSets[i];

                float distFromStart = Vector2.Distance(Submarine.MainSub.WorldPosition, level.StartPosition);
                float distFromEnd   = Vector2.Distance(Submarine.MainSub.WorldPosition, level.EndPosition);

                float distanceTraveled = MathHelper.Clamp(
                    (Submarine.MainSub.WorldPosition.X - level.StartPosition.X) / (level.EndPosition.X - level.StartPosition.X),
                    0.0f, 1.0f);

                //don't create new events if within 50 meters of the start/end of the level
                if (distanceTraveled <= 0.0f ||
                    distFromStart * Physics.DisplayToRealWorldRatio < 50.0f ||
                    distFromEnd * Physics.DisplayToRealWorldRatio < 50.0f)
                {
                    continue;
                }

                if ((Submarine.MainSub == null || distanceTraveled < eventSet.MinDistanceTraveled) &&
                    roundDuration < eventSet.MinMissionTime)
                {
                    continue;
                }

                if (CurrentIntensity < eventSet.MinIntensity || CurrentIntensity > eventSet.MaxIntensity)
                {
                    continue;
                }

                selectedEventSets.RemoveAt(i);

                if (eventSet.ChooseRandom)
                {
                    if (eventSet.EventPrefabs.Count > 0)
                    {
                        MTRandom rand     = new MTRandom(ToolBox.StringToInt(level.Seed));
                        var      newEvent = eventSet.EventPrefabs[rand.NextInt32() % eventSet.EventPrefabs.Count].CreateInstance();
                        newEvent.Init(true);
                        DebugConsole.Log("Initialized event " + newEvent.ToString());
                        events.Add(newEvent);
                    }
                    if (eventSet.ChildSets.Count > 0)
                    {
                        MTRandom rand        = new MTRandom(ToolBox.StringToInt(level.Seed));
                        var      newEventSet = SelectRandomEvents(eventSet.ChildSets);
                        if (newEventSet != null)
                        {
                            selectedEventSets.Add(newEventSet);
                        }
                    }
                }
                else
                {
                    foreach (ScriptedEventPrefab eventPrefab in eventSet.EventPrefabs)
                    {
                        var newEvent = eventPrefab.CreateInstance();
                        newEvent.Init(true);
                        DebugConsole.Log("Initialized event " + newEvent.ToString());
                        events.Add(newEvent);
                    }

                    selectedEventSets.AddRange(eventSet.ChildSets);
                }
            }
        }
示例#19
0
        public static Mission LoadRandom(Location[] locations, MTRandom rand, string missionType = "", bool isSinglePlayer = false)
        {
            missionType = missionType.ToLowerInvariant();

            var    files      = GameMain.SelectedPackage.GetFilesOfType(ContentType.Missions);
            string configFile = files[rand.Next(files.Count)];

            XDocument doc = ToolBox.TryLoadXml(configFile);

            if (doc == null)
            {
                return(null);
            }

            int eventCount = doc.Root.Elements().Count();

            //int[] commonness = new int[eventCount];
            float[] eventProbability = new float[eventCount];

            float probabilitySum = 0.0f;

            List <XElement> matchingElements = new List <XElement>();

            if (missionType == "random")
            {
                matchingElements = doc.Root.Elements().ToList();
            }
            else if (missionType == "none")
            {
                return(null);
            }
            else if (string.IsNullOrWhiteSpace(missionType))
            {
                matchingElements = doc.Root.Elements().ToList();
            }
            else
            {
                matchingElements = doc.Root.Elements().ToList().FindAll(m => m.Name.ToString().ToLowerInvariant().Replace("mission", "") == missionType);
            }

            if (isSinglePlayer)
            {
                matchingElements.RemoveAll(m => ToolBox.GetAttributeBool(m, "multiplayeronly", false));
            }
            else
            {
                matchingElements.RemoveAll(m => ToolBox.GetAttributeBool(m, "singleplayeronly", false));
            }

            int i = 0;

            foreach (XElement element in matchingElements)
            {
                eventProbability[i] = ToolBox.GetAttributeInt(element, "commonness", 1);

                probabilitySum += eventProbability[i];

                i++;
            }

            float randomNumber = (float)rand.NextDouble() * probabilitySum;

            i = 0;
            foreach (XElement element in matchingElements)
            {
                if (randomNumber <= eventProbability[i])
                {
                    Type   t;
                    string type = element.Name.ToString();

                    try
                    {
                        t = Type.GetType("Barotrauma." + type, true, true);
                        if (t == null)
                        {
                            DebugConsole.ThrowError("Error in " + configFile + "! Could not find a mission class of the type \"" + type + "\".");
                            continue;
                        }
                    }
                    catch
                    {
                        DebugConsole.ThrowError("Error in " + configFile + "! Could not find a mission class of the type \"" + type + "\".");
                        continue;
                    }

                    ConstructorInfo constructor = t.GetConstructor(new[] { typeof(XElement), typeof(Location[]) });

                    object instance = constructor.Invoke(new object[] { element, locations });

                    Mission mission = (Mission)instance;

                    return(mission);
                }

                randomNumber -= eventProbability[i];
                i++;
            }

            return(null);
        }
示例#20
0
        public void StartRound(Level level)
        {
            this.level = level;

            if (isClient)
            {
                return;
            }

            pendingEventSets.Clear();
            selectedEvents.Clear();
            activeEvents.Clear();

            pathFinder      = new PathFinder(WayPoint.WayPointList, false);
            totalPathLength = 0.0f;
            if (level != null)
            {
                var steeringPath = pathFinder.FindPath(ConvertUnits.ToSimUnits(level.StartPosition), ConvertUnits.ToSimUnits(level.EndPosition));
                totalPathLength = steeringPath.TotalLength;
            }

            SelectSettings();

            int seed = 0;

            if (level != null)
            {
                seed = ToolBox.StringToInt(level.Seed);
                foreach (var previousEvent in level.LevelData.EventHistory)
                {
                    seed ^= ToolBox.StringToInt(previousEvent.Identifier);
                }
            }
            MTRandom rand = new MTRandom(seed);

            EventSet initialEventSet = SelectRandomEvents(EventSet.List, rand);
            EventSet additiveSet     = null;

            if (initialEventSet != null && initialEventSet.Additive)
            {
                additiveSet     = initialEventSet;
                initialEventSet = SelectRandomEvents(EventSet.List.FindAll(e => !e.Additive), rand);
            }
            if (initialEventSet != null)
            {
                pendingEventSets.Add(initialEventSet);
                CreateEvents(initialEventSet, rand);
            }
            if (additiveSet != null)
            {
                pendingEventSets.Add(additiveSet);
                CreateEvents(additiveSet, rand);
            }

            if (level?.LevelData?.Type == LevelData.LevelType.Outpost)
            {
                //if the outpost is connected to a locked connection, create an event to unlock it
                if (level.StartLocation?.Connections.Any(c => c.Locked && level.StartLocation.MapPosition.X < c.OtherLocation(level.StartLocation).MapPosition.X) ?? false)
                {
                    var unlockPathPrefabs         = EventSet.PrefabList.FindAll(e => e.UnlockPathEvent);
                    var unlockPathPrefabsForBiome = unlockPathPrefabs.FindAll(e =>
                                                                              string.IsNullOrEmpty(e.BiomeIdentifier) ||
                                                                              e.BiomeIdentifier.Equals(level.LevelData.Biome.Identifier, StringComparison.OrdinalIgnoreCase));

                    var unlockPathEventPrefab = unlockPathPrefabsForBiome.Any() ?
                                                ToolBox.SelectWeightedRandom(unlockPathPrefabsForBiome, unlockPathPrefabsForBiome.Select(b => b.Commonness).ToList(), rand) :
                                                ToolBox.SelectWeightedRandom(unlockPathPrefabs, unlockPathPrefabs.Select(b => b.Commonness).ToList(), rand);
                    if (unlockPathEventPrefab != null)
                    {
                        var newEvent = unlockPathEventPrefab.CreateInstance();
                        newEvent.Init(true);
                        ActiveEvents.Add(newEvent);
                    }
                    else
                    {
                        //if no event that unlocks the path can be found, unlock it automatically
                        level.StartLocation.Connections.ForEach(c => c.Locked = false);
                    }
                }

                level.LevelData.EventHistory.AddRange(selectedEvents.Values.SelectMany(v => v).Select(e => e.Prefab).Where(e => !level.LevelData.EventHistory.Contains(e)));
                if (level.LevelData.EventHistory.Count > MaxEventHistory)
                {
                    level.LevelData.EventHistory.RemoveRange(0, level.LevelData.EventHistory.Count - MaxEventHistory);
                }
                AddChildEvents(initialEventSet);
                void AddChildEvents(EventSet eventSet)
                {
                    if (eventSet == null)
                    {
                        return;
                    }
                    if (eventSet.OncePerOutpost)
                    {
                        foreach (EventPrefab ep in eventSet.EventPrefabs.SelectMany(e => e.Prefabs))
                        {
                            if (!level.LevelData.NonRepeatableEvents.Contains(ep))
                            {
                                level.LevelData.NonRepeatableEvents.Add(ep);
                            }
                        }
                    }
                    foreach (EventSet childSet in eventSet.ChildSets)
                    {
                        AddChildEvents(childSet);
                    }
                }
            }

            PreloadContent(GetFilesToPreload());

            roundDuration        = 0.0f;
            isCrewAway           = false;
            crewAwayDuration     = 0.0f;
            crewAwayResetTimer   = 0.0f;
            intensityUpdateTimer = 0.0f;
            CalculateCurrentIntensity(0.0f);
            currentIntensity = targetIntensity;
            eventCoolDown    = 0.0f;
        }