From 8be0b0676ee672091eb74bfc2556175d7645b5e8 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Thu, 16 May 2019 05:13:40 +0300 Subject: [PATCH] (83868bb0e) Refactor AIObjectiveExtinguishFires to use the AIObjectiveLoop class. Significant refactoring of the other looping objectives. Reduce the duplicate code. --- .../Source/GUI/GUIComponent.cs | 2 + .../Source/GUI/GUIMessageBox.cs | 6 ++ .../Source/GameSession/CrewManager.cs | 95 ++++++++----------- .../BarotraumaClient/Source/Map/Hull.cs | 27 ++++++ .../Source/Characters/AI/EnemyAIController.cs | 2 + .../Source/Characters/AI/HumanAIController.cs | 2 +- .../Objectives/AIObjectiveChargeBatteries.cs | 34 +++---- .../Objectives/AIObjectiveExtinguishFire.cs | 7 +- .../Objectives/AIObjectiveExtinguishFires.cs | 75 +++++---------- .../AI/Objectives/AIObjectiveFixLeak.cs | 8 +- .../AI/Objectives/AIObjectiveFixLeaks.cs | 20 ++-- .../AI/Objectives/AIObjectiveLoop.cs | 13 +-- .../AI/Objectives/AIObjectivePumpWater.cs | 46 ++++----- .../AI/Objectives/AIObjectiveRepairItem.cs | 4 +- .../AI/Objectives/AIObjectiveRepairItems.cs | 6 +- .../Source/Characters/Character.cs | 4 + .../Items/Components/Machines/Steering.cs | 13 +++ .../BarotraumaShared/Source/Items/Item.cs | 4 + .../BarotraumaShared/Source/Map/FireSource.cs | 2 - .../BarotraumaShared/Source/Map/Hull.cs | 19 ++++ .../BarotraumaShared/Source/PlayerInput.cs | 15 +++ 21 files changed, 212 insertions(+), 192 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs index 3bf442d56..ddea12a60 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs @@ -190,6 +190,8 @@ namespace Barotrauma public bool IgnoreLayoutGroups; + public bool IgnoreLayoutGroups; + public virtual ScalableFont Font { get; diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs index df52bc128..4c3dcaf2a 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs @@ -221,6 +221,12 @@ namespace Barotrauma Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 }; 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) { string wrappedText = ToolBox.WrapText(text, Content.Rect.Width, GUI.Font); diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs index ff992b7b2..ddad8bfd9 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs @@ -98,56 +98,14 @@ namespace Barotrauma CanBeFocused = false }; - scrollButtonUp = new GUIButton(new RectTransform(scrollButtonSize, crewArea.RectTransform, Anchor.TopLeft, Pivot.TopLeft), "", Alignment.Center, "GUIButtonVerticalArrow") - { - Visible = false, - UserData = -1, - OnClicked = ScrollCharacterList - }; - scrollButtonDown = new GUIButton(new RectTransform(scrollButtonSize, crewArea.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft), "", Alignment.Center, "GUIButtonVerticalArrow") - { - Visible = false, - UserData = 1, - OnClicked = ScrollCharacterList - }; - scrollButtonDown.Children.ForEach(c => c.SpriteEffects = SpriteEffects.FlipVertically); - - if (isSinglePlayer) - { - ChatBox = new ChatBox(guiFrame, isSinglePlayer: true) + var characterInfo = new CharacterInfo(subElement); + characterInfos.Add(characterInfo); + foreach (XElement invElement in subElement.Elements()) { - OnEnterMessage = (textbox, text) => - { - if (Character.Controlled?.Info == null) - { - textbox.Deselect(); - textbox.Text = ""; - return true; - } - - textbox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Default]; - - if (!string.IsNullOrWhiteSpace(text)) - { - string msgCommand = ChatMessage.GetChatMessageCommand(text, out string msg); - AddSinglePlayerChatMessage( - Character.Controlled.Info.Name, - msg, - ((msgCommand == "r" || msgCommand == "radio") && ChatMessage.CanUseRadio(Character.Controlled)) ? ChatMessageType.Radio : ChatMessageType.Default, - Character.Controlled); - var headset = GetHeadset(Character.Controlled, true); - if (headset != null && headset.CanTransmit()) - { - headset.TransmitSignal(stepsTaken: 0, signal: msg, source: headset.Item, sender: Character.Controlled, sendToChat: false); - } - } - textbox.Deselect(); - textbox.Text = ""; - return true; - } - }; - - ChatBox.InputBox.OnTextChanged += ChatBox.TypingChatMessage; + if (invElement.Name.ToString().ToLowerInvariant() != "inventory") continue; + characterInfo.InventoryData = invElement; + break; + } } var reports = Order.PrefabList.FindAll(o => o.TargetAllCharacters && o.SymbolSprite != null); @@ -159,14 +117,39 @@ namespace Barotrauma CanBeFocused = false }; - var characterInfo = new CharacterInfo(subElement); - characterInfos.Add(characterInfo); - foreach (XElement invElement in subElement.Elements()) + //report buttons + foreach (Order order in reports) + { + if (!order.TargetAllCharacters || order.SymbolSprite == null) continue; + var btn = new GUIButton(new RectTransform(new Point(reportButtonFrame.Rect.Width), reportButtonFrame.RectTransform), style: null) { - if (invElement.Name.ToString().ToLowerInvariant() != "inventory") continue; - characterInfo.InventoryData = invElement; - break; - } + OnClicked = (GUIButton button, object userData) => + { + if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) return false; + SetCharacterOrder(null, order, null, Character.Controlled); + HumanAIController.PropagateHullSafety(Character.Controlled, Character.Controlled.CurrentHull); + return true; + }, + UserData = order, + 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 img = new GUIImage(new RectTransform(Vector2.One, btn.RectTransform), order.Prefab.SymbolSprite, scaleToFit: true) + { + Color = order.Color, + HoverColor = Color.Lerp(order.Color, Color.White, 0.5f), + ToolTip = order.Name + }; } screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight); diff --git a/Barotrauma/BarotraumaClient/Source/Map/Hull.cs b/Barotrauma/BarotraumaClient/Source/Map/Hull.cs index b73bfc0a8..e32f31ea7 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Hull.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Hull.cs @@ -1136,6 +1136,33 @@ namespace Barotrauma 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) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs index a55e74ab9..7f2daf1d0 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs @@ -1108,6 +1108,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; + //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 //sight/hearing range diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs index 6b6b31bab..ce4926c24 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs @@ -464,7 +464,7 @@ namespace Barotrauma // Even the smallest fire reduces the safety by 50% float fire = hull.FireSources.Count * 0.5f + hull.FireSources.Sum(fs => fs.DamageRange) / hull.Size.X; float fireFactor = ignoreFire ? 1 : MathHelper.Lerp(1, 0, MathHelper.Clamp(fire, 0, 1)); - int enemyCount = Character.CharacterList.Count(e => + int enemyCount = Character.CharacterList.Count(e => e.CurrentHull == hull && !e.IsDead && !e.IsUnconscious && (e.AIController is EnemyAIController || (e.TeamID != character.TeamID && character.TeamID != Character.TeamType.FriendlyNPC && e.TeamID != Character.TeamType.FriendlyNPC))); // The hull safety decreases 90% per enemy up to 100% (TODO: test smaller percentages) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveChargeBatteries.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveChargeBatteries.cs index 4eaeb4073..e671588bc 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveChargeBatteries.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveChargeBatteries.cs @@ -22,37 +22,29 @@ namespace Barotrauma protected override void FindTargets() { - foreach (Item item in Item.ItemList) - { - if (item.Prefab.Identifier != "battery" && !item.HasTag("battery")) { continue; } - if (item.Submarine == null) { continue; } - if (item.Submarine.TeamID != character.TeamID) { continue; } - if (character.Submarine != null && !character.Submarine.IsEntityFoundOnThisSub(item, true)) { continue; } - var battery = item.GetComponent(); - if (battery != null) - { - if (!ignoreList.Contains(battery)) - { - if (!targets.Contains(battery)) - { - targets.Add(battery); - } - } - } - } + base.FindTargets(); if (targets.None()) { character.Speak(TextManager.Get("DialogNoBatteries"), null, 4.0f, "nobatteries", 10.0f); } else { - targets.Sort((x, y) => x.ChargePercentage.CompareTo(y.ChargePercentage)); + // Sorting should be handled by the objective manager, because the targets should be subobjectives. + //targets.Sort((x, y) => x.ChargePercentage.CompareTo(y.ChargePercentage)); } } - protected override bool Filter(PowerContainer battery) => true; + protected override bool Filter(PowerContainer battery) + { + var item = battery.Item; + if (item.Submarine == null) { return false; } + if (item.Submarine.TeamID != character.TeamID) { return false; } + if (character.Submarine != null && !character.Submarine.IsEntityFoundOnThisSub(item, true)) { return false; } + return true; + } + protected override float TargetEvaluation() => targets.Max(t => 100 - t.ChargePercentage); protected override IEnumerable GetList() => batteryList; - protected override AIObjective ObjectiveConstructor(PowerContainer battery) => new AIObjectiveOperateItem(battery, character, Option, false) { IsLoop = true }; + protected override AIObjective ObjectiveConstructor(PowerContainer battery) => new AIObjectiveOperateItem(battery, character, Option, false, priorityModifier: PriorityModifier) { IsLoop = true }; } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveExtinguishFire.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveExtinguishFire.cs index 8484c5bf0..8f86798cc 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveExtinguishFire.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveExtinguishFire.cs @@ -31,9 +31,10 @@ namespace Barotrauma // Vertical distance matters more than horizontal (climbing up/down is harder than moving horizontally) float dist = Math.Abs(character.WorldPosition.X - targetHull.WorldPosition.X) + Math.Abs(character.WorldPosition.Y - targetHull.WorldPosition.Y) * 2.0f; float distanceFactor = MathHelper.Lerp(1, 0.1f, MathUtils.InverseLerp(0, 10000, dist)); - float severityFactor = MathHelper.Lerp(0, 1, MathHelper.Clamp(targetHull.FireSources.Sum(fs => fs.Size.X) / targetHull.Size.X, 0, 1)); - // Devotion? - return MathHelper.Lerp(0, 100, severityFactor * distanceFactor); + float severity = AIObjectiveExtinguishFires.GetFireSeverity(targetHull); + float severityFactor = MathHelper.Lerp(0, 1, severity / 100); + float devotion = Math.Max(Priority, 10) / 100; + return MathHelper.Lerp(0, 100, MathHelper.Clamp(devotion + severityFactor * distanceFactor, 0, 1)); } public override bool IsCompleted() diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveExtinguishFires.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveExtinguishFires.cs index 8d8c1ca91..1d1c4d517 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveExtinguishFires.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveExtinguishFires.cs @@ -1,71 +1,42 @@ -using System; -using System.Linq; +using System.Linq; using System.Collections.Generic; using Barotrauma.Extensions; -using Microsoft.Xna.Framework; namespace Barotrauma { - // TODO: use objective loop and sort the targets by severity - class AIObjectiveExtinguishFires : AIObjective + class AIObjectiveExtinguishFires : AIObjectiveLoop { public override string DebugTag => "extinguish fires"; public override bool ForceRun => true; public override bool KeepDivingGearOn => true; - private Dictionary extinguishObjectives = new Dictionary(); - public AIObjectiveExtinguishFires(Character character, float priorityModifier = 1) : base(character, "", priorityModifier) { } - public override float GetPriority(AIObjectiveManager objectiveManager) + protected override void FindTargets() { - if (character.Submarine == null) { return 0; } - float referenceSize = 100; - // If the fire sources of inside a hull are half the reference size in total(e.g.), the severity for that hull should be 50. - // The severity values for all hulls are added together. So three hulls with 50 severity, would be 150 in total. - // Thus the max priority of 100 is reached when one hull has firesources of size 100 in width, if the priority modifier is 1. - float severity = character.Submarine.GetHulls(true).Sum(h => h.FireSources.Sum(fs => fs.Size.X) / referenceSize * 100); - if (severity < 1) { return 0; } - if (objectiveManager.CurrentOrder == this) - { - return AIObjectiveManager.OrderPriority; - } - float basePriority = MathHelper.Clamp(Priority, 0, 10); - return MathHelper.Clamp(basePriority + severity * PriorityModifier, 0, 99); - } - - public override bool IsCompleted() => false; - public override bool CanBeCompleted => true; - - public override bool IsLoop { get => true; set => throw new System.Exception("Trying to set the value for IsLoop from: " + System.Environment.StackTrace); } - - public override bool IsDuplicate(AIObjective otherObjective) - { - return otherObjective is AIObjectiveExtinguishFires; - } - - protected override void Act(float deltaTime) - { - SyncRemovedObjectives(extinguishObjectives, Hull.hullList); - if (character.Submarine == null) { return; } - foreach (Hull hull in Hull.hullList) - { - if (hull.FireSources.None()) { continue; } - if (hull.Submarine == null) { continue; } - if (hull.Submarine.TeamID != character.TeamID) { continue; } - // If the character is inside, only take connected hulls into account. - if (character.Submarine != null && !character.Submarine.IsEntityFoundOnThisSub(hull, true)) { continue; } - if (!extinguishObjectives.TryGetValue(hull, out AIObjectiveExtinguishFire objective)) - { - objective = new AIObjectiveExtinguishFire(character, hull); - extinguishObjectives.Add(hull, objective); - AddSubObjective(objective); - } - } - if (extinguishObjectives.None()) + base.FindTargets(); + if (targets.None()) { character?.Speak(TextManager.Get("DialogNoFire"), null, 3.0f, "nofire", 30.0f); } } + + protected override bool Filter(Hull target) + { + if (target.FireSources.None()) { return false; } + if (target.Submarine == null) { return false; } + if (target.Submarine.TeamID != character.TeamID) { return false; } + if (character.Submarine != null && !character.Submarine.IsEntityFoundOnThisSub(target, true)) { return false; } + return true; + } + + protected override float TargetEvaluation() => (HumanAIController.ObjectiveManager.CurrentObjective == this || HumanAIController.ObjectiveManager.CurrentOrder == this) ? 100 : targets.Sum(t => GetFireSeverity(t)); + + public static float GetFireSeverity(Hull hull) => hull.FireSources.Sum(fs => fs.Size.X); + + public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveExtinguishFires; + protected override IEnumerable GetList() => Hull.hullList; + + protected override AIObjective ObjectiveConstructor(Hull target) => new AIObjectiveExtinguishFire(character, target, PriorityModifier); } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs index 39e11ea21..27f135c66 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs @@ -39,9 +39,13 @@ namespace Barotrauma public override float GetPriority(AIObjectiveManager objectiveManager) { if (leak.Open == 0.0f) { return 0.0f; } + // Vertical distance matters more than horizontal (climbing up/down is harder than moving horizontally) + float dist = Math.Abs(character.WorldPosition.X - leak.WorldPosition.X) + Math.Abs(character.WorldPosition.Y - leak.WorldPosition.Y) * 2.0f; + float distanceFactor = MathHelper.Lerp(1, 0.25f, MathUtils.InverseLerp(0, 10000, dist)); float severity = AIObjectiveFixLeaks.GetLeakSeverity(leak); - float max = MathHelper.Min((AIObjectiveManager.OrderPriority - 1), 90); - return MathHelper.Clamp(Priority + severity * PriorityModifier, 0, max); + float max = Math.Min((AIObjectiveManager.OrderPriority - 1), 90); + float devotion = Math.Min(Priority, 10) / 100; + return MathHelper.Lerp(0, max, MathHelper.Clamp(devotion + severity * distanceFactor * PriorityModifier, 0, 1)); } public override bool IsDuplicate(AIObjective otherObjective) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeaks.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeaks.cs index 250d4c940..165886cd4 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeaks.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeaks.cs @@ -17,29 +17,21 @@ namespace Barotrauma protected override void FindTargets() { base.FindTargets(); - targets.Sort((x, y) => GetLeakFixPriority(y).CompareTo(GetLeakFixPriority(x))); + // Sorting should be handled by the objective manager, because the targets should be subobjectives. + //targets.Sort((x, y) => GetLeakFixPriority(y).CompareTo(GetLeakFixPriority(x))); + // TODO: Add a dialog when no leaks are found. } protected override bool Filter(Gap gap) { - bool ignore = ignoreList.Contains(gap) || gap.ConnectedWall == null || gap.ConnectedDoor != null || gap.Open <= 0 || gap.linkedTo.All(l => l == null); + bool ignore = gap.ConnectedWall == null || gap.ConnectedDoor != null || gap.Open <= 0 || gap.linkedTo.All(l => l == null); if (!ignore) { if (gap.Submarine == null) { ignore = true; } else if (gap.Submarine.TeamID != character.TeamID) { ignore = true; } else if (character.Submarine != null && !character.Submarine.IsEntityFoundOnThisSub(gap, true)) { ignore = true; } } - return ignore; - } - - private float GetLeakFixPriority(Gap leak) - { - if (leak == null) { return 0; } - float severity = GetLeakSeverity(leak); - // Vertical distance matters more than horizontal (climbing up/down is harder than moving horizontally) - float dist = Math.Abs(character.WorldPosition.X - leak.WorldPosition.X) + Math.Abs(character.WorldPosition.Y - leak.WorldPosition.Y) * 2.0f; - float distanceFactor = MathHelper.Lerp(1, 0.25f, MathUtils.InverseLerp(0, 10000, dist)); - return severity * distanceFactor; + return !ignore; } public static float GetLeakSeverity(Gap leak) @@ -54,6 +46,6 @@ namespace Barotrauma public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveFixLeaks; protected override float TargetEvaluation() => targets.Max(t => GetLeakSeverity(t)); protected override IEnumerable GetList() => Gap.GapList; - protected override AIObjective ObjectiveConstructor(Gap gap) => new AIObjectiveFixLeak(gap, character); + protected override AIObjective ObjectiveConstructor(Gap gap) => new AIObjectiveFixLeak(gap, character, PriorityModifier); } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveLoop.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveLoop.cs index 445fb9b0e..9db973219 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveLoop.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveLoop.cs @@ -91,7 +91,8 @@ namespace Barotrauma { if (character.Submarine == null) { return 0; } if (targets.None()) { return 0; } - float targetValue = MathHelper.Clamp(TargetEvaluation(), 0, 100); + // Allow the target value to be more than 100. + float targetValue = TargetEvaluation(); // If the target value is less than 1% of the max value, let's just treat it as zero. if (targetValue < 1) { return 0; } if (objectiveManager.CurrentOrder == this) @@ -100,7 +101,7 @@ namespace Barotrauma } float max = MathHelper.Min(AIObjectiveManager.OrderPriority - 1, 90); float devotion = MathHelper.Min(10, Priority); - float value = MathHelper.Min((devotion + targetValue * PriorityModifier) / 100, 1); + float value = MathHelper.Clamp((devotion + targetValue * PriorityModifier) / 100, 0, 1); return MathHelper.Lerp(0, max, value); } @@ -115,8 +116,8 @@ namespace Barotrauma { foreach (T item in GetList()) { - if (Filter(item)) { continue; } - if (!targets.Contains(item)) + if (!Filter(item)) { continue; } + if (!ignoreList.Contains(item) && !targets.Contains(item)) { targets.Add(item); } @@ -141,10 +142,6 @@ namespace Barotrauma /// protected abstract IEnumerable GetList(); - /// - /// 0 to 100. - /// - /// protected abstract float TargetEvaluation(); protected abstract AIObjective ObjectiveConstructor(T target); diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectivePumpWater.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectivePumpWater.cs index 3c359997a..4142292da 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectivePumpWater.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectivePumpWater.cs @@ -22,36 +22,26 @@ namespace Barotrauma protected override void FindTargets() { if (option == null) { return; } - foreach (Item item in Item.ItemList) - { - if (item.HasTag("ballast")) { continue; } - if (item.Submarine == null) { continue; } - if (item.Submarine.TeamID != character.TeamID) { continue; } - if (character.Submarine != null && !character.Submarine.IsEntityFoundOnThisSub(item, true)) { continue; } - var pump = item.GetComponent(); - if (pump != null) - { - if (!ignoreList.Contains(pump)) - { - if (option == "stoppumping") - { - if (!pump.IsActive || pump.FlowPercentage == 0.0f) { continue; } - } - else - { - if (!pump.Item.InWater) { continue; } - if (pump.IsActive && pump.FlowPercentage <= -90.0f) { continue; } - } - if (!targets.Contains(pump)) - { - targets.Add(pump); - } - } - } - } + base.FindTargets(); } - protected override bool Filter(Pump pump) => true; + protected override bool Filter(Pump pump) + { + if (pump.Item.HasTag("ballast")) { return false; } + if (pump.Item.Submarine == null) { return false; } + if (pump.Item.Submarine.TeamID != character.TeamID) { return false; } + if (character.Submarine != null && !character.Submarine.IsEntityFoundOnThisSub(pump.Item, true)) { return false; } + if (option == "stoppumping") + { + if (!pump.IsActive || pump.FlowPercentage == 0.0f) { return false; } + } + else + { + if (!pump.Item.InWater) { return false; } + if (pump.IsActive && pump.FlowPercentage <= -90.0f) { return false; } + } + return true; + } protected override IEnumerable GetList() => pumpList; protected override AIObjective ObjectiveConstructor(Pump pump) => new AIObjectiveOperateItem(pump, character, Option, false) { IsLoop = true }; protected override float TargetEvaluation() => targets.Max(t => MathHelper.Lerp(100, 0, t.CurrFlow / t.MaxFlow)); diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs index 82ba27097..046fc8ff5 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs @@ -36,9 +36,9 @@ namespace Barotrauma float damagePriority = MathHelper.Lerp(1, 0, Item.Condition / Item.MaxCondition); float successFactor = MathHelper.Lerp(0, 1, Item.Repairables.Average(r => r.DegreeOfSuccess(character))); float isSelected = character.SelectedConstruction == Item ? 50 : 0; - float devotion = Math.Max(Priority + isSelected, 1); + float devotion = (Math.Min(Priority, 10) + isSelected) / 100; float max = MathHelper.Min(AIObjectiveManager.OrderPriority - 1, 90); - return MathHelper.Clamp(devotion * damagePriority * distanceFactor * successFactor * PriorityModifier, 0, max); + return MathHelper.Lerp(0, max, MathHelper.Clamp(devotion + damagePriority * distanceFactor * successFactor * PriorityModifier, 0, 1)); } public override bool CanBeCompleted => !abandon; diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItems.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItems.cs index 8aa4b3d52..ba7d071ab 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItems.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItems.cs @@ -38,7 +38,7 @@ namespace Barotrauma protected override bool Filter(Item item) { - bool ignore = ignoreList.Contains(item) || item.IsFullCondition; + bool ignore = item.IsFullCondition; if (!ignore) { if (item.Submarine == null) { ignore = true; } @@ -64,11 +64,11 @@ namespace Barotrauma } } } - return ignore; + return !ignore; } protected override float TargetEvaluation() => targets.Max(t => 100 - t.ConditionPercentage); protected override IEnumerable GetList() => Item.ItemList; - protected override AIObjective ObjectiveConstructor(Item item) => new AIObjectiveRepairItem(character, item); + protected override AIObjective ObjectiveConstructor(Item item) => new AIObjectiveRepairItem(character, item, PriorityModifier); } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs index 0155e3fa3..11e41e70a 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs @@ -2714,6 +2714,10 @@ namespace Barotrauma GameMain.GameSession?.CrewManager?.RemoveCharacter(this); #endif +#if CLIENT + GameMain.GameSession?.CrewManager?.RemoveCharacter(this); +#endif + #if CLIENT GameMain.GameSession?.CrewManager?.RemoveCharacter(this); #endif diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs index 04cfe56d8..15be6c324 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs @@ -562,6 +562,19 @@ namespace Barotrauma.Items.Components return true; } + public override void OnItemLoaded() + { + sonar = item.GetComponent(); + } + + public override bool Select(Character character) + { + if (!CanBeSelected) return false; + + user = character; + return true; + } + public override void Update(float deltaTime, Camera cam) { networkUpdateTimer -= deltaTime; diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs index f088060ab..3be49bf9d 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs @@ -1196,6 +1196,10 @@ namespace Barotrauma { ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime); } + if (!broken) + { + ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime); + } ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime); if (body == null || !body.Enabled || !inWater || ParentInventory != null || Removed) { return; } diff --git a/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs b/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs index 686cd222f..11bf41f6c 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs @@ -24,8 +24,6 @@ namespace Barotrauma private bool removed; - private bool removed; - #if CLIENT private List burnDecals = new List(); #endif diff --git a/Barotrauma/BarotraumaShared/Source/Map/Hull.cs b/Barotrauma/BarotraumaShared/Source/Map/Hull.cs index 810ed8812..6a5d96f45 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Hull.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Hull.cs @@ -641,6 +641,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 { get diff --git a/Barotrauma/BarotraumaShared/Source/PlayerInput.cs b/Barotrauma/BarotraumaShared/Source/PlayerInput.cs index e13028523..8ad826eea 100644 --- a/Barotrauma/BarotraumaShared/Source/PlayerInput.cs +++ b/Barotrauma/BarotraumaShared/Source/PlayerInput.cs @@ -162,6 +162,21 @@ namespace Barotrauma 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() { hit = binding.IsHit();