public Hull(MapEntityPrefab prefab, Rectangle rectangle) : this(prefab, rectangle, Submarine.MainSub) { }
protected override void StartMissionSpecific(Level level) { if (items.Any()) { #if DEBUG throw new Exception($"items.Count > 0 ({items.Count})"); #else DebugConsole.AddWarning("Item list was not empty at the start of a nest mission. The mission instance may not have been ended correctly on previous rounds."); items.Clear(); #endif } if (!IsClient) { //ruin/cave/wreck items are allowed to spawn close to the sub float minDistance = spawnPositionType == Level.PositionType.Ruin || spawnPositionType == Level.PositionType.Cave || spawnPositionType == Level.PositionType.Wreck ? 0.0f : Level.Loaded.Size.X * 0.3f; nestPosition = Level.Loaded.GetRandomItemPos(spawnPositionType, 100.0f, minDistance, 30.0f); List <GraphEdge> spawnEdges = new List <GraphEdge>(); if (spawnPositionType == Level.PositionType.Cave) { Level.Cave closestCave = null; float closestCaveDist = float.PositiveInfinity; foreach (var cave in Level.Loaded.Caves) { float dist = Vector2.DistanceSquared(nestPosition, cave.Area.Center.ToVector2()); if (dist < closestCaveDist) { closestCave = cave; closestCaveDist = dist; } } if (closestCave != null) { closestCave.DisplayOnSonar = true; SpawnNestObjects(level, closestCave); #if SERVER selectedCave = closestCave; #endif } var nearbyCells = Level.Loaded.GetCells(nestPosition, searchDepth: 3); if (nearbyCells.Any()) { List <GraphEdge> validEdges = new List <GraphEdge>(); foreach (var edge in nearbyCells.SelectMany(c => c.Edges)) { if (!edge.NextToCave || !edge.IsSolid) { continue; } if (Level.Loaded.ExtraWalls.Any(w => w.IsPointInside(edge.Center + edge.GetNormal(edge.Cell1 ?? edge.Cell2) * 100.0f))) { continue; } validEdges.Add(edge); } if (validEdges.Any()) { spawnEdges.AddRange(validEdges.Where(e => MathUtils.LineSegmentToPointDistanceSquared(e.Point1.ToPoint(), e.Point2.ToPoint(), nestPosition.ToPoint()) < itemSpawnRadius * itemSpawnRadius).Distinct()); } //no valid edges found close enough to the nest position, find the closest one if (!spawnEdges.Any()) { GraphEdge closestEdge = null; float closestDist = float.PositiveInfinity; foreach (var edge in nearbyCells.SelectMany(c => c.Edges)) { if (!edge.NextToCave || !edge.IsSolid) { continue; } float dist = Vector2.DistanceSquared(edge.Center, nestPosition); if (dist < closestDist) { closestEdge = edge; closestDist = dist; } } if (closestEdge != null) { spawnEdges.Add(closestEdge); } } } } foreach (XElement subElement in itemConfig.Elements()) { string itemIdentifier = subElement.GetAttributeString("identifier", ""); if (!(MapEntityPrefab.Find(null, itemIdentifier) is ItemPrefab itemPrefab)) { DebugConsole.ThrowError("Couldn't spawn item for nest mission: item prefab \"" + itemIdentifier + "\" not found"); continue; } Vector2 spawnPos = nestPosition; float rotation = 0.0f; if (spawnEdges.Any()) { var edge = spawnEdges.GetRandom(Rand.RandSync.Server); spawnPos = Vector2.Lerp(edge.Point1, edge.Point2, Rand.Range(0.1f, 0.9f, Rand.RandSync.Server)); Vector2 normal = Vector2.UnitY; if (edge.Cell1 != null && edge.Cell1.CellType == CellType.Solid) { normal = edge.GetNormal(edge.Cell1); } else if (edge.Cell2 != null && edge.Cell2.CellType == CellType.Solid) { normal = edge.GetNormal(edge.Cell2); } spawnPos += normal * 10.0f; rotation = MathUtils.VectorToAngle(normal) - MathHelper.PiOver2; } var item = new Item(itemPrefab, spawnPos, null); item.body.FarseerBody.BodyType = BodyType.Kinematic; item.body.SetTransformIgnoreContacts(item.body.SimPosition, rotation); item.FindHull(); items.Add(item); var statusEffectElement = subElement.Element("StatusEffectOnApproach") ?? subElement.Element("statuseffectonapproach"); if (statusEffectElement != null) { statusEffectOnApproach.Add(item, StatusEffect.Load(statusEffectElement, Prefab.Identifier)); } } } }
private bool IsThalamus(MapEntityPrefab entityPrefab) => IsThalamus(entityPrefab, Config.Entity);
private void LoadItemAsChild(XElement element, Item parent) { ItemPrefab itemPrefab; if (element.Attribute("name") != null) { DebugConsole.ThrowError("Error in cargo mission \"" + Name + "\" - use item identifiers instead of names to configure the items."); string itemName = element.GetAttributeString("name", ""); itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab; if (itemPrefab == null) { DebugConsole.ThrowError("Couldn't spawn item for cargo mission: item prefab \"" + itemName + "\" not found"); return; } } else { string itemIdentifier = element.GetAttributeString("identifier", ""); itemPrefab = MapEntityPrefab.Find(null, itemIdentifier) as ItemPrefab; if (itemPrefab == null) { DebugConsole.ThrowError("Couldn't spawn item for cargo mission: item prefab \"" + itemIdentifier + "\" not found"); return; } } if (itemPrefab == null) { DebugConsole.ThrowError("Couldn't spawn item for cargo mission: item prefab \"" + element.Name.ToString() + "\" not found"); return; } WayPoint cargoSpawnPos = WayPoint.GetRandom(SpawnType.Cargo, null, Submarine.MainSub, useSyncedRand: true); if (cargoSpawnPos == null) { DebugConsole.ThrowError("Couldn't spawn items for cargo mission, cargo spawnpoint not found"); return; } var cargoRoom = cargoSpawnPos.CurrentHull; if (cargoRoom == null) { DebugConsole.ThrowError("A waypoint marked as Cargo must be placed inside a room!"); return; } Vector2 position = new Vector2( cargoSpawnPos.Position.X + Rand.Range(-20.0f, 20.0f, Rand.RandSync.Server), cargoRoom.Rect.Y - cargoRoom.Rect.Height + itemPrefab.Size.Y / 2); var item = new Item(itemPrefab, position, cargoRoom.Submarine); item.FindHull(); items.Add(item); if (parent != null && parent.GetComponent <ItemContainer>() != null) { parentInventoryIDs.Add(item, parent.ID); parentItemContainerIndices.Add(item, (byte)parent.GetComponentIndex(parent.GetComponent <ItemContainer>())); parent.Combine(item, user: null); } foreach (XElement subElement in element.Elements()) { int amount = subElement.GetAttributeInt("amount", 1); for (int i = 0; i < amount; i++) { LoadItemAsChild(subElement, item); } } }
public SalvageMission(MissionPrefab prefab, Location[] locations) : base(prefab, locations) { containerTag = prefab.ConfigElement.GetAttributeString("containertag", ""); if (prefab.ConfigElement.Attribute("itemname") != null) { DebugConsole.ThrowError("Error in SalvageMission - use item identifier instead of the name of the item."); string itemName = prefab.ConfigElement.GetAttributeString("itemname", ""); itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab; if (itemPrefab == null) { DebugConsole.ThrowError("Error in SalvageMission: couldn't find an item prefab with the name " + itemName); } } else { string itemIdentifier = prefab.ConfigElement.GetAttributeString("itemidentifier", ""); itemPrefab = MapEntityPrefab.Find(null, itemIdentifier) as ItemPrefab; if (itemPrefab == null) { DebugConsole.ThrowError("Error in SalvageMission - couldn't find an item prefab with the identifier " + itemIdentifier); } } existingItemTag = prefab.ConfigElement.GetAttributeString("existingitemtag", ""); showMessageWhenPickedUp = prefab.ConfigElement.GetAttributeBool("showmessagewhenpickedup", false); string spawnPositionTypeStr = prefab.ConfigElement.GetAttributeString("spawntype", ""); if (string.IsNullOrWhiteSpace(spawnPositionTypeStr) || !Enum.TryParse(spawnPositionTypeStr, true, out spawnPositionType)) { spawnPositionType = Level.PositionType.Cave | Level.PositionType.Ruin; } foreach (XElement element in prefab.ConfigElement.Elements()) { switch (element.Name.ToString().ToLowerInvariant()) { case "statuseffect": { var newEffect = StatusEffect.Load(element, parentDebugName: prefab.Name); if (newEffect == null) { continue; } statusEffects.Add(new List <StatusEffect> { newEffect }); break; } case "chooserandom": statusEffects.Add(new List <StatusEffect>()); foreach (XElement subElement in element.Elements()) { var newEffect = StatusEffect.Load(subElement, parentDebugName: prefab.Name); if (newEffect == null) { continue; } statusEffects.Last().Add(newEffect); } break; } } }
private IEnumerable <object> Load() { if (GameSettings.VerboseLogging) { DebugConsole.NewMessage("LOADING COROUTINE", Color.Lime); } GUI.GraphicsDevice = base.GraphicsDevice; GUI.Init(Content); InitUserStats(); GUIComponent.Init(Window); DebugConsole.Init(Window); DebugConsole.Log(SelectedPackage == null ? "No content package selected" : "Content package \"" + SelectedPackage.Name + "\" selected"); yield return(CoroutineStatus.Running); LightManager = new Lights.LightManager(base.GraphicsDevice, Content); Hull.renderer = new WaterRenderer(base.GraphicsDevice, Content); TitleScreen.LoadState = 1.0f; yield return(CoroutineStatus.Running); GUI.LoadContent(); TitleScreen.LoadState = 2.0f; yield return(CoroutineStatus.Running); MissionPrefab.Init(); MapEntityPrefab.Init(); LevelGenerationParams.LoadPresets(); TitleScreen.LoadState = 10.0f; yield return(CoroutineStatus.Running); JobPrefab.LoadAll(SelectedPackage.GetFilesOfType(ContentType.Jobs)); // Add any missing jobs from the prefab into Config.JobNamePreferences. foreach (JobPrefab job in JobPrefab.List) { if (!Config.JobNamePreferences.Contains(job.Name)) { Config.JobNamePreferences.Add(job.Name); } } StructurePrefab.LoadAll(SelectedPackage.GetFilesOfType(ContentType.Structure)); TitleScreen.LoadState = 20.0f; yield return(CoroutineStatus.Running); ItemPrefab.LoadAll(SelectedPackage.GetFilesOfType(ContentType.Item)); TitleScreen.LoadState = 30.0f; yield return(CoroutineStatus.Running); Debug.WriteLine("sounds"); CoroutineManager.StartCoroutine(SoundPlayer.Init()); int i = 0; while (!SoundPlayer.Initialized) { i++; TitleScreen.LoadState = SoundPlayer.SoundCount == 0 ? 30.0f : Math.Min(30.0f + 40.0f * i / Math.Max(SoundPlayer.SoundCount, 1), 70.0f); yield return(CoroutineStatus.Running); } TitleScreen.LoadState = 70.0f; yield return(CoroutineStatus.Running); GameModePreset.Init(); Submarine.RefreshSavedSubs(); TitleScreen.LoadState = 80.0f; yield return(CoroutineStatus.Running); GameScreen = new GameScreen(GraphicsDeviceManager.GraphicsDevice, Content); TitleScreen.LoadState = 90.0f; yield return(CoroutineStatus.Running); MainMenuScreen = new MainMenuScreen(this); LobbyScreen = new LobbyScreen(); ServerListScreen = new ServerListScreen(); SubEditorScreen = new SubEditorScreen(Content); CharacterEditorScreen = new CharacterEditorScreen(); ParticleEditorScreen = new ParticleEditorScreen(); yield return(CoroutineStatus.Running); ParticleManager = new ParticleManager(GameScreen.Cam); ParticleManager.LoadPrefabs(); DecalManager = new DecalManager(); yield return(CoroutineStatus.Running); LocationType.Init(); MainMenuScreen.Select(); TitleScreen.LoadState = 100.0f; hasLoaded = true; if (GameSettings.VerboseLogging) { DebugConsole.NewMessage("LOADING COROUTINE FINISHED", Color.Lime); } yield return(CoroutineStatus.Success); }
private void GiveTreatment(float deltaTime) { if (treatmentTimer > 0.0f) { treatmentTimer -= deltaTime; } treatmentTimer = TreatmentDelay; var allAfflictions = targetCharacter.CharacterHealth.GetAllAfflictions() .Where(a => a.GetVitalityDecrease(targetCharacter.CharacterHealth) > 0) .ToList(); allAfflictions.Sort((a1, a2) => { return(Math.Sign(a2.GetVitalityDecrease(targetCharacter.CharacterHealth) - a1.GetVitalityDecrease(targetCharacter.CharacterHealth))); }); //check if we already have a suitable treatment for any of the afflictions foreach (Affliction affliction in allAfflictions) { foreach (KeyValuePair <string, float> treatmentSuitability in affliction.Prefab.TreatmentSuitability) { if (treatmentSuitability.Value > 0.0f) { Item matchingItem = character.Inventory.FindItemByIdentifier(treatmentSuitability.Key); if (matchingItem == null) { continue; } ApplyTreatment(affliction, matchingItem); return; } } } //didn't have any suitable treatments available, try to find some medical items HashSet <string> suitableItemIdentifiers = new HashSet <string>(); foreach (Affliction affliction in allAfflictions) { foreach (KeyValuePair <string, float> treatmentSuitability in affliction.Prefab.TreatmentSuitability) { if (treatmentSuitability.Value > 0.0f) { suitableItemIdentifiers.Add(treatmentSuitability.Key); } } } if (suitableItemIdentifiers.Count > 0) { List <string> itemNameList = new List <string>(); foreach (string itemIdentifier in suitableItemIdentifiers) { if (MapEntityPrefab.Find(null, itemIdentifier, showErrorMessages: false) is ItemPrefab itemPrefab) { itemNameList.Add(itemPrefab.Name); } //only list the first 4 items if (itemNameList.Count >= 4) { break; } } if (itemNameList.Count > 0) { string itemListStr = ""; if (itemNameList.Count == 1) { itemListStr = itemNameList[0]; } else { itemListStr = string.Join(" or ", string.Join(", ", itemNameList.Take(itemNameList.Count - 1)), itemNameList.Last()); } character?.Speak(TextManager.Get("DialogListRequiredTreatments") .Replace("[targetname]", targetCharacter.Name) .Replace("[treatmentlist]", itemListStr), null, 2.0f, "listrequiredtreatments" + targetCharacter.Name, 60.0f); } character.DeselectCharacter(); AddSubObjective(new AIObjectiveGetItem(character, suitableItemIdentifiers.ToArray(), true)); } character.AnimController.Anim = AnimController.Animation.CPR; }
public ItemAssemblyPrefab(string filePath) { FilePath = filePath; XDocument doc = XMLExtensions.TryLoadXml(filePath); if (doc == null) { return; } XElement element = doc.Root; if (element.IsOverride()) { element = element.Elements().First(); } originalName = element.GetAttributeString("name", ""); identifier = element.GetAttributeString("identifier", null) ?? originalName.ToLowerInvariant().Replace(" ", ""); configElement = element; Category = MapEntityCategory.ItemAssembly; SerializableProperty.DeserializeProperties(this, configElement); name = TextManager.Get("EntityName." + identifier, returnNull: true) ?? originalName; Description = TextManager.Get("EntityDescription." + identifier, returnNull: true) ?? Description; List <ushort> containedItemIDs = new List <ushort>(); foreach (XElement entityElement in element.Elements()) { var containerElement = entityElement.Elements().FirstOrDefault(e => e.Name.LocalName.Equals("itemcontainer", StringComparison.OrdinalIgnoreCase)); if (containerElement == null) { continue; } var itemIds = containerElement.GetAttributeIntArray("contained", new int[0]); containedItemIDs.AddRange(itemIds.Select(id => (ushort)id)); } int minX = int.MaxValue, minY = int.MaxValue; int maxX = int.MinValue, maxY = int.MinValue; DisplayEntities = new List <Pair <MapEntityPrefab, Rectangle> >(); foreach (XElement entityElement in element.Elements()) { ushort id = (ushort)entityElement.GetAttributeInt("ID", 0); if (id > 0 && containedItemIDs.Contains(id)) { continue; } string identifier = entityElement.GetAttributeString("identifier", entityElement.Name.ToString().ToLowerInvariant()); MapEntityPrefab mapEntity = List.FirstOrDefault(p => p.Identifier == identifier); if (mapEntity == null) { string entityName = entityElement.GetAttributeString("name", ""); mapEntity = List.FirstOrDefault(p => p.Name == entityName); } Rectangle rect = entityElement.GetAttributeRect("rect", Rectangle.Empty); if (mapEntity != null && !entityElement.Elements().Any(e => e.Name.LocalName.Equals("wire", StringComparison.OrdinalIgnoreCase))) { if (!entityElement.GetAttributeBool("hideinassemblypreview", false)) { DisplayEntities.Add(new Pair <MapEntityPrefab, Rectangle>(mapEntity, rect)); } minX = Math.Min(minX, rect.X); minY = Math.Min(minY, rect.Y - rect.Height); maxX = Math.Max(maxX, rect.Right); maxY = Math.Max(maxY, rect.Y); } } Bounds = minX == int.MaxValue ? new Rectangle(0, 0, 1, 1) : new Rectangle(minX, minY, maxX - minX, maxY - minY); Prefabs.Add(this, doc.Root.IsOverride()); }
private void InitializeJobItem(Character character, WayPoint spawnPoint, XElement itemElement, Item parentItem = null) { string itemName = itemElement.GetAttributeString("name", ""); ItemPrefab itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab; if (itemPrefab == null) { DebugConsole.ThrowError("Tried to spawn \"" + Name + "\" with the item \"" + itemName + "\". Matching item prefab not found."); return; } Item item = new Item(itemPrefab, character.Position, null); if (GameMain.Server != null && Entity.Spawner != null) { Entity.Spawner.CreateNetworkEvent(item, false); } if (itemElement.GetAttributeBool("equip", false)) { List <InvSlotType> allowedSlots = new List <InvSlotType>(item.AllowedSlots); allowedSlots.Remove(InvSlotType.Any); character.Inventory.TryPutItem(item, null, allowedSlots); } else { character.Inventory.TryPutItem(item, null, item.AllowedSlots); } if (item.Prefab.NameMatches("ID Card") && spawnPoint != null) { foreach (string s in spawnPoint.IdCardTags) { item.AddTag(s); } item.AddTag("name:" + character.Name); item.AddTag("job:" + Name); if (!string.IsNullOrWhiteSpace(spawnPoint.IdCardDesc)) { item.Description = spawnPoint.IdCardDesc; } } item.AddTag("Starter_Item"); foreach (WifiComponent wifiComponent in item.GetComponents <WifiComponent>()) { wifiComponent.TeamID = character.TeamID; } if (parentItem != null) { parentItem.Combine(item); } foreach (XElement childItemElement in itemElement.Elements()) { InitializeJobItem(character, spawnPoint, childItemElement, item); } }
static DebugConsole() { commands.Add(new Command("help", "", (string[] args) => { if (args.Length == 0) { foreach (Command c in commands) { if (string.IsNullOrEmpty(c.help)) { continue; } NewMessage(c.help, Color.Cyan); } } else { var matchingCommand = commands.Find(c => c.names.Any(name => name == args[0])); if (matchingCommand == null) { NewMessage("Command " + args[0] + " not found.", Color.Red); } else { NewMessage(matchingCommand.help, Color.Cyan); } } })); commands.Add(new Command("clientlist", "clientlist: List all the clients connected to the server.", (string[] args) => { if (GameMain.Server == null) { return; } NewMessage("***************", Color.Cyan); foreach (Client c in GameMain.Server.ConnectedClients) { NewMessage("- " + c.ID.ToString() + ": " + c.Name + ", " + c.Connection.RemoteEndPoint.Address.ToString(), Color.Cyan); } NewMessage("***************", Color.Cyan); })); commands.Add(new Command("createfilelist", "", (string[] args) => { UpdaterUtil.SaveFileList("filelist.xml"); })); commands.Add(new Command("spawn|spawncharacter", "spawn [creaturename] [near/inside/outside]: Spawn a creature at a random spawnpoint (use the second parameter to only select spawnpoints near/inside/outside the submarine).", (string[] args) => { if (args.Length == 0) { return; } Character spawnedCharacter = null; Vector2 spawnPosition = Vector2.Zero; WayPoint spawnPoint = null; if (args.Length > 1) { switch (args[1].ToLowerInvariant()) { case "inside": spawnPoint = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub); break; case "outside": spawnPoint = WayPoint.GetRandom(SpawnType.Enemy); break; case "near": case "close": float closestDist = -1.0f; foreach (WayPoint wp in WayPoint.WayPointList) { if (wp.Submarine != null) { continue; } //don't spawn inside hulls if (Hull.FindHull(wp.WorldPosition, null) != null) { continue; } float dist = Vector2.Distance(wp.WorldPosition, GameMain.GameScreen.Cam.WorldViewCenter); if (closestDist < 0.0f || dist < closestDist) { spawnPoint = wp; closestDist = dist; } } break; case "cursor": spawnPosition = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition); break; default: spawnPoint = WayPoint.GetRandom(args[0].ToLowerInvariant() == "human" ? SpawnType.Human : SpawnType.Enemy); break; } } else { spawnPoint = WayPoint.GetRandom(args[0].ToLowerInvariant() == "human" ? SpawnType.Human : SpawnType.Enemy); } if (string.IsNullOrWhiteSpace(args[0])) { return; } if (spawnPoint != null) { spawnPosition = spawnPoint.WorldPosition; } if (args[0].ToLowerInvariant() == "human") { spawnedCharacter = Character.Create(Character.HumanConfigFile, spawnPosition); #if CLIENT if (GameMain.GameSession != null) { SinglePlayerCampaign mode = GameMain.GameSession.GameMode as SinglePlayerCampaign; if (mode != null) { Character.Controlled = spawnedCharacter; GameMain.GameSession.CrewManager.AddCharacter(Character.Controlled); GameMain.GameSession.CrewManager.SelectCharacter(null, Character.Controlled); } } #endif } else { List <string> characterFiles = GameMain.Config.SelectedContentPackage.GetFilesOfType(ContentType.Character); foreach (string characterFile in characterFiles) { if (Path.GetFileNameWithoutExtension(characterFile).ToLowerInvariant() == args[0].ToLowerInvariant()) { Character.Create(characterFile, spawnPosition); return; } } ThrowError("No character matching the name \"" + args[0] + "\" found in the selected content package."); //attempt to open the config from the default path (the file may still be present even if it isn't included in the content package) string configPath = "Content/Characters/" + args[0].First().ToString().ToUpper() + args[0].Substring(1) + "/" + args[0].ToLower() + ".xml"; Character.Create(configPath, spawnPosition); } })); commands.Add(new Command("spawnitem", "spawnitem [itemname] [cursor/inventory]: Spawn an item at the position of the cursor, in the inventory of the controlled character or at a random spawnpoint if the last parameter is omitted.", (string[] args) => { if (args.Length < 1) { return; } Vector2?spawnPos = null; Inventory spawnInventory = null; int extraParams = 0; switch (args.Last()) { case "cursor": extraParams = 1; spawnPos = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition); break; case "inventory": extraParams = 1; spawnInventory = Character.Controlled == null ? null : Character.Controlled.Inventory; break; default: extraParams = 0; break; } string itemName = string.Join(" ", args.Take(args.Length - extraParams)).ToLowerInvariant(); var itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab; if (itemPrefab == null) { ThrowError("Item \"" + itemName + "\" not found!"); return; } if (spawnPos == null && spawnInventory == null) { var wp = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub); spawnPos = wp == null ? Vector2.Zero : wp.WorldPosition; } if (spawnPos != null) { Entity.Spawner.AddToSpawnQueue(itemPrefab, (Vector2)spawnPos); } else if (spawnInventory != null) { Entity.Spawner.AddToSpawnQueue(itemPrefab, spawnInventory); } })); commands.Add(new Command("disablecrewai", "disablecrewai: Disable the AI of the NPCs in the crew.", (string[] args) => { HumanAIController.DisableCrewAI = true; NewMessage("Crew AI disabled", Color.White); })); commands.Add(new Command("enablecrewai", "enablecrewai: Enable the AI of the NPCs in the crew.", (string[] args) => { HumanAIController.DisableCrewAI = false; NewMessage("Crew AI enabled", Color.White); })); commands.Add(new Command("autorestartinterval", "autorestartinterval [seconds]: Set how long the server waits between rounds before automatically starting a new one.", (string[] args) => { if (GameMain.Server == null) { return; } if (args.Length > 0) { int parsedInt = 0; if (int.TryParse(args[0], out parsedInt) && parsedInt >= 0) { GameMain.Server.AutoRestartInterval = parsedInt; NewMessage("Autorestart interval set to " + GameMain.Server.AutoRestartInterval + " seconds.", Color.White); } } })); commands.Add(new Command("autorestarttimer", "autorestarttimer [seconds]: Set the current autorestart countdown to the specified value.", (string[] args) => { if (GameMain.Server == null) { return; } if (args.Length > 0) { int parsedInt = 0; if (int.TryParse(args[0], out parsedInt) && parsedInt >= 0) { GameMain.Server.AutoRestartTimer = parsedInt; GameMain.NetLobbyScreen.LastUpdateID++; NewMessage("Autorestart timer set to " + GameMain.Server.AutoRestartTimer + " seconds.", Color.White); } } })); commands.Add(new Command("kick", "kick [name]: Kick a player out of the server.", (string[] args) => { if (GameMain.NetworkMember == null || args.Length == 0) { return; } string playerName = string.Join(" ", args); ShowQuestionPrompt("Reason for kicking \"" + playerName + "\"?", (reason) => { GameMain.NetworkMember.KickPlayer(playerName, reason); }); })); commands.Add(new Command("kickid", "kickid [id]: Kick the player with the specified client ID out of the server.", (string[] args) => { if (GameMain.Server == null || args.Length == 0) { return; } int id = 0; int.TryParse(args[0], out id); var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id); if (client == null) { ThrowError("Client id \"" + id + "\" not found."); return; } ShowQuestionPrompt("Reason for kicking \"" + client.Name + "\"?", (reason) => { GameMain.Server.KickPlayer(client.Name, reason); }); })); commands.Add(new Command("ban", "ban [name]: Kick and ban the player from the server.", (string[] args) => { if (GameMain.NetworkMember == null || args.Length == 0) { return; } string clientName = string.Join(" ", args); ShowQuestionPrompt("Reason for banning \"" + clientName + "\"?", (reason) => { ShowQuestionPrompt("Enter the duration of the ban (leave empty to ban permanently, or use the format \"[days] d [hours] h\")", (duration) => { TimeSpan?banDuration = null; if (!string.IsNullOrWhiteSpace(duration)) { TimeSpan parsedBanDuration; if (!TryParseTimeSpan(duration, out parsedBanDuration)) { ThrowError("\"" + duration + "\" is not a valid ban duration. Use the format \"[days] d [hours] h\", \"[days] d\" or \"[hours] h\"."); return; } banDuration = parsedBanDuration; } GameMain.NetworkMember.BanPlayer(clientName, reason, false, banDuration); }); }); })); commands.Add(new Command("banid", "banid [id]: Kick and ban the player with the specified client ID from the server.", (string[] args) => { if (GameMain.Server == null || args.Length == 0) { return; } int id = 0; int.TryParse(args[0], out id); var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id); if (client == null) { ThrowError("Client id \"" + id + "\" not found."); return; } ShowQuestionPrompt("Reason for banning \"" + client.Name + "\"?", (reason) => { ShowQuestionPrompt("Enter the duration of the ban (leave empty to ban permanently, or use the format \"[days] d [hours] h\")", (duration) => { TimeSpan?banDuration = null; if (!string.IsNullOrWhiteSpace(duration)) { TimeSpan parsedBanDuration; if (!TryParseTimeSpan(duration, out parsedBanDuration)) { ThrowError("\"" + duration + "\" is not a valid ban duration. Use the format \"[days] d [hours] h\", \"[days] d\" or \"[hours] h\"."); return; } banDuration = parsedBanDuration; } GameMain.Server.BanPlayer(client.Name, reason, false, banDuration); }); }); })); commands.Add(new Command("banip", "banip [ip]: Ban the IP address from the server.", (string[] args) => { if (GameMain.Server == null || args.Length == 0) { return; } ShowQuestionPrompt("Reason for banning the ip \"" + commands[1] + "\"?", (reason) => { ShowQuestionPrompt("Enter the duration of the ban (leave empty to ban permanently, or use the format \"[days] d [hours] h\")", (duration) => { TimeSpan?banDuration = null; if (!string.IsNullOrWhiteSpace(duration)) { TimeSpan parsedBanDuration; if (!TryParseTimeSpan(duration, out parsedBanDuration)) { ThrowError("\"" + duration + "\" is not a valid ban duration. Use the format \"[days] d [hours] h\", \"[days] d\" or \"[hours] h\"."); return; } banDuration = parsedBanDuration; } var client = GameMain.Server.ConnectedClients.Find(c => c.Connection.RemoteEndPoint.Address.ToString() == args[0]); if (client == null) { GameMain.Server.BanList.BanPlayer("Unnamed", args[0], reason, banDuration); } else { GameMain.Server.KickClient(client, reason); } }); }); })); commands.Add(new Command("teleportcharacter|teleport", "teleport [character name]: Teleport the specified character to the position of the cursor. If the name parameter is omitted, the controlled character will be teleported.", (string[] args) => { Character tpCharacter = null; if (args.Length == 0) { tpCharacter = Character.Controlled; } else { tpCharacter = FindMatchingCharacter(args, false); } if (tpCharacter == null) { return; } var cam = GameMain.GameScreen.Cam; tpCharacter.AnimController.CurrentHull = null; tpCharacter.Submarine = null; tpCharacter.AnimController.SetPosition(ConvertUnits.ToSimUnits(cam.ScreenToWorld(PlayerInput.MousePosition))); tpCharacter.AnimController.FindHull(cam.ScreenToWorld(PlayerInput.MousePosition), true); })); commands.Add(new Command("godmode", "godmode: Toggle submarine godmode. Makes the main submarine invulnerable to damage.", (string[] args) => { if (Submarine.MainSub == null) { return; } Submarine.MainSub.GodMode = !Submarine.MainSub.GodMode; NewMessage(Submarine.MainSub.GodMode ? "Godmode on" : "Godmode off", Color.White); })); commands.Add(new Command("lockx", "lockx: Lock horizontal movement of the main submarine.", (string[] args) => { Submarine.LockX = !Submarine.LockX; })); commands.Add(new Command("locky", "loxky: Lock vertical movement of the main submarine.", (string[] args) => { Submarine.LockY = !Submarine.LockY; })); commands.Add(new Command("dumpids", "", (string[] args) => { try { int count = args.Length == 0 ? 10 : int.Parse(args[0]); Entity.DumpIds(count); } catch (Exception e) { ThrowError("Failed to dump ids", e); } })); commands.Add(new Command("heal", "heal [character name]: Restore the specified character to full health. If the name parameter is omitted, the controlled character will be healed.", (string[] args) => { Character healedCharacter = null; if (args.Length == 0) { healedCharacter = Character.Controlled; } else { healedCharacter = FindMatchingCharacter(args); } if (healedCharacter != null) { healedCharacter.AddDamage(CauseOfDeath.Damage, -healedCharacter.MaxHealth, null); healedCharacter.Oxygen = 100.0f; healedCharacter.Bleeding = 0.0f; healedCharacter.SetStun(0.0f, true); } })); commands.Add(new Command("revive", "revive [character name]: Bring the specified character back from the dead. If the name parameter is omitted, the controlled character will be revived.", (string[] args) => { Character revivedCharacter = null; if (args.Length == 0) { revivedCharacter = Character.Controlled; } else { revivedCharacter = FindMatchingCharacter(args); } if (revivedCharacter == null) { return; } revivedCharacter.Revive(false); if (GameMain.Server != null) { foreach (Client c in GameMain.Server.ConnectedClients) { if (c.Character != revivedCharacter) { continue; } //clients stop controlling the character when it dies, force control back GameMain.Server.SetClientCharacter(c, revivedCharacter); break; } } })); commands.Add(new Command("freeze", "", (string[] args) => { if (Character.Controlled != null) { Character.Controlled.AnimController.Frozen = !Character.Controlled.AnimController.Frozen; } })); commands.Add(new Command("freecamera|freecam", "freecam: Detach the camera from the controlled character.", (string[] args) => { Character.Controlled = null; GameMain.GameScreen.Cam.TargetPos = Vector2.Zero; })); commands.Add(new Command("water|editwater", "water/editwater: Toggle water editing. Allows adding water into rooms by holding the left mouse button and removing it by holding the right mouse button.", (string[] args) => { if (GameMain.Client == null) { Hull.EditWater = !Hull.EditWater; NewMessage(Hull.EditWater ? "Water editing on" : "Water editing off", Color.White); } })); commands.Add(new Command("fire|editfire", "fire/editfire: Allows putting up fires by left clicking.", (string[] args) => { if (GameMain.Client == null) { Hull.EditFire = !Hull.EditFire; NewMessage(Hull.EditFire ? "Fire spawning on" : "Fire spawning off", Color.White); } })); commands.Add(new Command("explosion", "explosion [range] [force] [damage] [structuredamage]: Creates an explosion at the position of the cursor.", (string[] args) => { Vector2 explosionPos = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition); float range = 500, force = 10, damage = 50, structureDamage = 10; if (args.Length > 0) { float.TryParse(args[0], out range); } if (args.Length > 1) { float.TryParse(args[1], out force); } if (args.Length > 2) { float.TryParse(args[2], out damage); } if (args.Length > 3) { float.TryParse(args[3], out structureDamage); } new Explosion(range, force, damage, structureDamage).Explode(explosionPos); })); commands.Add(new Command("fixitems", "fixitems: Repairs all items and restores them to full condition.", (string[] args) => { foreach (Item it in Item.ItemList) { it.Condition = it.Prefab.Health; } })); commands.Add(new Command("fixhulls|fixwalls", "fixwalls/fixhulls: Fixes all walls.", (string[] args) => { foreach (Structure w in Structure.WallList) { for (int i = 0; i < w.SectionCount; i++) { w.AddDamage(i, -100000.0f); } } })); commands.Add(new Command("power", "power [temperature]: Immediately sets the temperature of the nuclear reactor to the specified value.", (string[] args) => { Item reactorItem = Item.ItemList.Find(i => i.GetComponent <Reactor>() != null); if (reactorItem == null) { return; } float power = 5000.0f; if (args.Length > 0) { float.TryParse(args[0], out power); } var reactor = reactorItem.GetComponent <Reactor>(); reactor.ShutDownTemp = power == 0 ? 0 : 7000.0f; reactor.AutoTemp = true; reactor.Temperature = power; if (GameMain.Server != null) { reactorItem.CreateServerEvent(reactor); } })); commands.Add(new Command("oxygen|air", "oxygen/air: Replenishes the oxygen levels in every room to 100%.", (string[] args) => { foreach (Hull hull in Hull.hullList) { hull.OxygenPercentage = 100.0f; } })); commands.Add(new Command("killmonsters", "killmonsters: Immediately kills all AI-controlled enemies in the level.", (string[] args) => { foreach (Character c in Character.CharacterList) { if (!(c.AIController is EnemyAIController)) { continue; } c.AddDamage(CauseOfDeath.Damage, 10000.0f, null); } })); commands.Add(new Command("netstats", "netstats: Toggles the visibility of the network statistics UI.", (string[] args) => { if (GameMain.Server == null) { return; } GameMain.Server.ShowNetStats = !GameMain.Server.ShowNetStats; })); commands.Add(new Command("setclientcharacter", "setclientcharacter [client name] ; [character name]: Gives the client control of the specified character.", (string[] args) => { if (GameMain.Server == null) { return; } int separatorIndex = Array.IndexOf(args, ";"); if (separatorIndex == -1 || args.Length < 3) { ThrowError("Invalid parameters. The command should be formatted as \"setclientcharacter [client] ; [character]\""); return; } string[] argsLeft = args.Take(separatorIndex).ToArray(); string[] argsRight = args.Skip(separatorIndex + 1).ToArray(); string clientName = String.Join(" ", argsLeft); var client = GameMain.Server.ConnectedClients.Find(c => c.Name == clientName); if (client == null) { ThrowError("Client \"" + clientName + "\" not found."); } var character = FindMatchingCharacter(argsRight, false); GameMain.Server.SetClientCharacter(client, character); })); commands.Add(new Command("campaigninfo|campaignstatus", "campaigninfo: Display information about the state of the currently active campaign.", (string[] args) => { var campaign = GameMain.GameSession?.GameMode as CampaignMode; if (campaign == null) { ThrowError("No campaign active!"); return; } campaign.LogState(); })); commands.Add(new Command("campaigndestination|setcampaigndestination", "campaigndestination [index]: Set the location to head towards in the currently active campaign.", (string[] args) => { var campaign = GameMain.GameSession?.GameMode as CampaignMode; if (campaign == null) { ThrowError("No campaign active!"); return; } if (args.Length == 0) { int i = 0; foreach (LocationConnection connection in campaign.Map.CurrentLocation.Connections) { NewMessage(" " + i + ". " + connection.OtherLocation(campaign.Map.CurrentLocation).Name, Color.White); i++; } ShowQuestionPrompt("Select a destination (0 - " + (campaign.Map.CurrentLocation.Connections.Count - 1) + "):", (string selectedDestination) => { int destinationIndex = -1; if (!int.TryParse(selectedDestination, out destinationIndex)) { return; } if (destinationIndex < 0 || destinationIndex >= campaign.Map.CurrentLocation.Connections.Count) { NewMessage("Index out of bounds!", Color.Red); return; } Location location = campaign.Map.CurrentLocation.Connections[destinationIndex].OtherLocation(campaign.Map.CurrentLocation); campaign.Map.SelectLocation(location); NewMessage(location.Name + " selected.", Color.White); }); } else { int destinationIndex = -1; if (!int.TryParse(args[0], out destinationIndex)) { return; } if (destinationIndex < 0 || destinationIndex >= campaign.Map.CurrentLocation.Connections.Count) { NewMessage("Index out of bounds!", Color.Red); return; } Location location = campaign.Map.CurrentLocation.Connections[destinationIndex].OtherLocation(campaign.Map.CurrentLocation); campaign.Map.SelectLocation(location); NewMessage(location.Name + " selected.", Color.White); } })); #if DEBUG commands.Add(new Command("spamevents", "A debug command that immediately creates entity events for all items, characters and structures.", (string[] args) => { foreach (Item item in Item.ItemList) { for (int i = 0; i < item.components.Count; i++) { if (item.components[i] is IServerSerializable) { GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ComponentState, i }); } var itemContainer = item.GetComponent <ItemContainer>(); if (itemContainer != null) { GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.InventoryState }); } GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.Status }); item.NeedsPositionUpdate = true; } } foreach (Character c in Character.CharacterList) { GameMain.Server.CreateEntityEvent(c, new object[] { NetEntityEvent.Type.Status }); } foreach (Structure wall in Structure.WallList) { GameMain.Server.CreateEntityEvent(wall); } })); #endif InitProjectSpecific(); commands.Sort((c1, c2) => c1.names[0].CompareTo(c2.names[0])); }
private void BakeMapEntity(XElement element) { string identifier = element.GetAttributeString("identifier", ""); if (string.IsNullOrEmpty(identifier)) { return; } Rectangle rect = element.GetAttributeRect("rect", Rectangle.Empty); if (rect.Equals(Rectangle.Empty)) { return; } float depth = element.GetAttributeFloat("spritedepth", 1f); bool flippedX = element.GetAttributeBool("flippedx", false); bool flippedY = element.GetAttributeBool("flippedy", false); float scale = element.GetAttributeFloat("scale", 1f); Color color = element.GetAttributeColor("spritecolor", Color.White); float rotation = element.GetAttributeFloat("rotation", 0f); MapEntityPrefab prefab = MapEntityPrefab.List.FirstOrDefault(p => p.Identifier.Equals(identifier, StringComparison.OrdinalIgnoreCase)); if (prefab == null) { return; } var texture = prefab.sprite.Texture; var srcRect = prefab.sprite.SourceRect; SpriteEffects spriteEffects = SpriteEffects.None; if (flippedX) { spriteEffects |= SpriteEffects.FlipHorizontally; } if (flippedY) { spriteEffects |= SpriteEffects.FlipVertically; } var prevEffects = prefab.sprite.effects; prefab.sprite.effects ^= spriteEffects; bool overrideSprite = false; ItemPrefab itemPrefab = prefab as ItemPrefab; StructurePrefab structurePrefab = prefab as StructurePrefab; if (itemPrefab != null) { BakeItemComponents(itemPrefab, rect, color, scale, rotation, depth, out overrideSprite); } if (!overrideSprite) { if (structurePrefab != null) { ParseUpgrades(structurePrefab.ConfigElement, ref scale); if (!prefab.ResizeVertical) { rect.Height = (int)(rect.Height * scale / prefab.Scale); } if (!prefab.ResizeHorizontal) { rect.Width = (int)(rect.Width * scale / prefab.Scale); } var textureScale = element.GetAttributeVector2("texturescale", Vector2.One); Vector2 backGroundOffset = Vector2.Zero; Vector2 textureOffset = element.GetAttributeVector2("textureoffset", Vector2.Zero); if (flippedX) { textureOffset.X = -textureOffset.X; } if (flippedY) { textureOffset.Y = -textureOffset.Y; } backGroundOffset = new Vector2( MathUtils.PositiveModulo((int)-textureOffset.X, prefab.sprite.SourceRect.Width), MathUtils.PositiveModulo((int)-textureOffset.Y, prefab.sprite.SourceRect.Height)); prefab.sprite.DrawTiled( spriteRecorder, rect.Location.ToVector2() * new Vector2(1f, -1f), rect.Size.ToVector2(), color: color, startOffset: backGroundOffset, textureScale: textureScale * scale, depth: depth); } else if (itemPrefab != null) { bool usePrefabValues = element.GetAttributeBool("isoverride", false) != itemPrefab.IsOverride; if (usePrefabValues) { scale = itemPrefab.ConfigElement.GetAttributeFloat(scale, "scale", "Scale"); } ParseUpgrades(itemPrefab.ConfigElement, ref scale); if (prefab.ResizeVertical || prefab.ResizeHorizontal) { if (!prefab.ResizeHorizontal) { rect.Width = (int)(prefab.sprite.size.X * scale); } if (!prefab.ResizeVertical) { rect.Height = (int)(prefab.sprite.size.Y * scale); } var spritePos = rect.Center.ToVector2(); //spritePos.Y = rect.Height - spritePos.Y; prefab.sprite.DrawTiled( spriteRecorder, rect.Location.ToVector2() * new Vector2(1f, -1f), rect.Size.ToVector2(), color: color, textureScale: Vector2.One * scale, depth: depth); foreach (var decorativeSprite in itemPrefab.DecorativeSprites) { float offsetState = 0f; Vector2 offset = decorativeSprite.GetOffset(ref offsetState, Vector2.Zero) * scale; if (flippedX && itemPrefab.CanSpriteFlipX) { offset.X = -offset.X; } if (flippedY && itemPrefab.CanSpriteFlipY) { offset.Y = -offset.Y; } decorativeSprite.Sprite.DrawTiled(spriteRecorder, new Vector2(spritePos.X + offset.X - rect.Width / 2, -(spritePos.Y + offset.Y + rect.Height / 2)), rect.Size.ToVector2(), color: color, textureScale: Vector2.One * scale, depth: Math.Min(depth + (decorativeSprite.Sprite.Depth - prefab.sprite.Depth), 0.999f)); } } else { rect.Width = (int)(rect.Width * scale / prefab.Scale); rect.Height = (int)(rect.Height * scale / prefab.Scale); var spritePos = rect.Center.ToVector2(); spritePos.Y -= rect.Height; //spritePos.Y = rect.Height - spritePos.Y; prefab.sprite.Draw( spriteRecorder, spritePos * new Vector2(1f, -1f), color, prefab.sprite.Origin, rotation, scale, prefab.sprite.effects, depth); foreach (var decorativeSprite in itemPrefab.DecorativeSprites) { float rotationState = 0f; float offsetState = 0f; float rot = decorativeSprite.GetRotation(ref rotationState, 0f); Vector2 offset = decorativeSprite.GetOffset(ref offsetState, Vector2.Zero) * scale; if (flippedX && itemPrefab.CanSpriteFlipX) { offset.X = -offset.X; } if (flippedY && itemPrefab.CanSpriteFlipY) { offset.Y = -offset.Y; } decorativeSprite.Sprite.Draw(spriteRecorder, new Vector2(spritePos.X + offset.X, -(spritePos.Y + offset.Y)), color, MathHelper.ToRadians(rotation) + rot, decorativeSprite.GetScale(0f) * scale, prefab.sprite.effects, depth: Math.Min(depth + (decorativeSprite.Sprite.Depth - prefab.sprite.Depth), 0.999f)); } } } } prefab.sprite.effects = prevEffects; }
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 (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)); 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 CancelItemSwap(Item itemToRemove, bool force = false) { if (!CanUpgradeSub()) { DebugConsole.ThrowError("Cannot swap items when switching to another submarine."); return; } if (itemToRemove?.PendingItemSwap == null && string.IsNullOrEmpty(itemToRemove?.Prefab.SwappableItem?.ReplacementOnUninstall)) { DebugConsole.ThrowError($"Cannot uninstall item \"{itemToRemove?.Name}\" (no replacement item configured)."); return; } SwappableItem?swappableItem = itemToRemove.Prefab.SwappableItem; if (swappableItem == null) { DebugConsole.ThrowError($"Failed to uninstall item \"{itemToRemove.Name}\" (not configured as a swappable item)."); return; } 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; } } var linkedItems = GetLinkedItemsToSwap(itemToRemove); foreach (Item itemToCancel in linkedItems) { if (itemToCancel.PendingItemSwap == null) { var replacement = MapEntityPrefab.Find("", swappableItem.ReplacementOnUninstall) as ItemPrefab; if (replacement == null) { DebugConsole.ThrowError($"Failed to uninstall item \"{itemToCancel.Name}\". Could not find the replacement item \"{swappableItem.ReplacementOnUninstall}\"."); return; } PurchasedItemSwaps.RemoveAll(p => p.ItemToRemove == itemToCancel); PurchasedItemSwaps.Add(new PurchasedItemSwap(itemToCancel, replacement)); DebugLog($"Uninstalled item item \"{itemToCancel.Name}\".", Color.Orange); itemToCancel.PendingItemSwap = replacement; } else { PurchasedItemSwaps.RemoveAll(p => p.ItemToRemove == itemToCancel); DebugLog($"Cancelled swapping the item \"{itemToCancel.Name}\" with \"{itemToCancel.PendingItemSwap.Name}\".", Color.Orange); itemToCancel.PendingItemSwap = null; } } #if CLIENT OnUpgradesChanged?.Invoke(); #endif }
public Gap(MapEntityPrefab prefab, Rectangle rectangle) : this(rectangle, Submarine.MainSub) { }
private IEnumerable <object> Load() { if (GameSettings.VerboseLogging) { DebugConsole.NewMessage("LOADING COROUTINE", Color.Lime); } SoundManager = new Sounds.SoundManager(); SoundManager.SetCategoryGainMultiplier("default", Config.SoundVolume); SoundManager.SetCategoryGainMultiplier("ui", Config.SoundVolume); SoundManager.SetCategoryGainMultiplier("waterambience", Config.SoundVolume); SoundManager.SetCategoryGainMultiplier("music", Config.MusicVolume); SoundManager.SetCategoryGainMultiplier("voip", Config.VoiceChatVolume); if (Config.EnableSplashScreen) { (TitleScreen as LoadingScreen).SplashScreen = new Video(base.GraphicsDevice, SoundManager, "Content/splashscreen.mp4", 1280, 720); } GUI.Init(Window, Config.SelectedContentPackages, GraphicsDevice); DebugConsole.Init(); SteamManager.Initialize(); if (Config.AutoUpdateWorkshopItems) { if (SteamManager.AutoUpdateWorkshopItems()) { ContentPackage.LoadAll(ContentPackage.Folder); Config.ReloadContentPackages(); } } if (SelectedPackages.Count == 0) { DebugConsole.Log("No content packages selected"); } else { DebugConsole.Log("Selected content packages: " + string.Join(", ", SelectedPackages.Select(cp => cp.Name))); } #if DEBUG GameSettings.ShowUserStatisticsPrompt = false; GameSettings.SendUserStatistics = false; #endif InitUserStats(); yield return(CoroutineStatus.Running); LightManager = new Lights.LightManager(base.GraphicsDevice, Content); WaterRenderer.Instance = new WaterRenderer(base.GraphicsDevice, Content); TitleScreen.LoadState = 1.0f; yield return(CoroutineStatus.Running); GUI.LoadContent(); TitleScreen.LoadState = 2.0f; yield return(CoroutineStatus.Running); MissionPrefab.Init(); MapEntityPrefab.Init(); Tutorials.Tutorial.Init(); MapGenerationParams.Init(); LevelGenerationParams.LoadPresets(); ScriptedEventSet.LoadPrefabs(); AfflictionPrefab.LoadAll(GetFilesOfType(ContentType.Afflictions)); TitleScreen.LoadState = 10.0f; yield return(CoroutineStatus.Running); StructurePrefab.LoadAll(GetFilesOfType(ContentType.Structure)); TitleScreen.LoadState = 15.0f; yield return(CoroutineStatus.Running); ItemPrefab.LoadAll(GetFilesOfType(ContentType.Item)); TitleScreen.LoadState = 25.0f; yield return(CoroutineStatus.Running); JobPrefab.LoadAll(GetFilesOfType(ContentType.Jobs)); // Add any missing jobs from the prefab into Config.JobNamePreferences. foreach (JobPrefab job in JobPrefab.List) { if (!Config.JobPreferences.Contains(job.Identifier)) { Config.JobPreferences.Add(job.Identifier); } } NPCConversation.LoadAll(GetFilesOfType(ContentType.NPCConversations)); ItemAssemblyPrefab.LoadAll(); TitleScreen.LoadState = 30.0f; 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 ? 30.0f : Math.Min(30.0f + 40.0f * i / Math.Max(SoundPlayer.SoundCount, 1), 70.0f); yield return(CoroutineStatus.Running); } TitleScreen.LoadState = 70.0f; yield return(CoroutineStatus.Running); GameModePreset.Init(); Submarine.RefreshSavedSubs(); TitleScreen.LoadState = 80.0f; yield return(CoroutineStatus.Running); GameScreen = new GameScreen(GraphicsDeviceManager.GraphicsDevice, Content); TitleScreen.LoadState = 90.0f; yield return(CoroutineStatus.Running); MainMenuScreen = new MainMenuScreen(this); LobbyScreen = new LobbyScreen(); ServerListScreen = new ServerListScreen(); if (SteamManager.USE_STEAM) { SteamWorkshopScreen = new SteamWorkshopScreen(); } SubEditorScreen = new SubEditorScreen(); ParticleEditorScreen = new ParticleEditorScreen(); LevelEditorScreen = new LevelEditorScreen(); SpriteEditorScreen = new SpriteEditorScreen(); CharacterEditorScreen = new CharacterEditorScreen(); yield return(CoroutineStatus.Running); TitleScreen.LoadState = 95.0f; ParticleManager = new ParticleManager(GameScreen.Cam); ParticleManager.LoadPrefabs(); TitleScreen.LoadState = 97.0f; LevelObjectPrefab.LoadAll(); DecalManager = new DecalManager(); TitleScreen.LoadState = 99.0f; yield return(CoroutineStatus.Running); LocationType.Init(); MainMenuScreen.Select(); CheckContentPackage(); TitleScreen.LoadState = 100.0f; hasLoaded = true; if (GameSettings.VerboseLogging) { DebugConsole.NewMessage("LOADING COROUTINE FINISHED", Color.Lime); } yield return(CoroutineStatus.Success); }
private void InitializeJobItem(Character character, XElement itemElement, WayPoint spawnPoint = null, Item parentItem = null) { ItemPrefab itemPrefab; if (itemElement.Attribute("name") != null) { string itemName = itemElement.Attribute("name").Value; DebugConsole.ThrowError("Error in Job config (" + Name + ") - use item identifiers instead of names to configure the items."); itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab; if (itemPrefab == null) { DebugConsole.ThrowError("Tried to spawn \"" + Name + "\" with the item \"" + itemName + "\". Matching item prefab not found."); return; } } else { string itemIdentifier = itemElement.GetAttributeString("identifier", ""); itemPrefab = MapEntityPrefab.Find(null, itemIdentifier) as ItemPrefab; if (itemPrefab == null) { DebugConsole.ThrowError("Tried to spawn \"" + Name + "\" with the item \"" + itemIdentifier + "\". Matching item prefab not found."); return; } } Item item = new Item(itemPrefab, character.Position, null); #if SERVER if (GameMain.Server != null && Entity.Spawner != null) { if (GameMain.Server.EntityEventManager.UniqueEvents.Any(ev => ev.Entity == item)) { string errorMsg = $"Error while spawning job items. Item {item.Name} created network events before the spawn event had been created."; DebugConsole.ThrowError(errorMsg); GameAnalyticsManager.AddErrorEventOnce("Job.InitializeJobItem:EventsBeforeSpawning", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); GameMain.Server.EntityEventManager.UniqueEvents.RemoveAll(ev => ev.Entity == item); GameMain.Server.EntityEventManager.Events.RemoveAll(ev => ev.Entity == item); } Entity.Spawner.CreateNetworkEvent(item, false); } #endif if (itemElement.GetAttributeBool("equip", false)) { List <InvSlotType> allowedSlots = new List <InvSlotType>(item.AllowedSlots); allowedSlots.Remove(InvSlotType.Any); character.Inventory.TryPutItem(item, null, allowedSlots); } else { character.Inventory.TryPutItem(item, null, item.AllowedSlots); } Wearable wearable = ((List <ItemComponent>)item.Components)?.Find(c => c is Wearable) as Wearable; if (wearable != null) { if (Variant > 0 && Variant <= wearable.Variants) { wearable.Variant = Variant; } else { wearable.Variant = wearable.Variant; //force server event if (wearable.Variants > 0 && Variant == 0) { //set variant to the same as the wearable to get the rest of the character's gear //to use the same variant (if possible) Variant = wearable.Variant; } } } if (item.Prefab.Identifier == "idcard" && spawnPoint != null) { foreach (string s in spawnPoint.IdCardTags) { item.AddTag(s); } item.AddTag("name:" + character.Name); item.AddTag("job:" + Name); if (!string.IsNullOrWhiteSpace(spawnPoint.IdCardDesc)) { item.Description = spawnPoint.IdCardDesc; } } foreach (WifiComponent wifiComponent in item.GetComponents <WifiComponent>()) { wifiComponent.TeamID = character.TeamID; } if (parentItem != null) { parentItem.Combine(item, user: null); } foreach (XElement childItemElement in itemElement.Elements()) { InitializeJobItem(character, childItemElement, spawnPoint, item); } }
public FabricationRecipe(XElement element, ItemPrefab itemPrefab) { TargetItem = itemPrefab; string displayName = element.GetAttributeString("displayname", ""); DisplayName = string.IsNullOrEmpty(displayName) ? itemPrefab.Name : TextManager.Get($"DisplayName.{displayName}"); SuitableFabricatorIdentifiers = element.GetAttributeStringArray("suitablefabricators", new string[0]); RequiredSkills = new List <Skill>(); RequiredTime = element.GetAttributeFloat("requiredtime", 1.0f); OutCondition = element.GetAttributeFloat("outcondition", 1.0f); RequiredItems = new List <RequiredItem>(); Amount = element.GetAttributeInt("amount", 1); foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "requiredskill": if (subElement.Attribute("name") != null) { DebugConsole.ThrowError("Error in fabricable item " + itemPrefab.Name + "! Use skill identifiers instead of names."); continue; } RequiredSkills.Add(new Skill( subElement.GetAttributeString("identifier", ""), subElement.GetAttributeInt("level", 0))); break; case "item": case "requireditem": string requiredItemIdentifier = subElement.GetAttributeString("identifier", ""); string requiredItemTag = subElement.GetAttributeString("tag", ""); if (string.IsNullOrWhiteSpace(requiredItemIdentifier) && string.IsNullOrEmpty(requiredItemTag)) { DebugConsole.ThrowError("Error in fabricable item " + itemPrefab.Name + "! One of the required items has no identifier or tag."); continue; } float minCondition = subElement.GetAttributeFloat("mincondition", 1.0f); //Substract mincondition from required item's condition or delete it regardless? bool useCondition = subElement.GetAttributeBool("usecondition", true); int count = subElement.GetAttributeInt("count", 1); if (!string.IsNullOrEmpty(requiredItemIdentifier)) { if (!(MapEntityPrefab.Find(null, requiredItemIdentifier.Trim()) is ItemPrefab requiredItem)) { DebugConsole.ThrowError("Error in fabricable item " + itemPrefab.Name + "! Required item \"" + requiredItemIdentifier + "\" not found."); continue; } var existing = RequiredItems.Find(r => r.ItemPrefabs.Count == 1 && r.ItemPrefabs[0] == requiredItem && MathUtils.NearlyEqual(r.MinCondition, minCondition)); if (existing == null) { RequiredItems.Add(new RequiredItem(requiredItem, count, minCondition, useCondition)); } else { existing.Amount += count; } } else { var matchingItems = ItemPrefab.Prefabs.Where(ip => ip.Tags.Any(t => t.Equals(requiredItemTag, StringComparison.OrdinalIgnoreCase))); if (!matchingItems.Any()) { DebugConsole.ThrowError("Error in fabricable item " + itemPrefab.Name + "! Could not find any items with the tag \"" + requiredItemTag + "\"."); continue; } var existing = RequiredItems.Find(r => r.ItemPrefabs.SequenceEqual(matchingItems) && MathUtils.NearlyEqual(r.MinCondition, minCondition)); if (existing == null) { RequiredItems.Add(new RequiredItem(matchingItems, count, minCondition, useCondition)); } else { existing.Amount += count; } } break; } } }
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", Config.VoiceChatVolume * 20.0f, 0); if (ConsoleArguments.Contains("-skipintro")) { Config.EnableSplashScreen = false; } if (Config.EnableSplashScreen) { var pendingSplashScreens = TitleScreen.PendingSplashScreens; float baseVolume = MathHelper.Clamp(Config.SoundVolume * 2.0f, 0.0f, 1.0f); pendingSplashScreens?.Enqueue(new Triplet <string, Point, float>("Content/Splash_UTG.mp4", new Point(1280, 720), baseVolume * 0.5f)); pendingSplashScreens?.Enqueue(new Triplet <string, Point, float>("Content/Splash_FF.mp4", new Point(1280, 720), baseVolume)); pendingSplashScreens?.Enqueue(new Triplet <string, Point, float>("Content/Splash_Daedalic.mp4", new Point(1920, 1080), baseVolume * 0.15f)); } //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.SelectedContentPackages, GraphicsDevice); DebugConsole.Init(); CrossThread.RequestExecutionOnMainThread(() => { if (Config.AutoUpdateWorkshopItems) { if (SteamManager.AutoUpdateWorkshopItems()) { ContentPackage.LoadAll(); Config.ReloadContentPackages(); } } }); if (SelectedPackages.None()) { DebugConsole.Log("No content packages selected"); } else { DebugConsole.Log("Selected content packages: " + string.Join(", ", SelectedPackages.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); Character.LoadAllConfigFiles(); MissionPrefab.Init(); TraitorMissionPrefab.Init(); MapEntityPrefab.Init(); Tutorials.Tutorial.Init(); MapGenerationParams.Init(); LevelGenerationParams.LoadPresets(); ScriptedEventSet.LoadPrefabs(); AfflictionPrefab.LoadAll(GetFilesOfType(ContentType.Afflictions)); TitleScreen.LoadState = 50.0f; yield return(CoroutineStatus.Running); StructurePrefab.LoadAll(GetFilesOfType(ContentType.Structure)); TitleScreen.LoadState = 53.0f; yield return(CoroutineStatus.Running); ItemPrefab.LoadAll(GetFilesOfType(ContentType.Item)); TitleScreen.LoadState = 55.0f; yield return(CoroutineStatus.Running); JobPrefab.LoadAll(GetFilesOfType(ContentType.Jobs)); NPCConversation.LoadAll(GetFilesOfType(ContentType.NPCConversations)); ItemAssemblyPrefab.LoadAll(); TitleScreen.LoadState = 60.0f; yield return(CoroutineStatus.Running); GameModePreset.Init(); Submarine.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); LobbyScreen = new LobbyScreen(); ServerListScreen = new ServerListScreen(); TitleScreen.LoadState = 70.0f; yield return(CoroutineStatus.Running); if (SteamManager.USE_STEAM) { SteamWorkshopScreen = new SteamWorkshopScreen(); if (SteamManager.IsInitialized) { SteamManager.Instance.Friends.OnInvitedToGame += OnInvitedToGame; SteamManager.Instance.Lobby.OnLobbyJoinRequested += OnLobbyJoinRequested; } } 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(); CharacterEditorScreen = new CharacterEditor.CharacterEditorScreen(); 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(); CheckContentPackage(); 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 GiveTreatment(float deltaTime) { if (targetCharacter == null) { string errorMsg = $"{character.Name}: Attempted to update a Rescue objective with no target!"; DebugConsole.ThrowError(errorMsg); Abandon = true; return; } SteeringManager?.Reset(); if (!targetCharacter.IsPlayer) { // If the target is a bot, don't let it move targetCharacter.AIController?.SteeringManager?.Reset(); } if (treatmentTimer > 0.0f) { treatmentTimer -= deltaTime; return; } treatmentTimer = TreatmentDelay; //find which treatments are the most suitable to treat the character's current condition targetCharacter.CharacterHealth.GetSuitableTreatments(currentTreatmentSuitabilities, normalize: false); //check if we already have a suitable treatment for any of the afflictions foreach (Affliction affliction in GetSortedAfflictions(targetCharacter)) { if (affliction == null) { throw new Exception("Affliction was null"); } if (affliction.Prefab == null) { throw new Exception("Affliction prefab was null"); } foreach (KeyValuePair <string, float> treatmentSuitability in affliction.Prefab.TreatmentSuitability) { if (currentTreatmentSuitabilities.ContainsKey(treatmentSuitability.Key) && currentTreatmentSuitabilities[treatmentSuitability.Key] > 0.0f) { Item matchingItem = character.Inventory.FindItemByIdentifier(treatmentSuitability.Key, true); if (matchingItem == null) { continue; } ApplyTreatment(affliction, matchingItem); //wait a bit longer after applying a treatment to wait for potential side-effects to manifest treatmentTimer = TreatmentDelay * 4; return; } } } // Find treatments outside of own inventory only if inside the own sub. if (character.Submarine != null && character.Submarine.TeamID == character.TeamID) { float cprSuitability = targetCharacter.Oxygen < 0.0f ? -targetCharacter.Oxygen * 100.0f : 0.0f; //didn't have any suitable treatments available, try to find some medical items if (currentTreatmentSuitabilities.Any(s => s.Value > cprSuitability)) { itemNameList.Clear(); suitableItemIdentifiers.Clear(); foreach (KeyValuePair <string, float> treatmentSuitability in currentTreatmentSuitabilities) { if (treatmentSuitability.Value <= cprSuitability) { continue; } if (MapEntityPrefab.Find(null, treatmentSuitability.Key, showErrorMessages: false) is ItemPrefab itemPrefab) { if (!Item.ItemList.Any(it => it.prefab.Identifier == treatmentSuitability.Key)) { continue; } suitableItemIdentifiers.Add(treatmentSuitability.Key); //only list the first 4 items if (itemNameList.Count < 4) { itemNameList.Add(itemPrefab.Name); } } } if (itemNameList.Count > 0) { string itemListStr = ""; if (itemNameList.Count == 1) { itemListStr = itemNameList[0]; } else { itemListStr = string.Join(" or ", string.Join(", ", itemNameList.Take(itemNameList.Count - 1)), itemNameList.Last()); } if (targetCharacter != character) { character.Speak(TextManager.GetWithVariables("DialogListRequiredTreatments", new string[2] { "[targetname]", "[treatmentlist]" }, new string[2] { targetCharacter.Name, itemListStr }, new bool[2] { false, true }), null, 2.0f, "listrequiredtreatments" + targetCharacter.Name, 60.0f); } character.DeselectCharacter(); RemoveSubObjective(ref getItemObjective); TryAddSubObjective(ref getItemObjective, constructor: () => new AIObjectiveGetItem(character, suitableItemIdentifiers.ToArray(), objectiveManager, equip: true, spawnItemIfNotFound: character.TeamID == Character.TeamType.FriendlyNPC), onCompleted: () => RemoveSubObjective(ref getItemObjective), onAbandon: () => RemoveSubObjective(ref getItemObjective)); } } } if (character != targetCharacter) { character.AnimController.Anim = AnimController.Animation.CPR; } }
public WayPoint(Rectangle newRect, Submarine submarine) : this(MapEntityPrefab.Find(null, "waypoint"), newRect, submarine) { }
private static bool IsThalamus(MapEntityPrefab entityPrefab, string tag) => entityPrefab.Category == MapEntityCategory.Thalamus || entityPrefab.Tags.Contains(tag);
private void InitializeItems(Character character, XElement itemElement, Submarine submarine, Item parentItem = null) { ItemPrefab itemPrefab; string itemIdentifier = itemElement.GetAttributeString("identifier", ""); itemPrefab = MapEntityPrefab.Find(null, itemIdentifier) as ItemPrefab; if (itemPrefab == null) { DebugConsole.ThrowError("Tried to spawn \"" + Identifier + "\" with the item \"" + itemIdentifier + "\". Matching item prefab not found."); return; } Item item = new Item(itemPrefab, character.Position, null); #if SERVER if (GameMain.Server != null && Entity.Spawner != null) { if (GameMain.Server.EntityEventManager.UniqueEvents.Any(ev => ev.Entity == item)) { string errorMsg = $"Error while spawning job items. Item {item.Name} created network events before the spawn event had been created."; DebugConsole.ThrowError(errorMsg); GameAnalyticsManager.AddErrorEventOnce("Job.InitializeJobItem:EventsBeforeSpawning", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); GameMain.Server.EntityEventManager.UniqueEvents.RemoveAll(ev => ev.Entity == item); GameMain.Server.EntityEventManager.Events.RemoveAll(ev => ev.Entity == item); } Entity.Spawner.CreateNetworkEvent(item, false); } #endif if (itemElement.GetAttributeBool("equip", false)) { List <InvSlotType> allowedSlots = new List <InvSlotType>(item.AllowedSlots); allowedSlots.Remove(InvSlotType.Any); character.Inventory.TryPutItem(item, null, allowedSlots); } else { character.Inventory.TryPutItem(item, null, item.AllowedSlots); } if (item.Prefab.Identifier == "idcard" || item.Prefab.Identifier == "idcardwreck") { item.AddTag("name:" + character.Name); item.ReplaceTag("wreck_id", Level.Loaded.GetWreckIDTag("wreck_id", submarine)); var job = character.Info?.Job; if (job != null) { item.AddTag("job:" + job.Name); } } foreach (WifiComponent wifiComponent in item.GetComponents <WifiComponent>()) { wifiComponent.TeamID = character.TeamID; } if (parentItem != null) { parentItem.Combine(item, user: null); } foreach (XElement childItemElement in itemElement.Elements()) { InitializeItems(character, childItemElement, submarine, item); } }
public ItemPrefab(XElement element, string filePath) { configFile = filePath; ConfigElement = element; OriginalName = element.GetAttributeString("name", ""); identifier = element.GetAttributeString("identifier", ""); //nameidentifier can be used to make multiple items use the same names and descriptions string nameIdentifier = element.GetAttributeString("nameidentifier", ""); if (string.IsNullOrEmpty(nameIdentifier)) { name = TextManager.Get("EntityName." + identifier, true) ?? OriginalName; } else { name = TextManager.Get("EntityName." + nameIdentifier, true) ?? OriginalName; } if (name == "") { DebugConsole.ThrowError("Unnamed item in " + filePath + "!"); } DebugConsole.Log(" " + name); Aliases = new HashSet <string> (element.GetAttributeStringArray("aliases", null, convertToLowerInvariant: true) ?? element.GetAttributeStringArray("Aliases", new string[0], convertToLowerInvariant: true)); Aliases.Add(OriginalName.ToLowerInvariant()); if (!Enum.TryParse(element.GetAttributeString("category", "Misc"), true, out MapEntityCategory category)) { category = MapEntityCategory.Misc; } Category = category; Triggers = new List <Rectangle>(); DeconstructItems = new List <DeconstructItem>(); FabricationRecipes = new List <FabricationRecipe>(); DeconstructTime = 1.0f; Tags = new HashSet <string>(element.GetAttributeStringArray("tags", new string[0], convertToLowerInvariant: true)); if (!Tags.Any()) { Tags = new HashSet <string>(element.GetAttributeStringArray("Tags", new string[0], convertToLowerInvariant: true)); } if (element.Attribute("cargocontainername") != null) { DebugConsole.ThrowError("Error in item prefab \"" + name + "\" - cargo container should be configured using the item's identifier, not the name."); } SerializableProperty.DeserializeProperties(this, element); string translatedDescription = ""; if (string.IsNullOrEmpty(nameIdentifier)) { translatedDescription = TextManager.Get("EntityDescription." + identifier, true); } else { translatedDescription = TextManager.Get("EntityDescription." + nameIdentifier, true); } if (!string.IsNullOrEmpty(translatedDescription)) { Description = translatedDescription; } foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "sprite": string spriteFolder = ""; if (!subElement.GetAttributeString("texture", "").Contains("/")) { spriteFolder = Path.GetDirectoryName(filePath); } canSpriteFlipX = subElement.GetAttributeBool("canflipx", true); canSpriteFlipY = subElement.GetAttributeBool("canflipy", true); sprite = new Sprite(subElement, spriteFolder, lazyLoad: true); if (subElement.Attribute("sourcerect") == null) { DebugConsole.ThrowError("Warning - sprite sourcerect not configured for item \"" + Name + "\"!"); } size = sprite.size; if (subElement.Attribute("name") == null && !string.IsNullOrWhiteSpace(Name)) { sprite.Name = Name; } sprite.EntityID = identifier; break; case "price": string locationType = subElement.GetAttributeString("locationtype", ""); if (prices == null) { prices = new Dictionary <string, PriceInfo>(); } prices[locationType.ToLowerInvariant()] = new PriceInfo(subElement); break; #if CLIENT case "inventoryicon": string iconFolder = ""; if (!subElement.GetAttributeString("texture", "").Contains("/")) { iconFolder = Path.GetDirectoryName(filePath); } InventoryIcon = new Sprite(subElement, iconFolder, lazyLoad: true); break; case "brokensprite": string brokenSpriteFolder = ""; if (!subElement.GetAttributeString("texture", "").Contains("/")) { brokenSpriteFolder = Path.GetDirectoryName(filePath); } var brokenSprite = new BrokenItemSprite( new Sprite(subElement, brokenSpriteFolder, lazyLoad: true), subElement.GetAttributeFloat("maxcondition", 0.0f), subElement.GetAttributeBool("fadein", false)); int spriteIndex = 0; for (int i = 0; i < BrokenSprites.Count && BrokenSprites[i].MaxCondition < brokenSprite.MaxCondition; i++) { spriteIndex = i; } BrokenSprites.Insert(spriteIndex, brokenSprite); break; case "decorativesprite": string decorativeSpriteFolder = ""; if (!subElement.GetAttributeString("texture", "").Contains("/")) { decorativeSpriteFolder = Path.GetDirectoryName(filePath); } int groupID = 0; DecorativeSprite decorativeSprite = null; if (subElement.Attribute("texture") == null) { groupID = subElement.GetAttributeInt("randomgroupid", 0); } else { decorativeSprite = new DecorativeSprite(subElement, decorativeSpriteFolder, lazyLoad: true); DecorativeSprites.Add(decorativeSprite); groupID = decorativeSprite.RandomGroupID; } if (!DecorativeSpriteGroups.ContainsKey(groupID)) { DecorativeSpriteGroups.Add(groupID, new List <DecorativeSprite>()); } DecorativeSpriteGroups[groupID].Add(decorativeSprite); break; case "containedsprite": string containedSpriteFolder = ""; if (!subElement.GetAttributeString("texture", "").Contains("/")) { containedSpriteFolder = Path.GetDirectoryName(filePath); } var containedSprite = new ContainedItemSprite(subElement, containedSpriteFolder, lazyLoad: true); if (containedSprite.Sprite != null) { ContainedSprites.Add(containedSprite); } break; #endif case "deconstruct": DeconstructTime = subElement.GetAttributeFloat("time", 1.0f); foreach (XElement deconstructItem in subElement.Elements()) { if (deconstructItem.Attribute("name") != null) { DebugConsole.ThrowError("Error in item config \"" + Name + "\" - use item identifiers instead of names to configure the deconstruct items."); continue; } DeconstructItems.Add(new DeconstructItem(deconstructItem)); } break; case "fabricate": case "fabricable": case "fabricableitem": fabricationRecipeElements.Add(subElement); break; case "trigger": Rectangle trigger = new Rectangle(0, 0, 10, 10) { X = subElement.GetAttributeInt("x", 0), Y = subElement.GetAttributeInt("y", 0), Width = subElement.GetAttributeInt("width", 0), Height = subElement.GetAttributeInt("height", 0) }; Triggers.Add(trigger); break; case "levelresource": foreach (XElement levelCommonnessElement in subElement.Elements()) { string levelName = levelCommonnessElement.GetAttributeString("levelname", "").ToLowerInvariant(); if (!LevelCommonness.ContainsKey(levelName)) { LevelCommonness.Add(levelName, levelCommonnessElement.GetAttributeFloat("commonness", 0.0f)); } } break; case "suitabletreatment": if (subElement.Attribute("name") != null) { DebugConsole.ThrowError("Error in item prefab \"" + Name + "\" - suitable treatments should be defined using item identifiers, not item names."); } string treatmentIdentifier = subElement.GetAttributeString("identifier", "").ToLowerInvariant(); List <AfflictionPrefab> matchingAfflictions = AfflictionPrefab.List.FindAll(a => a.Identifier == treatmentIdentifier || a.AfflictionType == treatmentIdentifier); if (matchingAfflictions.Count == 0) { DebugConsole.ThrowError("Error in item prefab \"" + Name + "\" - couldn't define as a treatment, no treatments with the identifier or type \"" + treatmentIdentifier + "\" were found."); continue; } float suitability = subElement.GetAttributeFloat("suitability", 0.0f); foreach (AfflictionPrefab matchingAffliction in matchingAfflictions) { if (matchingAffliction.TreatmentSuitability.ContainsKey(identifier)) { matchingAffliction.TreatmentSuitability[identifier] = Math.Max(matchingAffliction.TreatmentSuitability[identifier], suitability); } else { matchingAffliction.TreatmentSuitability.Add(identifier, suitability); } } break; } } if (sprite == null) { DebugConsole.ThrowError("Item \"" + Name + "\" has no sprite!"); #if SERVER sprite = new Sprite("", Vector2.Zero); sprite.SourceRect = new Rectangle(0, 0, 32, 32); #else sprite = new Sprite(TextureLoader.PlaceHolderTexture, null, null) { Origin = TextureLoader.PlaceHolderTexture.Bounds.Size.ToVector2() / 2 }; #endif size = sprite.size; sprite.EntityID = identifier; } if (!category.HasFlag(MapEntityCategory.Legacy) && string.IsNullOrEmpty(identifier)) { DebugConsole.ThrowError( "Item prefab \"" + name + "\" has no identifier. All item prefabs have a unique identifier string that's used to differentiate between items during saving and loading."); } if (!string.IsNullOrEmpty(identifier)) { MapEntityPrefab existingPrefab = List.Find(e => e.Identifier == identifier); if (existingPrefab != null) { DebugConsole.ThrowError( "Map entity prefabs \"" + name + "\" and \"" + existingPrefab.Name + "\" have the same identifier!"); } } AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList(); List.Add(this); }
private static bool IsThalamus(MapEntityPrefab entityPrefab, string tag) => entityPrefab.HasSubCategory("thalamus") || entityPrefab.Tags.Contains(tag);
public FabricationRecipe(XElement element, ItemPrefab itemPrefab) { TargetItem = itemPrefab; string displayName = element.GetAttributeString("displayname", ""); DisplayName = string.IsNullOrEmpty(displayName) ? itemPrefab.Name : TextManager.Get($"DisplayName.{displayName}"); SuitableFabricatorIdentifiers = element.GetAttributeStringArray("suitablefabricators", new string[0]); RequiredSkills = new List <Skill>(); RequiredTime = element.GetAttributeFloat("requiredtime", 1.0f); OutCondition = element.GetAttributeFloat("outcondition", 1.0f); RequiredItems = new List <RequiredItem>(); foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "requiredskill": if (subElement.Attribute("name") != null) { DebugConsole.ThrowError("Error in fabricable item " + itemPrefab.Name + "! Use skill identifiers instead of names."); continue; } RequiredSkills.Add(new Skill( subElement.GetAttributeString("identifier", ""), subElement.GetAttributeInt("level", 0))); break; case "item": case "requireditem": string requiredItemIdentifier = subElement.GetAttributeString("identifier", ""); if (string.IsNullOrWhiteSpace(requiredItemIdentifier)) { DebugConsole.ThrowError("Error in fabricable item " + itemPrefab.Name + "! One of the required items has no identifier."); continue; } float minCondition = subElement.GetAttributeFloat("mincondition", 1.0f); //Substract mincondition from required item's condition or delete it regardless? bool useCondition = subElement.GetAttributeBool("usecondition", true); int count = subElement.GetAttributeInt("count", 1); ItemPrefab requiredItem = MapEntityPrefab.Find(null, requiredItemIdentifier.Trim()) as ItemPrefab; if (requiredItem == null) { DebugConsole.ThrowError("Error in fabricable item " + itemPrefab.Name + "! Required item \"" + requiredItemIdentifier + "\" not found."); continue; } var existing = RequiredItems.Find(r => r.ItemPrefab == requiredItem); if (existing == null) { RequiredItems.Add(new RequiredItem(requiredItem, count, minCondition, useCondition)); } else { RequiredItems.Remove(existing); RequiredItems.Add(new RequiredItem(requiredItem, existing.Amount + count, minCondition, useCondition)); } break; } } }
public MapEntity(MapEntityPrefab prefab, Submarine submarine) : base(submarine) { this.prefab = prefab; }
public MapEntity(MapEntityPrefab prefab, Submarine submarine, ushort id) : base(submarine, id) { this.prefab = prefab; Scale = prefab != null ? prefab.Scale : 1; }
public override MapEntity Clone() { return(new Hull(MapEntityPrefab.Find(null, "hull"), rect, Submarine)); }
public static StructurePrefab Load(XElement element) { StructurePrefab sp = new StructurePrefab { name = element.GetAttributeString("name", "") }; sp.ConfigElement = element; if (string.IsNullOrEmpty(sp.name)) { sp.name = element.Name.ToString(); } sp.identifier = element.GetAttributeString("identifier", ""); string translatedName = TextManager.Get("EntityName." + sp.identifier, true); if (!string.IsNullOrEmpty(translatedName)) { sp.name = translatedName; } sp.Tags = new HashSet <string>(); string joinedTags = element.GetAttributeString("tags", ""); if (string.IsNullOrEmpty(joinedTags)) { joinedTags = element.GetAttributeString("Tags", ""); } foreach (string tag in joinedTags.Split(',')) { sp.Tags.Add(tag.Trim().ToLowerInvariant()); } foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString()) { case "sprite": sp.sprite = new Sprite(subElement, lazyLoad: true); if (subElement.Attribute("sourcerect") == null) { DebugConsole.ThrowError("Warning - sprite sourcerect not configured for structure \"" + sp.name + "\"!"); } if (subElement.GetAttributeBool("fliphorizontal", false)) { sp.sprite.effects = SpriteEffects.FlipHorizontally; } if (subElement.GetAttributeBool("flipvertical", false)) { sp.sprite.effects = SpriteEffects.FlipVertically; } sp.canSpriteFlipX = subElement.GetAttributeBool("canflipx", true); sp.canSpriteFlipY = subElement.GetAttributeBool("canflipy", true); if (subElement.Attribute("name") == null && !string.IsNullOrWhiteSpace(sp.Name)) { sp.sprite.Name = sp.Name; } sp.sprite.EntityID = sp.identifier; break; case "backgroundsprite": sp.BackgroundSprite = new Sprite(subElement, lazyLoad: true); if (subElement.Attribute("sourcerect") == null && sp.sprite != null) { sp.BackgroundSprite.SourceRect = sp.sprite.SourceRect; sp.BackgroundSprite.size = sp.sprite.size; sp.BackgroundSprite.size.X *= sp.sprite.SourceRect.Width; sp.BackgroundSprite.size.Y *= sp.sprite.SourceRect.Height; sp.BackgroundSprite.RelativeOrigin = subElement.GetAttributeVector2("origin", new Vector2(0.5f, 0.5f)); } if (subElement.GetAttributeBool("fliphorizontal", false)) { sp.BackgroundSprite.effects = SpriteEffects.FlipHorizontally; } if (subElement.GetAttributeBool("flipvertical", false)) { sp.BackgroundSprite.effects = SpriteEffects.FlipVertically; } break; } } if (!Enum.TryParse(element.GetAttributeString("category", "Structure"), true, out MapEntityCategory category)) { category = MapEntityCategory.Structure; } sp.Category = category; string aliases = element.GetAttributeString("aliases", ""); if (!string.IsNullOrWhiteSpace(aliases)) { sp.Aliases = aliases.Split(','); } SerializableProperty.DeserializeProperties(sp, element); if (sp.Body) { sp.Tags.Add("wall"); } string translatedDescription = TextManager.Get("EntityDescription." + sp.identifier, true); if (!string.IsNullOrEmpty(translatedDescription)) { sp.Description = translatedDescription; } //backwards compatibility if (element.Attribute("size") == null) { sp.size = Vector2.Zero; if (element.Attribute("width") == null && element.Attribute("height") == null) { sp.size.X = sp.sprite.SourceRect.Width; sp.size.Y = sp.sprite.SourceRect.Height; } else { sp.size.X = element.GetAttributeFloat("width", 0.0f); sp.size.Y = element.GetAttributeFloat("height", 0.0f); } } if (!category.HasFlag(MapEntityCategory.Legacy) && string.IsNullOrEmpty(sp.identifier)) { DebugConsole.ThrowError( "Structure prefab \"" + sp.name + "\" has no identifier. All structure prefabs have a unique identifier string that's used to differentiate between items during saving and loading."); } if (!string.IsNullOrEmpty(sp.identifier)) { MapEntityPrefab existingPrefab = List.Find(e => e.Identifier == sp.identifier); if (existingPrefab != null) { DebugConsole.ThrowError( "Map entity prefabs \"" + sp.name + "\" and \"" + existingPrefab.Name + "\" have the same identifier!"); } } return(sp); }