Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/ShipCommand/ShipIssueWorker.cs
T
Joonas Rikkonen c27e2ea5ab v0.14.6.0
2021-06-17 17:58:09 +03:00

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();
}
}