public override void Update(float deltaTime) { if (isFinished) { return; } if (GameMain.GameSession?.EventManager != null) { var eventPrefab = EventSet.GetEventPrefab(Identifier); if (eventPrefab == null) { DebugConsole.ThrowError($"Error in TriggerEventAction - could not find an event with the identifier {Identifier}."); } else { var ev = eventPrefab.CreateInstance(); if (ev != null) { GameMain.GameSession.EventManager.QueuedEvents.Enqueue(ev); } } } isFinished = true; }
private bool CanStartEventSet(EventSet eventSet) { ISpatialEntity refEntity = GetRefEntity(); float distFromStart = Vector2.Distance(refEntity.WorldPosition, level.StartPosition); float distFromEnd = Vector2.Distance(refEntity.WorldPosition, level.EndPosition); //don't create new events if within 50 meters of the start/end of the level if (!eventSet.AllowAtStart) { if (distanceTraveled <= 0.0f || distFromStart * Physics.DisplayToRealWorldRatio < 50.0f || distFromEnd * Physics.DisplayToRealWorldRatio < 50.0f) { return(false); } } if ((Submarine.MainSub == null || distanceTraveled < eventSet.MinDistanceTraveled) && roundDuration < eventSet.MinMissionTime) { return(false); } if (CurrentIntensity < eventSet.MinIntensity || CurrentIntensity > eventSet.MaxIntensity) { return(false); } return(true); }
static void CheckEventSet(EventDebugStats stats, EventSet thisSet) { if (thisSet.ChooseRandom) { var unusedEvents = thisSet.EventPrefabs.ToList(); for (int i = 0; i < thisSet.EventCount; i++) { var eventPrefab = ToolBox.SelectWeightedRandom(unusedEvents, unusedEvents.Select(e => e.Commonness).ToList(), Rand.RandSync.Unsynced); if (eventPrefab.Prefabs.Any(p => p != null)) { AddEvents(stats, eventPrefab.Prefabs); unusedEvents.Remove(eventPrefab); } } } else { foreach (var eventPrefab in thisSet.EventPrefabs) { AddEvents(stats, eventPrefab.Prefabs); } } foreach (var childSet in thisSet.ChildSets) { CheckEventSet(stats, childSet); } }
static void CheckEventSet(EventDebugStats stats, EventSet thisSet) { if (thisSet.ChooseRandom) { List <Pair <EventPrefab, float> > unusedEvents = new List <Pair <EventPrefab, float> >(thisSet.EventPrefabs); for (int i = 0; i < thisSet.EventCount; i++) { var eventPrefab = ToolBox.SelectWeightedRandom(unusedEvents, unusedEvents.Select(e => e.Second).ToList(), Rand.RandSync.Unsynced); if (eventPrefab != null) { AddEvent(stats, eventPrefab.First); unusedEvents.Remove(eventPrefab); } } } else { foreach (var eventPrefab in thisSet.EventPrefabs) { AddEvent(stats, eventPrefab.First); } } foreach (var childSet in thisSet.ChildSets) { CheckEventSet(stats, childSet); } }
/// <summary> /// Triggers the event immediately, ignoring any delays /// </summary> private void TriggerEvent(MissionPrefab.TriggerEvent trigger) { if (trigger.CampaignOnly && GameMain.GameSession?.Campaign == null) { return; } var eventPrefab = EventSet.GetAllEventPrefabs().Find(p => p.Identifier.Equals(trigger.EventIdentifier, StringComparison.OrdinalIgnoreCase)); if (eventPrefab == null) { DebugConsole.ThrowError($"Mission \"{Name}\" failed to trigger an event (couldn't find an event with the identifier \"{trigger.EventIdentifier}\")."); return; } if (GameMain.GameSession?.EventManager != null) { var newEvent = eventPrefab.CreateInstance(); GameMain.GameSession.EventManager.ActiveEvents.Add(newEvent); newEvent.Init(true); } }
public void Init() { NPCSet.LoadSets(); FactionPrefab.LoadFactions(); CharacterPrefab.LoadAll(); MissionPrefab.Init(); TraitorMissionPrefab.Init(); MapEntityPrefab.Init(); MapGenerationParams.Init(); LevelGenerationParams.LoadPresets(); CaveGenerationParams.LoadPresets(); OutpostGenerationParams.LoadPresets(); EventSet.LoadPrefabs(); Order.Init(); EventManagerSettings.Init(); ItemPrefab.LoadAll(GetFilesOfType(ContentType.Item)); AfflictionPrefab.LoadAll(GetFilesOfType(ContentType.Afflictions)); SkillSettings.Load(GetFilesOfType(ContentType.SkillSettings)); StructurePrefab.LoadAll(GetFilesOfType(ContentType.Structure)); UpgradePrefab.LoadAll(GetFilesOfType(ContentType.UpgradeModules)); JobPrefab.LoadAll(GetFilesOfType(ContentType.Jobs)); CorpsePrefab.LoadAll(GetFilesOfType(ContentType.Corpses)); NPCConversation.LoadAll(GetFilesOfType(ContentType.NPCConversations)); ItemAssemblyPrefab.LoadAll(); LevelObjectPrefab.LoadAll(); BallastFloraPrefab.LoadAll(GetFilesOfType(ContentType.MapCreature)); TalentPrefab.LoadAll(GetFilesOfType(ContentType.Talents)); TalentTree.LoadAll(GetFilesOfType(ContentType.TalentTrees)); GameModePreset.Init(); DecalManager = new DecalManager(); LocationType.Init(); SubmarineInfo.RefreshSavedSubs(); Screen.SelectNull(); NetLobbyScreen = new NetLobbyScreen(); CheckContentPackage(); }
private bool CanStartEventSet(EventSet eventSet) { ISpatialEntity refEntity = GetRefEntity(); float distFromStart = (float)Math.Sqrt(MathUtils.LineSegmentToPointDistanceSquared(level.StartExitPosition.ToPoint(), level.StartPosition.ToPoint(), refEntity.WorldPosition.ToPoint())); float distFromEnd = (float)Math.Sqrt(MathUtils.LineSegmentToPointDistanceSquared(level.EndExitPosition.ToPoint(), level.EndPosition.ToPoint(), refEntity.WorldPosition.ToPoint())); //don't create new events if within 50 meters of the start/end of the level if (!eventSet.AllowAtStart) { if (distanceTraveled <= 0.0f || distFromStart * Physics.DisplayToRealWorldRatio < 50.0f || distFromEnd * Physics.DisplayToRealWorldRatio < 50.0f) { return(false); } } if (eventSet.DelayWhenCrewAway) { if ((isCrewAway && crewAwayDuration < settings.FreezeDurationWhenCrewAway) || crewAwayResetTimer > 0.0f) { return(false); } } if ((Submarine.MainSub == null || distanceTraveled < eventSet.MinDistanceTraveled) && roundDuration < eventSet.MinMissionTime) { return(false); } if (CurrentIntensity < eventSet.MinIntensity || CurrentIntensity > eventSet.MaxIntensity) { return(false); } return(true); }
public static List <string> GetDebugStatistics(int simulatedRoundCount = 100) { List <string> debugLines = new List <string>(); foreach (var eventSet in List) { List <EventDebugStats> stats = new List <EventDebugStats>(); for (int i = 0; i < simulatedRoundCount; i++) { var newStats = new EventDebugStats(eventSet); CheckEventSet(newStats, eventSet); stats.Add(newStats); } debugLines.Add($"Event stats ({eventSet.DebugIdentifier}): "); LogEventStats(stats, debugLines); } for (int difficulty = 0; difficulty <= 100; difficulty += 10) { debugLines.Add($"Event stats on difficulty level {difficulty}: "); List <EventDebugStats> stats = new List <EventDebugStats>(); for (int i = 0; i < simulatedRoundCount; i++) { EventSet selectedSet = List.Where(s => difficulty >= s.MinLevelDifficulty && difficulty <= s.MaxLevelDifficulty).GetRandom(); if (selectedSet == null) { continue; } var newStats = new EventDebugStats(selectedSet); CheckEventSet(newStats, selectedSet); stats.Add(newStats); } LogEventStats(stats, debugLines); } return(debugLines);
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 EventDebugStats(EventSet rootSet) { RootSet = rootSet; }
private EventSet(XElement element, string debugIdentifier, EventSet parentSet = null) { DebugIdentifier = element.GetAttributeString("identifier", null) ?? debugIdentifier; Commonness = new Dictionary <string, float>(); EventPrefabs = new List <Pair <EventPrefab, float> >(); ChildSets = new List <EventSet>(); MinLevelDifficulty = element.GetAttributeFloat("minleveldifficulty", 0); MaxLevelDifficulty = Math.Max(element.GetAttributeFloat("maxleveldifficulty", 100), MinLevelDifficulty); string levelTypeStr = element.GetAttributeString("leveltype", "LocationConnection"); if (!Enum.TryParse(levelTypeStr, true, out LevelType)) { DebugConsole.ThrowError($"Error in event set \"{debugIdentifier}\". \"{levelTypeStr}\" is not a valid level type."); } string[] locationTypeStr = element.GetAttributeStringArray("locationtype", null); if (locationTypeStr != null) { LocationTypeIdentifiers = locationTypeStr; if (LocationType.List.Any()) { CheckLocationTypeErrors(); } } MinIntensity = element.GetAttributeFloat("minintensity", 0.0f); MaxIntensity = Math.Max(element.GetAttributeFloat("maxintensity", 100.0f), MinIntensity); ChooseRandom = element.GetAttributeBool("chooserandom", false); EventCount = element.GetAttributeInt("eventcount", 1); MinDistanceTraveled = element.GetAttributeFloat("mindistancetraveled", 0.0f); MinMissionTime = element.GetAttributeFloat("minmissiontime", 0.0f); AllowAtStart = element.GetAttributeBool("allowatstart", false); PerRuin = element.GetAttributeBool("perruin", false); PerCave = element.GetAttributeBool("percave", false); PerWreck = element.GetAttributeBool("perwreck", false); IgnoreCoolDown = element.GetAttributeBool("ignorecooldown", parentSet?.IgnoreCoolDown ?? (PerRuin || PerCave || PerWreck)); DelayWhenCrewAway = element.GetAttributeBool("delaywhencrewaway", !PerRuin && !PerCave && !PerWreck); OncePerOutpost = element.GetAttributeBool("perwreck", false); TriggerEventCooldown = element.GetAttributeBool("triggereventcooldown", true); Commonness[""] = 1.0f; foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "commonness": Commonness[""] = subElement.GetAttributeFloat("commonness", 0.0f); foreach (XElement overrideElement in subElement.Elements()) { if (overrideElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { string levelType = overrideElement.GetAttributeString("leveltype", ""); if (!Commonness.ContainsKey(levelType)) { Commonness.Add(levelType, overrideElement.GetAttributeFloat("commonness", 0.0f)); } } } break; case "eventset": ChildSets.Add(new EventSet(subElement, this.DebugIdentifier + "-" + ChildSets.Count, this)); break; default: //an element with just an identifier = reference to an event prefab if (!subElement.HasElements && subElement.Attributes().First().Name.ToString().Equals("identifier", StringComparison.OrdinalIgnoreCase)) { string identifier = subElement.GetAttributeString("identifier", ""); var prefab = PrefabList.Find(p => p.Identifier.Equals(identifier, StringComparison.OrdinalIgnoreCase)); if (prefab == null) { DebugConsole.ThrowError($"Error in event set \"{debugIdentifier}\" - could not find the event prefab \"{identifier}\"."); } else { float commonness = subElement.GetAttributeFloat("commonness", prefab.Commonness); EventPrefabs.Add(new Pair <EventPrefab, float>(prefab, commonness)); } } else { var prefab = new EventPrefab(subElement); EventPrefabs.Add(new Pair <EventPrefab, float>(prefab, prefab.Commonness)); } break; } } }
private void CreateEvents(EventSet eventSet, Random rand) { if (level == null) { return; } if (level.LevelData.HasHuntingGrounds && eventSet.DisableInHuntingGrounds) { return; } #if DEBUG DebugConsole.NewMessage($"Loading event set {eventSet.DebugIdentifier}", Color.LightBlue); #else DebugConsole.Log($"Loading event set {eventSet.DebugIdentifier}"); #endif int applyCount = 1; List <Func <Level.InterestingPosition, bool> > spawnPosFilter = new List <Func <Level.InterestingPosition, bool> >(); if (eventSet.PerRuin) { applyCount = level.Ruins.Count(); foreach (var ruin in level.Ruins) { spawnPosFilter.Add((Level.InterestingPosition pos) => { return(pos.Ruin == ruin); }); } } else if (eventSet.PerCave) { applyCount = level.Caves.Count(); foreach (var cave in level.Caves) { spawnPosFilter.Add((Level.InterestingPosition pos) => { return(pos.Cave == cave); }); } } else if (eventSet.PerWreck) { var wrecks = Submarine.Loaded.Where(s => s.Info.IsWreck && (s.WreckAI == null || !s.WreckAI.IsAlive)); applyCount = wrecks.Count(); foreach (var wreck in wrecks) { spawnPosFilter.Add((Level.InterestingPosition pos) => { return(pos.Submarine == wreck); }); } } bool isPrefabSuitable(EventPrefab p) => string.IsNullOrEmpty(p.BiomeIdentifier) || p.BiomeIdentifier.Equals(level.LevelData?.Biome?.Identifier, StringComparison.OrdinalIgnoreCase); var suitablePrefabSubsets = eventSet.EventPrefabs .FindAll(p => p.Prefabs.Any(isPrefabSuitable)); for (int i = 0; i < applyCount; i++) { if (eventSet.ChooseRandom) { if (suitablePrefabSubsets.Count > 0) { var unusedEvents = suitablePrefabSubsets.ToList(); for (int j = 0; j < eventSet.EventCount; j++) { if (unusedEvents.All(e => e.Prefabs.All(p => CalculateCommonness(p, e.Commonness) <= 0.0f))) { break; } EventSet.SubEventPrefab subEventPrefab = ToolBox.SelectWeightedRandom(unusedEvents, unusedEvents.Select(e => e.Prefabs.Max(p => CalculateCommonness(p, e.Commonness))).ToList(), rand); (IEnumerable <EventPrefab> eventPrefabs, float commonness, float probability) = subEventPrefab; if (eventPrefabs != null && rand.NextDouble() <= probability) { var finalPrefabs = eventPrefabs.Where(isPrefabSuitable).ToArray(); var finalPrefabCommonnesses = finalPrefabs.Select(p => p.Commonness).ToArray(); var eventPrefab = ToolBox.SelectWeightedRandom(finalPrefabs, finalPrefabCommonnesses, rand); var newEvent = eventPrefab.CreateInstance(); if (newEvent == null) { continue; } newEvent.Init(true); if (i < spawnPosFilter.Count) { newEvent.SpawnPosFilter = spawnPosFilter[i]; } #if DEBUG DebugConsole.NewMessage($"Initialized event {newEvent}"); #else DebugConsole.Log($"Initialized event {newEvent}"); #endif if (!selectedEvents.ContainsKey(eventSet)) { selectedEvents.Add(eventSet, new List <Event>()); } selectedEvents[eventSet].Add(newEvent); unusedEvents.Remove(subEventPrefab); } } } if (eventSet.ChildSets.Count > 0) { var newEventSet = SelectRandomEvents(eventSet.ChildSets, rand); if (newEventSet != null) { CreateEvents(newEventSet, rand); } } } else { foreach ((IEnumerable <EventPrefab> eventPrefabs, float commonness, float probability) in suitablePrefabSubsets) { if (rand.NextDouble() > probability) { continue; } var finalPrefabs = eventPrefabs.Where(isPrefabSuitable).ToArray(); var finalPrefabCommonnesses = finalPrefabs.Select(p => p.Commonness).ToArray(); var eventPrefab = ToolBox.SelectWeightedRandom(finalPrefabs, finalPrefabCommonnesses, rand); var newEvent = eventPrefab.CreateInstance(); if (newEvent == null) { continue; } newEvent.Init(true); #if DEBUG DebugConsole.NewMessage($"Initialized event {newEvent}"); #else DebugConsole.Log($"Initialized event {newEvent}"); #endif if (!selectedEvents.ContainsKey(eventSet)) { selectedEvents.Add(eventSet, new List <Event>()); } selectedEvents[eventSet].Add(newEvent); } foreach (EventSet childEventSet in eventSet.ChildSets) { CreateEvents(childEventSet, rand); } } } }
private static void CreateDialog(string text, Character speaker, IEnumerable <string> options, int[] closingOptions, string spriteIdentifier = null, ConversationAction actionInstance = null, UInt16?actionId = null, bool fadeToBlack = false, DialogTypes dialogType = DialogTypes.Regular, bool continueConversation = false) { Debug.Assert(actionInstance == null || actionId == null); if (GUI.InputBlockingMenuOpen) { if (actionId.HasValue) { SendIgnore(actionId.Value); } return; } shouldFadeToBlack = fadeToBlack; if (lastMessageBox != null && !lastMessageBox.Closed && GUIMessageBox.MessageBoxes.Contains(lastMessageBox)) { if (actionId != null && lastMessageBox.UserData is Pair <string, ushort> userData) { if (userData.Second == actionId) { return; } lastMessageBox.UserData = new Pair <string, ushort>("ConversationAction", actionId.Value); } GUIListBox conversationList = lastMessageBox.FindChild("conversationlist", true) as GUIListBox; Debug.Assert(conversationList != null); // gray out the last text block if (conversationList.Content.Children.LastOrDefault() is GUILayoutGroup lastElement) { if (lastElement.FindChild("text", true) is GUITextBlock textLayout) { textLayout.OverrideTextColor(Color.DarkGray * 0.8f); } } List <GUIButton> extraButtons = CreateConversation(conversationList, text, speaker, options, string.IsNullOrWhiteSpace(spriteIdentifier)); AssignActionsToButtons(extraButtons, lastMessageBox); RecalculateLastMessage(conversationList, true); conversationList.ScrollToEnd(0.5f); lastMessageBox.SetBackgroundIcon(EventSet.GetEventSprite(spriteIdentifier)); return; } var(relative, min) = GetSizes(dialogType); GUIMessageBox messageBox = new GUIMessageBox(string.Empty, string.Empty, new string[0], relativeSize: relative, minSize: min, type: GUIMessageBox.Type.InGame, backgroundIcon: EventSet.GetEventSprite(spriteIdentifier)) { UserData = "ConversationAction" }; lastMessageBox = messageBox; messageBox.InnerFrame.ClearChildren(); messageBox.AutoClose = false; GUI.Style.Apply(messageBox.InnerFrame, "DialogBox"); if (actionInstance != null) { lastActiveAction = actionInstance; actionInstance.dialogBox = messageBox; } else { messageBox.UserData = new Pair <string, UInt16>("ConversationAction", actionId.Value); } int padding = GUI.IntScale(16); GUIListBox listBox = new GUIListBox(new RectTransform(messageBox.InnerFrame.Rect.Size - new Point(padding * 2), messageBox.InnerFrame.RectTransform, Anchor.Center), style: null) { KeepSpaceForScrollBar = true, HoverCursor = CursorState.Default, UserData = "conversationlist" }; List <GUIButton> buttons = CreateConversation(listBox, text, speaker, options, string.IsNullOrWhiteSpace(spriteIdentifier)); AssignActionsToButtons(buttons, messageBox); RecalculateLastMessage(listBox, false); messageBox.InnerFrame.RectTransform.MinSize = new Point(0, Math.Max(listBox.RectTransform.MinSize.Y + padding * 2, (int)(100 * GUI.yScale))); var shadow = new GUIFrame(new RectTransform(messageBox.InnerFrame.Rect.Size + new Point(padding * 4), messageBox.InnerFrame.RectTransform, Anchor.Center), style: "OuterGlow") { Color = Color.Black * 0.7f }; shadow.SetAsFirstChild();
private static void CreateDialog(string text, Character speaker, IEnumerable <string> options, int[] closingOptions, string spriteIdentifier = null, ConversationAction actionInstance = null, UInt16?actionId = null, bool fadeToBlack = false, DialogTypes dialogType = DialogTypes.Regular, bool continueConversation = false) { Debug.Assert(actionInstance == null || actionId == null); shouldFadeToBlack = fadeToBlack; if (lastMessageBox != null && !lastMessageBox.Closed && GUIMessageBox.MessageBoxes.Contains(lastMessageBox)) { if (actionId != null && lastMessageBox.UserData is Pair <string, ushort> userData) { if (userData.Second == actionId) { return; } lastMessageBox.UserData = new Pair <string, ushort>("ConversationAction", actionId.Value); } GUIListBox conversationList = lastMessageBox.FindChild("conversationlist", true) as GUIListBox; Debug.Assert(conversationList != null); // gray out the last text block if (conversationList.Content.Children.LastOrDefault() is GUILayoutGroup lastElement) { if (lastElement.FindChild("text", true) is GUITextBlock textLayout) { textLayout.OverrideTextColor(Color.DarkGray * 0.8f); } } List <GUIButton> extraButtons = CreateConversation(conversationList, text, speaker, options, string.IsNullOrWhiteSpace(spriteIdentifier)); AssignActionsToButtons(extraButtons, lastMessageBox); RecalculateLastMessage(conversationList, true); conversationList.ScrollToEnd(0.5f); lastMessageBox.SetBackgroundIcon(EventSet.GetEventSprite(spriteIdentifier)); return; } var(relative, min) = GetSizes(dialogType); GUIMessageBox messageBox = new GUIMessageBox(string.Empty, string.Empty, new string[0], relativeSize: relative, minSize: min, type: GUIMessageBox.Type.InGame, backgroundIcon: EventSet.GetEventSprite(spriteIdentifier)) { UserData = "ConversationAction" }; lastMessageBox = messageBox; messageBox.InnerFrame.ClearChildren(); messageBox.AutoClose = false; GUI.Style.Apply(messageBox.InnerFrame, "DialogBox"); if (actionInstance != null) { lastActiveAction = actionInstance; actionInstance.dialogBox = messageBox; } else { messageBox.UserData = new Pair <string, UInt16>("ConversationAction", actionId.Value); } int padding = GUI.IntScale(16); GUIListBox listBox = new GUIListBox(new RectTransform(messageBox.InnerFrame.Rect.Size - new Point(padding * 2), messageBox.InnerFrame.RectTransform, Anchor.Center), style: null) { KeepSpaceForScrollBar = true, HoverCursor = CursorState.Default, UserData = "conversationlist" }; List <GUIButton> buttons = CreateConversation(listBox, text, speaker, options, string.IsNullOrWhiteSpace(spriteIdentifier)); AssignActionsToButtons(buttons, messageBox); RecalculateLastMessage(listBox, false); messageBox.InnerFrame.RectTransform.MinSize = new Point(0, Math.Max(listBox.RectTransform.MinSize.Y + padding * 2, (int)(100 * GUI.yScale))); var shadow = new GUIFrame(new RectTransform(messageBox.InnerFrame.Rect.Size + new Point(padding * 4), messageBox.InnerFrame.RectTransform, Anchor.Center), style: "OuterGlow") { Color = Color.Black * 0.7f }; shadow.SetAsFirstChild(); void RecalculateLastMessage(GUIListBox conversationList, bool append) { if (conversationList.Content.Children.LastOrDefault() is GUILayoutGroup lastElement) { GUILayoutGroup textLayout = lastElement.GetChild <GUILayoutGroup>(); if (lastElement.Rect.Size.Y < textLayout.Rect.Size.Y && !append) { lastElement.RectTransform.MinSize = textLayout.Rect.Size; } if (textLayout != null) { int textHeight = textLayout.Children.Sum(c => c.Rect.Height); textLayout.RectTransform.MaxSize = new Point(lastElement.RectTransform.MaxSize.X, textHeight); textLayout.Recalculate(); } int sumHeight = lastElement.Children.Sum(c => c.Rect.Height); lastElement.RectTransform.MaxSize = new Point(lastElement.RectTransform.MaxSize.X, sumHeight); lastElement.Recalculate(); conversationList.RecalculateChildren(); if (!append || textLayout == null) { return; } foreach (GUIComponent child in textLayout.Children) { conversationList.UpdateScrollBarSize(); float wait = conversationList.BarSize < 1.0f ? 0.5f : 0.0f; if (child is GUITextBlock) { child.FadeIn(wait, 0.5f); } if (child is GUIButton btn) { btn.FadeIn(wait, 1.0f); btn.TextBlock.FadeIn(wait, 0.5f); } } } } void AssignActionsToButtons(List <GUIButton> optionButtons, GUIMessageBox target) { if (!options.Any()) { GUIButton closeButton = new GUIButton(new RectTransform(Vector2.One, target.InnerFrame.RectTransform, Anchor.BottomRight, scaleBasis: ScaleBasis.Smallest) { MaxSize = new Point(GUI.IntScale(24)), MinSize = new Point(24), AbsoluteOffset = new Point(GUI.IntScale(48), GUI.IntScale(16)) }, style: "GUIButtonVerticalArrow") { UserData = "ContinueButton", IgnoreLayoutGroups = true, Bounce = true, OnClicked = (btn, userdata) => { if (actionInstance != null) { actionInstance.selectedOption = 0; } else if (actionId.HasValue) { SendResponse(actionId.Value, 0); } if (!continueConversation) { target.Close(); } else { btn.Frame.FadeOut(0.33f, true); } return(true); } }; closeButton.Children.ForEach(child => child.SpriteEffects = SpriteEffects.FlipVertically); closeButton.Frame.FadeIn(0.5f, 0.5f); closeButton.SlideIn(0.5f, 0.33f, 16, SlideDirection.Down); } for (int i = 0; i < optionButtons.Count; i++) { optionButtons[i].UserData = i; optionButtons[i].OnClicked += (btn, userdata) => { int selectedOption = (userdata as int?) ?? 0; if (actionInstance != null) { actionInstance.selectedOption = selectedOption; foreach (GUIButton otherButton in optionButtons) { otherButton.CanBeFocused = false; if (otherButton != btn) { otherButton.TextBlock.OverrideTextColor(Color.DarkGray * 0.8f); } } btn.ExternalHighlight = true; return(true); } if (actionId.HasValue) { SendResponse(actionId.Value, selectedOption); btn.CanBeFocused = false; btn.ExternalHighlight = true; foreach (GUIButton otherButton in optionButtons) { otherButton.CanBeFocused = false; if (otherButton != btn) { otherButton.TextBlock.OverrideTextColor(Color.DarkGray * 0.8f); } } return(true); } //should not happen return(false); }; if (closingOptions.Contains(i)) { optionButtons[i].OnClicked += target.Close; } } } }
private IEnumerable <object> Load(bool isSeparateThread) { if (GameSettings.VerboseLogging) { DebugConsole.NewMessage("LOADING COROUTINE", Color.Lime); } while (TitleScreen.WaitForLanguageSelection) { yield return(CoroutineStatus.Running); } SoundManager = new Sounds.SoundManager(); SoundManager.SetCategoryGainMultiplier("default", Config.SoundVolume, 0); SoundManager.SetCategoryGainMultiplier("ui", Config.SoundVolume, 0); SoundManager.SetCategoryGainMultiplier("waterambience", Config.SoundVolume, 0); SoundManager.SetCategoryGainMultiplier("music", Config.MusicVolume, 0); SoundManager.SetCategoryGainMultiplier("voip", Math.Min(Config.VoiceChatVolume, 1.0f), 0); if (Config.EnableSplashScreen && !ConsoleArguments.Contains("-skipintro")) { var pendingSplashScreens = TitleScreen.PendingSplashScreens; float baseVolume = MathHelper.Clamp(Config.SoundVolume * 2.0f, 0.0f, 1.0f); pendingSplashScreens?.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_UTG.webm", baseVolume * 0.5f)); pendingSplashScreens?.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_FF.webm", baseVolume)); pendingSplashScreens?.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_Daedalic.webm", baseVolume * 0.1f)); } //if not loading in a separate thread, wait for the splash screens to finish before continuing the loading //otherwise the videos will look extremely choppy if (!isSeparateThread) { while (TitleScreen.PlayingSplashScreen || TitleScreen.PendingSplashScreens.Count > 0) { yield return(CoroutineStatus.Running); } } GUI.Init(Window, Config.AllEnabledPackages, GraphicsDevice); DebugConsole.Init(); if (Config.AutoUpdateWorkshopItems) { Config.WaitingForAutoUpdate = true; TaskPool.Add("AutoUpdateWorkshopItemsAsync", SteamManager.AutoUpdateWorkshopItemsAsync(), (task) => { bool result = ((Task <bool>)task).Result; Config.WaitingForAutoUpdate = false; }); while (Config.WaitingForAutoUpdate) { yield return(CoroutineStatus.Running); } } #if DEBUG if (Config.ModBreakerMode) { Config.SelectCorePackage(ContentPackage.CorePackages.GetRandom()); foreach (var regularPackage in ContentPackage.RegularPackages) { if (Rand.Range(0.0, 1.0) <= 0.5) { Config.EnableRegularPackage(regularPackage); } else { Config.DisableRegularPackage(regularPackage); } } ContentPackage.SortContentPackages(p => { return(Rand.Int(int.MaxValue)); }); } #endif if (Config.AllEnabledPackages.None()) { DebugConsole.Log("No content packages selected"); } else { DebugConsole.Log("Selected content packages: " + string.Join(", ", Config.AllEnabledPackages.Select(cp => cp.Name))); } #if DEBUG GameSettings.ShowUserStatisticsPrompt = false; GameSettings.SendUserStatistics = false; #endif InitUserStats(); yield return(CoroutineStatus.Running); Debug.WriteLine("sounds"); int i = 0; foreach (object crObj in SoundPlayer.Init()) { CoroutineStatus status = (CoroutineStatus)crObj; if (status == CoroutineStatus.Success) { break; } i++; TitleScreen.LoadState = SoundPlayer.SoundCount == 0 ? 1.0f : Math.Min(40.0f * i / Math.Max(SoundPlayer.SoundCount, 1), 40.0f); yield return(CoroutineStatus.Running); } TitleScreen.LoadState = 40.0f; yield return(CoroutineStatus.Running); LightManager = new Lights.LightManager(base.GraphicsDevice, Content); TitleScreen.LoadState = 41.0f; yield return(CoroutineStatus.Running); GUI.LoadContent(); TitleScreen.LoadState = 42.0f; yield return(CoroutineStatus.Running); TaskPool.Add("InitRelayNetworkAccess", SteamManager.InitRelayNetworkAccess(), (t) => { }); FactionPrefab.LoadFactions(); NPCSet.LoadSets(); CharacterPrefab.LoadAll(); MissionPrefab.Init(); TraitorMissionPrefab.Init(); MapEntityPrefab.Init(); Tutorials.Tutorial.Init(); MapGenerationParams.Init(); LevelGenerationParams.LoadPresets(); CaveGenerationParams.LoadPresets(); OutpostGenerationParams.LoadPresets(); WreckAIConfig.LoadAll(); EventSet.LoadPrefabs(); ItemPrefab.LoadAll(GetFilesOfType(ContentType.Item)); AfflictionPrefab.LoadAll(GetFilesOfType(ContentType.Afflictions)); SkillSettings.Load(GetFilesOfType(ContentType.SkillSettings)); Order.Init(); EventManagerSettings.Init(); BallastFloraPrefab.LoadAll(GetFilesOfType(ContentType.MapCreature)); HintManager.Init(); TitleScreen.LoadState = 50.0f; yield return(CoroutineStatus.Running); StructurePrefab.LoadAll(GetFilesOfType(ContentType.Structure)); TitleScreen.LoadState = 55.0f; yield return(CoroutineStatus.Running); UpgradePrefab.LoadAll(GetFilesOfType(ContentType.UpgradeModules)); TitleScreen.LoadState = 56.0f; yield return(CoroutineStatus.Running); JobPrefab.LoadAll(GetFilesOfType(ContentType.Jobs)); CorpsePrefab.LoadAll(GetFilesOfType(ContentType.Corpses)); NPCConversation.LoadAll(GetFilesOfType(ContentType.NPCConversations)); ItemAssemblyPrefab.LoadAll(); TitleScreen.LoadState = 60.0f; yield return(CoroutineStatus.Running); GameModePreset.Init(); SaveUtil.DeleteDownloadedSubs(); SubmarineInfo.RefreshSavedSubs(); TitleScreen.LoadState = 65.0f; yield return(CoroutineStatus.Running); GameScreen = new GameScreen(GraphicsDeviceManager.GraphicsDevice, Content); TitleScreen.LoadState = 68.0f; yield return(CoroutineStatus.Running); MainMenuScreen = new MainMenuScreen(this); ServerListScreen = new ServerListScreen(); TitleScreen.LoadState = 70.0f; yield return(CoroutineStatus.Running); #if USE_STEAM SteamWorkshopScreen = new SteamWorkshopScreen(); if (SteamManager.IsInitialized) { Steamworks.SteamFriends.OnGameRichPresenceJoinRequested += OnInvitedToGame; Steamworks.SteamFriends.OnGameLobbyJoinRequested += OnLobbyJoinRequested; } #endif SubEditorScreen = new SubEditorScreen(); TitleScreen.LoadState = 75.0f; yield return(CoroutineStatus.Running); ParticleEditorScreen = new ParticleEditorScreen(); TitleScreen.LoadState = 80.0f; yield return(CoroutineStatus.Running); LevelEditorScreen = new LevelEditorScreen(); SpriteEditorScreen = new SpriteEditorScreen(); EventEditorScreen = new EventEditorScreen(); CharacterEditorScreen = new CharacterEditor.CharacterEditorScreen(); CampaignEndScreen = new CampaignEndScreen(); yield return(CoroutineStatus.Running); TitleScreen.LoadState = 85.0f; ParticleManager = new ParticleManager(GameScreen.Cam); ParticleManager.LoadPrefabs(); TitleScreen.LoadState = 88.0f; LevelObjectPrefab.LoadAll(); TitleScreen.LoadState = 90.0f; yield return(CoroutineStatus.Running); DecalManager = new DecalManager(); LocationType.Init(); MainMenuScreen.Select(); foreach (string steamError in SteamManager.InitializationErrors) { new GUIMessageBox(TextManager.Get("Error"), TextManager.Get(steamError)); } TitleScreen.LoadState = 100.0f; hasLoaded = true; if (GameSettings.VerboseLogging) { DebugConsole.NewMessage("LOADING COROUTINE FINISHED", Color.Lime); } yield return(CoroutineStatus.Success); }
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; }
private void CreateGUI() { GuiFrame = new GUIFrame(new RectTransform(new Vector2(0.2f, 0.4f), GUICanvas.Instance) { MinSize = new Point(300, 400) }); GUILayoutGroup layoutGroup = new GUILayoutGroup(RectTransform(0.9f, 0.9f, GuiFrame, Anchor.Center)) { Stretch = true }; // === BUTTONS === // GUILayoutGroup buttonLayout = new GUILayoutGroup(RectTransform(1.0f, 0.50f, layoutGroup)) { RelativeSpacing = 0.04f }; GUIButton newProjectButton = new GUIButton(RectTransform(1.0f, 0.33f, buttonLayout), TextManager.Get("EventEditor.NewProject")); GUIButton saveProjectButton = new GUIButton(RectTransform(1.0f, 0.33f, buttonLayout), TextManager.Get("EventEditor.SaveProject")); GUIButton loadProjectButton = new GUIButton(RectTransform(1.0f, 0.33f, buttonLayout), TextManager.Get("EventEditor.LoadProject")); GUIButton exportProjectButton = new GUIButton(RectTransform(1.0f, 0.33f, buttonLayout), TextManager.Get("EventEditor.Export")); // === LOAD PREFAB === // GUILayoutGroup loadEventLayout = new GUILayoutGroup(RectTransform(1.0f, 0.125f, layoutGroup)); new GUITextBlock(RectTransform(1.0f, 0.5f, loadEventLayout), TextManager.Get("EventEditor.LoadEvent"), font: GUI.SubHeadingFont); GUILayoutGroup loadDropdownLayout = new GUILayoutGroup(RectTransform(1.0f, 0.5f, loadEventLayout), isHorizontal: true, childAnchor: Anchor.CenterLeft); GUIDropDown loadDropdown = new GUIDropDown(RectTransform(0.8f, 1.0f, loadDropdownLayout), elementCount: 10); GUIButton loadButton = new GUIButton(RectTransform(0.2f, 1.0f, loadDropdownLayout), TextManager.Get("Load")); // === ADD ACTION === // GUILayoutGroup addActionLayout = new GUILayoutGroup(RectTransform(1.0f, 0.125f, layoutGroup)); new GUITextBlock(RectTransform(1.0f, 0.5f, addActionLayout), TextManager.Get("EventEditor.AddAction"), font: GUI.SubHeadingFont); GUILayoutGroup addActionDropdownLayout = new GUILayoutGroup(RectTransform(1.0f, 0.5f, addActionLayout), isHorizontal: true, childAnchor: Anchor.CenterLeft); GUIDropDown addActionDropdown = new GUIDropDown(RectTransform(0.8f, 1.0f, addActionDropdownLayout), elementCount: 10); GUIButton addActionButton = new GUIButton(RectTransform(0.2f, 1.0f, addActionDropdownLayout), TextManager.Get("EventEditor.Add")); // === ADD VALUE === // GUILayoutGroup addValueLayout = new GUILayoutGroup(RectTransform(1.0f, 0.125f, layoutGroup)); new GUITextBlock(RectTransform(1.0f, 0.5f, addValueLayout), TextManager.Get("EventEditor.AddValue"), font: GUI.SubHeadingFont); GUILayoutGroup addValueDropdownLayout = new GUILayoutGroup(RectTransform(1.0f, 0.5f, addValueLayout), isHorizontal: true, childAnchor: Anchor.CenterLeft); GUIDropDown addValueDropdown = new GUIDropDown(RectTransform(0.8f, 1.0f, addValueDropdownLayout), elementCount: 7); GUIButton addValueButton = new GUIButton(RectTransform(0.2f, 1.0f, addValueDropdownLayout), TextManager.Get("EventEditor.Add")); // === ADD SPECIAL === // GUILayoutGroup addSpecialLayout = new GUILayoutGroup(RectTransform(1.0f, 0.125f, layoutGroup)); new GUITextBlock(RectTransform(1.0f, 0.5f, addSpecialLayout), TextManager.Get("EventEditor.AddSpecial"), font: GUI.SubHeadingFont); GUILayoutGroup addSpecialDropdownLayout = new GUILayoutGroup(RectTransform(1.0f, 0.5f, addSpecialLayout), isHorizontal: true, childAnchor: Anchor.CenterLeft); GUIDropDown addSpecialDropdown = new GUIDropDown(RectTransform(0.8f, 1.0f, addSpecialDropdownLayout), elementCount: 1); GUIButton addSpecialButton = new GUIButton(RectTransform(0.2f, 1.0f, addSpecialDropdownLayout), TextManager.Get("EventEditor.Add")); // Add event prefabs with identifiers to the list foreach (EventPrefab eventPrefab in EventSet.GetAllEventPrefabs().Where(prefab => !string.IsNullOrWhiteSpace(prefab.Identifier)).Distinct()) { loadDropdown.AddItem(eventPrefab.Identifier, eventPrefab); } // Add all types that inherit the EventAction class foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(type => type.IsSubclassOf(typeof(EventAction)))) { addActionDropdown.AddItem(type.Name, type); } addSpecialDropdown.AddItem("Custom", typeof(CustomNode)); addValueDropdown.AddItem(nameof(Single), typeof(float)); addValueDropdown.AddItem(nameof(Boolean), typeof(bool)); addValueDropdown.AddItem(nameof(String), typeof(string)); addValueDropdown.AddItem(nameof(SpawnType), typeof(SpawnType)); addValueDropdown.AddItem(nameof(LimbType), typeof(LimbType)); addValueDropdown.AddItem(nameof(ReputationAction.ReputationType), typeof(ReputationAction.ReputationType)); addValueDropdown.AddItem(nameof(SpawnAction.SpawnLocationType), typeof(SpawnAction.SpawnLocationType)); loadButton.OnClicked += (button, o) => Load(loadDropdown.SelectedData as EventPrefab); addActionButton.OnClicked += (button, o) => AddAction(addActionDropdown.SelectedData as Type); addValueButton.OnClicked += (button, o) => AddValue(addValueDropdown.SelectedData as Type); addSpecialButton.OnClicked += (button, o) => AddSpecial(addSpecialDropdown.SelectedData as Type); exportProjectButton.OnClicked += ExportEventToFile; saveProjectButton.OnClicked += SaveProjectToFile; newProjectButton.OnClicked += TryCreateNewProject; loadProjectButton.OnClicked += (button, o) => { FileSelection.OnFileSelected = (file) => { XDocument?document = XMLExtensions.TryLoadXml(file); if (document?.Root != null) { Load(document.Root); } }; string directory = Path.GetFullPath("EventProjects"); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } FileSelection.ClearFileTypeFilters(); FileSelection.AddFileTypeFilter("Scripted Event", "*.sevproj"); FileSelection.SelectFileTypeFilter("*.sevproj"); FileSelection.CurrentDirectory = directory; FileSelection.Open = true; return(true); }; screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight); }
private void CreateEvents(EventSet eventSet, Random rand) { if (level == null) { return; } int applyCount = 1; List <Func <Level.InterestingPosition, bool> > spawnPosFilter = new List <Func <Level.InterestingPosition, bool> >(); if (eventSet.PerRuin) { applyCount = Level.Loaded.Ruins.Count(); foreach (var ruin in Level.Loaded.Ruins) { spawnPosFilter.Add((Level.InterestingPosition pos) => { return(pos.Ruin == ruin); }); } } else if (eventSet.PerCave) { applyCount = Level.Loaded.Caves.Count(); foreach (var cave in Level.Loaded.Caves) { spawnPosFilter.Add((Level.InterestingPosition pos) => { return(pos.Cave == cave); }); } } else if (eventSet.PerWreck) { var wrecks = Submarine.Loaded.Where(s => s.Info.IsWreck && (s.WreckAI == null || !s.WreckAI.IsAlive)); applyCount = wrecks.Count(); foreach (var wreck in wrecks) { spawnPosFilter.Add((Level.InterestingPosition pos) => { return(pos.Submarine == wreck); }); } } for (int i = 0; i < applyCount; i++) { if (eventSet.ChooseRandom) { if (eventSet.EventPrefabs.Count > 0) { 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(); if (newEvent == null) { continue; } newEvent.Init(true); if (i < spawnPosFilter.Count) { newEvent.SpawnPosFilter = spawnPosFilter[i]; } 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, rand); } } } else { foreach (Pair <EventPrefab, float> eventPrefab in eventSet.EventPrefabs) { var newEvent = eventPrefab.First.CreateInstance(); if (newEvent == null) { continue; } 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, rand); } } } }