diff --git a/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterHUD.cs b/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterHUD.cs index 80cfe1057..c4b648ed1 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterHUD.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterHUD.cs @@ -55,6 +55,10 @@ namespace Barotrauma }; TopContainer.Visible = SideContainer.Visible = false; + TopContainer.CanBeFocused = false; + TopContainer.Children.ForEach(c => c.CanBeFocused = false); + SideContainer.CanBeFocused = false; + SideContainer.Children.ForEach(c => c.CanBeFocused = false); } } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Fonts/ScalableFont.cs b/Barotrauma/BarotraumaClient/ClientSource/Fonts/ScalableFont.cs index b1e93b11c..2c6ab92ac 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Fonts/ScalableFont.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Fonts/ScalableFont.cs @@ -465,7 +465,7 @@ namespace Barotrauma if (currentRichTextData != null && currentRichTextData.StartIndex + lineNum <= i + rtdOffset && i + rtdOffset <= currentRichTextData.EndIndex + lineNum) { - currentTextColor = currentRichTextData.Color ?? color; + currentTextColor = currentRichTextData.Color * currentRichTextData.Alpha ?? color; if (!string.IsNullOrEmpty(currentRichTextData.Metadata)) { currentTextColor = Color.Lerp(currentTextColor, Color.White, 0.5f); diff --git a/Barotrauma/BarotraumaClient/ClientSource/GUI/ChatBox.cs b/Barotrauma/BarotraumaClient/ClientSource/GUI/ChatBox.cs index 67ad9e918..a9b3e4e50 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/GUI/ChatBox.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/GUI/ChatBox.cs @@ -584,6 +584,7 @@ namespace Barotrauma if (ToggleOpen) { + GUIFrame.CanBeFocused = true; openState += deltaTime * 5.0f; //delete all popup messages when the chatbox is open foreach (var popupMsg in popupMessages) @@ -594,6 +595,7 @@ namespace Barotrauma } else { + GUIFrame.CanBeFocused = false; openState -= deltaTime * 5.0f; int yOffset = 0; diff --git a/Barotrauma/BarotraumaClient/ClientSource/GUI/GUITextBlock.cs b/Barotrauma/BarotraumaClient/ClientSource/GUI/GUITextBlock.cs index 46941f61d..952cded4d 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/GUI/GUITextBlock.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/GUI/GUITextBlock.cs @@ -263,6 +263,8 @@ namespace Barotrauma public bool HasColorHighlight => RichTextData != null; + public bool OverrideRichTextDataAlpha = true; + public struct ClickableArea { public RichTextData Data; @@ -645,10 +647,13 @@ namespace Barotrauma } Font.DrawString(spriteBatch, textToShow, pos, colorToShow, 0.0f, origin, TextScale, SpriteEffects.None, textDepth); - } else { + if (OverrideRichTextDataAlpha) + { + RichTextData.ForEach(rt => rt.Alpha = currentTextColor.A / 255.0f); + } Font.DrawStringWithColors(spriteBatch, Censor ? censoredText : (Wrap ? wrappedText : text), pos, currentTextColor * (currentTextColor.A / 255.0f), 0.0f, origin, TextScale, SpriteEffects.None, textDepth, RichTextData); } diff --git a/Barotrauma/BarotraumaClient/ClientSource/GUI/GUITextBox.cs b/Barotrauma/BarotraumaClient/ClientSource/GUI/GUITextBox.cs index 3c709beab..865184d16 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/GUI/GUITextBox.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/GUI/GUITextBox.cs @@ -626,6 +626,9 @@ namespace Barotrauma { if (Text == null) Text = ""; + // Prevent alt gr from triggering any of these as that combination is often needed for special characters + if (PlayerInput.IsAltDown()) return; + switch (command) { case '\b' when !Readonly: //backspace @@ -667,7 +670,10 @@ namespace Barotrauma } break; case (char)0x1: // ctrl-a - SelectAll(); + if (PlayerInput.IsCtrlDown()) + { + SelectAll(); + } break; case (char)0x1A when !Readonly && !SubEditorScreen.IsSubEditor(): // ctrl-z text = memento.Undo(); diff --git a/Barotrauma/BarotraumaClient/ClientSource/GameSession/CrewManager.cs b/Barotrauma/BarotraumaClient/ClientSource/GameSession/CrewManager.cs index 424596618..310378f78 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/GameSession/CrewManager.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/GameSession/CrewManager.cs @@ -917,6 +917,13 @@ namespace Barotrauma var orderInfo = (OrderInfo)userData; SetCharacterOrder(character, orderInfo.Order, orderInfo.OrderOption, CharacterInfo.HighestManualOrderPriority, Character.Controlled); return true; + }, + OnSecondaryClicked = (button, userData) => + { + if (previousOrderIconGroup == null) { return false; } + previousOrderIconGroup.RemoveChild(button); + previousOrderIconGroup.Recalculate(); + return true; } }; prevOrderFrame.RectTransform.IsFixedSize = true; diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/CharacterInventory.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/CharacterInventory.cs index 35a8c3919..73cdda02b 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/CharacterInventory.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/CharacterInventory.cs @@ -695,6 +695,7 @@ namespace Barotrauma if (firstItem != null && !DraggingItems.Contains(firstItem) && Character.Controlled?.Inventory == this && GUI.KeyboardDispatcher.Subscriber == null && !CrewManager.IsCommandInterfaceOpen && PlayerInput.InventoryKeyHit(visualSlots[i].InventoryKeyIndex)) { + if (SubEditorScreen.IsSubEditor() && SubEditorScreen.SkipInventorySlotUpdate) { continue; } #if LINUX // some window managers on Linux use windows key + number to change workspaces or perform other actions if (PlayerInput.KeyDown(Keys.RightWindows) || PlayerInput.KeyDown(Keys.LeftWindows)) { continue; } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Turret.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Turret.cs index e0873cd96..e2efa47a6 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Turret.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Turret.cs @@ -587,7 +587,7 @@ namespace Barotrauma.Items.Components //ID ushort.MaxValue = launched without a projectile if (projectileID == ushort.MaxValue) { - Launch(null); + Launch(null, user); } else { @@ -596,7 +596,7 @@ namespace Barotrauma.Items.Components DebugConsole.ThrowError("Failed to launch a projectile - item with the ID \"" + projectileID + " not found"); return; } - Launch(projectile, launchRotation: newTargetRotation); + Launch(projectile, user, launchRotation: newTargetRotation); } } } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Networking/ServerSettings.cs b/Barotrauma/BarotraumaClient/ClientSource/Networking/ServerSettings.cs index 83f0362db..341085ff1 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Networking/ServerSettings.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Networking/ServerSettings.cs @@ -134,6 +134,7 @@ namespace Barotrauma.Networking HasPassword = incMsg.ReadBoolean(); IsPublic = incMsg.ReadBoolean(); GameMain.NetLobbyScreen.SetPublic(IsPublic); + AllowFileTransfers = incMsg.ReadBoolean(); incMsg.ReadPadBits(); TickRate = incMsg.ReadRangedInteger(1, 60); GameMain.NetworkMember.TickRate = TickRate; diff --git a/Barotrauma/BarotraumaClient/ClientSource/Particles/Particle.cs b/Barotrauma/BarotraumaClient/ClientSource/Particles/Particle.cs index 959915944..55dc6e385 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Particles/Particle.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Particles/Particle.cs @@ -27,7 +27,8 @@ namespace Barotrauma.Particles private float angularVelocity; private Vector2 dragVec = Vector2.Zero; - private int dragWait = 0; + private float dragWait = 0; + private float collisionIgnoreTimer = 0; private Vector2 size; private Vector2 sizeChange; @@ -103,7 +104,7 @@ namespace Barotrauma.Particles return debugName; } - public void Init(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation, Hull hullGuess = null, bool drawOnTop = false) + public void Init(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation, Hull hullGuess = null, bool drawOnTop = false, float collisionIgnoreTimer = 0f) { this.prefab = prefab; debugName = $"Particle ({prefab.Name})"; @@ -174,14 +175,22 @@ namespace Barotrauma.Particles } DrawOnTop = drawOnTop; + + this.collisionIgnoreTimer = collisionIgnoreTimer; } - public bool Update(float deltaTime) + public enum UpdateResult + { + Normal, + Delete + } + + public UpdateResult Update(float deltaTime) { if (startDelay > 0.0f) { startDelay -= deltaTime; - return true; + return UpdateResult.Normal; } prevPosition = position; @@ -251,7 +260,7 @@ namespace Barotrauma.Particles } lifeTime -= deltaTime; - if (lifeTime <= 0.0f || color.A <= 0 || size.X <= 0.0f || size.Y <= 0.0f) { return false; } + if (lifeTime <= 0.0f || color.A <= 0 || size.X <= 0.0f || size.Y <= 0.0f) { return UpdateResult.Delete; } if (hasSubEmitters) { @@ -261,7 +270,13 @@ namespace Barotrauma.Particles } } - if (!prefab.UseCollision) { return true; } + if (collisionIgnoreTimer > 0f) + { + collisionIgnoreTimer -= deltaTime; + if (collisionIgnoreTimer <= 0f) { currentHull ??= Hull.FindHull(position); } + return UpdateResult.Normal; + } + if (!prefab.UseCollision) { return UpdateResult.Normal; } if (HighQualityCollisionDetection) { @@ -278,17 +293,17 @@ namespace Barotrauma.Particles } } - return true; + return UpdateResult.Normal; } - private bool CollisionUpdate() + private UpdateResult CollisionUpdate() { if (currentHull == null) { Hull collidedHull = Hull.FindHull(position); if (collidedHull != null) { - if (prefab.DeleteOnCollision) return false; + if (prefab.DeleteOnCollision) return UpdateResult.Delete; OnWallCollisionOutside(collidedHull); } } @@ -298,12 +313,12 @@ namespace Barotrauma.Particles Vector2 collisionNormal = Vector2.Zero; if (velocity.Y < 0.0f && position.Y - prefab.CollisionRadius * size.Y < hullRect.Y - hullRect.Height) { - if (prefab.DeleteOnCollision) { return false; } + if (prefab.DeleteOnCollision) { return UpdateResult.Delete; } collisionNormal = new Vector2(0.0f, 1.0f); } else if (velocity.Y > 0.0f && position.Y + prefab.CollisionRadius * size.Y > hullRect.Y) { - if (prefab.DeleteOnCollision) { return false; } + if (prefab.DeleteOnCollision) { return UpdateResult.Delete; } collisionNormal = new Vector2(0.0f, -1.0f); } @@ -328,12 +343,12 @@ namespace Barotrauma.Particles if (velocity.X < 0.0f && position.X - prefab.CollisionRadius * size.X < hullRect.X) { - if (prefab.DeleteOnCollision) { return false; } + if (prefab.DeleteOnCollision) { return UpdateResult.Delete; } collisionNormal = new Vector2(1.0f, 0.0f); } else if (velocity.X > 0.0f && position.X + prefab.CollisionRadius * size.X > hullRect.Right) { - if (prefab.DeleteOnCollision) { return false; } + if (prefab.DeleteOnCollision) { return UpdateResult.Delete; } collisionNormal = new Vector2(-1.0f, 0.0f); } @@ -374,7 +389,7 @@ namespace Barotrauma.Particles } } - return true; + return UpdateResult.Normal; } private void ApplyDrag(float dragCoefficient, float deltaTime) @@ -389,10 +404,10 @@ namespace Barotrauma.Particles //TODO: some better way to handle particle drag //this doesn't work that well because the drag vector is only updated every 0.5 seconds, allowing the particle to accelerate way more than it should //(e.g. a falling particle can freely accelerate for 0.5 seconds before the drag takes effect) - dragWait--; - if (dragWait <= 0) + dragWait-=deltaTime; + if (dragWait <= 0f) { - dragWait = 30; + dragWait = 0.5f; float speed = velocity.Length(); diff --git a/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticleManager.cs b/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticleManager.cs index 68e4cc78c..bfc43ae7b 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticleManager.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticleManager.cs @@ -115,12 +115,12 @@ namespace Barotrauma.Particles Prefabs.RemoveByFile(configFile); } - public Particle CreateParticle(string prefabName, Vector2 position, float angle, float speed, Hull hullGuess = null) + public Particle CreateParticle(string prefabName, Vector2 position, float angle, float speed, Hull hullGuess = null, float collisionIgnoreTimer = 0f) { - return CreateParticle(prefabName, position, new Vector2((float)Math.Cos(angle), (float)-Math.Sin(angle)) * speed, angle, hullGuess); + return CreateParticle(prefabName, position, new Vector2((float)Math.Cos(angle), (float)-Math.Sin(angle)) * speed, angle, hullGuess, collisionIgnoreTimer); } - public Particle CreateParticle(string prefabName, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null) + public Particle CreateParticle(string prefabName, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null, float collisionIgnoreTimer = 0f) { ParticlePrefab prefab = FindPrefab(prefabName); @@ -130,10 +130,10 @@ namespace Barotrauma.Particles return null; } - return CreateParticle(prefab, position, velocity, rotation, hullGuess); + return CreateParticle(prefab, position, velocity, rotation, hullGuess, collisionIgnoreTimer: collisionIgnoreTimer); } - public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null, bool drawOnTop = false) + public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null, bool drawOnTop = false, float collisionIgnoreTimer = 0f) { if (particleCount >= MaxParticles || prefab == null || prefab.Sprites.Count == 0) { return null; } @@ -149,7 +149,7 @@ namespace Barotrauma.Particles if (particles[particleCount] == null) particles[particleCount] = new Particle(); - particles[particleCount].Init(prefab, position, velocity, rotation, hullGuess, drawOnTop); + particles[particleCount].Init(prefab, position, velocity, rotation, hullGuess, drawOnTop, collisionIgnoreTimer); particleCount++; @@ -181,10 +181,10 @@ namespace Barotrauma.Particles for (int i = 0; i < particleCount; i++) { - bool remove = false; + bool remove; try { - remove = !particles[i].Update(deltaTime); + remove = particles[i].Update(deltaTime) == Particle.UpdateResult.Delete; } catch (Exception e) { diff --git a/Barotrauma/BarotraumaClient/ClientSource/PlayerInput.cs b/Barotrauma/BarotraumaClient/ClientSource/PlayerInput.cs index f4a86f565..a2a3d770e 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/PlayerInput.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/PlayerInput.cs @@ -476,6 +476,11 @@ namespace Barotrauma #endif } + public static bool IsAltDown() + { + return KeyDown(Keys.LeftAlt) || KeyDown(Keys.RightAlt); + } + public static void Update(double deltaTime) { timeSinceClick += deltaTime; diff --git a/Barotrauma/BarotraumaClient/ClientSource/Screens/SubEditorScreen.cs b/Barotrauma/BarotraumaClient/ClientSource/Screens/SubEditorScreen.cs index cf0d71c47..f6c80e961 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Screens/SubEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Screens/SubEditorScreen.cs @@ -111,6 +111,8 @@ namespace Barotrauma public static bool TransparentWiringMode = true; + public static bool SkipInventorySlotUpdate; + private static object bulkItemBufferinUse; public static object BulkItemBufferInUse @@ -4109,6 +4111,7 @@ namespace Barotrauma /// public override void Update(double deltaTime) { + SkipInventorySlotUpdate = false; ImageManager.Update((float) deltaTime); if (GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y) @@ -4222,11 +4225,15 @@ namespace Barotrauma } List numberKeys = PlayerInput.NumberKeys; - if (numberKeys.Find(PlayerInput.KeyHit) is { } key) + if (numberKeys.Find(PlayerInput.KeyHit) is { } key && key != Keys.None) { // treat 0 as the last key instead of first int index = key == Keys.D0 ? numberKeys.Count : numberKeys.IndexOf(key) - 1; - listBox.Select(index, force: false, autoScroll: true, takeKeyBoardFocus: false); + if (index > -1 && index < listBox.Content.CountChildren) + { + listBox.Select(index, force: false, autoScroll: true, takeKeyBoardFocus: false); + SkipInventorySlotUpdate = true; + } } } } diff --git a/Barotrauma/BarotraumaClient/LinuxClient.csproj b/Barotrauma/BarotraumaClient/LinuxClient.csproj index ee86cc731..ae68bea09 100644 --- a/Barotrauma/BarotraumaClient/LinuxClient.csproj +++ b/Barotrauma/BarotraumaClient/LinuxClient.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma - 0.1300.0.5 + 0.1300.0.7 Copyright © FakeFish 2018-2020 AnyCPU;x64 Barotrauma diff --git a/Barotrauma/BarotraumaClient/MacClient.csproj b/Barotrauma/BarotraumaClient/MacClient.csproj index 728b21e0e..3075445f0 100644 --- a/Barotrauma/BarotraumaClient/MacClient.csproj +++ b/Barotrauma/BarotraumaClient/MacClient.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma - 0.1300.0.5 + 0.1300.0.7 Copyright © FakeFish 2018-2020 AnyCPU;x64 Barotrauma diff --git a/Barotrauma/BarotraumaClient/WindowsClient.csproj b/Barotrauma/BarotraumaClient/WindowsClient.csproj index 3b2a9a51f..d49271552 100644 --- a/Barotrauma/BarotraumaClient/WindowsClient.csproj +++ b/Barotrauma/BarotraumaClient/WindowsClient.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma - 0.1300.0.5 + 0.1300.0.7 Copyright © FakeFish 2018-2020 AnyCPU;x64 Barotrauma diff --git a/Barotrauma/BarotraumaClient/libfreetype6.so b/Barotrauma/BarotraumaClient/libfreetype6.so index 797dadf66..b6380ba49 100644 Binary files a/Barotrauma/BarotraumaClient/libfreetype6.so and b/Barotrauma/BarotraumaClient/libfreetype6.so differ diff --git a/Barotrauma/BarotraumaClient/webm_mem_playback_x64.so b/Barotrauma/BarotraumaClient/webm_mem_playback_x64.so index 5a5e0c642..37a47f811 100644 Binary files a/Barotrauma/BarotraumaClient/webm_mem_playback_x64.so and b/Barotrauma/BarotraumaClient/webm_mem_playback_x64.so differ diff --git a/Barotrauma/BarotraumaServer/LinuxServer.csproj b/Barotrauma/BarotraumaServer/LinuxServer.csproj index 1c08b89db..33795219b 100644 --- a/Barotrauma/BarotraumaServer/LinuxServer.csproj +++ b/Barotrauma/BarotraumaServer/LinuxServer.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma Dedicated Server - 0.1300.0.5 + 0.1300.0.7 Copyright © FakeFish 2018-2020 AnyCPU;x64 DedicatedServer diff --git a/Barotrauma/BarotraumaServer/MacServer.csproj b/Barotrauma/BarotraumaServer/MacServer.csproj index 4ec4c5f8a..94a2bef25 100644 --- a/Barotrauma/BarotraumaServer/MacServer.csproj +++ b/Barotrauma/BarotraumaServer/MacServer.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma Dedicated Server - 0.1300.0.5 + 0.1300.0.7 Copyright © FakeFish 2018-2020 AnyCPU;x64 DedicatedServer diff --git a/Barotrauma/BarotraumaServer/ServerSource/Characters/CharacterNetworking.cs b/Barotrauma/BarotraumaServer/ServerSource/Characters/CharacterNetworking.cs index bebadfc29..1e90df4f0 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Characters/CharacterNetworking.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Characters/CharacterNetworking.cs @@ -111,7 +111,7 @@ namespace Barotrauma // -> correct the position and the state of the Holdable component (in case the item was deattached client-side) item.PositionUpdateInterval = 0.0f; var holdable = item.GetComponent(); - holdable.Item?.CreateServerEvent(holdable); + holdable?.Item?.CreateServerEvent(holdable); } } else if (closestEntity is Character character) diff --git a/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs b/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs index 47ef711ac..a22805f97 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs @@ -2177,6 +2177,11 @@ namespace Barotrauma.Networking { respawnManager = new RespawnManager(this, serverSettings.UseRespawnShuttle && !isOutpost ? selectedShuttle : null); } + if (campaign != null) + { + campaign.CargoManager.CreatePurchasedItems(); + campaign.SendCrewState(null, default, null); + } Level.Loaded?.SpawnNPCs(); Level.Loaded?.SpawnCorpses(); diff --git a/Barotrauma/BarotraumaServer/ServerSource/Networking/ServerSettings.cs b/Barotrauma/BarotraumaServer/ServerSource/Networking/ServerSettings.cs index 4d4d61940..1f2107de1 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Networking/ServerSettings.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Networking/ServerSettings.cs @@ -49,6 +49,7 @@ namespace Barotrauma.Networking outMsg.Write((byte)MaxPlayers); outMsg.Write(HasPassword); outMsg.Write(IsPublic); + outMsg.Write(AllowFileTransfers); outMsg.WritePadBits(); outMsg.WriteRangedInteger(TickRate, 1, 60); diff --git a/Barotrauma/BarotraumaServer/WindowsServer.csproj b/Barotrauma/BarotraumaServer/WindowsServer.csproj index 06cdd2997..fa532bfbe 100644 --- a/Barotrauma/BarotraumaServer/WindowsServer.csproj +++ b/Barotrauma/BarotraumaServer/WindowsServer.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma Dedicated Server - 0.1300.0.5 + 0.1300.0.7 Copyright © FakeFish 2018-2020 AnyCPU;x64 DedicatedServer diff --git a/Barotrauma/BarotraumaShared/Data/ContentPackages/Vanilla 0.9.xml b/Barotrauma/BarotraumaShared/Data/ContentPackages/Vanilla 0.9.xml index bb1ccd4e0..47ab60408 100644 --- a/Barotrauma/BarotraumaShared/Data/ContentPackages/Vanilla 0.9.xml +++ b/Barotrauma/BarotraumaShared/Data/ContentPackages/Vanilla 0.9.xml @@ -100,6 +100,7 @@ + diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/EnemyAIController.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/EnemyAIController.cs index 9168a5e7e..dc73b621c 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/EnemyAIController.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/EnemyAIController.cs @@ -765,7 +765,7 @@ namespace Barotrauma { var location = memory.Location; float dist = Vector2.DistanceSquared(WorldPosition, location); - if (dist < 50 * 50) + if (dist < 50 * 50 || !IsPositionInsideAllowedZone(WorldPosition, out _)) { // Target is gone ResetAITarget(); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/HumanAIController.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/HumanAIController.cs index cbcf87483..b0c793796 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/HumanAIController.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/HumanAIController.cs @@ -1848,49 +1848,68 @@ namespace Barotrauma public static bool IsItemOperatedByAnother(Character character, ItemComponent target, out Character operatingCharacter) { operatingCharacter = null; + if (character == null) { return false; } if (target?.Item == null) { return false; } + bool isOrder = IsOrderedToOperateThis(character.AIController); foreach (var c in Character.CharacterList) { - if (character == null) { continue; } if (c == character) { continue; } if (c.IsDead || c.IsIncapacitated) { continue; } if (!IsFriendly(character, c, onlySameTeam: true)) { continue; } operatingCharacter = c; - if (c.AIController is HumanAIController controllingHumanAi) + if (c.IsPlayer) { - Item otherTarget = controllingHumanAi.objectiveManager.GetActiveObjective()?.Component.Item ?? c.SelectedConstruction; - if (otherTarget != target.Item) { continue; } - // If the other character is player, don't try to operate - if (c.IsPlayer) { return true; } - // If the other character is ordered to operate the item, let him do it - if (controllingHumanAi.ObjectiveManager.IsCurrentOrder()) + if (c.SelectedConstruction == target.Item) { + // If the other character is player, don't try to operate + return true; + } + } + else if (c.AIController is HumanAIController operatingAI) + { + if (operatingAI.ObjectiveManager.Objectives.None(o => o is AIObjectiveOperateItem operateObjective && operateObjective.Component.Item == target.Item)) + { + // Not targeting the same item. + continue; + } + bool isTargetOrdered = IsOrderedToOperateThis(c.AIController); + if (!isOrder && isTargetOrdered) + { + // If the other bot is ordered to operate the item, let him do it, unless we are ordered too return true; } else { - if (character == null) + if (isOrder && !isTargetOrdered) { - return true; - } - else if (target is Steering) - { - // Steering is hard-coded -> cannot use the required skills collection defined in the xml - return character.GetSkillLevel("helm") <= c.GetSkillLevel("helm"); + // We are ordered and the target is not -> allow to operate + continue; } else { - return target.DegreeOfSuccess(character) <= target.DegreeOfSuccess(c); + if (!isTargetOrdered && operatingAI.ObjectiveManager.CurrentOrder == operatingAI.ObjectiveManager.CurrentObjective) + { + // The other bot is ordered to do something else + continue; + } + if (target is Steering) + { + // Steering is hard-coded -> cannot use the required skills collection defined in the xml + if (character.GetSkillLevel("helm") <= c.GetSkillLevel("helm")) + { + return true; + } + } + else if (target.DegreeOfSuccess(character) <= target.DegreeOfSuccess(c)) + { + return true; + } } } } - else - { - return c.SelectedConstruction == target.Item; - } - } return false; + bool IsOrderedToOperateThis(AIController ai) => ai is HumanAIController humanAI && humanAI.ObjectiveManager.CurrentOrder is AIObjectiveOperateItem operateObjective && operateObjective.Component.Item == target.Item; } #region Wrappers diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveGetItem.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveGetItem.cs index 4490d4f1a..f055f2828 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveGetItem.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveGetItem.cs @@ -415,7 +415,7 @@ namespace Barotrauma #if DEBUG DebugConsole.NewMessage($"{character.Name}: Get item failed to reach {moveToTarget}", Color.Yellow); #endif - if (character.IsOnPlayerTeam && objectiveManager.CurrentOrder != null) + if (character.IsOnPlayerTeam && objectiveManager.CurrentOrder == objectiveManager.CurrentObjective) { string TargetName = (moveToTarget as MapEntity)?.Name ?? (moveToTarget as Character)?.Name ?? moveToTarget.ToString(); string msg = TargetName == null ? TextManager.Get("dialogcannotreachtarget", true) : TextManager.GetWithVariable("dialogcannotreachtarget", "[name]", TargetName, formatCapitals: !(moveToTarget is Character)); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveGoTo.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveGoTo.cs index ebc959fee..2afb92417 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveGoTo.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveGoTo.cs @@ -147,7 +147,7 @@ namespace Barotrauma #if DEBUG DebugConsole.NewMessage($"{character.Name}: Cannot reach the target: {Target}", Color.Yellow); #endif - if (character.IsOnPlayerTeam && objectiveManager.CurrentOrder != null && DialogueIdentifier != null && SpeakIfFails) + if (character.IsOnPlayerTeam && objectiveManager.CurrentOrder == objectiveManager.CurrentObjective && DialogueIdentifier != null && SpeakIfFails) { string msg = TargetName == null ? TextManager.Get(DialogueIdentifier, true) : TextManager.GetWithVariable(DialogueIdentifier, "[name]", TargetName, formatCapitals: !(Target is Character)); if (msg != null) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveManager.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveManager.cs index 90b22484a..99d2d2cfd 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveManager.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveManager.cs @@ -132,7 +132,13 @@ namespace Barotrauma } var order = new Order(orderPrefab, item ?? character.CurrentHull as Entity, orderPrefab.GetTargetItemComponent(item), orderGiver: character); if (order == null) { continue; } - if (autonomousObjective.ignoreAtOutpost && Level.IsLoadedOutpost && character.TeamID != CharacterTeamType.FriendlyNPC) { continue; } + if (autonomousObjective.ignoreAtOutpost && Level.IsLoadedOutpost && character.TeamID != CharacterTeamType.FriendlyNPC) + { + if (Submarine.MainSub != null && Submarine.MainSub.DockedTo.None(s => s.TeamID != CharacterTeamType.FriendlyNPC && s.TeamID != character.TeamID)) + { + continue; + } + } var objective = CreateObjective(order, autonomousObjective.option, character, isAutonomous: true, autonomousObjective.priorityModifier); if (objective != null && objective.CanBeCompleted) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveOperateItem.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveOperateItem.cs index 7312c2945..de9a89281 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveOperateItem.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveOperateItem.cs @@ -121,7 +121,7 @@ namespace Barotrauma { float value = CumulatedDevotion + (AIObjectiveManager.LowestOrderPriority * PriorityModifier); float max = AIObjectiveManager.LowestOrderPriority - 1; - if (reactor != null && reactor.PowerOn && Option == "powerup") + if (reactor != null && reactor.PowerOn && reactor.FissionRate > 1 && Option == "powerup") { // Decrease the priority when targeting a reactor that is already on. value /= 2; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs index 913ad3609..5276666c7 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs @@ -1343,6 +1343,22 @@ namespace Barotrauma /// public float SpeedMultiplier { get; private set; } = 1; + + private double propulsionSpeedMultiplierLastSet; + private float propulsionSpeedMultiplier; + /// + /// Can be used to modify the speed at which Propulsion ItemComponents move the character via StatusEffects (e.g. heavy suit can slow down underwater scooters) + /// + public float PropulsionSpeedMultiplier + { + get { return propulsionSpeedMultiplier; } + set + { + propulsionSpeedMultiplier = value; + propulsionSpeedMultiplierLastSet = Timing.TotalTime; + } + } + public void StackSpeedMultiplier(float val) { if (val < 1f) @@ -1365,6 +1381,10 @@ namespace Barotrauma { greatestPositiveSpeedMultiplier = 1f; greatestNegativeSpeedMultiplier = 1f; + if (Timing.TotalTime > propulsionSpeedMultiplierLastSet + 0.1) + { + propulsionSpeedMultiplier = 1.0f; + } } private float greatestNegativeHealthMultiplier = 1f; @@ -3420,6 +3440,7 @@ namespace Barotrauma if (statusEffect.type != actionType) { continue; } if (statusEffect.type == ActionType.OnDamaged) { + if (LastDamage.Afflictions == null || LastDamage.Afflictions.None(a => a.Prefab.AfflictionType == "damage")) { continue; } if (statusEffect.OnlyPlayerTriggered) { if (LastAttacker == null || !LastAttacker.IsPlayer) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Limb.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Limb.cs index 7f3a83ed3..310c2fec9 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Limb.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Limb.cs @@ -1127,6 +1127,7 @@ namespace Barotrauma if (statusEffect.type != actionType) { continue; } if (statusEffect.type == ActionType.OnDamaged) { + if (character.LastDamage.Afflictions == null || character.LastDamage.Afflictions.None(a => a.Prefab.AfflictionType == "damage")) { continue; } if (statusEffect.OnlyPlayerTriggered) { if (character.LastAttacker == null || !character.LastAttacker.IsPlayer) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Events/EventActions/UnlockPathAction.cs b/Barotrauma/BarotraumaShared/SharedSource/Events/EventActions/UnlockPathAction.cs index 1899c5c19..14c0c9763 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Events/EventActions/UnlockPathAction.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Events/EventActions/UnlockPathAction.cs @@ -26,7 +26,6 @@ namespace Barotrauma public override void Update(float deltaTime) { if (isFinished) { return; } - GameMain.GameSession?.Map?.CurrentLocation?.Connections.ForEach(c => c.Locked = false); if (GameMain.GameSession?.Map?.CurrentLocation?.Connections != null) { foreach (LocationConnection connection in GameMain.GameSession?.Map?.CurrentLocation?.Connections) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Events/EventManager.cs b/Barotrauma/BarotraumaShared/SharedSource/Events/EventManager.cs index c5b6cecdd..94784bb08 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Events/EventManager.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Events/EventManager.cs @@ -418,6 +418,7 @@ namespace Barotrauma List> unusedEvents = new List>(suitablePrefabs); for (int j = 0; j < eventSet.EventCount; j++) { + if (unusedEvents.All(e => CalculateCommonness(e) <= 0.0f)) { break; } var eventPrefab = ToolBox.SelectWeightedRandom(unusedEvents, unusedEvents.Select(e => CalculateCommonness(e)).ToList(), rand); if (eventPrefab != null) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Events/Missions/OutpostDestroyMission.cs b/Barotrauma/BarotraumaShared/SharedSource/Events/Missions/OutpostDestroyMission.cs index 6ec26f062..029db236f 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Events/Missions/OutpostDestroyMission.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Events/Missions/OutpostDestroyMission.cs @@ -100,7 +100,7 @@ namespace Barotrauma { spawnPos = new Vector2( MathHelper.Clamp(wp.WorldPosition.X + Rand.Range(-200, 200), wp.CurrentHull.WorldRect.X, wp.CurrentHull.WorldRect.Right), - wp.CurrentHull.WorldRect.Y - wp.CurrentHull.Rect.Height + 10.0f); + wp.CurrentHull.WorldRect.Y - wp.CurrentHull.Rect.Height + 16.0f); } var item = new Item(itemPrefab, spawnPos, null); items.Add(item); diff --git a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs index b5c48766e..3c8b2bd10 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs @@ -478,13 +478,6 @@ namespace Barotrauma } if (GameMode is MultiPlayerCampaign mpCampaign) { - if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer) - { - mpCampaign.CargoManager.CreatePurchasedItems(); -#if SERVER - mpCampaign.SendCrewState(null, default, null); -#endif - } mpCampaign.UpgradeManager.ApplyUpgrades(); mpCampaign.UpgradeManager.SanityCheckUpgrades(Submarine); } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/Propulsion.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/Propulsion.cs index 945b05189..7e5aa6ddd 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/Propulsion.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/Propulsion.cs @@ -41,25 +41,25 @@ namespace Barotrauma.Items.Components public override bool Use(float deltaTime, Character character = null) { if (character == null || character.Removed) return false; - if (!character.IsKeyDown(InputType.Aim) || character.Stun > 0.0f) return false; + if (!character.IsKeyDown(InputType.Aim) || character.Stun > 0.0f) { return false; } IsActive = true; useState = 0.1f; if (character.AnimController.InWater) { - if (UsableIn == UseEnvironment.Air) return true; + if (UsableIn == UseEnvironment.Air) { return true; } } else { - if (UsableIn == UseEnvironment.Water) return true; + if (UsableIn == UseEnvironment.Water) { return true; } } Vector2 dir = Vector2.Normalize(character.CursorPosition - character.Position); //move upwards if the cursor is at the position of the character if (!MathUtils.IsValid(dir)) dir = Vector2.UnitY; - Vector2 propulsion = dir * Force; + Vector2 propulsion = dir * Force * character.PropulsionSpeedMultiplier; if (character.AnimController.InWater) character.AnimController.TargetMovement = dir; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Reactor.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Reactor.cs index 592a01cc9..0a66e7c23 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Reactor.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Reactor.cs @@ -333,7 +333,7 @@ namespace Barotrauma.Items.Components if (item.CurrentHull != null) { var aiTarget = item.CurrentHull.AiTarget; - if (aiTarget != null) + if (aiTarget != null && MaxPowerOutput > 0) { float range = Math.Abs(currPowerConsumption) / MaxPowerOutput; float noise = MathHelper.Lerp(aiTarget.MinSoundRange, aiTarget.MaxSoundRange, range); @@ -341,7 +341,7 @@ namespace Barotrauma.Items.Components } } - if (item.AiTarget != null) + if (item.AiTarget != null && MaxPowerOutput > 0) { var aiTarget = item.AiTarget; float range = Math.Abs(currPowerConsumption) / MaxPowerOutput; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Steering.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Steering.cs index e4a16ab57..c61efaf2c 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Steering.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Steering.cs @@ -711,7 +711,7 @@ namespace Barotrauma.Items.Components steeringAdjustSpeed = DefaultSteeringAdjustSpeed; steeringInput = XMLExtensions.ParseVector2(signal.value, errorMessages: false); steeringInput.X = MathHelper.Clamp(steeringInput.X, -100.0f, 100.0f); - steeringInput.Y = MathHelper.Clamp(steeringInput.Y, -100.0f, 100.0f); + steeringInput.Y = MathHelper.Clamp(-steeringInput.Y, -100.0f, 100.0f); } else { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs index dca0ec85d..3717fa3e4 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs @@ -1,13 +1,10 @@ -using FarseerPhysics; +using Barotrauma.IO; +using Barotrauma.Items.Components; using Microsoft.Xna.Framework; using System; using System.Collections.Generic; -using Barotrauma.IO; -using System.Xml.Linq; using System.Linq; -using Barotrauma.Items.Components; -using Barotrauma.Extensions; -using Voronoi2; +using System.Xml.Linq; namespace Barotrauma { @@ -1077,7 +1074,10 @@ namespace Barotrauma priceInfo = null; if (location?.Type == null) { return false; } priceInfo = GetPriceInfo(location); - return priceInfo != null && priceInfo.CanBeBought; + return + priceInfo != null && + priceInfo.CanBeBought && + (location.LevelData?.Difficulty ?? 0) >= priceInfo.MinLevelDifficulty; } public static ItemPrefab Find(string name, string identifier) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/Map/Map.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/Map/Map.cs index c6ada18cf..da547ecb3 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/Map/Map.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/Map/Map.cs @@ -419,7 +419,7 @@ namespace Barotrauma int zone1 = GetZoneIndex(Connections[i].Locations[0].MapPosition.X); int zone2 = GetZoneIndex(Connections[i].Locations[1].MapPosition.X); if (zone1 == zone2) { continue; } - if (zone2 == generationParams.DifficultyZones) { continue; } + if (zone1 == generationParams.DifficultyZones || zone2 == generationParams.DifficultyZones) { continue; } if (!connectionsBetweenZones.Contains(Connections[i])) { @@ -464,7 +464,10 @@ namespace Barotrauma foreach (Location location in Locations) { - location.LevelData = new LevelData(location); + location.LevelData = new LevelData(location) + { + Difficulty = MathHelper.Clamp(location.MapPosition.X / Width * 100, 0.0f, 100.0f) + }; if (location.Type.MissionIdentifiers.Any()) { location.UnlockMissionByIdentifier(location.Type.MissionIdentifiers.GetRandom()); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/PriceInfo.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/PriceInfo.cs index e9eea6444..78a7e14f3 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/PriceInfo.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/PriceInfo.cs @@ -20,15 +20,20 @@ namespace Barotrauma /// Can the item be a Daily Special or a Requested Good /// public readonly bool CanBeSpecial; + /// + /// The item isn't available in stores unless the level's difficulty is above this value + /// + public readonly int MinLevelDifficulty; /// /// Support for the old style of determining item prices /// when there were individual Price elements for each location type /// where the item was for sale. /// - public PriceInfo (XElement element) + public PriceInfo(XElement element) { Price = element.GetAttributeInt("buyprice", 0); + MinLevelDifficulty = element.GetAttributeInt("minleveldifficulty", 0); CanBeBought = true; var minAmount = GetMinAmount(element); MinAvailableAmount = Math.Min(minAmount, CargoManager.MaxQuantity); @@ -37,13 +42,14 @@ namespace Barotrauma MaxAvailableAmount = Math.Max(maxAmount, MinAvailableAmount); } - public PriceInfo(int price, bool canBeBought, int minAmount = 0, int maxAmount = 0, bool canBeSpecial = true) + public PriceInfo(int price, bool canBeBought, int minAmount = 0, int maxAmount = 0, bool canBeSpecial = true, int minLevelDifficulty = 0) { Price = price; CanBeBought = canBeBought; MinAvailableAmount = Math.Min(minAmount, CargoManager.MaxQuantity); maxAmount = Math.Min(maxAmount, CargoManager.MaxQuantity); MaxAvailableAmount = Math.Max(maxAmount, minAmount); + MinLevelDifficulty = minLevelDifficulty; CanBeSpecial = canBeSpecial; } @@ -54,6 +60,7 @@ namespace Barotrauma var soldByDefault = element.GetAttributeBool("soldbydefault", true); var minAmount = GetMinAmount(element); var maxAmount = GetMaxAmount(element); + var minLevelDifficulty = element.GetAttributeInt("minleveldifficulty", 0); var canBeSpecial = element.GetAttributeBool("canbespecial", true); var priceInfos = new List>(); @@ -65,14 +72,16 @@ namespace Barotrauma new PriceInfo(price: (int)(priceMultiplier * basePrice), canBeBought: sold, minAmount: sold ? GetMinAmount(childElement, minAmount) : 0, maxAmount: sold ? GetMaxAmount(childElement, maxAmount) : 0, - canBeSpecial: canBeSpecial))); + canBeSpecial, + childElement.GetAttributeInt("minleveldifficulty", minLevelDifficulty)))); } var canBeBoughtAtOtherLocations = soldByDefault && element.GetAttributeBool("soldeverywhere", true); defaultPrice = new PriceInfo(basePrice, canBeBoughtAtOtherLocations, minAmount: canBeBoughtAtOtherLocations ? minAmount : 0, maxAmount: canBeBoughtAtOtherLocations ? maxAmount : 0, - canBeSpecial: canBeSpecial); + canBeSpecial, + minLevelDifficulty); return priceInfos; } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/Structure.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/Structure.cs index 2b4fcedd4..6c7fe54dc 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/Structure.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/Structure.cs @@ -819,16 +819,12 @@ namespace Barotrauma } for (int i = 1; i <= particleAmount; i++) { + var worldRect = section.WorldRect; Vector2 particlePos = new Vector2( - Rand.Range(section.rect.X, section.rect.Right), - Rand.Range(section.rect.Y - section.rect.Height, section.rect.Y)); + Rand.Range(worldRect.X, worldRect.Right), + Rand.Range(worldRect.Y - worldRect.Height, worldRect.Y)); - if (Submarine != null) - { - particlePos += Submarine.DrawPosition; - } - - var particle = GameMain.ParticleManager.CreateParticle("shrapnel", particlePos, Rand.Vector(Rand.Range(1.0f, 50.0f))); + var particle = GameMain.ParticleManager.CreateParticle("shrapnel", particlePos, Rand.Vector(Rand.Range(1.0f, 50.0f)), collisionIgnoreTimer: 1f); if (particle == null) break; } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Utils/RichTextData.cs b/Barotrauma/BarotraumaShared/SharedSource/Utils/RichTextData.cs index 07064ae46..fd7cb014d 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Utils/RichTextData.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Utils/RichTextData.cs @@ -9,6 +9,8 @@ namespace Barotrauma public Color? Color; public string Metadata; + public float Alpha = 1.0f; + private const char definitionIndicator = '‖'; private const char attributeSeparator = ';'; private const char keyValueSeparator = ':'; diff --git a/Barotrauma/BarotraumaShared/Submarines/R-29.sub b/Barotrauma/BarotraumaShared/Submarines/R-29.sub index 52b6147ed..be89e7cf0 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/R-29.sub and b/Barotrauma/BarotraumaShared/Submarines/R-29.sub differ diff --git a/Barotrauma/BarotraumaShared/changelog.txt b/Barotrauma/BarotraumaShared/changelog.txt index 5d0ce56fd..8a18e401c 100644 --- a/Barotrauma/BarotraumaShared/changelog.txt +++ b/Barotrauma/BarotraumaShared/changelog.txt @@ -1,10 +1,43 @@ +--------------------------------------------------------------------------------------------------------- +v0.1300.0.7 (unstable) +--------------------------------------------------------------------------------------------------------- + +Changes: +- Bandit outfits aren't sold at outposts. +- Charybdis: Increased the attack cooldown from 3 to 4. Tweaked the texture. Adjusted the ragdoll and the animations. More tentacles. +- Molochs: Boosted the structural damage slightly. Increased the attack and damage ranges slightly to help the attacks to hit the target. +- Added black moloch mission variants. +- Icons for previous orders can now be removed from crew list by right-clicking on them. +- Diving suits have an effect on underwater scooter speed (slower movement when wearing an abyss suit, faster when wearing a combat suit). +- Abyss/combat diving suits aren't sold in outpost for the first quarter of the campaign. +- Nerfed nuclear shell's EMP effect. + +Fixes: +- Fixed entity IDs getting messed up when purchasing items in the MP campaign, which lead to disconnects with an "entity not found" error message. Happened because the server created the purchased items before loading the respawn shuttle, while the clients did it the other way around. +- Fixed clients not getting the prompt to download a custom sub they don't have unless they have permissions to edit server settings. +- Fixed edge of the chatbox stealing cursor focus when the chatbox is hidden (preventing firing turrets when the cursor is in the bottom-left corner of the screen). +- Fixed inconsistency in the way vertical velocity in/out signals are handled by the nav terminals. Previously "velocity_in" would interpret positive y as upwards, even though "velocity_y_out" outputs a negative value when going up. Now positive is always down (= corresponds with the "descent velocity" value displayed on the terminal). +- Fixed non-repeatable outpost events starting to repeat once all of them have been triggered. +- Fixed gate outpost still sometimes generating before the last level/biome. +- Reduced the amount of clown gear in the "Praise the Honkmother" mission to fit everything in the crate. +- Fixed boss health bars not appearing in multiplayer when damaging a boss monster with a turret. +- Fixed clients not getting notified when a path between biomes is unlocked, preventing them from proceeding without saving and reloading the campaign. +- Fixed crashing on startup with the error message "unable to load shared library 'freetype6' or one of its dependencies" on some Linux systems. +- Fixed monsters trying to follow the last target while in the idle state even when the target is outside of the allowed area (only unstable). +- Fixed multiple issues regarding bots targeting the reactor. +- Fixed OnDamaged status effect triggering from burns, poisons etc. Only afflictions of type "damage" can now trigger it. Fixes Moloch spawning a lot of particles after being hit with a nuclear shell (#5412). +- Fixed black moloch doing only 62.5% of the structure damage compared to the regular moloch. +- Fixes to R-29: fixed top docking port's control circuit, adjustments to pre-placed supplies, adjusted discharge coil power consumption, minor visual fixes. +- Fixed wall damage particles sometimes spawning at an incorrect position. + --------------------------------------------------------------------------------------------------------- v0.1300.0.6 (unstable) --------------------------------------------------------------------------------------------------------- Fixes: - Fixed bots trying to clean up items that have changed place and shouldn't be allowed to clean up anymore. Fixes #5400 - +- Fixed "attempted to set SoundRange to NaN" error when a reactor's maximum power output is 0. +- Fixed nullref exception when forcing an item position correction upon interaction failure. --------------------------------------------------------------------------------------------------------- v0.1300.0.5 (unstable)