Unstable v0.1300.0.0 (February 19th 2021)
This commit is contained in:
@@ -19,27 +19,62 @@ namespace Barotrauma
|
||||
|
||||
struct OrderInfo
|
||||
{
|
||||
public string ComponentIdentifier { get; set; }
|
||||
public Order Order { get; private set; }
|
||||
public string OrderOption { get; private set; }
|
||||
public Order Order { get; }
|
||||
public string OrderOption { get; }
|
||||
public int ManualPriority { get; }
|
||||
public OrderType Type { get; }
|
||||
public AIObjective Objective { get; }
|
||||
public bool IsCurrentOrder => Type == OrderType.Current;
|
||||
|
||||
public OrderInfo(Order order, string orderOption)
|
||||
public enum OrderType
|
||||
{
|
||||
Current,
|
||||
Previous
|
||||
}
|
||||
|
||||
private OrderInfo(Order order, string orderOption, int manualPriority, OrderType orderType, AIObjective objective)
|
||||
{
|
||||
ComponentIdentifier = "currentorder";
|
||||
Order = order;
|
||||
OrderOption = orderOption;
|
||||
ManualPriority = Math.Min(manualPriority, CharacterInfo.HighestManualOrderPriority);
|
||||
Type = orderType;
|
||||
Objective = objective;
|
||||
}
|
||||
|
||||
public OrderInfo(OrderInfo orderInfo)
|
||||
{
|
||||
ComponentIdentifier = "previousorder";
|
||||
Order = orderInfo.Order;
|
||||
OrderOption = orderInfo.OrderOption;
|
||||
}
|
||||
public OrderInfo(Order order, string orderOption, int manualPriority) : this(order, orderOption, manualPriority, OrderType.Current, null) { }
|
||||
|
||||
public OrderInfo(Order order, string orderOption, int manualPriority, AIObjective objective) : this(order, orderOption, manualPriority, OrderType.Current, objective) { }
|
||||
|
||||
public OrderInfo(OrderInfo orderInfo, int manualPriority) : this(orderInfo.Order, orderInfo.OrderOption, manualPriority, orderInfo.Type, orderInfo.Objective) { }
|
||||
|
||||
public OrderInfo(OrderInfo orderInfo, OrderType type) : this(orderInfo.Order, orderInfo.OrderOption, orderInfo.ManualPriority, type, orderInfo.Objective) { }
|
||||
|
||||
public bool MatchesOrder(string orderIdentifier, string orderOption) =>
|
||||
(orderIdentifier == Order?.Identifier || (string.IsNullOrEmpty(orderIdentifier) && string.IsNullOrEmpty(Order?.Identifier))) &&
|
||||
(orderOption == OrderOption || (string.IsNullOrEmpty(orderOption) && string.IsNullOrEmpty(OrderOption)));
|
||||
|
||||
public bool MatchesOrder(Order order, string option) =>
|
||||
order.Identifier == Order.Identifier &&
|
||||
option == OrderOption;
|
||||
MatchesOrder(order?.Identifier, option);
|
||||
|
||||
public bool MatchesOrder(OrderInfo orderInfo) =>
|
||||
MatchesOrder(orderInfo.Order?.Identifier, orderInfo.OrderOption);
|
||||
|
||||
public bool MatchesDismissedOrder(string dismissOrderOption)
|
||||
{
|
||||
string[] dismissedOrder = dismissOrderOption?.Split('.');
|
||||
if (dismissedOrder != null && dismissedOrder.Length > 0)
|
||||
{
|
||||
string dismissedOrderIdentifier = dismissedOrder.Length > 0 ? dismissedOrder[0] : null;
|
||||
if (dismissedOrderIdentifier == null || dismissedOrderIdentifier != Order?.Identifier) { return false; }
|
||||
string dismissedOrderOption = dismissedOrder.Length > 1 ? dismissedOrder[1] : null;
|
||||
if (dismissedOrderOption == null && string.IsNullOrEmpty(OrderOption)) { return true; }
|
||||
return dismissedOrderOption == OrderOption;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Order
|
||||
@@ -59,6 +94,10 @@ namespace Barotrauma
|
||||
public Order Prefab { get; private set; }
|
||||
|
||||
public readonly string Name;
|
||||
/// <summary>
|
||||
/// Name that can be used with the contextual version of the order
|
||||
/// </summary>
|
||||
public readonly string ContextualName;
|
||||
|
||||
public readonly Sprite SymbolSprite;
|
||||
|
||||
@@ -97,7 +136,6 @@ namespace Barotrauma
|
||||
public bool TargetAllCharacters { get; }
|
||||
public bool IsReport => TargetAllCharacters && !MustSetTarget;
|
||||
|
||||
|
||||
public readonly float FadeOutTime;
|
||||
|
||||
public Entity TargetEntity;
|
||||
@@ -119,9 +157,9 @@ namespace Barotrauma
|
||||
private readonly Dictionary<string, Sprite> minimapIcons;
|
||||
public Dictionary<string, Sprite> MinimapIcons => IsPrefab ? minimapIcons : Prefab.minimapIcons;
|
||||
|
||||
public readonly float Weight;
|
||||
public readonly bool MustSetTarget;
|
||||
public readonly string AppropriateSkill;
|
||||
public readonly bool Hidden;
|
||||
|
||||
public bool HasOptions => (IsPrefab ? Options : Prefab.Options).Length > 1;
|
||||
public bool IsPrefab { get; private set; }
|
||||
@@ -159,6 +197,11 @@ namespace Barotrauma
|
||||
public int? WallSectionIndex { get; }
|
||||
public bool IsIgnoreOrder { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Should the order icon be drawn when the order target is inside a container
|
||||
/// </summary>
|
||||
public bool DrawIconWhenContained { get; }
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
Prefabs = new Dictionary<string, Order>();
|
||||
@@ -239,7 +282,8 @@ namespace Barotrauma
|
||||
private Order(XElement orderElement)
|
||||
{
|
||||
Identifier = orderElement.GetAttributeString("identifier", "");
|
||||
Name = TextManager.Get("OrderName." + Identifier, true) ?? "Name not found";
|
||||
Name = TextManager.Get("OrderName." + Identifier, returnNull: true) ?? "Name not found";
|
||||
ContextualName = TextManager.Get("OrderNameContextual." + Identifier, returnNull: true) ?? Name;
|
||||
|
||||
string targetItemType = orderElement.GetAttributeString("targetitemtype", "");
|
||||
if (!string.IsNullOrWhiteSpace(targetItemType))
|
||||
@@ -267,6 +311,7 @@ namespace Barotrauma
|
||||
if (!string.IsNullOrWhiteSpace(category)) { this.Category = (OrderCategory)Enum.Parse(typeof(OrderCategory), category, true); }
|
||||
MustSetTarget = orderElement.GetAttributeBool("mustsettarget", false);
|
||||
AppropriateSkill = orderElement.GetAttributeString("appropriateskill", null);
|
||||
Hidden = orderElement.GetAttributeBool("hidden", false);
|
||||
|
||||
var optionNames = TextManager.Get("OrderOptions." + Identifier, true)?.Split(',', ',') ??
|
||||
orderElement.GetAttributeStringArray("optionnames", new string[0]);
|
||||
@@ -315,6 +360,7 @@ namespace Barotrauma
|
||||
IsPrefab = true;
|
||||
MustManuallyAssign = orderElement.GetAttributeBool("mustmanuallyassign", false);
|
||||
IsIgnoreOrder = Identifier == "ignorethis" || Identifier == "unignorethis";
|
||||
DrawIconWhenContained = orderElement.GetAttributeBool("displayiconwhencontained", false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -324,23 +370,26 @@ namespace Barotrauma
|
||||
{
|
||||
Prefab = prefab.Prefab ?? prefab;
|
||||
|
||||
Name = prefab.Name;
|
||||
Identifier = prefab.Identifier;
|
||||
ItemComponentType = prefab.ItemComponentType;
|
||||
CanTypeBeSubclass = prefab.CanTypeBeSubclass;
|
||||
TargetItems = prefab.TargetItems;
|
||||
Options = prefab.Options;
|
||||
SymbolSprite = prefab.SymbolSprite;
|
||||
Color = prefab.Color;
|
||||
UseController = prefab.UseController;
|
||||
TargetAllCharacters = prefab.TargetAllCharacters;
|
||||
AppropriateJobs = prefab.AppropriateJobs;
|
||||
FadeOutTime = prefab.FadeOutTime;
|
||||
MustSetTarget = prefab.MustSetTarget;
|
||||
AppropriateSkill = prefab.AppropriateSkill;
|
||||
Category = prefab.Category;
|
||||
MustManuallyAssign = prefab.MustManuallyAssign;
|
||||
IsIgnoreOrder = prefab.IsIgnoreOrder;
|
||||
Name = prefab.Name;
|
||||
ContextualName = prefab.ContextualName;
|
||||
Identifier = prefab.Identifier;
|
||||
ItemComponentType = prefab.ItemComponentType;
|
||||
CanTypeBeSubclass = prefab.CanTypeBeSubclass;
|
||||
TargetItems = prefab.TargetItems;
|
||||
Options = prefab.Options;
|
||||
SymbolSprite = prefab.SymbolSprite;
|
||||
Color = prefab.Color;
|
||||
UseController = prefab.UseController;
|
||||
TargetAllCharacters = prefab.TargetAllCharacters;
|
||||
AppropriateJobs = prefab.AppropriateJobs;
|
||||
FadeOutTime = prefab.FadeOutTime;
|
||||
MustSetTarget = prefab.MustSetTarget;
|
||||
AppropriateSkill = prefab.AppropriateSkill;
|
||||
Category = prefab.Category;
|
||||
MustManuallyAssign = prefab.MustManuallyAssign;
|
||||
IsIgnoreOrder = prefab.IsIgnoreOrder;
|
||||
DrawIconWhenContained = prefab.DrawIconWhenContained;
|
||||
Hidden = prefab.Hidden;
|
||||
|
||||
OrderGiver = orderGiver;
|
||||
TargetEntity = targetEntity;
|
||||
@@ -351,9 +400,7 @@ namespace Barotrauma
|
||||
ConnectedController = targetItem.Item?.FindController();
|
||||
if (ConnectedController == null)
|
||||
{
|
||||
#if DEBUG
|
||||
throw new Exception("Tried to use controller, but couldn't find one");
|
||||
#endif
|
||||
DebugConsole.AddWarning("AI: Tried to use a controller for operating an item, but couldn't find any.");
|
||||
UseController = false;
|
||||
}
|
||||
}
|
||||
@@ -400,7 +447,7 @@ namespace Barotrauma
|
||||
orderOption ??= "";
|
||||
|
||||
string messageTag = (givingOrderToSelf && !TargetAllCharacters ? "OrderDialogSelf." : "OrderDialog.") + Identifier;
|
||||
if (!string.IsNullOrEmpty(orderOption)) { messageTag += "." + orderOption; }
|
||||
if (Identifier != "dismissed" && !string.IsNullOrEmpty(orderOption)) { messageTag += "." + orderOption; }
|
||||
|
||||
if (targetCharacterName == null) { targetCharacterName = ""; }
|
||||
if (targetRoomName == null) { targetRoomName = ""; }
|
||||
@@ -433,7 +480,8 @@ namespace Barotrauma
|
||||
return firstMatchingComponent != null;
|
||||
}
|
||||
|
||||
public List<Item> GetMatchingItems(Submarine submarine, bool mustBelongToPlayerSub, Character.TeamType? requiredTeam = null)
|
||||
/// <param name="interactableFor">Only returns items which are interactable for this character</param>
|
||||
public List<Item> GetMatchingItems(Submarine submarine, bool mustBelongToPlayerSub, CharacterTeamType? requiredTeam = null, Character interactableFor = null)
|
||||
{
|
||||
List<Item> matchingItems = new List<Item>();
|
||||
if (submarine == null) { return matchingItems; }
|
||||
@@ -456,16 +504,23 @@ namespace Barotrauma
|
||||
{
|
||||
matchingItems.RemoveAll(i => i.Components.None(c => c.GetType() == ItemComponentType) && !i.TryFindController(out _));
|
||||
}
|
||||
if (interactableFor != null)
|
||||
{
|
||||
matchingItems.RemoveAll(it => !it.IsInteractable(interactableFor) ||
|
||||
(UseController && it.FindController() is Controller c && !c.Item.IsInteractable(interactableFor)));
|
||||
}
|
||||
}
|
||||
return matchingItems;
|
||||
}
|
||||
|
||||
public List<Item> GetMatchingItems(bool mustBelongToPlayerSub)
|
||||
|
||||
/// <param name="interactableFor">Only returns items which are interactable for this character</param>
|
||||
public List<Item> GetMatchingItems(bool mustBelongToPlayerSub, Character interactableFor = null)
|
||||
{
|
||||
Submarine submarine = Character.Controlled != null && Character.Controlled.TeamID == Character.TeamType.Team2 && Submarine.MainSubs.Length > 1 ?
|
||||
Submarine submarine = Character.Controlled != null && Character.Controlled.TeamID == CharacterTeamType.Team2 && Submarine.MainSubs.Length > 1 ?
|
||||
Submarine.MainSubs[1] :
|
||||
Submarine.MainSub;
|
||||
return GetMatchingItems(submarine, mustBelongToPlayerSub);
|
||||
return GetMatchingItems(submarine, mustBelongToPlayerSub, interactableFor: interactableFor);
|
||||
}
|
||||
|
||||
public string GetOptionName(string id)
|
||||
@@ -478,5 +533,23 @@ namespace Barotrauma
|
||||
if (index < 0 || index >= Options.Length) { return null; }
|
||||
return GetOptionName(Options[index]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to create the order option for the Dismiss order to know which order it targets
|
||||
/// </summary>
|
||||
/// <param name="orderInfo">The order to target with the dismiss order</param>
|
||||
public static string GetDismissOrderOption(OrderInfo orderInfo)
|
||||
{
|
||||
if (orderInfo.Order != null)
|
||||
{
|
||||
string option = orderInfo.Order.Identifier;
|
||||
if (!string.IsNullOrEmpty(orderInfo.OrderOption))
|
||||
{
|
||||
option += $".{orderInfo.OrderOption}";
|
||||
}
|
||||
return option;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user