public bool CanBeApplied(XElement element, UpgradePrefab prefab) { if (string.Equals("Structure", element.Name.ToString(), StringComparison.OrdinalIgnoreCase)) { return(IsWallUpgrade); } string identifier = element.GetAttributeString("identifier", string.Empty); if (string.IsNullOrWhiteSpace(identifier)) { return(false); } ItemPrefab?item = ItemPrefab.Find(null, identifier); if (item == null) { return(false); } string[] disallowedUpgrades = element.GetAttributeStringArray("disallowedupgrades", new string[0]); if (disallowedUpgrades.Any(s => s.Equals(Identifier, StringComparison.OrdinalIgnoreCase) || s.Equals(prefab.Identifier, StringComparison.OrdinalIgnoreCase))) { return(false); } return(item.GetAllowedUpgrades().Contains(Identifier) || ItemTags.Any(tag => item.Tags.Contains(tag) || item.Identifier.Equals(tag, StringComparison.OrdinalIgnoreCase))); }
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(); }
public UpgradePrice(UpgradePrefab prefab, XElement element) { Prefab = prefab; IncreaseLow = UpgradePrefab.ParsePercentage(element.GetAttributeString("increaselow", string.Empty), "IncreaseLow", element, suppressWarnings: prefab.SuppressWarnings); IncreaseHigh = UpgradePrefab.ParsePercentage(element.GetAttributeString("increasehigh", string.Empty), "IncreaseHigh", element, suppressWarnings: prefab.SuppressWarnings); BasePrice = element.GetAttributeInt("baseprice", -1); if (BasePrice == -1) { if (prefab.SuppressWarnings) { DebugConsole.AddWarning($"Price attribute \"baseprice\" is not defined for {prefab?.Identifier}.\n " + "The value has been assumed to be '1000'."); BasePrice = 1000; } } }
static bool IsOverMaxLevel(int level, UpgradePrefab prefab) => level > prefab.MaxLevel;
public void Deconstruct(out UpgradePrefab prefab, out UpgradeCategory category, out int level) { prefab = Prefab; category = Category; level = Level; }
public PurchasedUpgrade(UpgradePrefab upgradePrefab, UpgradeCategory category, int level = 1) { Category = category; Prefab = upgradePrefab; Level = level; }
public void PurchaseUpgrade(UpgradePrefab prefab, UpgradeCategory category) { if (!CanUpgradeSub()) { DebugConsole.ThrowError("Cannot upgrade when switching to another submarine."); return; } int price = prefab.Price.GetBuyprice(GetUpgradeLevel(prefab, category), Campaign.Map?.CurrentLocation); int currentLevel = GetUpgradeLevel(prefab, category); if (currentLevel + 1 > prefab.MaxLevel) { DebugConsole.ThrowError($"Tried to purchase \"{prefab.Name}\" over the max level! ({currentLevel + 1} > {prefab.MaxLevel}). The transaction has been cancelled."); return; } if (price < 0) { Location?location = Campaign.Map?.CurrentLocation; LogError($"Upgrade price is less than 0! ({price})", new Dictionary <string, object?> { { "Level", currentLevel }, { "Saved Level", GetRealUpgradeLevel(prefab, category) }, { "Upgrade", $"{category.Identifier}.{prefab.Identifier}" }, { "Location", location?.Type }, { "Reputation", $"{location?.Reputation?.Value} / {location?.Reputation?.MaxReputation}" }, { "Base Price", prefab.Price.BasePrice } }); } if (Campaign.Money > price) { if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer) { // only make the NPC speak if more than 5 minutes have passed since the last purchased service if (lastUpgradeSpeak == DateTime.MinValue || lastUpgradeSpeak.AddMinutes(5) < DateTime.Now) { UpgradeNPCSpeak(TextManager.Get("Dialog.UpgradePurchased"), Campaign.IsSinglePlayer); lastUpgradeSpeak = DateTime.Now; } } Campaign.Money -= price; spentMoney += price; PurchasedUpgrade?upgrade = FindMatchingUpgrade(prefab, category); #if CLIENT DebugLog($"CLIENT: Purchased level {GetUpgradeLevel(prefab, category) + 1} {category.Name}.{prefab.Name} for ${price}", GUI.Style.Orange); #endif if (upgrade == null) { PendingUpgrades.Add(new PurchasedUpgrade(prefab, category)); } else { upgrade.Level++; } #if CLIENT // tell the server that this item is yet to be paid for server side PurchasedUpgrades.Add(new PurchasedUpgrade(prefab, category)); #endif OnUpgradesChanged?.Invoke(); } else { DebugConsole.ThrowError("Tried to purchase an upgrade with insufficient funds, the transaction has not been completed.\n" + $"Upgrade: {prefab.Name}, Cost: {price}, Have: {Campaign.Money}"); } }
//static because we may need to instantiate the campaign if it hasn't been done yet public static void ClientRead(IReadMessage msg) { bool isFirstRound = msg.ReadBoolean(); byte campaignID = msg.ReadByte(); UInt16 updateID = msg.ReadUInt16(); UInt16 saveID = msg.ReadUInt16(); string mapSeed = msg.ReadString(); UInt16 currentLocIndex = msg.ReadUInt16(); UInt16 selectedLocIndex = msg.ReadUInt16(); byte selectedMissionIndex = msg.ReadByte(); bool allowDebugTeleport = msg.ReadBoolean(); float? reputation = null; if (msg.ReadBoolean()) { reputation = msg.ReadSingle(); } Dictionary <string, float> factionReps = new Dictionary <string, float>(); byte factionsCount = msg.ReadByte(); for (int i = 0; i < factionsCount; i++) { factionReps.Add(msg.ReadString(), msg.ReadSingle()); } bool forceMapUI = msg.ReadBoolean(); int money = msg.ReadInt32(); bool purchasedHullRepairs = msg.ReadBoolean(); bool purchasedItemRepairs = msg.ReadBoolean(); bool purchasedLostShuttles = msg.ReadBoolean(); byte missionCount = msg.ReadByte(); List <Pair <string, byte> > availableMissions = new List <Pair <string, byte> >(); for (int i = 0; i < missionCount; i++) { string missionIdentifier = msg.ReadString(); byte connectionIndex = msg.ReadByte(); availableMissions.Add(new Pair <string, byte>(missionIdentifier, connectionIndex)); } UInt16?storeBalance = null; if (msg.ReadBoolean()) { storeBalance = msg.ReadUInt16(); } UInt16 buyCrateItemCount = msg.ReadUInt16(); List <PurchasedItem> buyCrateItems = new List <PurchasedItem>(); for (int i = 0; i < buyCrateItemCount; i++) { string itemPrefabIdentifier = msg.ReadString(); int itemQuantity = msg.ReadRangedInteger(0, CargoManager.MaxQuantity); buyCrateItems.Add(new PurchasedItem(ItemPrefab.Prefabs[itemPrefabIdentifier], itemQuantity)); } UInt16 purchasedItemCount = msg.ReadUInt16(); List <PurchasedItem> purchasedItems = new List <PurchasedItem>(); for (int i = 0; i < purchasedItemCount; i++) { string itemPrefabIdentifier = msg.ReadString(); int itemQuantity = msg.ReadRangedInteger(0, CargoManager.MaxQuantity); purchasedItems.Add(new PurchasedItem(ItemPrefab.Prefabs[itemPrefabIdentifier], itemQuantity)); } UInt16 soldItemCount = msg.ReadUInt16(); List <SoldItem> soldItems = new List <SoldItem>(); for (int i = 0; i < soldItemCount; i++) { string itemPrefabIdentifier = msg.ReadString(); UInt16 id = msg.ReadUInt16(); bool removed = msg.ReadBoolean(); byte sellerId = msg.ReadByte(); soldItems.Add(new SoldItem(ItemPrefab.Prefabs[itemPrefabIdentifier], id, removed, sellerId)); } ushort pendingUpgradeCount = msg.ReadUInt16(); List <PurchasedUpgrade> pendingUpgrades = new List <PurchasedUpgrade>(); for (int i = 0; i < pendingUpgradeCount; i++) { string upgradeIdentifier = msg.ReadString(); UpgradePrefab prefab = UpgradePrefab.Find(upgradeIdentifier); string categoryIdentifier = msg.ReadString(); UpgradeCategory category = UpgradeCategory.Find(categoryIdentifier); int upgradeLevel = msg.ReadByte(); if (prefab == null || category == null) { continue; } pendingUpgrades.Add(new PurchasedUpgrade(prefab, category, upgradeLevel)); } bool hasCharacterData = msg.ReadBoolean(); CharacterInfo myCharacterInfo = null; if (hasCharacterData) { myCharacterInfo = CharacterInfo.ClientRead(CharacterPrefab.HumanSpeciesName, msg); } if (!(GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign) || campaignID != campaign.CampaignID) { string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer); GameMain.GameSession = new GameSession(null, savePath, GameModePreset.MultiPlayerCampaign, mapSeed); campaign = (MultiPlayerCampaign)GameMain.GameSession.GameMode; campaign.CampaignID = campaignID; GameMain.NetLobbyScreen.ToggleCampaignMode(true); } //server has a newer save file if (NetIdUtils.IdMoreRecent(saveID, campaign.PendingSaveID)) { campaign.PendingSaveID = saveID; } if (NetIdUtils.IdMoreRecent(updateID, campaign.lastUpdateID)) { campaign.SuppressStateSending = true; campaign.IsFirstRound = isFirstRound; //we need to have the latest save file to display location/mission/store if (campaign.LastSaveID == saveID) { campaign.ForceMapUI = forceMapUI; UpgradeStore.WaitForServerUpdate = false; campaign.Map.SetLocation(currentLocIndex == UInt16.MaxValue ? -1 : currentLocIndex); campaign.Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex); campaign.Map.SelectMission(selectedMissionIndex); campaign.Map.AllowDebugTeleport = allowDebugTeleport; campaign.CargoManager.SetItemsInBuyCrate(buyCrateItems); campaign.CargoManager.SetPurchasedItems(purchasedItems); campaign.CargoManager.SetSoldItems(soldItems); if (storeBalance.HasValue) { campaign.Map.CurrentLocation.StoreCurrentBalance = storeBalance.Value; } campaign.UpgradeManager.SetPendingUpgrades(pendingUpgrades); campaign.UpgradeManager.PurchasedUpgrades.Clear(); foreach (var(identifier, rep) in factionReps) { Faction faction = campaign.Factions.FirstOrDefault(f => f.Prefab.Identifier.Equals(identifier, StringComparison.OrdinalIgnoreCase)); if (faction?.Reputation != null) { faction.Reputation.Value = rep; } else { DebugConsole.ThrowError($"Received an update for a faction that doesn't exist \"{identifier}\"."); } } if (reputation.HasValue) { campaign.Map.CurrentLocation.Reputation.Value = reputation.Value; campaign?.CampaignUI?.UpgradeStore?.RefreshAll(); } foreach (var availableMission in availableMissions) { MissionPrefab missionPrefab = MissionPrefab.List.Find(mp => mp.Identifier == availableMission.First); if (missionPrefab == null) { DebugConsole.ThrowError($"Error when receiving campaign data from the server: mission prefab \"{availableMission.First}\" not found."); continue; } if (availableMission.Second < 0 || availableMission.Second >= campaign.Map.CurrentLocation.Connections.Count) { DebugConsole.ThrowError($"Error when receiving campaign data from the server: connection index for mission \"{availableMission.First}\" out of range (index: {availableMission.Second}, current location: {campaign.Map.CurrentLocation.Name}, connections: {campaign.Map.CurrentLocation.Connections.Count})."); continue; } LocationConnection connection = campaign.Map.CurrentLocation.Connections[availableMission.Second]; campaign.Map.CurrentLocation.UnlockMission(missionPrefab, connection); } GameMain.NetLobbyScreen.ToggleCampaignMode(true); } bool shouldRefresh = campaign.Money != money || campaign.PurchasedHullRepairs != purchasedHullRepairs || campaign.PurchasedItemRepairs != purchasedItemRepairs || campaign.PurchasedLostShuttles != purchasedLostShuttles; campaign.Money = money; campaign.PurchasedHullRepairs = purchasedHullRepairs; campaign.PurchasedItemRepairs = purchasedItemRepairs; campaign.PurchasedLostShuttles = purchasedLostShuttles; if (shouldRefresh) { campaign?.CampaignUI?.UpgradeStore?.RefreshAll(); } if (myCharacterInfo != null) { GameMain.Client.CharacterInfo = myCharacterInfo; GameMain.NetLobbyScreen.SetCampaignCharacterInfo(myCharacterInfo); } else { GameMain.NetLobbyScreen.SetCampaignCharacterInfo(null); } campaign.lastUpdateID = updateID; campaign.SuppressStateSending = false; } }
public void ServerRead(IReadMessage msg, Client sender) { UInt16 currentLocIndex = msg.ReadUInt16(); UInt16 selectedLocIndex = msg.ReadUInt16(); byte selectedMissionCount = msg.ReadByte(); List <int> selectedMissionIndices = new List <int>(); for (int i = 0; i < selectedMissionCount; i++) { selectedMissionIndices.Add(msg.ReadByte()); } bool purchasedHullRepairs = msg.ReadBoolean(); bool purchasedItemRepairs = msg.ReadBoolean(); bool purchasedLostShuttles = msg.ReadBoolean(); UInt16 buyCrateItemCount = msg.ReadUInt16(); List <PurchasedItem> buyCrateItems = new List <PurchasedItem>(); for (int i = 0; i < buyCrateItemCount; i++) { string itemPrefabIdentifier = msg.ReadString(); int itemQuantity = msg.ReadRangedInteger(0, CargoManager.MaxQuantity); buyCrateItems.Add(new PurchasedItem(ItemPrefab.Prefabs[itemPrefabIdentifier], itemQuantity)); } UInt16 purchasedItemCount = msg.ReadUInt16(); List <PurchasedItem> purchasedItems = new List <PurchasedItem>(); for (int i = 0; i < purchasedItemCount; i++) { string itemPrefabIdentifier = msg.ReadString(); int itemQuantity = msg.ReadRangedInteger(0, CargoManager.MaxQuantity); purchasedItems.Add(new PurchasedItem(ItemPrefab.Prefabs[itemPrefabIdentifier], itemQuantity)); } UInt16 soldItemCount = msg.ReadUInt16(); List <SoldItem> soldItems = new List <SoldItem>(); for (int i = 0; i < soldItemCount; i++) { string itemPrefabIdentifier = msg.ReadString(); UInt16 id = msg.ReadUInt16(); bool removed = msg.ReadBoolean(); byte sellerId = msg.ReadByte(); soldItems.Add(new SoldItem(ItemPrefab.Prefabs[itemPrefabIdentifier], id, removed, sellerId)); } ushort purchasedUpgradeCount = msg.ReadUInt16(); List <PurchasedUpgrade> purchasedUpgrades = new List <PurchasedUpgrade>(); for (int i = 0; i < purchasedUpgradeCount; i++) { string upgradeIdentifier = msg.ReadString(); UpgradePrefab prefab = UpgradePrefab.Find(upgradeIdentifier); string categoryIdentifier = msg.ReadString(); UpgradeCategory category = UpgradeCategory.Find(categoryIdentifier); int upgradeLevel = msg.ReadByte(); if (category == null || prefab == null) { continue; } purchasedUpgrades.Add(new PurchasedUpgrade(prefab, category, upgradeLevel)); } ushort purchasedItemSwapCount = msg.ReadUInt16(); List <PurchasedItemSwap> purchasedItemSwaps = new List <PurchasedItemSwap>(); for (int i = 0; i < purchasedItemSwapCount; i++) { UInt16 itemToRemoveID = msg.ReadUInt16(); Item itemToRemove = Entity.FindEntityByID(itemToRemoveID) as Item; string itemToInstallIdentifier = msg.ReadString(); ItemPrefab itemToInstall = string.IsNullOrEmpty(itemToInstallIdentifier) ? null : ItemPrefab.Find(string.Empty, itemToInstallIdentifier); if (itemToRemove == null) { continue; } purchasedItemSwaps.Add(new PurchasedItemSwap(itemToRemove, itemToInstall)); } if (!AllowedToManageCampaign(sender)) { DebugConsole.ThrowError("Client \"" + sender.Name + "\" does not have a permission to manage the campaign"); return; } Location location = Map.CurrentLocation; int hullRepairCost = location?.GetAdjustedMechanicalCost(HullRepairCost) ?? HullRepairCost; int itemRepairCost = location?.GetAdjustedMechanicalCost(ItemRepairCost) ?? ItemRepairCost; int shuttleRetrieveCost = location?.GetAdjustedMechanicalCost(ShuttleReplaceCost) ?? ShuttleReplaceCost; if (purchasedHullRepairs != this.PurchasedHullRepairs) { if (purchasedHullRepairs && Money >= hullRepairCost) { this.PurchasedHullRepairs = true; Money -= hullRepairCost; } else if (!purchasedHullRepairs) { this.PurchasedHullRepairs = false; Money += hullRepairCost; } } if (purchasedItemRepairs != this.PurchasedItemRepairs) { if (purchasedItemRepairs && Money >= itemRepairCost) { this.PurchasedItemRepairs = true; Money -= itemRepairCost; } else if (!purchasedItemRepairs) { this.PurchasedItemRepairs = false; Money += itemRepairCost; } } if (purchasedLostShuttles != this.PurchasedLostShuttles) { if (GameMain.GameSession?.SubmarineInfo != null && GameMain.GameSession.SubmarineInfo.LeftBehindSubDockingPortOccupied) { GameMain.Server.SendDirectChatMessage(TextManager.FormatServerMessage("ReplaceShuttleDockingPortOccupied"), sender, ChatMessageType.MessageBox); } else if (purchasedLostShuttles && Money >= shuttleRetrieveCost) { this.PurchasedLostShuttles = true; Money -= shuttleRetrieveCost; } else if (!purchasedItemRepairs) { this.PurchasedLostShuttles = false; Money += shuttleRetrieveCost; } } if (currentLocIndex < Map.Locations.Count && Map.AllowDebugTeleport) { Map.SetLocation(currentLocIndex); } Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex); if (Map.SelectedLocation == null) { Map.SelectRandomLocation(preferUndiscovered: true); } if (Map.SelectedConnection != null) { Map.SelectMission(selectedMissionIndices); } CheckTooManyMissions(Map.CurrentLocation, sender); List <PurchasedItem> currentBuyCrateItems = new List <PurchasedItem>(CargoManager.ItemsInBuyCrate); currentBuyCrateItems.ForEach(i => CargoManager.ModifyItemQuantityInBuyCrate(i.ItemPrefab, -i.Quantity)); buyCrateItems.ForEach(i => CargoManager.ModifyItemQuantityInBuyCrate(i.ItemPrefab, i.Quantity)); CargoManager.SellBackPurchasedItems(new List <PurchasedItem>(CargoManager.PurchasedItems)); CargoManager.PurchaseItems(purchasedItems, false); // for some reason CargoManager.SoldItem is never cleared by the server, I've added a check to SellItems that ignores all // sold items that are removed so they should be discarded on the next message CargoManager.BuyBackSoldItems(new List <SoldItem>(CargoManager.SoldItems)); CargoManager.SellItems(soldItems); foreach (var(prefab, category, _) in purchasedUpgrades) { UpgradeManager.PurchaseUpgrade(prefab, category); // unstable logging int price = prefab.Price.GetBuyprice(UpgradeManager.GetUpgradeLevel(prefab, category), Map?.CurrentLocation); int level = UpgradeManager.GetUpgradeLevel(prefab, category); GameServer.Log($"SERVER: Purchased level {level} {category.Identifier}.{prefab.Identifier} for {price}", ServerLog.MessageType.ServerMessage); } foreach (var purchasedItemSwap in purchasedItemSwaps) { if (purchasedItemSwap.ItemToInstall == null) { UpgradeManager.CancelItemSwap(purchasedItemSwap.ItemToRemove); } else { UpgradeManager.PurchaseItemSwap(purchasedItemSwap.ItemToRemove, purchasedItemSwap.ItemToInstall); } } foreach (Item item in Item.ItemList) { if (item.PendingItemSwap != null && !purchasedItemSwaps.Any(it => it.ItemToRemove == item)) { UpgradeManager.CancelItemSwap(item); item.PendingItemSwap = null; } } }
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); }
private void DrawConnection(SpriteBatch spriteBatch, LocationConnection connection, Rectangle viewArea, Vector2 viewOffset, Color?overrideColor = null) { Color connectionColor; if (GameMain.DebugDraw) { float sizeFactor = MathUtils.InverseLerp( generationParams.SmallLevelConnectionLength, generationParams.LargeLevelConnectionLength, connection.Length); connectionColor = ToolBox.GradientLerp(sizeFactor, Color.LightGreen, GUI.Style.Orange, GUI.Style.Red); } else if (overrideColor.HasValue) { connectionColor = overrideColor.Value; } else { connectionColor = connection.Passed ? generationParams.ConnectionColor : generationParams.UnvisitedConnectionColor; } int width = (int)(generationParams.LocationConnectionWidth * zoom); if (Level.Loaded?.LevelData == connection.LevelData) { connectionColor = generationParams.HighlightedConnectionColor; width = (int)(width * 1.5f); } if (SelectedLocation != CurrentDisplayLocation && (connection.Locations.Contains(SelectedLocation) && connection.Locations.Contains(CurrentDisplayLocation))) { connectionColor = generationParams.HighlightedConnectionColor; width *= 2; } else if (HighlightedLocation != CurrentDisplayLocation && (connection.Locations.Contains(HighlightedLocation) && connection.Locations.Contains(CurrentDisplayLocation))) { connectionColor = generationParams.HighlightedConnectionColor; width *= 2; } Vector2 rectCenter = viewArea.Center.ToVector2(); int startIndex = connection.CrackSegments.Count > 2 ? 1 : 0; int endIndex = connection.CrackSegments.Count > 2 ? connection.CrackSegments.Count - 1 : connection.CrackSegments.Count; Vector2?connectionStart = null; Vector2?connectionEnd = null; for (int i = startIndex; i < endIndex; i++) { var segment = connection.CrackSegments[i]; Vector2 start = rectCenter + (segment[0] + viewOffset) * zoom; if (!connectionStart.HasValue) { connectionStart = start; } Vector2 end = rectCenter + (segment[1] + viewOffset) * zoom; connectionEnd = end; if (!viewArea.Contains(start) && !viewArea.Contains(end)) { continue; } else { if (MathUtils.GetLineRectangleIntersection(start, end, new Rectangle(viewArea.X, viewArea.Y + viewArea.Height, viewArea.Width, viewArea.Height), out Vector2 intersection)) { if (!viewArea.Contains(start)) { start = intersection; } else { end = intersection; } } } float a = 1.0f; if (!connection.Locations[0].Discovered && !connection.Locations[1].Discovered) { if (IsInFogOfWar(connection.Locations[0])) { a = (float)i / connection.CrackSegments.Count; } else if (IsInFogOfWar(connection.Locations[1])) { a = 1.0f - (float)i / connection.CrackSegments.Count; } } float dist = Vector2.Distance(start, end); var connectionSprite = connection.Passed ? generationParams.PassedConnectionSprite : generationParams.ConnectionSprite; spriteBatch.Draw(connectionSprite.Texture, new Rectangle((int)start.X, (int)start.Y, (int)(dist - 1 * zoom), width), connectionSprite.SourceRect, connectionColor * a, MathUtils.VectorToAngle(end - start), new Vector2(0, connectionSprite.size.Y / 2), SpriteEffects.None, 0.01f); } if (connectionStart.HasValue && connectionEnd.HasValue) { GUIComponentStyle crushDepthWarningIconStyle = null; string tooltip = null; var subCrushDepth = Submarine.MainSub?.RealWorldCrushDepth ?? Level.DefaultRealWorldCrushDepth; if (GameMain.GameSession?.Campaign?.UpgradeManager != null) { var hullUpgradePrefab = UpgradePrefab.Find("increasewallhealth"); if (hullUpgradePrefab != null) { int pendingLevel = GameMain.GameSession.Campaign.UpgradeManager.GetUpgradeLevel(hullUpgradePrefab, hullUpgradePrefab.UpgradeCategories.First()); int currentLevel = GameMain.GameSession.Campaign.UpgradeManager.GetRealUpgradeLevel(hullUpgradePrefab, hullUpgradePrefab.UpgradeCategories.First()); if (pendingLevel > currentLevel) { string updateValueStr = hullUpgradePrefab.SourceElement?.Element("Structure")?.GetAttributeString("crushdepth", null); if (!string.IsNullOrEmpty(updateValueStr)) { subCrushDepth = PropertyReference.CalculateUpgrade(subCrushDepth, pendingLevel - currentLevel, updateValueStr); } } } } if (connection.LevelData.InitialDepth * Physics.DisplayToRealWorldRatio > subCrushDepth) { crushDepthWarningIconStyle = GUI.Style.GetComponentStyle("CrushDepthWarningHighIcon"); tooltip = "crushdepthwarninghigh"; } else if ((connection.LevelData.InitialDepth + connection.LevelData.Size.Y) * Physics.DisplayToRealWorldRatio > subCrushDepth) { crushDepthWarningIconStyle = GUI.Style.GetComponentStyle("CrushDepthWarningLowIcon"); tooltip = "crushdepthwarninglow"; } if (crushDepthWarningIconStyle != null) { Vector2 iconPos = (connectionStart.Value + connectionEnd.Value) / 2; float iconSize = 32.0f * GUI.Scale; bool mouseOn = HighlightedLocation == null && Vector2.DistanceSquared(iconPos, PlayerInput.MousePosition) < iconSize * iconSize; Sprite crushDepthWarningIcon = crushDepthWarningIconStyle.GetDefaultSprite(); crushDepthWarningIcon.Draw(spriteBatch, iconPos, mouseOn ? crushDepthWarningIconStyle.HoverColor : crushDepthWarningIconStyle.Color, scale: iconSize / crushDepthWarningIcon.size.X); if (mouseOn) { connectionTooltip = new Pair <Rectangle, string>( new Rectangle(iconPos.ToPoint(), new Point((int)iconSize)), TextManager.Get(tooltip) .Replace("[initialdepth]", ((int)(connection.LevelData.InitialDepth * Physics.DisplayToRealWorldRatio)).ToString()) .Replace("[submarinecrushdepth]", ((int)subCrushDepth).ToString())); } } } if (GameMain.DebugDraw && zoom > 1.0f && generationParams.ShowLevelTypeNames) { Vector2 center = rectCenter + (connection.CenterPos + viewOffset) * zoom; if (viewArea.Contains(center) && connection.Biome != null) { GUI.DrawString(spriteBatch, center, connection.Biome.Identifier + " (" + connection.Difficulty + ")", Color.White); } } }