/// <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; }
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)); } } } } }
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); }
/// <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; }
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); }
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)); }
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); }
/// <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)); }
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); }
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); }
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)); } }
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; } }
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; }
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); } } } }
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)); } } } } }
public static NPCPersonalityTrait GetRandom(string seed) { var rand = new MTRandom(ToolBox.StringToInt(seed)); return(ToolBox.SelectWeightedRandom(list, list.Select(t => t.commonness).ToList(), rand)); }
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); } } }
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); }
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; }