diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs index 8f9276859..bcf133b30 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs @@ -152,6 +152,32 @@ namespace Barotrauma } + if (character.MemLocalState.Count > 120) character.MemLocalState.RemoveRange(0, character.MemLocalState.Count - 120); + character.MemState.Clear(); + } + } + + partial void ImpactProjSpecific(float impact, Body body) + { + float volume = MathHelper.Clamp(impact - 3.0f, 0.5f, 1.0f); + + if (body.UserData is Limb limb && character.Stun <= 0f) + { + if (impact > 3.0f) { PlayImpactSound(limb); } + } + else if (body.UserData is Limb || body == Collider.FarseerBody) + { + if (!character.IsRemotePlayer && impact > ImpactTolerance) + { + SoundPlayer.PlayDamageSound("LimbBlunt", strongestImpact, Collider); + } + } + if (Character.Controlled == character) + { + GameMain.GameScreen.Cam.Shake = Math.Min(Math.Max(strongestImpact, GameMain.GameScreen.Cam.Shake), 3.0f); + } + } + if (character.MemState.Count < 1) return; overrideTargetMovement = Vector2.Zero; diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs index de1384c9b..b6fc705e8 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs @@ -117,53 +117,6 @@ namespace Barotrauma }; scrollButtonDown.Children.ForEach(c => c.SpriteEffects = SpriteEffects.FlipVertically); - if (isSinglePlayer) - { - ChatBox = new ChatBox(guiFrame, isSinglePlayer: true) - { - 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; - } - - var reports = Order.PrefabList.FindAll(o => o.TargetAllCharacters && o.SymbolSprite != null); - reportButtonFrame = new GUILayoutGroup(new RectTransform( - new Point((HUDLayoutSettings.CrewArea.Height - (int)((reports.Count - 1) * 5 * GUI.Scale)) / reports.Count, HUDLayoutSettings.CrewArea.Height), guiFrame.RectTransform)) - { - AbsoluteSpacing = (int)(5 * GUI.Scale), - UserData = "reportbuttons", - CanBeFocused = false - }; - var characterInfo = new CharacterInfo(subElement); characterInfos.Add(characterInfo); foreach (XElement invElement in subElement.Elements()) diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs b/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs index 3715541cb..5ec817bc0 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs @@ -732,6 +732,8 @@ namespace Barotrauma private GUILayoutGroup subPreviewContainer; + private GUILayoutGroup subPreviewContainer; + private GUIButton loadGameButton; public Action StartNewGame; diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs index 4dafc480e..b4c59842e 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs @@ -445,6 +445,85 @@ namespace Barotrauma } } + protected void ReportProblems() + { + Order newOrder = null; + if (Character.CurrentHull != null) + { + foreach (var hull in VisibleHulls) + { + foreach (Character c in Character.CharacterList) + { + if (c.CurrentHull != hull) { continue; } + if (AIObjectiveFightIntruders.IsValidTarget(c, Character)) + { + AddTargets(Character, c); + if (newOrder == null) + { + var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportintruders"); + newOrder = new Order(orderPrefab, c.CurrentHull, null); + } + } + } + if (AIObjectiveExtinguishFires.IsValidTarget(hull, Character)) + { + AddTargets(Character, hull); + if (newOrder == null) + { + var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportfire"); + newOrder = new Order(orderPrefab, hull, null); + } + } + foreach (Character c in Character.CharacterList) + { + if (c.CurrentHull != hull) { continue; } + if (AIObjectiveRescueAll.IsValidTarget(c, Character)) + { + AddTargets(c, Character); + if (newOrder == null) + { + var orderPrefab = Order.PrefabList.Find(o => o.AITag == "requestfirstaid"); + newOrder = new Order(orderPrefab, c.CurrentHull, null); + } + } + } + foreach (var gap in hull.ConnectedGaps) + { + if (AIObjectiveFixLeaks.IsValidTarget(gap, Character)) + { + AddTargets(Character, gap); + if (newOrder == null) + { + var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportbreach"); + newOrder = new Order(orderPrefab, hull, null); + } + } + } + foreach (Item item in Item.ItemList) + { + if (item.CurrentHull != hull) { continue; } + if (AIObjectiveRepairItems.IsValidTarget(item, Character)) + { + if (item.Repairables.All(r => item.Condition > r.ShowRepairUIThreshold)) { continue; } + AddTargets(Character, item); + if (newOrder == null) + { + var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportbrokendevices"); + newOrder = new Order(orderPrefab, item.CurrentHull, item.Repairables?.FirstOrDefault()); + } + } + } + } + } + if (newOrder != null) + { + if (GameMain.GameSession?.CrewManager != null && GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime)) + { + Character.Speak(newOrder.GetChatMessage("", Character.CurrentHull?.DisplayName, givingOrderToSelf: false), ChatMessageType.Order); + } + } + } + private void UpdateSpeaking() { if (Character.Oxygen < 20.0f) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs index 2bf4ab696..8f50e02b8 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs @@ -569,6 +569,32 @@ 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 * 1.5f; + 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 }); + } + if (subObjectives.Any()) { return; } + 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 88881b170..b617e56e7 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs @@ -74,36 +74,6 @@ namespace Barotrauma } } - public override void Update(float deltaTime) - { - if (objectiveManager.CurrentObjective == this) - { - if (randomTimer > 0) - { - randomTimer -= deltaTime; - } - else - { - SetRandom(); - } - } - } - - 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 c4d7d28f4..0d6361ca3 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs @@ -865,6 +865,10 @@ namespace Barotrauma { isCompleted = true; } + if (component.AIOperate(deltaTime, character, this)) + { + isCompleted = true; + } } else { diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs index cc2e7af08..922c12222 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs @@ -1145,6 +1145,15 @@ namespace Barotrauma SmoothedCursorPosition = cursorPosition - smoothedCursorDiff; } + if (!(this is AICharacter) || Controlled == this || IsRemotePlayer) + { + //apply some smoothing to the cursor positions of remote players when playing as a client + //to make aiming look a little less choppy + Vector2 smoothedCursorDiff = cursorPosition - SmoothedCursorPosition; + smoothedCursorDiff = NetConfig.InterpolateCursorPositionError(smoothedCursorDiff); + SmoothedCursorPosition = cursorPosition - smoothedCursorDiff; + } + if (!(this is AICharacter) || Controlled == this || IsRemotePlayer) { if (speedMultipliers.Count == 0) return 1f; diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs index a7bfd66b6..debf07635 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs @@ -1019,6 +1019,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 f6d19e87b..7a471a65c 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs @@ -144,6 +144,17 @@ namespace Barotrauma.Items.Components } } + public Vector2 SteeringInput + { + get { return steeringInput; } + set + { + if (!MathUtils.IsValid(value)) return; + steeringInput.X = MathHelper.Clamp(value.X, -100.0f, 100.0f); + steeringInput.Y = MathHelper.Clamp(value.Y, -100.0f, 100.0f); + } + } + public SteeringPath SteeringPath { if (!CanBeSelected) return false; @@ -164,12 +175,6 @@ namespace Barotrauma.Items.Components set { posToMaintain = value; } } - public Vector2? PosToMaintain - { - get { return posToMaintain; } - set { posToMaintain = value; } - } - struct ObstacleDebugInfo { public Vector2 Point1; diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs index badc65546..fcfcb9e02 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs @@ -1139,6 +1139,38 @@ namespace Barotrauma } } + public void UpdateTransform() + { + Submarine prevSub = Submarine; + + FindHull(); + + if (Submarine == null && prevSub != null) + { + body.SetTransform(body.SimPosition + prevSub.SimPosition, body.Rotation); + } + else if (Submarine != null && prevSub == null) + { + body.SetTransform(body.SimPosition - Submarine.SimPosition, body.Rotation); + } + else if (Submarine != null && prevSub != null && Submarine != prevSub) + { + body.SetTransform(body.SimPosition + prevSub.SimPosition - Submarine.SimPosition, body.Rotation); + } + + Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition); + rect.X = (int)(displayPos.X - rect.Width / 2.0f); + rect.Y = (int)(displayPos.Y + rect.Height / 2.0f); + + if (Math.Abs(body.LinearVelocity.X) > NetConfig.MaxPhysicsBodyVelocity || + Math.Abs(body.LinearVelocity.Y) > NetConfig.MaxPhysicsBodyVelocity) + { + body.LinearVelocity = new Vector2( + MathHelper.Clamp(body.LinearVelocity.X, -NetConfig.MaxPhysicsBodyVelocity, NetConfig.MaxPhysicsBodyVelocity), + MathHelper.Clamp(body.LinearVelocity.Y, -NetConfig.MaxPhysicsBodyVelocity, NetConfig.MaxPhysicsBodyVelocity)); + } + } + public void UpdateTransform() { Submarine prevSub = Submarine; diff --git a/Barotrauma/BarotraumaShared/Source/Map/Hull.cs b/Barotrauma/BarotraumaShared/Source/Map/Hull.cs index ff3d5557d..b3d4e67fc 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Hull.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Hull.cs @@ -533,6 +533,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/Submarines/RemoraDrone.sub b/Barotrauma/BarotraumaShared/Submarines/RemoraDrone.sub index 30fd1a083..eb9b88997 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/RemoraDrone.sub and b/Barotrauma/BarotraumaShared/Submarines/RemoraDrone.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Selkie.sub b/Barotrauma/BarotraumaShared/Submarines/Selkie.sub index d1f2e056f..3252dd755 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Selkie.sub and b/Barotrauma/BarotraumaShared/Submarines/Selkie.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Typhon.sub b/Barotrauma/BarotraumaShared/Submarines/Typhon.sub index 4a0fe1857..8605eff50 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Typhon.sub and b/Barotrauma/BarotraumaShared/Submarines/Typhon.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Venture.sub b/Barotrauma/BarotraumaShared/Submarines/Venture.sub index ce2074cc1..834680457 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Venture.sub and b/Barotrauma/BarotraumaShared/Submarines/Venture.sub differ