From 6fc8b8b5738eedcadb977648534a3cb3aaf6b961 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Thu, 16 May 2019 06:02:10 +0300 Subject: [PATCH] (2d7903da7) Replaced some horizontal light components with vertical ones in tutorial outpost --- .../Source/Characters/Animation/Ragdoll.cs | 83 ------ .../Source/GameSession/CrewManager.cs | 247 +++--------------- .../Source/Screens/CampaignSetupUI.cs | 2 + .../Source/Screens/MainMenuScreen.cs | 4 - .../Characters/AI/Objectives/AIObjective.cs | 12 - .../AI/Objectives/AIObjectiveCombat.cs | 178 ++++++------- .../Objectives/AIObjectiveFightIntruders.cs | 2 +- .../AI/Objectives/AIObjectiveFixLeak.cs | 25 ++ .../AI/Objectives/AIObjectiveIdle.cs | 15 -- .../AI/Objectives/AIObjectiveOperateItem.cs | 4 + .../AI/Objectives/AIObjectiveRepairItem.cs | 40 +-- .../Source/Characters/AI/PathFinder.cs | 6 - .../Components/Machines/Deconstructor.cs | 19 ++ .../Items/Components/Machines/Steering.cs | 27 ++ .../BarotraumaShared/Source/Items/Item.cs | 4 + .../BarotraumaShared/Source/Map/Hull.cs | 19 ++ 16 files changed, 208 insertions(+), 479 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs index fa30d8a82..8f9276859 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs @@ -121,90 +121,7 @@ namespace Barotrauma MainLimb.PullJointWorldAnchorB = Collider.SimPosition; MainLimb.PullJointEnabled = true; } - character.SelectedConstruction = character.MemState[0].SelectedItem; } - - if (character.MemState[0].Animation == AnimController.Animation.CPR) - { - character.AnimController.Anim = AnimController.Animation.CPR; - } - else if (character.AnimController.Anim == AnimController.Animation.CPR) - { - character.AnimController.Anim = AnimController.Animation.None; - } - - Vector2 newVelocity = Collider.LinearVelocity; - Vector2 newPosition = Collider.SimPosition; - float newRotation = Collider.Rotation; - float newAngularVelocity = Collider.AngularVelocity; - Collider.CorrectPosition(character.MemState, out newPosition, out newVelocity, out newRotation, out newAngularVelocity); - - newVelocity = newVelocity.ClampLength(100.0f); - if (!MathUtils.IsValid(newVelocity)) { newVelocity = Vector2.Zero; } - overrideTargetMovement = newVelocity.LengthSquared() > 0.01f ? newVelocity : Vector2.Zero; - - Collider.LinearVelocity = newVelocity; - Collider.AngularVelocity = newAngularVelocity; - - float distSqrd = Vector2.DistanceSquared(newPosition, Collider.SimPosition); - float errorTolerance = character.AllowInput ? 0.01f : 0.2f; - if (distSqrd > errorTolerance) - { - if (distSqrd > 10.0f || !character.AllowInput) - { - Collider.TargetRotation = newRotation; - SetPosition(newPosition, lerp: distSqrd < 5.0f, ignorePlatforms: false); - } - else - { - Collider.TargetRotation = newRotation; - Collider.TargetPosition = newPosition; - Collider.MoveToTargetPosition(true); - } - } - - //unconscious/dead characters can't correct their position using AnimController movement - // -> we need to correct it manually - if (!character.AllowInput) - { - float mainLimbDistSqrd = Vector2.DistanceSquared(MainLimb.PullJointWorldAnchorA, Collider.SimPosition); - float mainLimbErrorTolerance = 0.1f; - //if the main limb is roughly at the correct position and the collider isn't moving (much at least), - //don't attempt to correct the position. - if (mainLimbDistSqrd > mainLimbErrorTolerance || Collider.LinearVelocity.LengthSquared() > 0.05f) - { - MainLimb.PullJointWorldAnchorB = Collider.SimPosition; - MainLimb.PullJointEnabled = true; - } - } - } - character.MemLocalState.Clear(); - } - else - { - //remove states with a timestamp (there may still timestamp-based states - //in the list if the controlled character switches from timestamp-based interpolation to ID-based) - character.MemState.RemoveAll(m => m.Timestamp > 0.0f); - - for (int i = 0; i < character.MemLocalState.Count; i++) - { - if (character.Submarine == null) - { - //transform in-sub coordinates to outside coordinates - if (character.MemLocalState[i].Position.Y > lowestSubPos) - { - character.MemLocalState[i].TransformInToOutside(); - } - } - else if (currentHull?.Submarine != null) - { - //transform outside coordinates to in-sub coordinates - if (character.MemLocalState[i].Position.Y < lowestSubPos) - { - character.MemLocalState[i].TransformOutToInside(currentHull.Submarine); - } - } - } character.MemLocalState.Clear(); } diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs index 8b52b1fd9..e9bd2ba83 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs @@ -74,17 +74,12 @@ namespace Barotrauma public CrewManager(XElement element, bool isSinglePlayer) : this(isSinglePlayer) { - if (GameMain.Client != null) + if (!isSinglePlayer) { - //let the server create random conversations in MP + DebugConsole.ThrowError("Cannot add messages to single player chat box in multiplayer mode!\n" + Environment.StackTrace); return; } - List availableSpeakers = Character.CharacterList.FindAll(c => - c.AIController is HumanAIController && - !c.IsDead && - c.SpeechImpediment <= 100.0f); - pendingConversationLines.AddRange(NPCConversation.CreateRandom(availableSpeakers)); - } + if (string.IsNullOrEmpty(text)) { return; } var characterInfo = new CharacterInfo(subElement); characterInfos.Add(characterInfo); @@ -95,6 +90,7 @@ namespace Barotrauma break; } } + ChatBox.AddMessage(ChatMessage.Create(senderName, text, messageType, sender)); } partial void InitProjectSpecific() @@ -243,24 +239,27 @@ namespace Barotrauma public IEnumerable GetCharacters() { - if (characterInfos.Contains(characterInfo)) - { - DebugConsole.ThrowError("Tried to add the same character info to CrewManager twice.\n" + Environment.StackTrace); - return; - } + if (character?.Inventory == null) return null; - characterInfos.Add(characterInfo); + var radioItem = character.Inventory.Items.FirstOrDefault(it => it != null && it.GetComponent() != null); + if (radioItem == null) return null; + if (requireEquipped && !character.HasEquippedItem(radioItem)) return null; + + return radioItem.GetComponent(); } public IEnumerable GetCharacterInfos() { - if (character == null) + if (GameMain.Client != null) { - DebugConsole.ThrowError("Tried to remove a null character from CrewManager.\n" + Environment.StackTrace); + //let the server create random conversations in MP return; } - characters.Remove(character); - if (removeInfo) characterInfos.Remove(character.Info); + List availableSpeakers = Character.CharacterList.FindAll(c => + c.AIController is HumanAIController && + !c.IsDead && + c.SpeechImpediment <= 100.0f); + pendingConversationLines.AddRange(NPCConversation.CreateRandom(availableSpeakers)); } public void AddCharacter(Character character) @@ -634,183 +633,9 @@ namespace Barotrauma { characterListBox.BarScroll = roundedPos; } - var characterArea = new GUIButton(new RectTransform(new Point(characterInfoWidth, frame.Rect.Height), frame.RectTransform, Anchor.CenterLeft), style: "GUITextBox") - { - UserData = character, - Color = frame.Color, - SelectedColor = frame.SelectedColor, - HoverColor = frame.HoverColor, - ToolTip = characterToolTip - }; - - var soundIcon = new GUIImage(new RectTransform(new Point((int)(characterArea.Rect.Height * 0.5f)), characterArea.RectTransform, Anchor.CenterRight) { AbsoluteOffset = new Point(5, 0) }, - "GUISoundIcon") - { - UserData = "soundicon", - CanBeFocused = false, - Visible = true - }; - soundIcon.Color = new Color(soundIcon.Color, 0.0f); - new GUIImage(new RectTransform(new Point((int)(characterArea.Rect.Height * 0.5f)), characterArea.RectTransform, Anchor.CenterRight) { AbsoluteOffset = new Point(5, 0) }, - "GUISoundIconDisabled") - { - UserData = "soundicondisabled", - CanBeFocused = true, - Visible = false - }; - - if (isSinglePlayer) - { - characterArea.OnClicked = CharacterClicked; - } - else - { - characterArea.CanBeFocused = false; - characterArea.CanBeSelected = false; - } - - var characterImage = new GUICustomComponent(new RectTransform(new Point(characterArea.Rect.Height), characterArea.RectTransform, Anchor.CenterLeft), - onDraw: (sb, component) => character.Info.DrawIcon(sb, component.Rect.Center.ToVector2(), targetAreaSize: component.Rect.Size.ToVector2())) - { - CanBeFocused = false, - HoverColor = Color.White, - SelectedColor = Color.White, - ToolTip = characterToolTip - }; - - var characterName = new GUITextBlock(new RectTransform(new Point(characterArea.Rect.Width - characterImage.Rect.Width - soundIcon.Rect.Width - 10, characterArea.Rect.Height), - characterArea.RectTransform, Anchor.CenterRight) { AbsoluteOffset = new Point(soundIcon.Rect.Width + 10, 0) }, - character.Name, textColor: frame.Color, font: GUI.SmallFont, wrap: true) - { - Color = frame.Color, - HoverColor = Color.Transparent, - SelectedColor = Color.Transparent, - CanBeFocused = false, - ToolTip = characterToolTip, - AutoScale = true - }; - - //---------------- order buttons ---------------- - - var orderButtonFrame = new GUILayoutGroup(new RectTransform(new Point(100, frame.Rect.Height), frame.RectTransform) - { AbsoluteOffset = new Point(characterInfoWidth + spacing, 0) }, - isHorizontal: true, childAnchor: Anchor.CenterLeft) - { - AbsoluteSpacing = (int)(10 * GUI.Scale), - UserData = "orderbuttons", - CanBeFocused = false - }; - - //listbox for holding the orders inappropriate for this character - //(so we can easily toggle their visibility) - var wrongOrderList = new GUIListBox(new RectTransform(new Point(50, orderButtonFrame.Rect.Height), orderButtonFrame.RectTransform), isHorizontal: true, style: null) - { - ScrollBarEnabled = false, - ScrollBarVisible = false, - Enabled = false, - Spacing = spacing, - ClampMouseRectToParent = false - }; - wrongOrderList.Content.ClampMouseRectToParent = false; - - for (int i = 0; i < orders.Count; i++) - { - var order = orders[i]; - if (order.TargetAllCharacters) continue; - - RectTransform btnParent = (i >= correctOrderCount + neutralOrderCount) ? - wrongOrderList.Content.RectTransform : - orderButtonFrame.RectTransform; - - var btn = new GUIButton(new RectTransform(new Point(iconSize, iconSize), btnParent, Anchor.CenterLeft), - style: null) - { - UserData = order - }; - - new GUIFrame(new RectTransform(new Vector2(1.5f), btn.RectTransform, Anchor.Center), "OuterGlow") - { - Color = Color.Lerp(order.Color, frame.Color, 0.5f) * 0.8f, - HoverColor = Color.Lerp(order.Color, frame.Color, 0.5f) * 1.0f, - PressedColor = Color.Lerp(order.Color, frame.Color, 0.5f) * 0.6f, - UserData = "selected", - CanBeFocused = false, - Visible = false - }; - - var img = new GUIImage(new RectTransform(Vector2.One, btn.RectTransform), order.Prefab.SymbolSprite); - img.Scale = iconSize / (float)img.SourceRect.Width; - img.Color = Color.Lerp(order.Color, frame.Color, 0.5f); - img.ToolTip = order.Name; - img.HoverColor = Color.Lerp(img.Color, Color.White, 0.5f); - - btn.OnClicked += (GUIButton button, object userData) => - { - if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) return false; - - if (btn.GetChildByUserData("selected").Visible) - { - SetCharacterOrder(character, Order.PrefabList.Find(o => o.AITag == "dismissed"), null, Character.Controlled); - } - else - { - if (order.ItemComponentType != null || order.ItemIdentifiers.Length > 0 || order.Options.Length > 1) - { - CreateOrderTargetFrame(button, character, order); - } - else - { - SetCharacterOrder(character, order, null, Character.Controlled); - } - } - return true; - }; - btn.UserData = order; - btn.ToolTip = order.Name; - - //divider between different groups of orders - if (i == correctOrderCount - 1 || i == correctOrderCount + neutralOrderCount - 1) - { - //TODO: divider sprite - new GUIFrame(new RectTransform(new Point(8, iconSize), orderButtonFrame.RectTransform), style: "GUIButton"); - } - } - - var toggleWrongOrderBtn = new GUIButton(new RectTransform(new Point((int)(30 * GUI.Scale), wrongOrderList.Rect.Height), wrongOrderList.Content.RectTransform), - "", style: "UIToggleButton") - { - UserData = "togglewrongorder", - CanBeFocused = false - }; - - wrongOrderList.RectTransform.NonScaledSize = new Point( - wrongOrderList.Content.Children.Sum(c => c.Rect.Width + wrongOrderList.Spacing), - wrongOrderList.RectTransform.NonScaledSize.Y); - wrongOrderList.RectTransform.SetAsLastChild(); - - new GUIFrame(new RectTransform(new Point( - wrongOrderList.Rect.Width - toggleWrongOrderBtn.Rect.Width - wrongOrderList.Spacing * 2, - wrongOrderList.Rect.Height), wrongOrderList.Content.RectTransform), - style: null) - { - CanBeFocused = false - }; - - //scale to fit the content - orderButtonFrame.RectTransform.NonScaledSize = new Point( - orderButtonFrame.Children.Sum(c => c.Rect.Width + orderButtonFrame.AbsoluteSpacing), - orderButtonFrame.RectTransform.NonScaledSize.Y); - - frame.RectTransform.NonScaledSize = new Point( - characterInfoWidth + spacing + (orderButtonFrame.Rect.Width - wrongOrderList.Rect.Width), - frame.RectTransform.NonScaledSize.Y); - - characterListBox.RectTransform.NonScaledSize = new Point( - characterListBox.Content.Children.Max(c => c.Rect.Width) + wrongOrderList.Rect.Width, - characterListBox.RectTransform.NonScaledSize.Y); - characterListBox.Content.RectTransform.NonScaledSize = characterListBox.RectTransform.NonScaledSize; - characterListBox.UpdateScrollBarSize(); - return frame; + soundIcon.Visible = !muted && !mutedLocally; + soundIconDisabled.Visible = muted || mutedLocally; + soundIconDisabled.ToolTip = TextManager.Get(mutedLocally ? "MutedLocally" : "MutedGlobally"); } private IEnumerable KillCharacterAnim(GUIComponent component) @@ -954,12 +779,6 @@ namespace Barotrauma } return; } - List availableSpeakers = Character.CharacterList.FindAll(c => - c.AIController is HumanAIController && - !c.IsDead && - c.SpeechImpediment <= 100.0f); - pendingConversationLines.AddRange(NPCConversation.CreateRandom(availableSpeakers)); - } character.SetOrder(order, option, orderGiver, speak: orderGiver != character); if (IsSinglePlayer) @@ -1017,23 +836,19 @@ namespace Barotrauma } } } - - character.SetOrder(order, option, orderGiver, speak: orderGiver != character); - if (IsSinglePlayer) + //only one target (or an order with no particular targets), just show options + else { - orderGiver?.Speak( - order.GetChatMessage(character.Name, orderGiver.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option), null); - } - else if (orderGiver != null) - { - OrderChatMessage msg = new OrderChatMessage(order, option, order.TargetItemComponent?.Item, character, orderGiver); - if (GameMain.Client != null) + orderTargetFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.2f + order.Options.Length * 0.1f, 0.18f), GUI.Canvas) + { AbsoluteOffset = new Point(orderButton.Rect.Center.X, orderButton.Rect.Bottom) }, + isHorizontal: true, childAnchor: Anchor.BottomLeft) { - GameMain.Client.SendChatMessage(msg); - } - } - DisplayCharacterOrder(character, order); - } + UserData = character, + Stretch = true + }; + //line connecting the order button to the option buttons + //TODO: sprite + new GUIFrame(new RectTransform(new Vector2(0.5f, 1.0f), orderTargetFrame.RectTransform), style: null); /// /// Create the UI panel that's used to select the target and options for a given order diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs b/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs index ce4fa721c..91929e77c 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs @@ -358,6 +358,8 @@ namespace Barotrauma private GUILayoutGroup subPreviewContainer; + private GUILayoutGroup subPreviewContainer; + private GUIButton loadGameButton; public Action StartNewGame; diff --git a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs index 96c441896..287ac0265 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs @@ -789,10 +789,6 @@ namespace Barotrauma GUI.Draw(Cam, spriteBatch); - spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, GameMain.ScissorTestEnable); - - GUI.Draw(Cam, spriteBatch); - GUI.Draw(Cam, spriteBatch); #if DEBUG diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs index 9f23a116a..b991f524f 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs @@ -106,18 +106,6 @@ namespace Barotrauma subObjectives.Add(objective); } - public void RemoveSubObjective(ref T objective) where T : AIObjective - { - if (objective != null) - { - if (subObjectives.Contains(objective)) - { - subObjectives.Remove(objective); - } - objective = null; - } - } - public void SortSubObjectives() { if (subObjectives.None()) { return; } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs index 047d55861..ce7122b63 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs @@ -11,10 +11,9 @@ namespace Barotrauma class AIObjectiveCombat : AIObjective { public override string DebugTag => "combat"; + public bool useCoolDown = true; - private readonly CombatMode initialMode; - - const float coolDown = 10.0f; + const float CoolDown = 10.0f; public Character Enemy { get; private set; } @@ -26,7 +25,14 @@ namespace Barotrauma { _weapon = value; _weaponComponent = null; - RemoveSubObjective(ref reloadWeaponObjective); + if (reloadWeaponObjective != null) + { + if (subObjectives.Contains(reloadWeaponObjective)) + { + subObjectives.Remove(reloadWeaponObjective); + } + reloadWeaponObjective = null; + } } } private ItemComponent _weaponComponent; @@ -34,7 +40,6 @@ namespace Barotrauma { get { - if (Weapon == null) { return null; } if (_weaponComponent == null) { _weaponComponent = @@ -59,8 +64,6 @@ namespace Barotrauma private Hull retreatTarget; private float coolDownTimer; - private IEnumerable myBodies; - private float aimTimer; public enum CombatMode { @@ -75,7 +78,7 @@ namespace Barotrauma : base(character, objectiveManager, priorityModifier) { Enemy = enemy; - coolDownTimer = coolDown; + coolDownTimer = CoolDown; findSafety = objectiveManager.GetObjective(); if (findSafety != null) { @@ -83,7 +86,6 @@ namespace Barotrauma findSafety.unreachable.Clear(); } Mode = mode; - initialMode = Mode; if (Enemy == null) { Mode = CombatMode.Retreat; @@ -102,7 +104,7 @@ namespace Barotrauma public override bool IsCompleted() { - bool completed = (Enemy != null && (Enemy.Removed || Enemy.IsDead)) || (initialMode != CombatMode.Offensive && coolDownTimer <= 0); + bool completed = (Enemy != null && (Enemy.Removed || Enemy.IsDead)) || (useCoolDown && coolDownTimer <= 0); if (completed) { if (objectiveManager.CurrentOrder == this && Enemy != null && Enemy.IsDead) @@ -119,73 +121,58 @@ namespace Barotrauma protected override void Act(float deltaTime) { - if (initialMode != CombatMode.Offensive) + if (useCoolDown) { coolDownTimer -= deltaTime; } if (abandon) { return; } - TryArm(); - if (reloadWeaponObjective == null || !subObjectives.Contains(reloadWeaponObjective)) - { - Move(); - OperateWeapon(deltaTime); - } + Arm(deltaTime); + Move(deltaTime); } - private void Move() + private void Arm(float deltaTime) { switch (Mode) { case CombatMode.Offensive: - Engage(); - break; case CombatMode.Defensive: + if (Weapon != null && !character.Inventory.Items.Contains(_weapon) || _weaponComponent != null && !_weaponComponent.HasRequiredContainedItems(false)) + { + Weapon = null; + } + if (Weapon == null) + { + Weapon = GetWeapon(); + } + if (Weapon == null) + { + Mode = CombatMode.Retreat; + } + if (Equip()) + { + if (Reload(deltaTime)) + { + Attack(deltaTime); + } + } + break; case CombatMode.Retreat: - Retreat(); break; default: throw new NotImplementedException(); } } - private void TryArm() - { - if (Weapon != null) - { - if (!character.Inventory.Items.Contains(Weapon) || WeaponComponent == null) - { - Weapon = null; - } - else if (!WeaponComponent.HasRequiredContainedItems(false)) - { - //if (!Reload()) - //{ - // Weapon = null; - // Mode = CombatMode.Retreat; - //} - //return; - Weapon = null; - } - } - if (Weapon == null) - { - Weapon = GetWeapon(); - } - Mode = Weapon == null ? CombatMode.Retreat : initialMode; - } - - private void OperateWeapon(float deltaTime) + private void Move(float deltaTime) { switch (Mode) { case CombatMode.Offensive: - case CombatMode.Defensive: - if (Equip()) - { - Attack(deltaTime); - } + Engage(deltaTime); break; + case CombatMode.Defensive: case CombatMode.Retreat: + Retreat(deltaTime); break; default: throw new NotImplementedException(); @@ -266,7 +253,6 @@ namespace Barotrauma Weapon.Drop(character); } } - return true; } private bool Equip() @@ -277,11 +263,9 @@ namespace Barotrauma if (character.Inventory.TryPutItem(Weapon, character, slots)) { Weapon.Equip(character); - aimTimer = Rand.Range(0.5f, 1f); } else { - Weapon = null; Mode = CombatMode.Retreat; return false; } @@ -289,10 +273,16 @@ namespace Barotrauma return true; } - private void Retreat() + private void Retreat(float deltaTime) { - RemoveSubObjective(ref followTargetObjective); - RemoveSubObjective(ref reloadWeaponObjective); + if (followTargetObjective != null) + { + if (subObjectives.Contains(followTargetObjective)) + { + subObjectives.Remove(followTargetObjective); + } + followTargetObjective = null; + } if (retreatObjective != null && retreatObjective.Target != retreatTarget) { retreatObjective = null; @@ -304,14 +294,16 @@ namespace Barotrauma TryAddSubObjective(ref retreatObjective, () => new AIObjectiveGoTo(retreatTarget, character, objectiveManager, false, true)); } - private void Engage() + private void Engage(float deltaTime) { retreatTarget = null; - RemoveSubObjective(ref retreatObjective); - RemoveSubObjective(ref reloadWeaponObjective); - if (followTargetObjective != null && followTargetObjective.Target != Enemy) + if (retreatObjective != null) { - followTargetObjective = null; + if (subObjectives.Contains(retreatObjective)) + { + subObjectives.Remove(retreatObjective); + } + retreatObjective = null; } TryAddSubObjective(ref followTargetObjective, constructor: () => new AIObjectiveGoTo(Enemy, character, objectiveManager, repeat: true, getDivingGearIfNeeded: true) @@ -326,44 +318,35 @@ namespace Barotrauma }, onAbandon: () => { - Mode = CombatMode.Retreat; SteeringManager.Reset(); + Mode = CombatMode.Retreat; }); } - private bool Reload() + private bool Reload(float deltaTime) { - // TODO: reload all ammunition - if (WeaponComponent == null) { return false; } - if (WeaponComponent.requiredItems.ContainsKey(RelatedItem.RelationType.Contained)) + if (WeaponComponent != null && WeaponComponent.requiredItems.ContainsKey(RelatedItem.RelationType.Contained)) { var containedItems = Weapon.ContainedItems; - RelatedItem item = null; - Item ammunition = null; foreach (RelatedItem requiredItem in WeaponComponent.requiredItems[RelatedItem.RelationType.Contained]) { - item = requiredItem; - ammunition = containedItems.FirstOrDefault(it => it.Condition > 0.0f && requiredItem.MatchesItem(it)); - if (ammunition != null) { return true; } - } - if (ammunition == null) - { - retreatTarget = null; - RemoveSubObjective(ref retreatObjective); - RemoveSubObjective(ref followTargetObjective); - TryAddSubObjective(ref reloadWeaponObjective, - constructor: () => new AIObjectiveContainItem(character, item.Identifiers, Weapon.GetComponent(), objectiveManager), - onAbandon: () => - { - Weapon = null; - Mode = CombatMode.Retreat; - SteeringManager.Reset(); - }); + Item containedItem = containedItems.FirstOrDefault(it => it.Condition > 0.0f && requiredItem.MatchesItem(it)); + if (containedItem == null) + { + TryAddSubObjective(ref reloadWeaponObjective, + constructor: () => new AIObjectiveContainItem(character, requiredItem.Identifiers, Weapon.GetComponent(), objectiveManager), + onAbandon: () => + { + SteeringManager.Reset(); + Mode = CombatMode.Retreat; + }); + } } } - return true; + return reloadWeaponObjective == null || reloadWeaponObjective.IsCompleted(); } + private IEnumerable myBodies; private void Attack(float deltaTime) { float squaredDistance = Vector2.DistanceSquared(character.Position, Enemy.Position); @@ -388,16 +371,6 @@ namespace Barotrauma character.SetInput(InputType.Aim, false, true); } } - bool isFacing = character.AnimController.Dir > 0 && Enemy.WorldPosition.X > character.WorldPosition.X || character.AnimController.Dir < 0 && Enemy.WorldPosition.X < character.WorldPosition.X; - if (!isFacing) - { - aimTimer = Rand.Range(1f, 1.5f); - } - if (aimTimer > 0) - { - aimTimer -= deltaTime; - return; - } if (WeaponComponent is MeleeWeapon meleeWeapon) { if (squaredDistance <= meleeWeapon.Range * meleeWeapon.Range) @@ -412,14 +385,14 @@ namespace Barotrauma { if (squaredDistance > repairTool.Range * repairTool.Range) { return; } } - if (VectorExtensions.Angle(VectorExtensions.Forward(Weapon.body.TransformedRotation), Enemy.Position - Weapon.Position) < MathHelper.PiOver4) + if (VectorExtensions.Angle(VectorExtensions.Forward(Weapon.body.TransformedRotation), Enemy.Position - character.Position) < MathHelper.PiOver4) { if (myBodies == null) { myBodies = character.AnimController.Limbs.Select(l => l.body.FarseerBody); } var collisionCategories = Physics.CollisionCharacter | Physics.CollisionWall; - var pickedBody = Submarine.PickBody(Weapon.SimPosition, Enemy.SimPosition, myBodies, collisionCategories); + var pickedBody = Submarine.PickBody(character.SimPosition, Enemy.SimPosition, myBodies, collisionCategories); if (pickedBody != null) { Character target = null; @@ -431,11 +404,10 @@ namespace Barotrauma { target = limb.character; } - if (target != null && (target == Enemy || !HumanAIController.IsFriendly(target))) + if (target != null && target == Enemy) { character.SetInput(InputType.Shoot, false, true); Weapon.Use(deltaTime, character); - aimTimer = Rand.Range(0.25f, 0.5f); } } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFightIntruders.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFightIntruders.cs index 9039a5011..91ebb94f6 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFightIntruders.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFightIntruders.cs @@ -29,7 +29,7 @@ namespace Barotrauma protected override IEnumerable GetList() => Character.CharacterList; - protected override AIObjective ObjectiveConstructor(Character target) => new AIObjectiveCombat(character, target, AIObjectiveCombat.CombatMode.Offensive, objectiveManager, PriorityModifier); + protected override AIObjective ObjectiveConstructor(Character target) => new AIObjectiveCombat(character, target, AIObjectiveCombat.CombatMode.Offensive, objectiveManager, PriorityModifier) { useCoolDown = false }; protected override float TargetEvaluation() { diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs index d93807bd6..0229d8111 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs @@ -375,6 +375,31 @@ namespace Barotrauma { #if DEBUG DebugConsole.ThrowError("AIObjectiveFixLeak failed - the item \"" + weldingTool + "\" has no RepairTool component but is tagged as a welding tool"); +#endif + abandon = true; + return; + } + Vector2 gapDiff = Leak.WorldPosition - character.WorldPosition; + // TODO: use the collider size/reach? + if (!character.AnimController.InWater && Math.Abs(gapDiff.X) < 100 && gapDiff.Y < 0.0f && gapDiff.Y > -150) + { + HumanAIController.AnimController.Crouching = true; + } + float reach = ConvertUnits.ToSimUnits(repairTool.Range); + bool canOperate = ConvertUnits.ToSimUnits(gapDiff.Length()) < reach; + if (canOperate) + { + TryAddSubObjective(ref operateObjective, () => new AIObjectiveOperateItem(repairTool, character, objectiveManager, option: "", requireEquip: true, operateTarget: Leak)); + } + else + { + TryAddSubObjective(ref gotoObjective, () => new AIObjectiveGoTo(ConvertUnits.ToSimUnits(GetStandPosition()), character, objectiveManager) { CloseEnough = reach * 0.75f }); + } + var repairTool = weldingTool.GetComponent(); + if (repairTool == null) + { +#if DEBUG + DebugConsole.ThrowError("AIObjectiveFixLeak failed - the item \"" + weldingTool + "\" has no RepairTool component but is tagged as a welding tool"); #endif abandon = true; return; diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs index 1e1e961f6..eeef8131c 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs @@ -73,21 +73,6 @@ namespace Barotrauma } } - public override void Update(float deltaTime) - { - if (objectiveManager.CurrentObjective == this) - { - if (randomTimer > 0) - { - randomTimer -= deltaTime; - } - else - { - SetRandom(); - } - } - } - public override bool IsCompleted() => false; public override bool CanBeCompleted => true; diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs index aeaa12996..612b76f9c 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs @@ -118,6 +118,10 @@ namespace Barotrauma { isCompleted = true; } + if (component.AIOperate(deltaTime, character, this)) + { + isCompleted = true; + } } else { diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs index 010c5f5ee..b64af04a5 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs @@ -4,7 +4,6 @@ using System; using System.Linq; using Barotrauma.Extensions; using FarseerPhysics; -using Barotrauma.Items.Components; namespace Barotrauma { @@ -15,7 +14,6 @@ namespace Barotrauma public Item Item { get; private set; } private AIObjectiveGoTo goToObjective; - private AIObjectiveContainItem refuelObjective; private float previousCondition = -1; private RepairTool repairTool; @@ -73,46 +71,11 @@ namespace Barotrauma } } // Only continue when the get item sub objectives have been completed. - if (subObjectives.Any()) { return; } + if (subObjectives.Any(so => so is AIObjectiveGetItem)) { return; } if (repairTool == null) { FindRepairTool(); } - if (repairTool != null) - { - var containedItems = repairTool.Item.ContainedItems; - if (containedItems == null) - { -#if DEBUG - DebugConsole.ThrowError("AIObjectiveRepairItem failed - the item \"" + repairTool + "\" has no proper inventory"); -#endif - abandon = true; - return; - } - // Drop empty tanks - foreach (Item containedItem in containedItems) - { - if (containedItem == null) { continue; } - if (containedItem.Condition <= 0.0f) - { - containedItem.Drop(character); - } - } - RelatedItem item = null; - Item fuel = null; - foreach (RelatedItem requiredItem in repairTool.requiredItems[RelatedItem.RelationType.Contained]) - { - item = requiredItem; - fuel = containedItems.FirstOrDefault(it => it.Condition > 0.0f && requiredItem.MatchesItem(it)); - if (fuel != null) { break; } - } - if (fuel == null) - { - RemoveSubObjective(ref goToObjective); - TryAddSubObjective(ref refuelObjective, () => new AIObjectiveContainItem(character, item.Identifiers, repairTool.Item.GetComponent(), objectiveManager)); - return; - } - } if (character.CurrentHull == Item.CurrentHull && character.CanInteractWith(Item)) { if (repairTool != null) @@ -149,7 +112,6 @@ namespace Barotrauma } else { - RemoveSubObjective(ref refuelObjective); // If cannot reach the item, approach it. TryAddSubObjective(ref goToObjective, constructor: () => diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs index 8e822ac4f..a014a6137 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs @@ -203,9 +203,7 @@ namespace Barotrauma if (startNode == null) { -#if DEBUG DebugConsole.NewMessage("Pathfinding error, couldn't find a start node. "+ errorMsgStr, Color.DarkRed); -#endif return new SteeringPath(true); } @@ -255,9 +253,7 @@ namespace Barotrauma if (endNode == null) { -#if DEBUG DebugConsole.NewMessage("Pathfinding error, couldn't find an end node. " + errorMsgStr, Color.DarkRed); -#endif return new SteeringPath(true); } @@ -285,9 +281,7 @@ namespace Barotrauma if (startNode == null || endNode == null) { -#if DEBUG DebugConsole.NewMessage("Pathfinding error, couldn't find matching pathnodes to waypoints.", Color.DarkRed); -#endif return new SteeringPath(true); } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs index 6aa2c2514..76b490647 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs @@ -658,6 +658,25 @@ namespace Barotrauma.Items.Components } } + if (targetItem.Prefab.DeconstructItems.Any()) + { + inputContainer.Inventory.RemoveItem(targetItem); + Entity.Spawner.AddToRemoveQueue(targetItem); + MoveInputQueue(); + PutItemsToLinkedContainer(); + } + else + { + if (outputContainer.Inventory.Items.All(i => i != null)) + { + targetItem.Drop(dropper: null); + } + else + { + outputContainer.Inventory.TryPutItem(targetItem, user: null, createNetworkEvent: true); + } + } + if (targetItem.Prefab.DeconstructItems.Any()) { inputContainer.Inventory.RemoveItem(targetItem); diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs index 2aafee648..a251165ce 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs @@ -212,6 +212,33 @@ namespace Barotrauma.Items.Components } } + public Vector2? PosToMaintain + { + get { return posToMaintain; } + set { posToMaintain = value; } + } + + struct ObstacleDebugInfo + { + public Vector2 Point1; + public Vector2 Point2; + + public Vector2? Intersection; + + public float Dot; + + public Vector2 AvoidStrength; + + public ObstacleDebugInfo(GraphEdge edge, Vector2? intersection, float dot, Vector2 avoidStrength) + { + Point1 = edge.Point1; + Point2 = edge.Point2; + Intersection = intersection; + Dot = dot; + AvoidStrength = avoidStrength; + } + } + //edge point 1, edge point 2, avoid strength private List debugDrawObstacles = new List(); diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs index 22999726e..4aca28c5e 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs @@ -1876,6 +1876,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/Hull.cs b/Barotrauma/BarotraumaShared/Source/Map/Hull.cs index 210df583d..1701f7a6f 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Hull.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Hull.cs @@ -721,6 +721,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