Merge remote-tracking branch 'upstream/master' into develop

This commit is contained in:
EvilFactory
2024-04-24 12:20:11 -03:00
397 changed files with 15250 additions and 6473 deletions
@@ -67,6 +67,10 @@ namespace Barotrauma
}
private AIObjective currentOrder;
public AIObjective ForcedOrder { get; private set; }
/// <summary>
/// Includes orders.
/// </summary>
public AIObjective CurrentObjective { get; private set; }
public AIObjectiveManager(Character character)
@@ -113,6 +117,8 @@ namespace Barotrauma
public Dictionary<AIObjective, CoroutineHandle> DelayedObjectives { get; private set; } = new Dictionary<AIObjective, CoroutineHandle>();
public bool FailedAutonomousObjectives { get; private set; }
public bool FailedToFindDivingGearForDepth;
private void ClearIgnored()
{
if (character.AIController is HumanAIController humanAi)
@@ -229,8 +235,11 @@ namespace Barotrauma
if (previousObjective == CurrentObjective) { return CurrentObjective; }
previousObjective?.OnDeselected();
CurrentObjective?.OnSelected();
GetObjective<AIObjectiveIdle>().CalculatePriority(Math.Max(CurrentObjective.Priority - 10, 0));
if (CurrentObjective != null)
{
CurrentObjective.OnSelected();
GetObjective<AIObjectiveIdle>().CalculatePriority(Math.Max(CurrentObjective.Priority - 10, 0));
}
if (GameMain.NetworkMember is { IsServer: true })
{
GameMain.NetworkMember.CreateEntityEvent(character,
@@ -239,9 +248,14 @@ namespace Barotrauma
return CurrentObjective;
}
/// <summary>
/// Returns the highest priority of the current objective and its subobjectives.
/// </summary>
public float GetCurrentPriority()
{
return CurrentObjective == null ? 0.0f : CurrentObjective.Priority;
if (CurrentObjective == null) { return 0; }
float subObjectivePriority = CurrentObjective.SubObjectives.Any() ? CurrentObjective.SubObjectives.Max(so => so.Priority) : 0;
return Math.Max(CurrentObjective.Priority, subObjectivePriority);
}
public void UpdateObjectives(float deltaTime)
@@ -250,7 +264,7 @@ namespace Barotrauma
if (CurrentOrders.Any())
{
foreach(var order in CurrentOrders)
foreach (var order in CurrentOrders)
{
var orderObjective = order.Objective;
UpdateOrderObjective(orderObjective);
@@ -405,6 +419,9 @@ namespace Barotrauma
}
}
//reset this here so the bots can retry finding a better suit if it's needed for the new order
FailedToFindDivingGearForDepth = false;
var newCurrentObjective = CreateObjective(order);
if (newCurrentObjective != null)
{
@@ -601,6 +618,9 @@ namespace Barotrauma
case "loaditems":
newObjective = new AIObjectiveLoadItems(character, this, order.Option, order.GetTargetItems(order.Option), order.TargetEntity as Item, priorityModifier);
break;
case "deconstructitems":
newObjective = new AIObjectiveDeconstructItems(character, this, priorityModifier);
break;
default:
if (order.TargetItemComponent == null) { return null; }
if (!order.TargetItemComponent.Item.IsInteractable(character)) { return null; }
@@ -622,6 +642,11 @@ namespace Barotrauma
return newObjective;
}
/// <summary>
/// Sets the order as dismissed, and enables the option to reissue the order on the crew list.
/// Note that this is not the same thing as just removing the order entirely!
/// </summary>
/// <param name="order"></param>
private void DismissSelf(Order order)
{
var currentOrder = CurrentOrders.FirstOrDefault(oi => oi.MatchesOrder(order.Identifier, order.Option));
@@ -660,13 +685,27 @@ namespace Barotrauma
return true;
}
/// <summary>
/// Only checks the current order. Deprecated, use pattern matching instead.
/// </summary>
public bool IsCurrentOrder<T>() where T : AIObjective => CurrentOrder is T;
/// <summary>
/// Checks the current objective (which can be an order too). Deprecated, use pattern matching instead.
/// </summary>
public bool IsCurrentObjective<T>() where T : AIObjective => CurrentObjective is T;
public bool IsActiveObjective<T>() where T : AIObjective => GetActiveObjective() is T;
public AIObjective GetActiveObjective() => CurrentObjective?.GetActiveObjective();
/// <summary>
/// Return the first order whose objective is of the given type. Can return null.
/// </summary>
public T GetOrder<T>() where T : AIObjective => CurrentOrders.FirstOrDefault(o => o.Objective is T)?.Objective as T;
/// <summary>
/// Return the first order with the specified objective. Can return null.
/// </summary>
public Order GetOrder(AIObjective objective) => CurrentOrders.FirstOrDefault(o => o.Objective == objective);
public T GetLastActiveObjective<T>() where T : AIObjective
=> CurrentObjective?.GetSubObjectivesRecursive(includingSelf: true).LastOrDefault(so => so is T) as T;
@@ -674,12 +713,12 @@ namespace Barotrauma
=> CurrentObjective?.GetSubObjectivesRecursive(includingSelf: true).FirstOrDefault(so => so is T) as T;
/// <summary>
/// Returns all active objectives of the specific type. Creates a new collection -> don't use too frequently.
/// Returns all active objectives of the specific type.
/// </summary>
public IEnumerable<T> GetActiveObjectives<T>() where T : AIObjective
{
if (CurrentObjective == null) { return Enumerable.Empty<T>(); }
return CurrentObjective.GetSubObjectivesRecursive(includingSelf: true).Where(so => so is T).Select(so => so as T);
return CurrentObjective.GetSubObjectivesRecursive(includingSelf: true).OfType<T>();
}
public bool HasActiveObjective<T>() where T : AIObjective => CurrentObjective is T || CurrentObjective != null && CurrentObjective.GetSubObjectivesRecursive().Any(so => so is T);