public static void LoadAll(IEnumerable <ContentFile> files) { CPRSettings.Unload(); InternalDamage = null; ImpactDamage = null; Bleeding = null; Burn = null; OxygenLow = null; Bloodloss = null; Pressure = null; Stun = null; #if CLIENT CharacterHealth.DamageOverlay?.Remove(); CharacterHealth.DamageOverlay = null; CharacterHealth.DamageOverlayFile = string.Empty; #endif var prevPrefabs = Prefabs.AllPrefabs.SelectMany(kvp => kvp.Value).ToList(); foreach (var prefab in prevPrefabs) { prefab?.Dispose(); } System.Diagnostics.Debug.Assert(Prefabs.Count() == 0, "All previous AfflictionPrefabs were not removed in AfflictionPrefab.LoadAll"); foreach (ContentFile file in files) { LoadFromFile(file); } if (InternalDamage == null) { DebugConsole.ThrowError("Affliction \"Internal Damage\" not defined in the affliction prefabs."); } if (Bleeding == null) { DebugConsole.ThrowError("Affliction \"Bleeding\" not defined in the affliction prefabs."); } if (Burn == null) { DebugConsole.ThrowError("Affliction \"Burn\" not defined in the affliction prefabs."); } if (OxygenLow == null) { DebugConsole.ThrowError("Affliction \"OxygenLow\" not defined in the affliction prefabs."); } if (Bloodloss == null) { DebugConsole.ThrowError("Affliction \"Bloodloss\" not defined in the affliction prefabs."); } if (Pressure == null) { DebugConsole.ThrowError("Affliction \"Pressure\" not defined in the affliction prefabs."); } if (Stun == null) { DebugConsole.ThrowError("Affliction \"Stun\" not defined in the affliction prefabs."); } }
public static void RemoveByFile(string filePath) { if (CPRSettings.FilePath == filePath) { CPRSettings.Unload(); } #if CLIENT if (CharacterHealth.DamageOverlayFile == filePath) { CharacterHealth.DamageOverlay?.Remove(); CharacterHealth.DamageOverlay = null; } #endif Prefabs.RemoveByFile(filePath); }
public static void LoadFromFile(ContentFile file) { XDocument doc = XMLExtensions.TryLoadXml(file.Path); if (doc == null) { return; } var mainElement = doc.Root.IsOverride() ? doc.Root.FirstElement() : doc.Root; if (doc.Root.IsOverride()) { DebugConsole.ThrowError("Cannot override all afflictions, because many of them are required by the main game! Please try overriding them one by one."); } foreach (XElement element in mainElement.Elements()) { bool isOverride = element.IsOverride(); XElement sourceElement = isOverride ? element.FirstElement() : element; string elementName = sourceElement.Name.ToString().ToLowerInvariant(); string identifier = sourceElement.GetAttributeString("identifier", null); if (!elementName.Equals("cprsettings", StringComparison.OrdinalIgnoreCase) && !elementName.Equals("damageoverlay", StringComparison.OrdinalIgnoreCase)) { if (string.IsNullOrWhiteSpace(identifier)) { DebugConsole.ThrowError($"No identifier defined for the affliction '{elementName}' in file '{file.Path}'"); continue; } if (Prefabs.ContainsKey(identifier)) { if (isOverride) { DebugConsole.NewMessage($"Overriding an affliction or a buff with the identifier '{identifier}' using the file '{file.Path}'", Color.Yellow); } else { DebugConsole.ThrowError($"Duplicate affliction: '{identifier}' defined in {elementName} of '{file.Path}'"); continue; } } } string type = sourceElement.GetAttributeString("type", ""); switch (sourceElement.Name.ToString().ToLowerInvariant()) { case "cprsettings": type = "cprsettings"; break; case "damageoverlay": type = "damageoverlay"; break; } AfflictionPrefab prefab = null; switch (type) { case "damageoverlay": #if CLIENT if (CharacterHealth.DamageOverlay != null) { if (isOverride) { DebugConsole.NewMessage($"Overriding damage overlay with '{file.Path}'", Color.Yellow); } else { DebugConsole.ThrowError($"Error in '{file.Path}': damage overlay already loaded. Add <override></override> tags as the parent of the custom damage overlay sprite to allow overriding the vanilla one."); break; } } CharacterHealth.DamageOverlay?.Remove(); CharacterHealth.DamageOverlay = new Sprite(element); CharacterHealth.DamageOverlayFile = file.Path; #endif break; case "bleeding": prefab = new AfflictionPrefab(sourceElement, file.Path, typeof(AfflictionBleeding)); break; case "huskinfection": prefab = new AfflictionPrefabHusk(sourceElement, file.Path, typeof(AfflictionHusk)); break; case "cprsettings": if (CPRSettings.IsLoaded) { if (isOverride) { DebugConsole.NewMessage($"Overriding the CPR settings with '{file.Path}'", Color.Yellow); } else { DebugConsole.ThrowError($"Error in '{file.Path}': CPR settings already loaded. Add <override></override> tags as the parent of the custom CPRSettings to allow overriding the vanilla values."); break; } } CPRSettings.Load(sourceElement, file.Path); break; case "damage": case "burn": case "oxygenlow": case "bloodloss": case "stun": case "pressure": case "internaldamage": prefab = new AfflictionPrefab(sourceElement, file.Path, typeof(Affliction)) { ContentPackage = file.ContentPackage }; break; default: prefab = new AfflictionPrefab(sourceElement, file.Path) { ContentPackage = file.ContentPackage }; break; } switch (identifier) { case "internaldamage": InternalDamage = prefab; break; case "bleeding": Bleeding = prefab; break; case "burn": Burn = prefab; break; case "oxygenlow": OxygenLow = prefab; break; case "bloodloss": Bloodloss = prefab; break; case "pressure": Pressure = prefab; break; case "stun": Stun = prefab; break; } if (prefab != null) { Prefabs.Add(prefab, isOverride); } } using MD5 md5 = MD5.Create(); foreach (AfflictionPrefab prefab in Prefabs) { prefab.UIntIdentifier = ToolBox.StringToUInt32Hash(prefab.Identifier, md5); //it's theoretically possible for two different values to generate the same hash, but the probability is astronomically small var collision = Prefabs.Find(p => p != prefab && p.UIntIdentifier == prefab.UIntIdentifier); if (collision != null) { DebugConsole.ThrowError("Hashing collision when generating uint identifiers for Afflictions: " + prefab.Identifier + " has the same identifier as " + collision.Identifier + " (" + prefab.UIntIdentifier + ")"); collision.UIntIdentifier++; } } }
public static void LoadAll(IEnumerable <string> filePaths) { foreach (string filePath in filePaths) { XDocument doc = XMLExtensions.TryLoadXml(filePath); if (doc == null || doc.Root == null) { continue; } foreach (XElement element in doc.Root.Elements()) { switch (element.Name.ToString().ToLowerInvariant()) { case "internaldamage": List.Add(InternalDamage = new AfflictionPrefab(element, typeof(Affliction))); break; case "bleeding": List.Add(Bleeding = new AfflictionPrefab(element, typeof(AfflictionBleeding))); break; case "burn": List.Add(Burn = new AfflictionPrefab(element, typeof(Affliction))); break; case "oxygenlow": List.Add(OxygenLow = new AfflictionPrefab(element, typeof(Affliction))); break; case "bloodloss": List.Add(Bloodloss = new AfflictionPrefab(element, typeof(Affliction))); break; case "pressure": List.Add(Pressure = new AfflictionPrefab(element, typeof(Affliction))); break; case "stun": List.Add(Stun = new AfflictionPrefab(element, typeof(Affliction))); break; case "husk": case "afflictionhusk": List.Add(Husk = new AfflictionPrefab(element, typeof(AfflictionHusk))); break; case "cprsettings": CPRSettings.Load(element); break; default: List.Add(new AfflictionPrefab(element)); break; } } } if (InternalDamage == null) { DebugConsole.ThrowError("Affliction \"Internal Damage\" not defined in the affliction prefabs."); } if (Bleeding == null) { DebugConsole.ThrowError("Affliction \"Bleeding\" not defined in the affliction prefabs."); } if (Burn == null) { DebugConsole.ThrowError("Affliction \"Burn\" not defined in the affliction prefabs."); } if (OxygenLow == null) { DebugConsole.ThrowError("Affliction \"OxygenLow\" not defined in the affliction prefabs."); } if (Bloodloss == null) { DebugConsole.ThrowError("Affliction \"Bloodloss\" not defined in the affliction prefabs."); } if (Pressure == null) { DebugConsole.ThrowError("Affliction \"Pressure\" not defined in the affliction prefabs."); } if (Stun == null) { DebugConsole.ThrowError("Affliction \"Stun\" not defined in the affliction prefabs."); } if (Husk == null) { DebugConsole.ThrowError("Affliction \"Husk\" not defined in the affliction prefabs."); } }
public static void LoadFromFile(ContentFile file) { XDocument doc = XMLExtensions.TryLoadXml(file.Path); if (doc == null) { return; } var mainElement = doc.Root.IsOverride() ? doc.Root.FirstElement() : doc.Root; if (doc.Root.IsOverride()) { DebugConsole.ThrowError("Cannot override all afflictions, because many of them are required by the main game! Please try overriding them one by one."); } List <(AfflictionPrefab prefab, XElement element)> loadedAfflictions = new List <(AfflictionPrefab prefab, XElement element)>(); foreach (XElement element in mainElement.Elements()) { bool isOverride = element.IsOverride(); XElement sourceElement = isOverride ? element.FirstElement() : element; string elementName = sourceElement.Name.ToString().ToLowerInvariant(); string identifier = sourceElement.GetAttributeString("identifier", null); if (!elementName.Equals("cprsettings", StringComparison.OrdinalIgnoreCase) && !elementName.Equals("damageoverlay", StringComparison.OrdinalIgnoreCase)) { if (string.IsNullOrWhiteSpace(identifier)) { DebugConsole.ThrowError($"No identifier defined for the affliction '{elementName}' in file '{file.Path}'"); continue; } if (Prefabs.ContainsKey(identifier)) { if (isOverride) { DebugConsole.NewMessage($"Overriding an affliction or a buff with the identifier '{identifier}' using the file '{file.Path}'", Color.Yellow); } else { DebugConsole.ThrowError($"Duplicate affliction: '{identifier}' defined in {elementName} of '{file.Path}'"); continue; } } } string type = sourceElement.GetAttributeString("type", ""); switch (sourceElement.Name.ToString().ToLowerInvariant()) { case "cprsettings": type = "cprsettings"; break; case "damageoverlay": type = "damageoverlay"; break; } AfflictionPrefab prefab = null; switch (type) { case "damageoverlay": #if CLIENT if (CharacterHealth.DamageOverlay != null) { if (isOverride) { DebugConsole.NewMessage($"Overriding damage overlay with '{file.Path}'", Color.Yellow); } else { DebugConsole.ThrowError($"Error in '{file.Path}': damage overlay already loaded. Add <override></override> tags as the parent of the custom damage overlay sprite to allow overriding the vanilla one."); break; } } CharacterHealth.DamageOverlay?.Remove(); CharacterHealth.DamageOverlay = new Sprite(element); CharacterHealth.DamageOverlayFile = file.Path; #endif break; case "bleeding": prefab = new AfflictionPrefab(sourceElement, file.Path, typeof(AfflictionBleeding)); break; case "huskinfection": case "alieninfection": prefab = new AfflictionPrefabHusk(sourceElement, file.Path, typeof(AfflictionHusk)); break; case "cprsettings": if (CPRSettings.IsLoaded) { if (isOverride) { DebugConsole.NewMessage($"Overriding the CPR settings with '{file.Path}'", Color.Yellow); } else { DebugConsole.ThrowError($"Error in '{file.Path}': CPR settings already loaded. Add <override></override> tags as the parent of the custom CPRSettings to allow overriding the vanilla values."); break; } } CPRSettings.Load(sourceElement, file.Path); break; case "damage": case "burn": case "oxygenlow": case "bloodloss": case "stun": case "pressure": case "internaldamage": prefab = new AfflictionPrefab(sourceElement, file.Path, typeof(Affliction)) { ContentPackage = file.ContentPackage }; break; default: prefab = new AfflictionPrefab(sourceElement, file.Path) { ContentPackage = file.ContentPackage }; break; } switch (identifier) { case "internaldamage": InternalDamage = prefab; break; case "blunttrauma": ImpactDamage = prefab; break; case "bleeding": Bleeding = prefab; break; case "burn": Burn = prefab; break; case "oxygenlow": OxygenLow = prefab; break; case "bloodloss": Bloodloss = prefab; break; case "pressure": Pressure = prefab; break; case "stun": Stun = prefab; break; case "radiationsickness": RadiationSickness = prefab; break; } if (ImpactDamage == null) { ImpactDamage = InternalDamage; } if (prefab != null) { loadedAfflictions.Add((prefab, sourceElement)); Prefabs.Add(prefab, isOverride); prefab.CalculatePrefabUIntIdentifier(Prefabs); } } //load the effects after all the afflictions in the file have been instantiated //otherwise afflictions can't inflict other afflictions that are defined at a later point in the file foreach ((AfflictionPrefab prefab, XElement element) in loadedAfflictions) { prefab.LoadEffects(element); } }
public static void LoadAll(IEnumerable <string> filePaths) { foreach (string filePath in filePaths) { XDocument doc = XMLExtensions.TryLoadXml(filePath); if (doc == null) { continue; } var mainElement = doc.Root.IsOverride() ? doc.Root.FirstElement() : doc.Root; if (doc.Root.IsOverride()) { DebugConsole.ThrowError("Cannot override all afflictions, because many of them are required by the main game! Please try overriding them one by one."); } foreach (XElement element in mainElement.Elements()) { bool isOverride = element.IsOverride(); XElement sourceElement = isOverride ? element.FirstElement() : element; string elementName = sourceElement.Name.ToString().ToLowerInvariant(); string identifier = sourceElement.GetAttributeString("identifier", null); if (!elementName.Equals("cprsettings", StringComparison.OrdinalIgnoreCase)) { if (string.IsNullOrWhiteSpace(identifier)) { DebugConsole.ThrowError($"No identifier defined for the affliction '{elementName}' in file '{filePath}'"); continue; } var duplicate = List.FirstOrDefault(a => a.Identifier == identifier); if (duplicate != null) { if (isOverride) { DebugConsole.NewMessage($"Overriding an affliction or a buff with the identifier '{identifier}' using the file '{filePath}'", Color.Yellow); List.Remove(duplicate); } else { DebugConsole.ThrowError($"Duplicate affliction: '{identifier}' defined in {elementName} of '{filePath}'"); continue; } } } string type = sourceElement.GetAttributeString("type", null); if (sourceElement.Name.ToString().ToLowerInvariant() == "cprsettings") { //backwards compatibility type = "cprsettings"; } AfflictionPrefab prefab = null; switch (type) { case "bleeding": prefab = new AfflictionPrefab(sourceElement, typeof(AfflictionBleeding)); break; case "huskinfection": prefab = new AfflictionPrefabHusk(sourceElement, typeof(AfflictionHusk)); break; case "cprsettings": if (CPRSettings.IsLoaded) { if (isOverride) { DebugConsole.NewMessage($"Overriding the CPR settings with '{filePath}'", Color.Yellow); } else { DebugConsole.ThrowError($"Error in '{filePath}': CPR settings already loaded. Add <override></override> tags as the parent of the custom CPRSettings to allow overriding the vanilla values."); break; } } CPRSettings.Load(sourceElement); break; case "damage": case "burn": case "oxygenlow": case "bloodloss": case "stun": case "pressure": case "internaldamage": prefab = new AfflictionPrefab(sourceElement, typeof(Affliction)); break; default: prefab = new AfflictionPrefab(sourceElement); break; } switch (identifier) { case "internaldamage": InternalDamage = prefab; break; case "bleeding": Bleeding = prefab; break; case "burn": Burn = prefab; break; case "oxygenlow": OxygenLow = prefab; break; case "bloodloss": Bloodloss = prefab; break; case "pressure": Pressure = prefab; break; case "stun": Stun = prefab; break; } if (prefab != null) { List.Add(prefab); } } } if (InternalDamage == null) { DebugConsole.ThrowError("Affliction \"Internal Damage\" not defined in the affliction prefabs."); } if (Bleeding == null) { DebugConsole.ThrowError("Affliction \"Bleeding\" not defined in the affliction prefabs."); } if (Burn == null) { DebugConsole.ThrowError("Affliction \"Burn\" not defined in the affliction prefabs."); } if (OxygenLow == null) { DebugConsole.ThrowError("Affliction \"OxygenLow\" not defined in the affliction prefabs."); } if (Bloodloss == null) { DebugConsole.ThrowError("Affliction \"Bloodloss\" not defined in the affliction prefabs."); } if (Pressure == null) { DebugConsole.ThrowError("Affliction \"Pressure\" not defined in the affliction prefabs."); } if (Stun == null) { DebugConsole.ThrowError("Affliction \"Stun\" not defined in the affliction prefabs."); } }