(3bb9485ad) Add automatic orders as objectives instead of orders so that we can take advantage of the existing priority system. Turn the priority values defined in the xml into modifiers.

This commit is contained in:
Joonas Rikkonen
2019-05-16 05:04:53 +03:00
parent 5def53f7bd
commit d0795791e7
38 changed files with 172 additions and 105 deletions
@@ -136,6 +136,8 @@ namespace Barotrauma
public bool IgnoreLayoutGroups; public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public virtual ScalableFont Font public virtual ScalableFont Font
{ {
get; get;
@@ -59,6 +59,12 @@ namespace Barotrauma
Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 }; Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 };
Tag = tag; Tag = tag;
InnerFrame = new GUIFrame(new RectTransform(new Point(width, height), RectTransform, Anchor.Center) { IsFixedSize = false }, style: null);
GUI.Style.Apply(InnerFrame, "", this);
Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 };
Tag = tag;
if (height == 0) if (height == 0)
{ {
string wrappedText = ToolBox.WrapText(text, Content.Rect.Width, GUI.Font); string wrappedText = ToolBox.WrapText(text, Content.Rect.Width, GUI.Font);
@@ -105,6 +105,12 @@ namespace Barotrauma
return style; return style;
} }
public GUIComponentStyle GetComponentStyle(string name)
{
componentStyles.TryGetValue(name.ToLowerInvariant(), out GUIComponentStyle style);
return style;
}
public void Apply(GUIComponent targetComponent, string styleName = "", GUIComponent parent = null) public void Apply(GUIComponent targetComponent, string styleName = "", GUIComponent parent = null)
{ {
GUIComponentStyle componentStyle = null; GUIComponentStyle componentStyle = null;
@@ -178,6 +178,10 @@ namespace Barotrauma
GUI.KeyboardDispatcher = new EventInput.KeyboardDispatcher(Window); GUI.KeyboardDispatcher = new EventInput.KeyboardDispatcher(Window);
GUI.KeyboardDispatcher = new EventInput.KeyboardDispatcher(Window);
PerformanceCounter = new PerformanceCounter();
PerformanceCounter = new PerformanceCounter(); PerformanceCounter = new PerformanceCounter();
@@ -69,11 +69,6 @@ namespace Barotrauma
public CrewManager(XElement element, bool isSinglePlayer) public CrewManager(XElement element, bool isSinglePlayer)
: this(isSinglePlayer) : this(isSinglePlayer)
{
return characterListBox.Rect;
}
partial void InitProjectSpecific()
{ {
guiFrame = new GUIFrame(new RectTransform(Vector2.One, GUICanvas.Instance), null, Color.Transparent) guiFrame = new GUIFrame(new RectTransform(Vector2.One, GUICanvas.Instance), null, Color.Transparent)
{ {
@@ -181,16 +176,6 @@ namespace Barotrauma
ToolTip = order.Name ToolTip = order.Name
}; };
new GUIFrame(new RectTransform(new Vector2(1.5f), btn.RectTransform, Anchor.Center), "OuterGlow")
{
Color = Color.Red * 0.8f,
HoverColor = Color.Red * 1.0f,
PressedColor = Color.Red * 0.6f,
UserData = "highlighted",
CanBeFocused = false,
Visible = false
};
var characterInfo = new CharacterInfo(subElement); var characterInfo = new CharacterInfo(subElement);
characterInfos.Add(characterInfo); characterInfos.Add(characterInfo);
foreach (XElement invElement in subElement.Elements()) foreach (XElement invElement in subElement.Elements())
@@ -208,6 +193,16 @@ namespace Barotrauma
ToggleCrewAreaOpen = GameMain.Config.CrewMenuOpen; ToggleCrewAreaOpen = GameMain.Config.CrewMenuOpen;
} }
#endregion
#region Character list management
public Rectangle GetCharacterListArea()
{
return characterListBox.Rect;
}
partial void InitProjectSpecific() partial void InitProjectSpecific()
{ {
guiFrame = new GUIFrame(new RectTransform(Vector2.One, GUICanvas.Instance), null, Color.Transparent) guiFrame = new GUIFrame(new RectTransform(Vector2.One, GUICanvas.Instance), null, Color.Transparent)
@@ -729,7 +724,7 @@ namespace Barotrauma
characterListBox.BarScroll = roundedPos; characterListBox.BarScroll = roundedPos;
} }
ChatBox.AddMessage(ChatMessage.Create(senderName, text, messageType, sender)); return radioItem.GetComponent<WifiComponent>();
} }
private IEnumerable<object> KillCharacterAnim(GUIComponent component) private IEnumerable<object> KillCharacterAnim(GUIComponent component)
@@ -407,6 +407,33 @@ namespace Barotrauma
Color.Green, width: 2); Color.Green, width: 2);
} }
} }
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
} }
public static void UpdateVertices(GraphicsDevice graphicsDevice, Camera cam, WaterRenderer renderer) public static void UpdateVertices(GraphicsDevice graphicsDevice, Camera cam, WaterRenderer renderer)
@@ -18,11 +18,6 @@ namespace Barotrauma
private GUIListBox myItemList; private GUIListBox myItemList;
private GUIListBox storeItemList; private GUIListBox storeItemList;
private GUITextBox searchBox;
private GUIComponent missionPanel;
private GUIComponent selectedLocationInfo;
private GUIListBox selectedMissionInfo;
private GUIComponent missionPanel; private GUIComponent missionPanel;
private GUIComponent selectedLocationInfo; private GUIComponent selectedLocationInfo;
@@ -312,6 +312,25 @@ namespace Barotrauma
return true; return true;
}; };
playYourself = new GUITickBox(new RectTransform(new Vector2(0.06f, 0.06f), myCharacterFrame.RectTransform) { RelativeOffset = new Vector2(0.05f,0.05f) },
TextManager.Get("PlayYourself"))
{
Selected = true,
OnSelected = TogglePlayYourself,
UserData = "playyourself"
};
var toggleMyPlayerFrame = new GUIButton(new RectTransform(new Point(25, 70), myCharacterFrame.RectTransform, Anchor.TopLeft, Pivot.TopRight), "", style: "GUIButtonHorizontalArrow");
toggleMyPlayerFrame.OnClicked += (GUIButton btn, object userdata) =>
{
MyCharacterFrameOpen = !MyCharacterFrameOpen;
foreach (GUIComponent child in btn.Children)
{
child.SpriteEffects = MyCharacterFrameOpen ? SpriteEffects.FlipHorizontally : SpriteEffects.None;
}
return true;
};
playYourself = new GUITickBox(new RectTransform(new Vector2(0.06f, 0.06f), myCharacterFrame.RectTransform) { RelativeOffset = new Vector2(0.05f,0.05f) }, playYourself = new GUITickBox(new RectTransform(new Vector2(0.06f, 0.06f), myCharacterFrame.RectTransform) { RelativeOffset = new Vector2(0.05f,0.05f) },
TextManager.Get("PlayYourself")) TextManager.Get("PlayYourself"))
{ {
@@ -1052,6 +1052,8 @@ namespace Barotrauma
private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure; private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
//goes through all the AItargets, evaluates how preferable it is to attack the target, //goes through all the AItargets, evaluates how preferable it is to attack the target,
//whether the Character can see/hear the target and chooses the most preferable target within //whether the Character can see/hear the target and chooses the most preferable target within
//sight/hearing range //sight/hearing range
@@ -55,7 +55,6 @@ namespace Barotrauma
objectiveManager = new AIObjectiveManager(c); objectiveManager = new AIObjectiveManager(c);
objectiveManager.AddObjective(new AIObjectiveFindSafety(c)); objectiveManager.AddObjective(new AIObjectiveFindSafety(c));
objectiveManager.AddObjective(new AIObjectiveIdle(c)); objectiveManager.AddObjective(new AIObjectiveIdle(c));
// TODO: do this only when the player hasn't issued an order for a while
foreach (var automaticOrder in c.Info.Job.Prefab.AutomaticOrders) foreach (var automaticOrder in c.Info.Job.Prefab.AutomaticOrders)
{ {
var orderPrefab = Order.PrefabList.Find(o => o.AITag == automaticOrder.aiTag); var orderPrefab = Order.PrefabList.Find(o => o.AITag == automaticOrder.aiTag);
@@ -66,16 +65,8 @@ namespace Barotrauma
matchingItems.RemoveAll(it => it.Submarine != c.Submarine); matchingItems.RemoveAll(it => it.Submarine != c.Submarine);
var item = matchingItems.GetRandom(); var item = matchingItems.GetRandom();
var order = new Order(orderPrefab, item ?? c.CurrentHull as Entity, item?.Components.FirstOrDefault(ic => ic.GetType() == orderPrefab.ItemComponentType)); var order = new Order(orderPrefab, item ?? c.CurrentHull as Entity, item?.Components.FirstOrDefault(ic => ic.GetType() == orderPrefab.ItemComponentType));
SetOrder(order, automaticOrder.option, c, true); //SetOrder(order, automaticOrder.option, c, true);
objectiveManager.AddObjective(objectiveManager.CreateObjective(order, automaticOrder.option, c, automaticOrder.priorityModifier));
//#if CLIENT
// GameMain.GameSession?.CrewManager?.SetCharacterOrder(c, order, automaticOrder.option, c);
//#endif
// if (GameMain.GameSession?.CrewManager != null && GameMain.GameSession.CrewManager.AddOrder(order, order.FadeOutTime))
// {
// Character.Speak(order.GetChatMessage("", Character.CurrentHull?.RoomName, givingOrderToSelf: true), ChatMessageType.Order);
// }
} }
updateObjectiveTimer = Rand.Range(0.0f, UpdateObjectiveInterval); updateObjectiveTimer = Rand.Range(0.0f, UpdateObjectiveInterval);
@@ -16,6 +16,7 @@ namespace Barotrauma
protected readonly List<AIObjective> subObjectives = new List<AIObjective>(); protected readonly List<AIObjective> subObjectives = new List<AIObjective>();
public float Priority { get; set; } public float Priority { get; set; }
public float PriorityModifier { get; private set; }
protected readonly Character character; protected readonly Character character;
protected string option; protected string option;
protected bool abandon; protected bool abandon;
@@ -33,11 +34,11 @@ namespace Barotrauma
get { return option; } get { return option; }
} }
public AIObjective(Character character, string option) public AIObjective(Character character, string option, float priorityModifier)
{ {
this.character = character; this.character = character;
this.option = option; this.option = option;
PriorityModifier = priorityModifier;
#if DEBUG #if DEBUG
IsDuplicate(null); IsDuplicate(null);
#endif #endif
@@ -117,6 +118,7 @@ namespace Barotrauma
{ {
Priority += Devotion * deltaTime; Priority += Devotion * deltaTime;
} }
Priority *= PriorityModifier;
Priority = MathHelper.Clamp(Priority, 0, 100); Priority = MathHelper.Clamp(Priority, 0, 100);
subObjectives.ForEach(so => so.Update(objectiveManager, deltaTime)); subObjectives.ForEach(so => so.Update(objectiveManager, deltaTime));
} }
@@ -57,7 +57,7 @@ namespace Barotrauma
public CombatMode Mode { get; private set; } public CombatMode Mode { get; private set; }
public AIObjectiveCombat(Character character, Character enemy, CombatMode mode) : base(character, "") public AIObjectiveCombat(Character character, Character enemy, CombatMode mode, float priorityModifier = 1) : base(character, "", priorityModifier)
{ {
Enemy = enemy; Enemy = enemy;
coolDownTimer = CoolDown; coolDownTimer = CoolDown;
@@ -25,13 +25,9 @@ namespace Barotrauma
private AIObjectiveGetItem getItemObjective; private AIObjectiveGetItem getItemObjective;
private AIObjectiveGoTo goToObjective; private AIObjectiveGoTo goToObjective;
public AIObjectiveContainItem(Character character, string itemIdentifier, ItemContainer container) public AIObjectiveContainItem(Character character, string itemIdentifier, ItemContainer container, float priorityModifier = 1) : this(character, new string[] { itemIdentifier }, container, priorityModifier) { }
: this(character, new string[] { itemIdentifier }, container)
{
}
public AIObjectiveContainItem(Character character, string[] itemIdentifiers, ItemContainer container) public AIObjectiveContainItem(Character character, string[] itemIdentifiers, ItemContainer container, float priorityModifier = 1) : base (character, "", priorityModifier)
: base (character, "")
{ {
this.itemIdentifiers = itemIdentifiers; this.itemIdentifiers = itemIdentifiers;
for (int i = 0; i < itemIdentifiers.Length; i++) for (int i = 0; i < itemIdentifiers.Length; i++)
@@ -21,21 +21,16 @@ namespace Barotrauma
private AIObjectiveGoTo goToObjective; private AIObjectiveGoTo goToObjective;
private Item targetItem; private Item targetItem;
public AIObjectiveDecontainItem(Character character, Item targetItem, ItemContainer container) public AIObjectiveDecontainItem(Character character, Item targetItem, ItemContainer container, float priorityModifier = 1) : base(character, "", priorityModifier)
: base(character, "")
{ {
this.targetItem = targetItem; this.targetItem = targetItem;
this.container = container; this.container = container;
} }
public AIObjectiveDecontainItem(Character character, string itemIdentifier, ItemContainer container) public AIObjectiveDecontainItem(Character character, string itemIdentifier, ItemContainer container, float priorityModifier = 1) : this(character, new string[] { itemIdentifier }, container, priorityModifier) { }
: this(character, new string[] { itemIdentifier }, container)
{
}
public AIObjectiveDecontainItem(Character character, string[] itemIdentifiers, ItemContainer container) public AIObjectiveDecontainItem(Character character, string[] itemIdentifiers, ItemContainer container, float priorityModifier = 1) : base(character, "", priorityModifier)
: base(character, "")
{ {
this.itemIdentifiers = itemIdentifiers; this.itemIdentifiers = itemIdentifiers;
for (int i = 0; i < itemIdentifiers.Length; i++) for (int i = 0; i < itemIdentifiers.Length; i++)
@@ -20,7 +20,7 @@ namespace Barotrauma
private float useExtinquisherTimer; private float useExtinquisherTimer;
public AIObjectiveExtinguishFire(Character character, Hull targetHull) : base(character, "") public AIObjectiveExtinguishFire(Character character, Hull targetHull, float priorityModifier = 1) : base(character, "", priorityModifier)
{ {
this.targetHull = targetHull; this.targetHull = targetHull;
} }
@@ -13,7 +13,7 @@ namespace Barotrauma
private Dictionary<Hull, AIObjectiveExtinguishFire> extinguishObjectives = new Dictionary<Hull, AIObjectiveExtinguishFire>(); private Dictionary<Hull, AIObjectiveExtinguishFire> extinguishObjectives = new Dictionary<Hull, AIObjectiveExtinguishFire>();
public AIObjectiveExtinguishFires(Character character) : base(character, "") { } public AIObjectiveExtinguishFires(Character character, float priorityModifier = 1) : base(character, "", priorityModifier) { }
public override float GetPriority(AIObjectiveManager objectiveManager) public override float GetPriority(AIObjectiveManager objectiveManager)
{ {
@@ -29,7 +29,7 @@ namespace Barotrauma
return false; return false;
} }
public AIObjectiveFindDivingGear(Character character, bool needDivingSuit) : base(character, "") public AIObjectiveFindDivingGear(Character character, bool needDivingSuit, float priorityModifier = 1) : base(character, "", priorityModifier)
{ {
gearTag = needDivingSuit ? "divingsuit" : "diving"; gearTag = needDivingSuit ? "divingsuit" : "diving";
} }
@@ -27,7 +27,7 @@ namespace Barotrauma
private AIObjectiveGoTo goToObjective; private AIObjectiveGoTo goToObjective;
private AIObjectiveFindDivingGear divingGearObjective; private AIObjectiveFindDivingGear divingGearObjective;
public AIObjectiveFindSafety(Character character) : base(character, "") { } public AIObjectiveFindSafety(Character character, float priorityModifier = 1) : base(character, "", priorityModifier) { }
public override bool IsCompleted() => false; public override bool IsCompleted() => false;
public override bool CanBeCompleted => true; public override bool CanBeCompleted => true;
@@ -24,7 +24,7 @@ namespace Barotrauma
get { return leak; } get { return leak; }
} }
public AIObjectiveFixLeak(Gap leak, Character character) : base (character, "") public AIObjectiveFixLeak(Gap leak, Character character, float priorityModifier = 1) : base (character, "", priorityModifier)
{ {
this.leak = leak; this.leak = leak;
} }
@@ -12,7 +12,7 @@ namespace Barotrauma
public override bool KeepDivingGearOn => true; public override bool KeepDivingGearOn => true;
public override bool ForceRun => true; public override bool ForceRun => true;
public AIObjectiveFixLeaks(Character character) : base (character, "") { } public AIObjectiveFixLeaks(Character character, float priorityModifier = 1) : base(character, "", priorityModifier) { }
public override float GetPriority(AIObjectiveManager objectiveManager) public override float GetPriority(AIObjectiveManager objectiveManager)
{ {
@@ -36,16 +36,16 @@ namespace Barotrauma
return 1.0f; return 1.0f;
} }
public AIObjectiveGetItem(Character character, Item targetItem, bool equip = false) : base(character, "") public AIObjectiveGetItem(Character character, Item targetItem, bool equip = false, float priorityModifier = 1) : base(character, "", priorityModifier)
{ {
currSearchIndex = -1; currSearchIndex = -1;
this.equip = equip; this.equip = equip;
this.targetItem = targetItem; this.targetItem = targetItem;
} }
public AIObjectiveGetItem(Character character, string itemIdentifier, bool equip = false) : this(character, new string[] { itemIdentifier }, equip) { } public AIObjectiveGetItem(Character character, string itemIdentifier, bool equip = false, float priorityModifier = 1) : this(character, new string[] { itemIdentifier }, equip, priorityModifier) { }
public AIObjectiveGetItem(Character character, string[] itemIdentifiers, bool equip = false) : base(character, "") public AIObjectiveGetItem(Character character, string[] itemIdentifiers, bool equip = false, float priorityModifier = 1) : base(character, "", priorityModifier)
{ {
currSearchIndex = -1; currSearchIndex = -1;
this.equip = equip; this.equip = equip;
@@ -84,8 +84,7 @@ namespace Barotrauma
public bool FollowControlledCharacter; public bool FollowControlledCharacter;
public AIObjectiveGoTo(Entity target, Character character, bool repeat = false, bool getDivingGearIfNeeded = true) public AIObjectiveGoTo(Entity target, Character character, bool repeat = false, bool getDivingGearIfNeeded = true, float priorityModifier = 1) : base (character, "", priorityModifier)
: base (character, "")
{ {
this.Target = target; this.Target = target;
this.repeat = repeat; this.repeat = repeat;
@@ -96,8 +95,7 @@ namespace Barotrauma
} }
public AIObjectiveGoTo(Vector2 simPos, Character character, bool repeat = false, bool getDivingGearIfNeeded = true) public AIObjectiveGoTo(Vector2 simPos, Character character, bool repeat = false, bool getDivingGearIfNeeded = true, float priorityModifier = 1) : base(character, "", priorityModifier)
: base(character, "")
{ {
this.targetPos = simPos; this.targetPos = simPos;
this.repeat = repeat; this.repeat = repeat;
@@ -29,7 +29,7 @@ namespace Barotrauma
private readonly List<Hull> targetHulls = new List<Hull>(20); private readonly List<Hull> targetHulls = new List<Hull>(20);
private readonly List<float> hullWeights = new List<float>(20); private readonly List<float> hullWeights = new List<float>(20);
public AIObjectiveIdle(Character character) : base(character, "") public AIObjectiveIdle(Character character, float priorityModifier = 1) : base(character, "", priorityModifier)
{ {
standStillTimer = Rand.Range(-10.0f, 10.0f); standStillTimer = Rand.Range(-10.0f, 10.0f);
walkDuration = Rand.Range(0.0f, 10.0f); walkDuration = Rand.Range(0.0f, 10.0f);
@@ -17,7 +17,7 @@ namespace Barotrauma
protected virtual float IgnoreListClearInterval => 0; protected virtual float IgnoreListClearInterval => 0;
protected virtual float TargetUpdateInterval => 2; protected virtual float TargetUpdateInterval => 2;
public AIObjectiveLoop(Character character, string option) : base(character, option) public AIObjectiveLoop(Character character, string option, float priorityModifier = 1) : base(character, option, priorityModifier)
{ {
Reset(); Reset();
} }
@@ -144,13 +144,17 @@ namespace Barotrauma
public void SetOrder(Order order, string option, Character orderGiver) public void SetOrder(Order order, string option, Character orderGiver)
{ {
CurrentOrder = null; CurrentOrder = CreateObjective(order, option, orderGiver);
if (order == null) return; }
public AIObjective CreateObjective(Order order, string option, Character orderGiver, float priorityModifier = 1)
{
if (order == null) { return null; }
AIObjective newObjective;
switch (order.AITag.ToLowerInvariant()) switch (order.AITag.ToLowerInvariant())
{ {
case "follow": case "follow":
CurrentOrder = new AIObjectiveGoTo(orderGiver, character, true) newObjective = new AIObjectiveGoTo(orderGiver, character, true, priorityModifier: priorityModifier)
{ {
CloseEnough = 1.5f, CloseEnough = 1.5f,
AllowGoingOutside = true, AllowGoingOutside = true,
@@ -159,40 +163,41 @@ namespace Barotrauma
}; };
break; break;
case "wait": case "wait":
CurrentOrder = new AIObjectiveGoTo(character, character, true) newObjective = new AIObjectiveGoTo(character, character, true, priorityModifier: priorityModifier)
{ {
AllowGoingOutside = true AllowGoingOutside = true
}; };
break; break;
case "fixleaks": case "fixleaks":
CurrentOrder = new AIObjectiveFixLeaks(character); newObjective = new AIObjectiveFixLeaks(character, priorityModifier: priorityModifier);
break; break;
case "chargebatteries": case "chargebatteries":
CurrentOrder = new AIObjectiveChargeBatteries(character, option); newObjective = new AIObjectiveChargeBatteries(character, option);
break; break;
case "rescue": case "rescue":
CurrentOrder = new AIObjectiveRescueAll(character); newObjective = new AIObjectiveRescueAll(character, priorityModifier: priorityModifier);
break; break;
case "repairsystems": case "repairsystems":
CurrentOrder = new AIObjectiveRepairItems(character) { RequireAdequateSkills = option != "all" }; newObjective = new AIObjectiveRepairItems(character, priorityModifier: priorityModifier) { RequireAdequateSkills = option != "all" };
break; break;
case "pumpwater": case "pumpwater":
CurrentOrder = new AIObjectivePumpWater(character, option); newObjective = new AIObjectivePumpWater(character, option, priorityModifier: priorityModifier);
break; break;
case "extinguishfires": case "extinguishfires":
CurrentOrder = new AIObjectiveExtinguishFires(character); newObjective = new AIObjectiveExtinguishFires(character, priorityModifier: priorityModifier);
break; break;
case "steer": case "steer":
var steering = (order?.TargetEntity as Item)?.GetComponent<Steering>(); var steering = (order?.TargetEntity as Item)?.GetComponent<Steering>();
if (steering != null) steering.PosToMaintain = steering.Item.Submarine?.WorldPosition; if (steering != null) steering.PosToMaintain = steering.Item.Submarine?.WorldPosition;
if (order.TargetItemComponent == null) return; if (order.TargetItemComponent == null) { return null; }
CurrentOrder = new AIObjectiveOperateItem(order.TargetItemComponent, character, option, false, null, order.UseController); newObjective = new AIObjectiveOperateItem(order.TargetItemComponent, character, option, false, null, order.UseController, priorityModifier: priorityModifier);
break; break;
default: default:
if (order.TargetItemComponent == null) return; if (order.TargetItemComponent == null) { return null; }
CurrentOrder = new AIObjectiveOperateItem(order.TargetItemComponent, character, option, false, null, order.UseController); newObjective = new AIObjectiveOperateItem(order.TargetItemComponent, character, option, false, null, order.UseController, priorityModifier: priorityModifier);
break; break;
} }
return newObjective;
} }
} }
} }
@@ -52,8 +52,7 @@ namespace Barotrauma
return base.GetPriority(objectiveManager); return base.GetPriority(objectiveManager);
} }
public AIObjectiveOperateItem(ItemComponent item, Character character, string option, bool requireEquip, Entity operateTarget = null, bool useController = false) public AIObjectiveOperateItem(ItemComponent item, Character character, string option, bool requireEquip, Entity operateTarget = null, bool useController = false, float priorityModifier = 1) : base (character, option, priorityModifier)
: base (character, option)
{ {
this.component = item ?? throw new System.ArgumentNullException("item", "Attempted to create an AIObjectiveOperateItem with a null target."); this.component = item ?? throw new System.ArgumentNullException("item", "Attempted to create an AIObjectiveOperateItem with a null target.");
this.requireEquip = requireEquip; this.requireEquip = requireEquip;
@@ -10,7 +10,7 @@ namespace Barotrauma
public override bool KeepDivingGearOn => true; public override bool KeepDivingGearOn => true;
private readonly IEnumerable<Pump> pumpList; private readonly IEnumerable<Pump> pumpList;
public AIObjectivePumpWater(Character character, string option) : base(character, option) public AIObjectivePumpWater(Character character, string option, float priorityModifier = 1) : base(character, option, priorityModifier)
{ {
pumpList = character.Submarine.GetItems(true).Select(i => i.GetComponent<Pump>()).Where(p => p != null); pumpList = character.Submarine.GetItems(true).Select(i => i.GetComponent<Pump>()).Where(p => p != null);
} }
@@ -19,7 +19,7 @@ namespace Barotrauma
private float previousCondition = -1; private float previousCondition = -1;
public AIObjectiveRepairItem(Character character, Item item) : base(character, "") public AIObjectiveRepairItem(Character character, Item item, float priorityModifier = 1) : base(character, "", priorityModifier)
{ {
Item = item; Item = item;
} }
@@ -114,7 +114,7 @@ namespace Barotrauma
{ {
// If the current condition is less than the previous condition, we can't complete the task, so let's abandon it. The item is probably deteriorating at a greater speed than we can repair it. // If the current condition is less than the previous condition, we can't complete the task, so let's abandon it. The item is probably deteriorating at a greater speed than we can repair it.
abandon = true; abandon = true;
character?.Speak(TextManager.Get("DialogRepairFailed").Replace("[itemname]", Item.Name), null, 0.0f, "repairfailed", 10.0f); character?.Speak(TextManager.Get("DialogCannotRepair").Replace("[itemname]", Item.Name), null, 0.0f, "cannotrepair", 10.0f);
} }
} }
repairable.CurrentFixer = abandon && repairable.CurrentFixer == character ? null : character; repairable.CurrentFixer = abandon && repairable.CurrentFixer == character ? null : character;
@@ -14,9 +14,8 @@ namespace Barotrauma
/// </summary> /// </summary>
public bool RequireAdequateSkills; public bool RequireAdequateSkills;
public AIObjectiveRepairItems(Character character) : base(character, "") { } public AIObjectiveRepairItems(Character character, float priorityModifier = 1) : base(character, "", priorityModifier) { }
// TODO: This can allow two active repair items objectives, if RequireAdequateSkills is not at the same value. We don't want that.
public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveRepairItems repairItems && repairItems.RequireAdequateSkills == RequireAdequateSkills; public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveRepairItems repairItems && repairItems.RequireAdequateSkills == RequireAdequateSkills;
protected override void CreateObjectives() protected override void CreateObjectives()
@@ -37,8 +37,7 @@ namespace Barotrauma
} }
} }
public AIObjectiveRescue(Character character, Character targetCharacter) public AIObjectiveRescue(Character character, Character targetCharacter, float priorityModifier = 1) : base(character, "", priorityModifier)
: base(character, "")
{ {
Debug.Assert(character != targetCharacter); Debug.Assert(character != targetCharacter);
this.targetCharacter = targetCharacter; this.targetCharacter = targetCharacter;
@@ -15,7 +15,7 @@ namespace Barotrauma
private List<Character> rescueTargets; private List<Character> rescueTargets;
public AIObjectiveRescueAll(Character character) : base (character, "") public AIObjectiveRescueAll(Character character, float priorityModifier = 1) : base (character, "", priorityModifier)
{ {
rescueTargets = new List<Character>(); rescueTargets = new List<Character>();
} }
@@ -2606,6 +2606,10 @@ namespace Barotrauma
GameMain.GameSession?.CrewManager?.RemoveCharacter(this); GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif #endif
#if CLIENT
GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif
#if CLIENT #if CLIENT
GameMain.GameSession?.CrewManager?.RemoveCharacter(this); GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif #endif
@@ -9,13 +9,14 @@ namespace Barotrauma
{ {
public string aiTag; public string aiTag;
public string option; public string option;
public float priority; public float priorityModifier;
public AutomaticOrder(XElement element) public AutomaticOrder(XElement element)
{ {
aiTag = element.GetAttributeString("aitag", null); aiTag = element.GetAttributeString("aitag", null);
option = element.GetAttributeString("option", null); option = element.GetAttributeString("option", null);
priority = element.GetAttributeFloat("priority", 0); priorityModifier = element.GetAttributeFloat("prioritymodifier", 1);
priorityModifier = MathHelper.Max(priorityModifier, 0);
} }
} }
@@ -211,6 +211,19 @@ namespace Barotrauma.Items.Components
return true; return true;
} }
public override void OnItemLoaded()
{
sonar = item.GetComponent<Sonar>();
}
public override bool Select(Character character)
{
if (!CanBeSelected) return false;
user = character;
return true;
}
public override void Update(float deltaTime, Camera cam) public override void Update(float deltaTime, Camera cam)
{ {
networkUpdateTimer -= deltaTime; networkUpdateTimer -= deltaTime;
@@ -24,6 +24,8 @@ namespace Barotrauma
private bool removed; private bool removed;
private bool removed;
#if CLIENT #if CLIENT
private List<Decal> burnDecals = new List<Decal>(); private List<Decal> burnDecals = new List<Decal>();
#endif #endif
@@ -128,6 +128,25 @@ namespace Barotrauma
} }
} }
public string DisplayName
{
get;
private set;
}
private string roomName;
[Editable, Serialize("", true, translationTextTag: "RoomName.")]
public string RoomName
{
get { return roomName; }
set
{
if (roomName == value) { return; }
roomName = value;
DisplayName = TextManager.Get(roomName, returnNull: true) ?? roomName;
}
}
public override Rectangle Rect public override Rectangle Rect
{ {
get get
@@ -1209,6 +1209,9 @@ namespace Barotrauma
if (FlippedX) element.Add(new XAttribute("flippedx", true)); if (FlippedX) element.Add(new XAttribute("flippedx", true));
if (FlippedY) element.Add(new XAttribute("flippedy", true)); if (FlippedY) element.Add(new XAttribute("flippedy", true));
if (FlippedX) element.Add(new XAttribute("flippedx", true));
if (FlippedY) element.Add(new XAttribute("flippedy", true));
for (int i = 0; i < Sections.Length; i++) for (int i = 0; i < Sections.Length; i++)
{ {
if (Sections[i].damage == 0.0f) continue; if (Sections[i].damage == 0.0f) continue;
@@ -162,21 +162,6 @@ namespace Barotrauma
get { return binding; } get { return binding; }
} }
public void SetState()
{
hit = binding.IsHit();
if (hit) hitQueue = true;
held = binding.IsDown();
if (held) heldQueue = true;
}
#endif
public KeyOrMouse State
{
get { return binding; }
}
public void SetState() public void SetState()
{ {
hit = binding.IsHit(); hit = binding.IsHit();