133 lines
4.6 KiB
C#
133 lines
4.6 KiB
C#
using Barotrauma.Items.Components;
|
|
using Microsoft.Xna.Framework;
|
|
|
|
namespace Barotrauma
|
|
{
|
|
abstract class ShipIssueWorker
|
|
{
|
|
public const float MaxImportance = 100f;
|
|
public const float MinImportance = 0f;
|
|
public Order SuggestedOrderPrefab { 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 string Option { get; set; }
|
|
public Character OrderedCharacter { get; set; }
|
|
public Order CurrentOrder { get; private set; }
|
|
public ItemComponent TargetItemComponent { get; protected set; }
|
|
public Item TargetItem { get; protected set; }
|
|
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 suggestedOrderPrefab, string option = null)
|
|
{
|
|
this.shipCommandManager = shipCommandManager;
|
|
SuggestedOrderPrefab = suggestedOrderPrefab;
|
|
Option = option;
|
|
}
|
|
|
|
public void SetOrder(Character orderedCharacter)
|
|
{
|
|
OrderedCharacter = orderedCharacter;
|
|
if (orderedCharacter != CommandingCharacter)
|
|
{
|
|
CommandingCharacter.Speak(SuggestedOrderPrefab.GetChatMessage(OrderedCharacter.Name, "", false));
|
|
}
|
|
|
|
// not sure if new orders are supposed to be created each time. TODO m61: check later
|
|
CurrentOrder = new Order(SuggestedOrderPrefab, TargetItem, TargetItemComponent, CommandingCharacter);
|
|
OrderedCharacter.SetOrder(CurrentOrder, Option, priority: 3, CommandingCharacter, CommandingCharacter != OrderedCharacter);
|
|
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()?.Order != CurrentOrder)
|
|
{
|
|
#if DEBUG
|
|
ShipCommandManager.ShipCommandLog($"Order {CurrentOrder.Name} did not match current order for character {OrderedCharacter} in {this}");
|
|
#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();
|
|
}
|
|
}
|