Unstable 0.17.0.0
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -23,7 +25,7 @@ namespace Barotrauma
|
||||
Legacy = 1024
|
||||
}
|
||||
|
||||
abstract partial class MapEntityPrefab : IPrefab, IDisposable
|
||||
abstract partial class MapEntityPrefab : PrefabWithUintIdentifier
|
||||
{
|
||||
public static IEnumerable<MapEntityPrefab> List
|
||||
{
|
||||
@@ -51,207 +53,15 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
protected string originalName;
|
||||
protected string identifier;
|
||||
|
||||
public Sprite sprite;
|
||||
//which prefab has been selected for placing
|
||||
public static MapEntityPrefab Selected { get; set; }
|
||||
|
||||
//the position where the structure is being placed (needed when stretching the structure)
|
||||
protected static Vector2 placePosition;
|
||||
|
||||
protected ConstructorInfo constructor;
|
||||
|
||||
//is it possible to stretch the entity horizontally/vertically
|
||||
[Serialize(false, false)]
|
||||
public bool ResizeHorizontal { get; protected set; }
|
||||
|
||||
[Serialize(false, false)]
|
||||
public bool ResizeVertical { get; protected set; }
|
||||
|
||||
//which prefab has been selected for placing
|
||||
protected static MapEntityPrefab selected;
|
||||
|
||||
public string OriginalName
|
||||
{
|
||||
get { return originalName; }
|
||||
}
|
||||
|
||||
public virtual string Name
|
||||
{
|
||||
get { return originalName; }
|
||||
}
|
||||
|
||||
public string GetItemNameTextId()
|
||||
{
|
||||
var textId = $"entityname.{Identifier}";
|
||||
return TextManager.ContainsTag(textId) ? textId : null;
|
||||
}
|
||||
|
||||
public string GetHullNameTextId()
|
||||
{
|
||||
var textId = $"roomname.{Identifier}";
|
||||
return TextManager.ContainsTag(textId) ? textId : null;
|
||||
}
|
||||
|
||||
//Used to differentiate between items when saving/loading
|
||||
//Allows changing the name of an item without breaking existing subs or having multiple items with the same name
|
||||
public string Identifier
|
||||
{
|
||||
get { return identifier; }
|
||||
}
|
||||
|
||||
public string FilePath { get; protected set; }
|
||||
|
||||
public ContentPackage ContentPackage { get; protected set; }
|
||||
|
||||
public HashSet<string> Tags
|
||||
{
|
||||
get;
|
||||
protected set;
|
||||
} = new HashSet<string>();
|
||||
|
||||
public static MapEntityPrefab Selected
|
||||
{
|
||||
get { return selected; }
|
||||
set { selected = value; }
|
||||
}
|
||||
|
||||
[Serialize("", false)]
|
||||
public string Description
|
||||
{
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
|
||||
[Serialize("", false)]
|
||||
public string AllowedUpgrades { get; set; }
|
||||
|
||||
[Serialize(false, false)]
|
||||
public bool HideInMenus { get; set; }
|
||||
|
||||
[Serialize("", false)]
|
||||
public string Subcategory { get; set; }
|
||||
|
||||
[Serialize(false, false)]
|
||||
public bool Linkable
|
||||
{
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Links defined to identifiers.
|
||||
/// </summary>
|
||||
public List<string> AllowedLinks { get; protected set; } = new List<string>();
|
||||
|
||||
public MapEntityCategory Category
|
||||
{
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
|
||||
[Serialize("1.0,1.0,1.0,1.0", false)]
|
||||
public Color SpriteColor
|
||||
{
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
|
||||
[Serialize(1f, true), Editable(0.1f, 10f, DecimalCount = 3)]
|
||||
public float Scale { get; protected set; }
|
||||
|
||||
//If a matching prefab is not found when loading a sub, the game will attempt to find a prefab with a matching alias.
|
||||
//(allows changing names while keeping backwards compatibility with older sub files)
|
||||
public HashSet<string> Aliases
|
||||
{
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
CoreEntityPrefab ep = new CoreEntityPrefab
|
||||
{
|
||||
identifier = "hull",
|
||||
originalName = TextManager.Get("EntityName.hull"),
|
||||
Description = TextManager.Get("EntityDescription.hull"),
|
||||
constructor = typeof(Hull).GetConstructor(new Type[] { typeof(MapEntityPrefab), typeof(Rectangle) }),
|
||||
ResizeHorizontal = true,
|
||||
ResizeVertical = true,
|
||||
Linkable = true
|
||||
};
|
||||
ep.AllowedLinks.Add("hull");
|
||||
ep.Aliases = new HashSet<string> { "hull" };
|
||||
CoreEntityPrefab.Prefabs.Add(ep, false);
|
||||
|
||||
ep = new CoreEntityPrefab
|
||||
{
|
||||
identifier = "gap",
|
||||
originalName = TextManager.Get("EntityName.gap"),
|
||||
Description = TextManager.Get("EntityDescription.gap"),
|
||||
constructor = typeof(Gap).GetConstructor(new Type[] { typeof(MapEntityPrefab), typeof(Rectangle) }),
|
||||
ResizeHorizontal = true,
|
||||
ResizeVertical = true
|
||||
};
|
||||
CoreEntityPrefab.Prefabs.Add(ep, false);
|
||||
ep.Aliases = new HashSet<string> { "gap" };
|
||||
|
||||
ep = new CoreEntityPrefab
|
||||
{
|
||||
identifier = "waypoint",
|
||||
originalName = TextManager.Get("EntityName.waypoint"),
|
||||
Description = TextManager.Get("EntityDescription.waypoint"),
|
||||
constructor = typeof(WayPoint).GetConstructor(new Type[] { typeof(MapEntityPrefab), typeof(Rectangle) })
|
||||
};
|
||||
CoreEntityPrefab.Prefabs.Add(ep, false);
|
||||
ep.Aliases = new HashSet<string> { "waypoint" };
|
||||
|
||||
ep = new CoreEntityPrefab
|
||||
{
|
||||
identifier = "spawnpoint",
|
||||
originalName = TextManager.Get("EntityName.spawnpoint"),
|
||||
Description = TextManager.Get("EntityDescription.spawnpoint"),
|
||||
constructor = typeof(WayPoint).GetConstructor(new Type[] { typeof(MapEntityPrefab), typeof(Rectangle) })
|
||||
};
|
||||
CoreEntityPrefab.Prefabs.Add(ep, false);
|
||||
ep.Aliases = new HashSet<string> { "spawnpoint" };
|
||||
}
|
||||
|
||||
public abstract void Dispose();
|
||||
|
||||
public MapEntityPrefab()
|
||||
{
|
||||
Category = MapEntityCategory.Structure;
|
||||
}
|
||||
|
||||
public string[] GetAllowedUpgrades()
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(AllowedUpgrades) ? new string[0] : AllowedUpgrades.Split(",");
|
||||
}
|
||||
|
||||
public bool HasSubCategory(string subcategory)
|
||||
{
|
||||
return subcategory?.Equals(this.Subcategory, StringComparison.OrdinalIgnoreCase) ?? false;
|
||||
}
|
||||
|
||||
protected virtual void CreateInstance(Rectangle rect)
|
||||
{
|
||||
if (constructor == null) return;
|
||||
object[] lobject = new object[] { this, rect };
|
||||
constructor.Invoke(lobject);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
public void DebugCreateInstance()
|
||||
{
|
||||
Rectangle rect = new Rectangle(new Point((int)Screen.Selected.Cam.WorldViewCenter.X, (int)Screen.Selected.Cam.WorldViewCenter.Y), new Point((int)Submarine.GridSize.X, (int)Submarine.GridSize.Y));
|
||||
CreateInstance(rect);
|
||||
}
|
||||
#endif
|
||||
|
||||
public static bool SelectPrefab(object selection)
|
||||
{
|
||||
if ((selected = selection as MapEntityPrefab) != null)
|
||||
if ((Selected = selection as MapEntityPrefab) != null)
|
||||
{
|
||||
placePosition = Vector2.Zero;
|
||||
return true;
|
||||
@@ -262,37 +72,45 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
//a method that allows the GUIListBoxes to check through a delegate if the entityprefab is still selected
|
||||
public static object GetSelected()
|
||||
{
|
||||
return (object)Selected;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find a matching map entity prefab
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the item (can be omitted when searching based on identifier)</param>
|
||||
/// <param name="identifier">The identifier of the item (if null, the identifier is ignored and the search is done only based on the name)</param>
|
||||
[Obsolete("Prefer MapEntityPrefab.FindByIdentifier or MapEntityPrefab.FindByName")]
|
||||
public static MapEntityPrefab Find(string name, string identifier = null, bool showErrorMessages = true)
|
||||
{
|
||||
if (name != null)
|
||||
{
|
||||
name = name.ToLowerInvariant();
|
||||
}
|
||||
return Find(name, (identifier ?? "").ToIdentifier(), showErrorMessages);
|
||||
}
|
||||
|
||||
[Obsolete("Prefer MapEntityPrefab.FindByIdentifier or MapEntityPrefab.FindByName")]
|
||||
public static MapEntityPrefab Find(string name, Identifier identifier, bool showErrorMessages = true)
|
||||
{
|
||||
//try to search based on identifier first
|
||||
if (string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(identifier))
|
||||
if (string.IsNullOrEmpty(name) && !identifier.IsEmpty)
|
||||
{
|
||||
foreach (MapEntityPrefab prefab in List)
|
||||
{
|
||||
if (prefab.identifier == identifier) { return prefab; }
|
||||
}
|
||||
if (CoreEntityPrefab.Prefabs.ContainsKey(identifier)) { return CoreEntityPrefab.Prefabs[identifier]; }
|
||||
if (StructurePrefab.Prefabs.ContainsKey(identifier)) { return StructurePrefab.Prefabs[identifier]; }
|
||||
if (ItemPrefab.Prefabs.ContainsKey(identifier)) { return ItemPrefab.Prefabs[identifier]; }
|
||||
if (ItemAssemblyPrefab.Prefabs.ContainsKey(identifier)) { return ItemAssemblyPrefab.Prefabs[identifier]; }
|
||||
}
|
||||
|
||||
foreach (MapEntityPrefab prefab in List)
|
||||
{
|
||||
if (identifier != null)
|
||||
if (!identifier.IsEmpty)
|
||||
{
|
||||
if (prefab.identifier != identifier)
|
||||
if (prefab.Identifier != identifier)
|
||||
{
|
||||
if (prefab.Aliases != null && prefab.Aliases.Any(a => a.Equals(identifier, StringComparison.OrdinalIgnoreCase)))
|
||||
if (prefab.Aliases != null && prefab.Aliases.Any(a => a == identifier))
|
||||
{
|
||||
return prefab;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
@@ -302,8 +120,8 @@ namespace Barotrauma
|
||||
}
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
if (prefab.Name.Equals(name, StringComparison.OrdinalIgnoreCase) ||
|
||||
prefab.originalName.Equals(name, StringComparison.OrdinalIgnoreCase) ||
|
||||
if (prefab.Name.Equals(name, StringComparison.OrdinalIgnoreCase) ||
|
||||
prefab.OriginalName.Equals(name, StringComparison.OrdinalIgnoreCase) ||
|
||||
(prefab.Aliases != null && prefab.Aliases.Any(a => a.Equals(name, StringComparison.OrdinalIgnoreCase))))
|
||||
{
|
||||
return prefab;
|
||||
@@ -332,28 +150,133 @@ namespace Barotrauma
|
||||
return List.FirstOrDefault(p => predicate(p));
|
||||
}
|
||||
|
||||
|
||||
public static MapEntityPrefab FindByName(string name)
|
||||
{
|
||||
if (name.IsNullOrEmpty()) { throw new ArgumentException($"{nameof(name)} must not be null or empty"); }
|
||||
|
||||
return Find(prefab =>
|
||||
prefab.Name.Equals(name, StringComparison.OrdinalIgnoreCase) ||
|
||||
prefab.OriginalName.Equals(name, StringComparison.OrdinalIgnoreCase) ||
|
||||
(prefab.Aliases != null &&
|
||||
prefab.Aliases.Any(a => a.Equals(name, StringComparison.OrdinalIgnoreCase))));
|
||||
}
|
||||
|
||||
public static MapEntityPrefab FindByIdentifier(Identifier identifier)
|
||||
=> CoreEntityPrefab.Prefabs.TryGet(identifier, out var corePrefab) ? corePrefab
|
||||
: ItemPrefab.Prefabs.TryGet(identifier, out var itemPrefab) ? itemPrefab
|
||||
: StructurePrefab.Prefabs.TryGet(identifier, out var structurePrefab) ? structurePrefab
|
||||
: ItemAssemblyPrefab.Prefabs.TryGet(identifier, out var itemAssemblyPrefab) ? itemAssemblyPrefab
|
||||
: (MapEntityPrefab)null;
|
||||
|
||||
public abstract Sprite Sprite { get; }
|
||||
|
||||
public abstract string OriginalName { get; }
|
||||
|
||||
public abstract LocalizedString Name { get; }
|
||||
|
||||
public abstract ImmutableHashSet<Identifier> Tags { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Links defined to identifiers.
|
||||
/// </summary>
|
||||
public abstract ImmutableHashSet<Identifier> AllowedLinks { get; }
|
||||
|
||||
public abstract MapEntityCategory Category { get; }
|
||||
|
||||
//If a matching prefab is not found when loading a sub, the game will attempt to find a prefab with a matching alias.
|
||||
//(allows changing names while keeping backwards compatibility with older sub files)
|
||||
public abstract ImmutableHashSet<string> Aliases { get; }
|
||||
|
||||
//is it possible to stretch the entity horizontally/vertically
|
||||
[Serialize(false, IsPropertySaveable.No)]
|
||||
public bool ResizeHorizontal { get; protected set; }
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No)]
|
||||
public bool ResizeVertical { get; protected set; }
|
||||
|
||||
[Serialize("", IsPropertySaveable.No)]
|
||||
public LocalizedString Description { get; protected set; }
|
||||
|
||||
[Serialize("", IsPropertySaveable.No)]
|
||||
public string AllowedUpgrades { get; protected set; }
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No)]
|
||||
public bool HideInMenus { get; protected set; }
|
||||
|
||||
[Serialize("", IsPropertySaveable.No)]
|
||||
public string Subcategory { get; protected set; }
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No)]
|
||||
public bool Linkable { get; protected set; }
|
||||
|
||||
[Serialize("1.0,1.0,1.0,1.0", IsPropertySaveable.No)]
|
||||
public Color SpriteColor { get; protected set; }
|
||||
|
||||
[Serialize(1f, IsPropertySaveable.Yes), Editable(0.1f, 10f, DecimalCount = 3)]
|
||||
public float Scale { get; protected set; }
|
||||
|
||||
protected MapEntityPrefab(Identifier identifier) : base(null, identifier) { }
|
||||
|
||||
public MapEntityPrefab(ContentXElement element, ContentFile file) : base(file, element) { }
|
||||
|
||||
public string GetItemNameTextId()
|
||||
{
|
||||
var textId = $"entityname.{Identifier}";
|
||||
return TextManager.ContainsTag(textId) ? textId : null;
|
||||
}
|
||||
|
||||
public string GetHullNameTextId()
|
||||
{
|
||||
var textId = $"roomname.{Identifier}";
|
||||
return TextManager.ContainsTag(textId) ? textId : null;
|
||||
}
|
||||
|
||||
private string cachedAllowedUpgrades = "";
|
||||
private ImmutableHashSet<Identifier> allowedUpgradeSet;
|
||||
public IEnumerable<Identifier> GetAllowedUpgrades()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(AllowedUpgrades)) { return Enumerable.Empty<Identifier>(); }
|
||||
if (allowedUpgradeSet is null || cachedAllowedUpgrades != AllowedUpgrades)
|
||||
{
|
||||
allowedUpgradeSet = AllowedUpgrades.Split(",").ToIdentifiers().ToImmutableHashSet();
|
||||
cachedAllowedUpgrades = AllowedUpgrades;
|
||||
}
|
||||
|
||||
return allowedUpgradeSet;
|
||||
}
|
||||
|
||||
public bool HasSubCategory(string subcategory)
|
||||
{
|
||||
return subcategory?.Equals(this.Subcategory, StringComparison.OrdinalIgnoreCase) ?? false;
|
||||
}
|
||||
|
||||
protected abstract void CreateInstance(Rectangle rect);
|
||||
|
||||
#if DEBUG
|
||||
public void DebugCreateInstance()
|
||||
{
|
||||
Rectangle rect = new Rectangle(new Point((int)Screen.Selected.Cam.WorldViewCenter.X, (int)Screen.Selected.Cam.WorldViewCenter.Y), new Point((int)Submarine.GridSize.X, (int)Submarine.GridSize.Y));
|
||||
CreateInstance(rect);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Check if the name or any of the aliases of this prefab match the given name.
|
||||
/// </summary>
|
||||
public bool NameMatches(string name, StringComparison comparisonType) => originalName.Equals(name, comparisonType) || (Aliases != null && Aliases.Any(a => a.Equals(name, comparisonType)));
|
||||
public bool NameMatches(string name, StringComparison comparisonType) => OriginalName.Equals(name, comparisonType) || (Aliases != null && Aliases.Any(a => a.Equals(name, comparisonType)));
|
||||
|
||||
public bool NameMatches(IEnumerable<string> allowedNames, StringComparison comparisonType) => allowedNames.Any(n => NameMatches(n, comparisonType));
|
||||
|
||||
public bool IsLinkAllowed(MapEntityPrefab target)
|
||||
{
|
||||
if (target == null) { return false; }
|
||||
if (target is StructurePrefab && AllowedLinks.Contains("structure")) { return true; }
|
||||
if (target is ItemPrefab && AllowedLinks.Contains("item")) { return true; }
|
||||
if (target is LinkedSubmarinePrefab && Tags.Contains("dock")) { return true; }
|
||||
if (this is LinkedSubmarinePrefab && target.Tags.Contains("dock")) { return true; }
|
||||
return AllowedLinks.Contains(target.Identifier) || target.AllowedLinks.Contains(identifier)
|
||||
|| target.Tags.Any(t => AllowedLinks.Contains(t)) || Tags.Any(t => target.AllowedLinks.Contains(t));
|
||||
}
|
||||
|
||||
//a method that allows the GUIListBoxes to check through a delegate if the entityprefab is still selected
|
||||
public static object GetSelected()
|
||||
{
|
||||
return (object)selected;
|
||||
if (target is StructurePrefab && AllowedLinks.Contains("structure".ToIdentifier())) { return true; }
|
||||
if (target is ItemPrefab && AllowedLinks.Contains("item".ToIdentifier())) { return true; }
|
||||
if (target is LinkedSubmarinePrefab && Tags.Contains("dock".ToIdentifier())) { return true; }
|
||||
if (this is LinkedSubmarinePrefab && target.Tags.Contains("dock".ToIdentifier())) { return true; }
|
||||
return AllowedLinks.Contains(target.Identifier) || target.AllowedLinks.Contains(Identifier)
|
||||
|| target.Tags.Any(t => AllowedLinks.Contains(t)) || Tags.Any(t => target.AllowedLinks.Contains(t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user