140 lines
5.1 KiB
C#
140 lines
5.1 KiB
C#
using Barotrauma.Items.Components;
|
|
using Barotrauma.Extensions;
|
|
using Microsoft.Xna.Framework;
|
|
|
|
namespace Barotrauma
|
|
{
|
|
abstract class ShipIssueWorker
|
|
{
|
|
public const float MaxImportance = 100f;
|
|
public const float MinImportance = 0f;
|
|
public Order SuggestedOrder { get; }
|
|
|
|
private float importance;
|
|
public float Importance
|
|
{
|
|
get
|
|
{
|
|
return importance;
|
|
}
|
|
set
|
|
{
|
|
importance = MathHelper.Clamp(value, MinImportance, MaxImportance);
|
|
}
|
|
}
|
|
public float CurrentRedundancy { get; set; }
|
|
|
|
public readonly ShipCommandManager shipCommandManager;
|
|
public Identifier Option => SuggestedOrder.Option;
|
|
public Character OrderedCharacter { get; set; }
|
|
public Order CurrentOrder { get; private set; }
|
|
public ItemComponent TargetItemComponent => SuggestedOrder.TargetItemComponent;
|
|
public Item TargetItem => SuggestedOrder.TargetEntity as Item;
|
|
public bool Active { get; protected set; } = true; // used to turn off the instance if errors are detected
|
|
|
|
protected virtual Character CommandingCharacter => shipCommandManager.character;
|
|
public virtual float TimeSinceLastAttempt { get; set; }
|
|
public virtual float RedundantIssueModifier => 0.5f;
|
|
public virtual bool StopDuringEmergency => true; // limit certain issue assessments when invaded by the enemies
|
|
public virtual bool AllowEasySwitching => false;
|
|
|
|
public ShipIssueWorker(ShipCommandManager shipCommandManager, Order suggestedOrder)
|
|
{
|
|
this.shipCommandManager = shipCommandManager;
|
|
SuggestedOrder = suggestedOrder;
|
|
}
|
|
|
|
public void SetOrder(Character orderedCharacter)
|
|
{
|
|
OrderedCharacter = orderedCharacter;
|
|
if (OrderedCharacter.AIController is HumanAIController humanAI &&
|
|
humanAI.ObjectiveManager.CurrentOrders.None(o => o.MatchesOrder(SuggestedOrder.Identifier, Option) && o.TargetEntity == TargetItem))
|
|
{
|
|
if (orderedCharacter != CommandingCharacter)
|
|
{
|
|
CommandingCharacter.Speak(SuggestedOrder.GetChatMessage(OrderedCharacter.Name, "", givingOrderToSelf: false), minDurationBetweenSimilar: 5);
|
|
}
|
|
CurrentOrder = SuggestedOrder
|
|
.WithOption(Option)
|
|
.WithItemComponent(TargetItem, TargetItemComponent)
|
|
.WithOrderGiver(CommandingCharacter)
|
|
.WithManualPriority(CharacterInfo.HighestManualOrderPriority);
|
|
OrderedCharacter.SetOrder(CurrentOrder, CommandingCharacter != OrderedCharacter);
|
|
OrderedCharacter.Speak(TextManager.Get("DialogAffirmative").Value, delay: 1.0f, minDurationBetweenSimilar: 5);
|
|
}
|
|
TimeSinceLastAttempt = 0f;
|
|
}
|
|
|
|
public void RemoveOrder()
|
|
{
|
|
OrderedCharacter = null;
|
|
CurrentOrder = null;
|
|
}
|
|
|
|
protected virtual bool IsIssueViable()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public float CalculateImportance(bool isEmergency)
|
|
{
|
|
Importance = 0f; // reset anything that needs resetting
|
|
|
|
if (!Active)
|
|
{
|
|
return Importance;
|
|
}
|
|
|
|
Active = IsIssueViable();
|
|
|
|
if (isEmergency && StopDuringEmergency)
|
|
{
|
|
return Importance;
|
|
}
|
|
|
|
CalculateImportanceSpecific();
|
|
|
|
// if there are other orders of the same type already being attended to, such as fixing leaks
|
|
// reduce the relative importance of this issue
|
|
CurrentRedundancy = 1f;
|
|
foreach (ShipIssueWorker shipIssueWorker in shipCommandManager.ShipIssueWorkers)
|
|
{
|
|
if (shipIssueWorker.GetType() == GetType() && shipIssueWorker != this && shipIssueWorker.OrderAttendedTo())
|
|
{
|
|
CurrentRedundancy *= RedundantIssueModifier;
|
|
}
|
|
}
|
|
Importance *= CurrentRedundancy;
|
|
|
|
return Importance;
|
|
}
|
|
|
|
public bool OrderAttendedTo(float timeSinceLastCheck = 0f)
|
|
{
|
|
if (!HumanAIController.IsActive(OrderedCharacter))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// accept only the highest priority order
|
|
if (CurrentOrder == null || OrderedCharacter.GetCurrentOrderWithTopPriority() != CurrentOrder)
|
|
{
|
|
#if DEBUG
|
|
ShipCommandManager.ShipCommandLog($"{this} is no longer the top priority of {OrderedCharacter}, considering the issue unattended.");
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
if (!shipCommandManager.AbleToTakeOrder(OrderedCharacter))
|
|
{
|
|
#if DEBUG
|
|
ShipCommandManager.ShipCommandLog(OrderedCharacter + " was unable to perform assigned order in " + this);
|
|
#endif
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
public abstract void CalculateImportanceSpecific();
|
|
}
|
|
}
|