From 3d2b7bcf63ae98b65f687dd19e7662e836ef2a0a Mon Sep 17 00:00:00 2001 From: Juan Pablo Arce Date: Fri, 15 May 2020 13:06:19 -0300 Subject: [PATCH] (63916eda9) Unstable v0.9.1001.0 --- .../Characters/AI/EnemyAIController.cs | 15 ++-- .../ClientSource/Characters/Limb.cs | 10 ++- .../Items/Components/Machines/Steering.cs | 40 ++++------- .../Items/Components/Repairable.cs | 10 ++- .../ClientSource/Items/Item.cs | 28 ++++++-- .../ClientSource/Items/ItemPrefab.cs | 4 +- .../ClientSource/Map/Submarine.cs | 1 + .../ClientSource/Networking/SteamManager.cs | 5 +- .../ClientSource/Particles/ParticleManager.cs | 10 +-- .../ClientSource/Particles/ParticlePrefab.cs | 5 ++ .../ClientSource/PlayerInput.cs | 4 ++ .../ClientSource/Screens/SubEditorScreen.cs | 5 +- .../ClientSource/Sounds/Sound.cs | 2 + .../ClientSource/Sounds/SoundPlayer.cs | 8 ++- .../DeformAnimations/CustomDeformation.cs | 4 +- .../Sprite/DeformAnimations/Inflate.cs | 2 +- .../DeformAnimations/JointBendDeformation.cs | 2 +- .../DeformAnimations/NoiseDeformation.cs | 2 +- .../DeformAnimations/PositionalDeformation.cs | 2 +- .../DeformAnimations/SpriteDeformation.cs | 23 ++++-- .../StatusEffects/StatusEffect.cs | 4 +- .../ClientSource/Utils/TextureLoader.cs | 2 +- .../BarotraumaClient/LinuxClient.csproj | 2 +- Barotrauma/BarotraumaClient/MacClient.csproj | 2 +- .../BarotraumaClient/WindowsClient.csproj | 2 +- .../BarotraumaServer/LinuxServer.csproj | 2 +- Barotrauma/BarotraumaServer/MacServer.csproj | 2 +- .../ServerSource/DebugConsole.cs | 39 +++++++--- .../ServerSource/Items/Inventory.cs | 3 + .../BarotraumaServer/WindowsServer.csproj | 2 +- .../Characters/AI/EnemyAIController.cs | 72 +++++++++++-------- .../AI/Objectives/AIObjectiveGetItem.cs | 1 + .../AI/Objectives/AIObjectiveOperateItem.cs | 2 +- .../SharedSource/Characters/AICharacter.cs | 12 ++-- .../Characters/Animation/Ragdoll.cs | 2 +- .../SharedSource/Characters/Character.cs | 12 +--- .../Health/Afflictions/AfflictionPrefab.cs | 7 ++ .../Characters/Params/CharacterParams.cs | 4 +- .../SharedSource/Events/MonsterEvent.cs | 46 +++++++++++- .../Items/Components/Holdable/RepairTool.cs | 20 +++++- .../Items/Components/Projectile.cs | 4 ++ .../Items/Components/Repairable.cs | 5 +- .../Items/Components/Signal/WifiComponent.cs | 2 +- .../SharedSource/Items/ItemPrefab.cs | 3 +- .../SharedSource/Map/Explosion.cs | 4 +- .../SharedSource/Map/Levels/CaveGenerator.cs | 2 +- .../SharedSource/Map/Levels/Level.cs | 4 +- .../SharedSource/Map/SubmarineBody.cs | 9 ++- .../StatusEffects/DelayedEffect.cs | 2 +- .../StatusEffects/PropertyConditional.cs | 50 +++++++++---- .../StatusEffects/StatusEffect.cs | 2 +- Barotrauma/BarotraumaShared/changelog.txt | 21 ++++++ 52 files changed, 364 insertions(+), 164 deletions(-) diff --git a/Barotrauma/BarotraumaClient/ClientSource/Characters/AI/EnemyAIController.cs b/Barotrauma/BarotraumaClient/ClientSource/Characters/AI/EnemyAIController.cs index b773968c5..7d612effb 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Characters/AI/EnemyAIController.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Characters/AI/EnemyAIController.cs @@ -19,11 +19,14 @@ namespace Barotrauma var target = _selectedAiTarget ?? _lastAiTarget; if (target != null && target.Entity != null) { - var memory = GetTargetMemory(target); - Vector2 targetPos = memory.Location; - targetPos.Y = -targetPos.Y; - GUI.DrawLine(spriteBatch, pos, targetPos, Color.White * 0.5f, 0, 4); - GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{target.Entity.ToString()} ({memory.Priority.FormatZeroDecimal()})", Color.White, Color.Black); + var memory = GetTargetMemory(target, false); + if (memory != null) + { + Vector2 targetPos = memory.Location; + targetPos.Y = -targetPos.Y; + GUI.DrawLine(spriteBatch, pos, targetPos, Color.White * 0.5f, 0, 4); + GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{target.Entity} ({memory.Priority.FormatZeroDecimal()})", Color.White, Color.Black); + } } } else if (SelectedAiTarget?.Entity != null) @@ -43,7 +46,7 @@ namespace Barotrauma GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Orange, false); GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5); } - GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity.ToString()} ({GetTargetMemory(SelectedAiTarget).Priority.FormatZeroDecimal()})", GUI.Style.Red, Color.Black); + GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity} ({GetTargetMemory(SelectedAiTarget, false)?.Priority.FormatZeroDecimal()})", GUI.Style.Red, Color.Black); GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 40.0f, $"({targetValue.FormatZeroDecimal()})", GUI.Style.Red, Color.Black); } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Characters/Limb.cs b/Barotrauma/BarotraumaClient/ClientSource/Characters/Limb.cs index e44ed6055..9511fb746 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Characters/Limb.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Characters/Limb.cs @@ -568,6 +568,10 @@ namespace Barotrauma { LightSource.LightSprite.Depth = ActiveSprite.Depth; } + if (LightSource.DeformableLightSprite != null) + { + LightSource.DeformableLightSprite.Sprite.Depth = ActiveSprite.Depth; + } } UpdateSpriteStates(deltaTime); @@ -625,7 +629,11 @@ namespace Barotrauma { var deformation = SpriteDeformation.GetDeformation(Deformations, deformSprite.Size); deformSprite.Deform(deformation); - LightSource?.DeformableLightSprite?.Deform(deformation); + if (LightSource != null && LightSource.DeformableLightSprite != null) + { + deformation = SpriteDeformation.GetDeformation(Deformations, deformSprite.Size, dir == Direction.Left); + LightSource.DeformableLightSprite.Deform(deformation); + } } else { diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/Steering.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/Steering.cs index bbba34b4d..f51566b02 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/Steering.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/Steering.cs @@ -438,11 +438,8 @@ namespace Barotrauma.Items.Components if (Voltage < MinVoltage) { return; } Rectangle velRect = new Rectangle(x + 20, y + 20, width - 40, height - 40); - Vector2 displaySubPos = (-sonar.DisplayOffset * sonar.Zoom) / sonar.Range * sonar.DisplayRadius * sonar.Zoom; - displaySubPos.Y = -displaySubPos.Y; - displaySubPos = displaySubPos.ClampLength(velRect.Width / 2); - displaySubPos = steerArea.Rect.Center.ToVector2() + displaySubPos; - + Vector2 steeringOrigin = steerArea.Rect.Center.ToVector2(); + if (!AutoPilot) { Vector2 unitSteeringInput = steeringInput / 100.0f; @@ -450,18 +447,18 @@ namespace Barotrauma.Items.Components Vector2 steeringInputPos = new Vector2( steeringInput.X * (float)Math.Sqrt(1.0f - 0.5f * unitSteeringInput.Y * unitSteeringInput.Y), -steeringInput.Y * (float)Math.Sqrt(1.0f - 0.5f * unitSteeringInput.X * unitSteeringInput.X)); - steeringInputPos += displaySubPos; + steeringInputPos += steeringOrigin; if (steeringIndicator != null) { - Vector2 dir = steeringInputPos - displaySubPos; + Vector2 dir = steeringInputPos - steeringOrigin; float angle = (float)Math.Atan2(dir.Y, dir.X); - steeringIndicator.Draw(spriteBatch, displaySubPos, Color.White, origin: steeringIndicator.Origin, rotate: angle, + steeringIndicator.Draw(spriteBatch, steeringOrigin, Color.White, origin: steeringIndicator.Origin, rotate: angle, scale: new Vector2(dir.Length() / steeringIndicator.size.X, 1.0f)); } else { - GUI.DrawLine(spriteBatch, displaySubPos, steeringInputPos, Color.LightGray); + GUI.DrawLine(spriteBatch, steeringOrigin, steeringInputPos, Color.LightGray); GUI.DrawRectangle(spriteBatch, new Rectangle((int)steeringInputPos.X - 5, (int)steeringInputPos.Y - 5, 10, 10), Color.White); } @@ -475,7 +472,7 @@ namespace Barotrauma.Items.Components Sonar sonar = item.GetComponent(); if (sonar != null && controlledSub != null) { - Vector2 displayPosToMaintain = ((posToMaintain.Value - sonar.DisplayOffset * sonar.Zoom - controlledSub.WorldPosition)) / sonar.Range * sonar.DisplayRadius * sonar.Zoom; + Vector2 displayPosToMaintain = ((posToMaintain.Value - controlledSub.WorldPosition)) / sonar.Range * sonar.DisplayRadius * sonar.Zoom; displayPosToMaintain.Y = -displayPosToMaintain.Y; displayPosToMaintain = displayPosToMaintain.ClampLength(velRect.Width / 2); displayPosToMaintain = steerArea.Rect.Center.ToVector2() + displayPosToMaintain; @@ -494,11 +491,11 @@ namespace Barotrauma.Items.Components if (maintainPosOriginIndicator != null) { - maintainPosOriginIndicator.Draw(spriteBatch, displaySubPos, GUI.Style.Orange, scale: 0.5f * sonar.Zoom); + maintainPosOriginIndicator.Draw(spriteBatch, steeringOrigin, GUI.Style.Orange, scale: 0.5f * sonar.Zoom); } else { - GUI.DrawRectangle(spriteBatch, new Rectangle((int)displaySubPos.X - 5, (int)displaySubPos.Y - 5, 10, 10), GUI.Style.Orange); + GUI.DrawRectangle(spriteBatch, new Rectangle((int)steeringOrigin.X - 5, (int)steeringOrigin.Y - 5, 10, 10), GUI.Style.Orange); } } } @@ -508,20 +505,19 @@ namespace Barotrauma.Items.Components Vector2 steeringPos = new Vector2( targetVelocity.X * 0.9f * (float)Math.Sqrt(1.0f - 0.5f * unitTargetVel.Y * unitTargetVel.Y), -targetVelocity.Y * 0.9f * (float)Math.Sqrt(1.0f - 0.5f * unitTargetVel.X * unitTargetVel.X)); - steeringPos += displaySubPos; - + steeringPos += steeringOrigin; if (steeringIndicator != null) { - Vector2 dir = steeringPos - displaySubPos; + Vector2 dir = steeringPos - steeringOrigin; float angle = (float)Math.Atan2(dir.Y, dir.X); - steeringIndicator.Draw(spriteBatch, displaySubPos, Color.Gray, origin: steeringIndicator.Origin, rotate: angle, + steeringIndicator.Draw(spriteBatch, steeringOrigin, Color.Gray, origin: steeringIndicator.Origin, rotate: angle, scale: new Vector2(dir.Length() / steeringIndicator.size.X, 0.7f)); } else { GUI.DrawLine(spriteBatch, - displaySubPos, + steeringOrigin, steeringPos, Color.CadetBlue, 0, 2); } @@ -669,11 +665,7 @@ namespace Barotrauma.Items.Components { if (PlayerInput.PrimaryMouseButtonHeld() && !CrewManager.IsCommandInterfaceOpen && !GameSession.IsTabMenuOpen) { - Vector2 displaySubPos = (-sonar.DisplayOffset * sonar.Zoom) / sonar.Range * sonar.DisplayRadius * sonar.Zoom; - displaySubPos.Y = -displaySubPos.Y; - displaySubPos = steerArea.Rect.Center.ToVector2() + displaySubPos; - - Vector2 inputPos = PlayerInput.MousePosition - displaySubPos; + Vector2 inputPos = PlayerInput.MousePosition - steerArea.Rect.Center.ToVector2(); inputPos.Y = -inputPos.Y; if (AutoPilot && !LevelStartSelected && !LevelEndSelected) { @@ -848,7 +840,6 @@ namespace Barotrauma.Items.Components Vector2 newSteeringInput = steeringInput; Vector2 newTargetVelocity = targetVelocity; float newSteeringAdjustSpeed = steeringAdjustSpeed; - bool maintainPos = false; Vector2? newPosToMaintain = null; bool headingToStart = false; @@ -859,8 +850,7 @@ namespace Barotrauma.Items.Components if (autoPilot) { - maintainPos = msg.ReadBoolean(); - if (maintainPos) + if (msg.ReadBoolean()) { newPosToMaintain = new Vector2( msg.ReadSingle(), diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Repairable.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Repairable.cs index 1391bcecd..42a9f28b5 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Repairable.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Repairable.cs @@ -138,7 +138,15 @@ namespace Barotrauma.Items.Components partial void UpdateProjSpecific(float deltaTime) { - FakeBrokenTimer -= deltaTime; + if (Character.Controlled == null || (Character.Controlled.CharacterHealth.GetAffliction("psychosis")?.Strength ?? 0.0f) <= 0.0f) + { + FakeBrokenTimer = 0.0f; + } + else + { + FakeBrokenTimer -= deltaTime; + } + item.FakeBroken = FakeBrokenTimer > 0.0f; if (!GameMain.IsMultiplayer) diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Item.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Item.cs index afb63312a..91244fc72 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Item.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Item.cs @@ -147,9 +147,9 @@ namespace Barotrauma for (int i = 0; i < Prefab.BrokenSprites.Count;i++) { + if (Prefab.BrokenSprites[i].FadeIn) { continue; } float minCondition = i > 0 ? Prefab.BrokenSprites[i - i].MaxCondition : 0.0f; - if (condition <= minCondition || - condition <= Prefab.BrokenSprites[i].MaxCondition && !Prefab.BrokenSprites[i].FadeIn) + if (condition <= minCondition || condition <= Prefab.BrokenSprites[i].MaxCondition) { activeSprite = Prefab.BrokenSprites[i].Sprite; break; @@ -232,6 +232,7 @@ namespace Barotrauma BrokenItemSprite fadeInBrokenSprite = null; float fadeInBrokenSpriteAlpha = 0.0f; float displayCondition = FakeBroken ? 0.0f : condition; + Vector2 drawOffset = Vector2.Zero; if (displayCondition < Prefab.Health) { for (int i = 0; i < Prefab.BrokenSprites.Count; i++) @@ -241,7 +242,7 @@ namespace Barotrauma float min = i > 0 ? Prefab.BrokenSprites[i - i].MaxCondition : 0.0f; float max = Prefab.BrokenSprites[i].MaxCondition; fadeInBrokenSpriteAlpha = 1.0f - ((displayCondition - min) / (max - min)); - if (fadeInBrokenSpriteAlpha > 0.0f && fadeInBrokenSpriteAlpha < 1.0f) + if (fadeInBrokenSpriteAlpha > 0.0f && fadeInBrokenSpriteAlpha <= 1.0f) { fadeInBrokenSprite = Prefab.BrokenSprites[i]; } @@ -250,6 +251,7 @@ namespace Barotrauma if (displayCondition <= Prefab.BrokenSprites[i].MaxCondition) { activeSprite = Prefab.BrokenSprites[i].Sprite; + drawOffset = Prefab.BrokenSprites[i].Offset.ToVector2() * Scale; break; } } @@ -271,9 +273,13 @@ namespace Barotrauma { if (prefab.ResizeHorizontal || prefab.ResizeVertical) { - activeSprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X - rect.Width / 2, -(DrawPosition.Y + rect.Height / 2)), new Vector2(rect.Width, rect.Height), color: color, + Vector2 size = new Vector2(rect.Width, rect.Height); + activeSprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X - rect.Width / 2, -(DrawPosition.Y + rect.Height / 2)) + drawOffset, + size, color: color, + textureScale: Vector2.One * Scale, depth: depth); - fadeInBrokenSprite?.Sprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X - rect.Width / 2, -(DrawPosition.Y + rect.Height / 2)), new Vector2(rect.Width, rect.Height), color: color * fadeInBrokenSpriteAlpha, + fadeInBrokenSprite?.Sprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X - rect.Width / 2, -(DrawPosition.Y + rect.Height / 2)) + fadeInBrokenSprite.Offset.ToVector2() * Scale, size, color: color * fadeInBrokenSpriteAlpha, + textureScale: Vector2.One * Scale, depth: depth - 0.000001f); foreach (var decorativeSprite in Prefab.DecorativeSprites) { @@ -287,8 +293,8 @@ namespace Barotrauma } else { - activeSprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y), color, SpriteRotation, Scale, activeSprite.effects, depth); - fadeInBrokenSprite?.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y), color * fadeInBrokenSpriteAlpha, SpriteRotation, Scale, activeSprite.effects, depth - 0.000001f); + activeSprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + drawOffset, color, SpriteRotation, Scale, activeSprite.effects, depth); + fadeInBrokenSprite?.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + fadeInBrokenSprite.Offset.ToVector2() * Scale, color * fadeInBrokenSpriteAlpha, SpriteRotation, Scale, activeSprite.effects, depth - 0.000001f); foreach (var decorativeSprite in Prefab.DecorativeSprites) { if (!spriteAnimState[decorativeSprite].IsActive) { continue; } @@ -1270,6 +1276,14 @@ namespace Barotrauma inventory = container.Inventory; } } + else if (inventoryOwner == null) + { + DebugConsole.ThrowError($"Failed to spawn item \"{(itemIdentifier ?? "null")}\" in the inventory of an entity with the ID {inventoryId} (entity not found)"); + } + else + { + DebugConsole.ThrowError($"Failed to spawn item \"{(itemIdentifier ?? "null")}\" in the inventory of \"{inventoryOwner} ({inventoryOwner.ID})\" (invalid entity, should be an item or a character)"); + } } var item = new Item(itemPrefab, pos, sub) diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/ItemPrefab.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/ItemPrefab.cs index 1b11c5ead..ec6c72cff 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/ItemPrefab.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/ItemPrefab.cs @@ -14,12 +14,14 @@ namespace Barotrauma public readonly float MaxCondition; public readonly Sprite Sprite; public readonly bool FadeIn; + public readonly Point Offset; - public BrokenItemSprite(Sprite sprite, float maxCondition, bool fadeIn) + public BrokenItemSprite(Sprite sprite, float maxCondition, bool fadeIn, Point offset) { Sprite = sprite; MaxCondition = MathHelper.Clamp(maxCondition, 0.0f, 100.0f); FadeIn = fadeIn; + Offset = offset; } } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Map/Submarine.cs b/Barotrauma/BarotraumaClient/ClientSource/Map/Submarine.cs index 43a5d1494..6e7c82795 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Map/Submarine.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Map/Submarine.cs @@ -31,6 +31,7 @@ namespace Barotrauma Stream = sound.Stream; Range = element.GetAttributeFloat("range", 1000.0f); Volume = element.GetAttributeFloat("volume", 1.0f); + sound.DisableMuffle = element.GetAttributeBool("disablemuffle", false); } } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Networking/SteamManager.cs b/Barotrauma/BarotraumaClient/ClientSource/Networking/SteamManager.cs index 299cb6d00..581fd85f1 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Networking/SteamManager.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Networking/SteamManager.cs @@ -1574,7 +1574,10 @@ namespace Barotrauma.Steam { exists |= File.Exists(contentFilePath + ".dll"); } - return contentFilePath; + if (exists) + { + return contentFilePath; + } } string[] splitPath = contentFilePath.Split('/'); diff --git a/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticleManager.cs b/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticleManager.cs index 4666696e9..68e4cc78c 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticleManager.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticleManager.cs @@ -120,13 +120,13 @@ namespace Barotrauma.Particles return CreateParticle(prefabName, position, new Vector2((float)Math.Cos(angle), (float)-Math.Sin(angle)) * speed, angle, hullGuess); } - 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) { ParticlePrefab prefab = FindPrefab(prefabName); if (prefab == null) { - DebugConsole.ThrowError("Particle prefab \"" + prefabName+"\" not found!"); + DebugConsole.ThrowError("Particle prefab \"" + prefabName + "\" not found!"); return null; } @@ -135,7 +135,7 @@ namespace Barotrauma.Particles public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null, bool drawOnTop = false) { - if (particleCount >= MaxParticles || prefab == null) return null; + if (particleCount >= MaxParticles || prefab == null || prefab.Sprites.Count == 0) { return null; } Vector2 particleEndPos = prefab.CalculateEndPosition(position, velocity); @@ -144,8 +144,8 @@ namespace Barotrauma.Particles Rectangle expandedViewRect = MathUtils.ExpandRect(cam.WorldView, MaxOutOfViewDist); - if (minPos.X > expandedViewRect.Right || maxPos.X < expandedViewRect.X) return null; - if (minPos.Y > expandedViewRect.Y || maxPos.Y < expandedViewRect.Y - expandedViewRect.Height) return null; + if (minPos.X > expandedViewRect.Right || maxPos.X < expandedViewRect.X) { return null; } + if (minPos.Y > expandedViewRect.Y || maxPos.Y < expandedViewRect.Y - expandedViewRect.Height) { return null; } if (particles[particleCount] == null) particles[particleCount] = new Particle(); diff --git a/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticlePrefab.cs b/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticlePrefab.cs index 9a0cb6a6c..e1a6b2b06 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticlePrefab.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticlePrefab.cs @@ -255,6 +255,11 @@ namespace Barotrauma.Particles } } + if (Sprites.Count == 0) + { + DebugConsole.ThrowError($"Particle prefab \"{Name}\" in the file \"{file}\" has no sprites defined!"); + } + //if velocity change in water is not given, it defaults to the normal velocity change if (element.Attribute("velocitychangewater") == null) { diff --git a/Barotrauma/BarotraumaClient/ClientSource/PlayerInput.cs b/Barotrauma/BarotraumaClient/ClientSource/PlayerInput.cs index 3b9293bef..f4a86f565 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/PlayerInput.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/PlayerInput.cs @@ -469,7 +469,11 @@ namespace Barotrauma public static bool IsCtrlDown() { +#if !OSX return KeyDown(Keys.LeftControl) || KeyDown(Keys.RightControl); +#else + return KeyDown(Keys.LeftWindows) || KeyDown(Keys.RightWindows); +#endif } public static void Update(double deltaTime) diff --git a/Barotrauma/BarotraumaClient/ClientSource/Screens/SubEditorScreen.cs b/Barotrauma/BarotraumaClient/ClientSource/Screens/SubEditorScreen.cs index 38bc27a7a..544e51f87 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Screens/SubEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Screens/SubEditorScreen.cs @@ -1245,7 +1245,8 @@ namespace Barotrauma string prevDir = Path.GetDirectoryName(Submarine.MainSub.Info.FilePath).CleanUpPath(); string[] subDirs = prevDir.Split('/'); bool forceToSubFolder = Steam.SteamManager.IsInitialized; - if (forceToSubFolder && subDirs.Length>1 && subDirs[0].Equals("Mods", StringComparison.InvariantCultureIgnoreCase)) + bool isInSubFolder = subDirs.Length > 0 && subDirs[0].Equals("Submarines", StringComparison.InvariantCultureIgnoreCase); + if (forceToSubFolder && subDirs.Length > 1 && subDirs[0].Equals("Mods", StringComparison.InvariantCultureIgnoreCase)) { string modName = subDirs[1]; ContentPackage contentPackage = ContentPackage.List.Find(p => p.Name.Equals(modName, StringComparison.InvariantCultureIgnoreCase)); @@ -1261,7 +1262,7 @@ namespace Barotrauma } } } - savePath = Path.Combine(forceToSubFolder ? SubmarineInfo.SavePath : prevDir, savePath).CleanUpPath(); + savePath = Path.Combine(forceToSubFolder && !isInSubFolder ? SubmarineInfo.SavePath : prevDir, savePath).CleanUpPath(); } else { diff --git a/Barotrauma/BarotraumaClient/ClientSource/Sounds/Sound.cs b/Barotrauma/BarotraumaClient/ClientSource/Sounds/Sound.cs index 700007424..155d38266 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Sounds/Sound.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Sounds/Sound.cs @@ -76,6 +76,8 @@ namespace Barotrauma.Sounds protected set; } + public bool DisableMuffle { get; set; } + /// /// How many instances of the same sound clip can be playing at the same time /// diff --git a/Barotrauma/BarotraumaClient/ClientSource/Sounds/SoundPlayer.cs b/Barotrauma/BarotraumaClient/ClientSource/Sounds/SoundPlayer.cs index 53ae31dd9..f3ada5ea7 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Sounds/SoundPlayer.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Sounds/SoundPlayer.cs @@ -644,8 +644,12 @@ namespace Barotrauma float far = range ?? sound.BaseFar; - if (Vector2.DistanceSquared(new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y), position) > far * far) return null; - return sound.Play(volume ?? sound.BaseGain, far, position, muffle: ShouldMuffleSound(Character.Controlled, position, far, hullGuess)); + if (Vector2.DistanceSquared(new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y), position) > far * far) + { + return null; + } + bool muffle = !sound.DisableMuffle && ShouldMuffleSound(Character.Controlled, position, far, hullGuess); + return sound.Play(volume ?? sound.BaseGain, far, position, muffle: muffle); } private static void UpdateMusic(float deltaTime) diff --git a/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/CustomDeformation.cs b/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/CustomDeformation.cs index e75074efb..91175d95a 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/CustomDeformation.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/CustomDeformation.cs @@ -109,12 +109,12 @@ namespace Barotrauma.SpriteDeformations } } - protected override void GetDeformation(out Vector2[,] deformation, out float multiplier) + protected override void GetDeformation(out Vector2[,] deformation, out float multiplier, bool inverse) { deformation = Deformation; multiplier = CustomDeformationParams.Frequency <= 0.0f ? CustomDeformationParams.Amplitude : - (float)Math.Sin(phase) * CustomDeformationParams.Amplitude; + (float)Math.Sin(inverse ? -phase : phase) * CustomDeformationParams.Amplitude; multiplier *= Params.Strength; } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/Inflate.cs b/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/Inflate.cs index e0ebfe766..6b7d599dd 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/Inflate.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/Inflate.cs @@ -54,7 +54,7 @@ namespace Barotrauma.SpriteDeformations phase = Rand.Range(0.0f, MathHelper.TwoPi); } - protected override void GetDeformation(out Vector2[,] deformation, out float multiplier) + protected override void GetDeformation(out Vector2[,] deformation, out float multiplier, bool inverse) { deformation = this.deformation; multiplier = InflateParams.Frequency <= 0.0f ? InflateParams.Scale : (float)(Math.Sin(phase) + 1.0f) / 2.0f * InflateParams.Scale; diff --git a/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/JointBendDeformation.cs b/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/JointBendDeformation.cs index c94d6a148..0c6d1058f 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/JointBendDeformation.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/JointBendDeformation.cs @@ -56,7 +56,7 @@ namespace Barotrauma.SpriteDeformations public JointBendDeformation(XElement element) : base(element, new JointBendDeformationParams(element)) { } - protected override void GetDeformation(out Vector2[,] deformation, out float multiplier) + protected override void GetDeformation(out Vector2[,] deformation, out float multiplier, bool inverse) { deformation = Deformation; multiplier = 1.0f;// this.multiplier; diff --git a/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/NoiseDeformation.cs b/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/NoiseDeformation.cs index 7df0d7ad5..3830daaa1 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/NoiseDeformation.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/NoiseDeformation.cs @@ -47,7 +47,7 @@ namespace Barotrauma.SpriteDeformations } } - protected override void GetDeformation(out Vector2[,] deformation, out float multiplier) + protected override void GetDeformation(out Vector2[,] deformation, out float multiplier, bool inverse) { deformation = Deformation; multiplier = NoiseDeformationParams.Amplitude * Params.Strength; diff --git a/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/PositionalDeformation.cs b/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/PositionalDeformation.cs index a211ca8b8..6b38a7826 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/PositionalDeformation.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/PositionalDeformation.cs @@ -100,7 +100,7 @@ namespace Barotrauma.SpriteDeformations } } - protected override void GetDeformation(out Vector2[,] deformation, out float multiplier) + protected override void GetDeformation(out Vector2[,] deformation, out float multiplier, bool inverse) { deformation = Deformation; multiplier = 1.0f; diff --git a/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/SpriteDeformation.cs b/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/SpriteDeformation.cs index d88669f5a..118734f9e 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/SpriteDeformation.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Sprite/DeformAnimations/SpriteDeformation.cs @@ -195,11 +195,12 @@ namespace Barotrauma.SpriteDeformations Deformation = new Vector2[Params.Resolution.X, Params.Resolution.Y]; } - protected abstract void GetDeformation(out Vector2[,] deformation, out float multiplier); + protected abstract void GetDeformation(out Vector2[,] deformation, out float multiplier, bool inverse); public abstract void Update(float deltaTime); - public static Vector2[,] GetDeformation(IEnumerable animations, Vector2 scale) + private static readonly List yValues = new List(); + public static Vector2[,] GetDeformation(IEnumerable animations, Vector2 scale, bool inverseY = false) { foreach (SpriteDeformation animation in animations) { @@ -221,8 +222,16 @@ namespace Barotrauma.SpriteDeformations Vector2[,] deformation = new Vector2[resolution.X, resolution.Y]; foreach (SpriteDeformation animation in animations) { - animation.GetDeformation(out Vector2[,] animDeformation, out float multiplier); - + yValues.Clear(); + for (int y = 0; y < resolution.Y; y++) + { + yValues.Add(y); + } + if (inverseY && animation is CustomDeformation) + { + yValues.Reverse(); + } + animation.GetDeformation(out Vector2[,] animDeformation, out float multiplier, inverseY); for (int x = 0; x < resolution.X; x++) { for (int y = 0; y < resolution.Y; y++) @@ -230,13 +239,13 @@ namespace Barotrauma.SpriteDeformations switch (animation.Params.BlendMode) { case DeformationBlendMode.Override: - deformation[x,y] = animDeformation[x,y] * scale * multiplier; + deformation[x, yValues[y]] = animDeformation[x, y] * scale * multiplier; break; case DeformationBlendMode.Add: - deformation[x, y] += animDeformation[x, y] * scale * multiplier; + deformation[x, yValues[y]] += animDeformation[x, y] * scale * multiplier; break; case DeformationBlendMode.Multiply: - deformation[x, y] *= animDeformation[x, y] * multiplier; + deformation[x, yValues[y]] *= animDeformation[x, y] * multiplier; break; } } diff --git a/Barotrauma/BarotraumaClient/ClientSource/StatusEffects/StatusEffect.cs b/Barotrauma/BarotraumaClient/ClientSource/StatusEffects/StatusEffect.cs index 9ccf7dc16..0e3b95f8d 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/StatusEffects/StatusEffect.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/StatusEffects/StatusEffect.cs @@ -15,7 +15,7 @@ namespace Barotrauma private static HashSet ActiveLoopingSounds = new HashSet(); private static double LastMuffleCheckTime; - private List sounds = new List(); + private readonly List sounds = new List(); private SoundSelectionMode soundSelectionMode; private SoundChannel soundChannel; private Entity soundEmitter; @@ -76,7 +76,7 @@ namespace Barotrauma } else { - int selectedSoundIndex = 0; + int selectedSoundIndex; if (soundSelectionMode == SoundSelectionMode.ItemSpecific && entity is Item item) { selectedSoundIndex = item.ID % sounds.Count; diff --git a/Barotrauma/BarotraumaClient/ClientSource/Utils/TextureLoader.cs b/Barotrauma/BarotraumaClient/ClientSource/Utils/TextureLoader.cs index e729ecb33..a921f129e 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Utils/TextureLoader.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Utils/TextureLoader.cs @@ -208,7 +208,7 @@ namespace Barotrauma } else { - DebugConsole.NewMessage($"Could not compress a texture because the dimensions are a multiple of 4 (path: {path ?? "null"}, size: {width}x{height})", Color.Orange); + DebugConsole.NewMessage($"Could not compress a texture because the dimensions aren't a multiple of 4 (path: {path ?? "null"}, size: {width}x{height})", Color.Orange); } } diff --git a/Barotrauma/BarotraumaClient/LinuxClient.csproj b/Barotrauma/BarotraumaClient/LinuxClient.csproj index c889cf39b..b227fdac4 100644 --- a/Barotrauma/BarotraumaClient/LinuxClient.csproj +++ b/Barotrauma/BarotraumaClient/LinuxClient.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma - 0.9.1000.0 + 0.9.1001.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 Barotrauma diff --git a/Barotrauma/BarotraumaClient/MacClient.csproj b/Barotrauma/BarotraumaClient/MacClient.csproj index 80ac177e3..5382cb343 100644 --- a/Barotrauma/BarotraumaClient/MacClient.csproj +++ b/Barotrauma/BarotraumaClient/MacClient.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma - 0.9.1000.0 + 0.9.1001.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 Barotrauma diff --git a/Barotrauma/BarotraumaClient/WindowsClient.csproj b/Barotrauma/BarotraumaClient/WindowsClient.csproj index 74b2aeb89..b5e73a429 100644 --- a/Barotrauma/BarotraumaClient/WindowsClient.csproj +++ b/Barotrauma/BarotraumaClient/WindowsClient.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma - 0.9.1000.0 + 0.9.1001.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 Barotrauma diff --git a/Barotrauma/BarotraumaServer/LinuxServer.csproj b/Barotrauma/BarotraumaServer/LinuxServer.csproj index b2396bd0f..d63fc5fb7 100644 --- a/Barotrauma/BarotraumaServer/LinuxServer.csproj +++ b/Barotrauma/BarotraumaServer/LinuxServer.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma Dedicated Server - 0.9.1000.0 + 0.9.1001.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 DedicatedServer diff --git a/Barotrauma/BarotraumaServer/MacServer.csproj b/Barotrauma/BarotraumaServer/MacServer.csproj index bf962cfdb..eff7c1785 100644 --- a/Barotrauma/BarotraumaServer/MacServer.csproj +++ b/Barotrauma/BarotraumaServer/MacServer.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma Dedicated Server - 0.9.1000.0 + 0.9.1001.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 DedicatedServer diff --git a/Barotrauma/BarotraumaServer/ServerSource/DebugConsole.cs b/Barotrauma/BarotraumaServer/ServerSource/DebugConsole.cs index c16cff5b1..8bfe7b4b4 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/DebugConsole.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/DebugConsole.cs @@ -615,28 +615,45 @@ namespace Barotrauma return; } - ShowQuestionPrompt("Console command permissions to grant to \"" + client.Name + "\"? You may enter multiple commands separated with a space.", (commandsStr) => + ShowQuestionPrompt("Console command permissions to grant to \"" + client.Name + "\"? You may enter multiple commands separated with a space, or \"all\" to allow using any console command.", (commandsStr) => { string[] splitCommands = commandsStr.Split(' '); + bool giveAll = splitCommands.Length > 0 && splitCommands[0].Equals("all", StringComparison.OrdinalIgnoreCase); + List grantedCommands = new List(); - for (int i = 0; i < splitCommands.Length; i++) + if (giveAll) { - splitCommands[i] = splitCommands[i].Trim().ToLowerInvariant(); - Command matchingCommand = commands.Find(c => c.names.Contains(splitCommands[i])); - if (matchingCommand == null) + grantedCommands.AddRange(commands); + } + else + { + for (int i = 0; i < splitCommands.Length; i++) { - ThrowError("Could not find the command \"" + splitCommands[i] + "\"!"); - } - else - { - grantedCommands.Add(matchingCommand); + splitCommands[i] = splitCommands[i].Trim().ToLowerInvariant(); + Command matchingCommand = commands.Find(c => c.names.Contains(splitCommands[i])); + if (matchingCommand == null) + { + ThrowError("Could not find the command \"" + splitCommands[i] + "\"!"); + } + else + { + grantedCommands.Add(matchingCommand); + } } } client.GivePermission(ClientPermissions.ConsoleCommands); client.SetPermissions(client.Permissions, client.PermittedConsoleCommands.Union(grantedCommands).Distinct().ToList()); GameMain.Server.UpdateClientPermissions(client); - NewMessage("Gave the client \"" + client.Name + "\" the permission to use console commands " + string.Join(", ", grantedCommands.Select(c => c.names[0])) + ".", Color.White); + if (giveAll) + { + NewMessage("Gave the client \"" + client.Name + "\" the permission to use all console commands.", Color.White); + } + else + { + NewMessage("Gave the client \"" + client.Name + "\" the permission to use console commands " + string.Join(", ", grantedCommands.Select(c => c.names[0])) + ".", Color.White); + } + }, args, 1); }); diff --git a/Barotrauma/BarotraumaServer/ServerSource/Items/Inventory.cs b/Barotrauma/BarotraumaServer/ServerSource/Items/Inventory.cs index 0574ec775..6695c336d 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Items/Inventory.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Items/Inventory.cs @@ -101,6 +101,9 @@ namespace Barotrauma if (!prevItems.Contains(item) && !item.CanClientAccess(c)) { +#if DEBUG || UNSTABLE + DebugConsole.NewMessage($"Client {c.Name} failed to pick up item \"{item}\" (parent inventory: {(item.ParentInventory?.Owner.ToString() ?? "null")}). No access.", Color.Yellow); +#endif if (item.body != null && !c.PendingPositionUpdates.Contains(item)) { c.PendingPositionUpdates.Enqueue(item); diff --git a/Barotrauma/BarotraumaServer/WindowsServer.csproj b/Barotrauma/BarotraumaServer/WindowsServer.csproj index 38d0a73c6..ac68954bc 100644 --- a/Barotrauma/BarotraumaServer/WindowsServer.csproj +++ b/Barotrauma/BarotraumaServer/WindowsServer.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma Dedicated Server - 0.9.1000.0 + 0.9.1001.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 DedicatedServer diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/EnemyAIController.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/EnemyAIController.cs index 0940a9091..d122a7418 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/EnemyAIController.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/EnemyAIController.cs @@ -210,7 +210,7 @@ namespace Barotrauma public void SelectTarget(AITarget target, float priority) { SelectedAiTarget = target; - selectedTargetMemory = GetTargetMemory(target); + selectedTargetMemory = GetTargetMemory(target, true); selectedTargetMemory.Priority = priority; } @@ -439,7 +439,10 @@ namespace Barotrauma throw new NotImplementedException(); } - LatchOntoAI?.Update(this, deltaTime); + if (!Character.AnimController.SimplePhysicsEnabled) + { + LatchOntoAI?.Update(this, deltaTime); + } IsSteeringThroughGap = false; if (SwarmBehavior != null) { @@ -478,7 +481,7 @@ namespace Barotrauma if (target?.Entity != null && !target.Entity.Removed && PreviousState == AIState.Attack && Character.CurrentHull == null) { // Keep heading to the last known position of the target - var memory = GetTargetMemory(target); + var memory = GetTargetMemory(target, false); if (memory != null) { var location = memory.Location; @@ -908,7 +911,7 @@ namespace Barotrauma } if (!Character.AnimController.SimplePhysicsEnabled && SelectedAiTarget.Entity.Submarine != null && Character.Submarine == null && (!canAttackDoors || !canAttackWalls || !AIParams.TargetOuterWalls)) { - if (Vector2.Distance(Character.WorldPosition, attackWorldPos) < 2000 * 2000) + if (Vector2.DistanceSquared(Character.WorldPosition, attackWorldPos) < 2000 * 2000) { // Check that we are not bumping into a door or a wall Vector2 rayStart = SimPosition; @@ -916,8 +919,8 @@ namespace Barotrauma { rayStart -= SelectedAiTarget.Entity.Submarine.SimPosition; } - Vector2 toTarget = SelectedAiTarget.WorldPosition - WorldPosition; - Vector2 rayEnd = rayStart + toTarget.ClampLength(Character.AnimController.Collider.GetLocalFront().Length() * 2); + Vector2 dir = SelectedAiTarget.WorldPosition - WorldPosition; + Vector2 rayEnd = rayStart + dir.ClampLength(Character.AnimController.Collider.GetLocalFront().Length() * 2); Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd, ignoreSubs: true); if (Submarine.LastPickedFraction != 1.0f && closestBody != null && (!AIParams.TargetOuterWalls || !canAttackWalls && closestBody.UserData is Structure s && s.Submarine != null || !canAttackDoors && closestBody.UserData is Item i && i.Submarine != null && i.GetComponent() != null)) @@ -933,25 +936,30 @@ namespace Barotrauma float distance = 0; Limb attackTargetLimb = null; Character targetCharacter = SelectedAiTarget.Entity as Character; - if (canAttack && !Character.AnimController.SimplePhysicsEnabled) + if (canAttack) { - // Target a specific limb instead of the target center position - if (wallTarget == null && targetCharacter != null) + if (!Character.AnimController.SimplePhysicsEnabled) { - var targetLimbType = AttackingLimb.Params.Attack.Attack.TargetLimbType; - attackTargetLimb = GetTargetLimb(AttackingLimb, targetCharacter, targetLimbType); - if (attackTargetLimb == null) + // Target a specific limb instead of the target center position + if (wallTarget == null && targetCharacter != null) { - State = AIState.Idle; - IgnoreTarget(SelectedAiTarget); - ResetAITarget(); - return; + var targetLimbType = AttackingLimb.Params.Attack.Attack.TargetLimbType; + attackTargetLimb = GetTargetLimb(AttackingLimb, targetCharacter, targetLimbType); + if (attackTargetLimb == null) + { + State = AIState.Idle; + IgnoreTarget(SelectedAiTarget); + ResetAITarget(); + return; + } + attackWorldPos = attackTargetLimb.WorldPosition; + attackSimPos = Character.GetRelativeSimPosition(attackTargetLimb); } - attackWorldPos = attackTargetLimb.WorldPosition; - attackSimPos = Character.GetRelativeSimPosition(attackTargetLimb); } - // Check that we can reach the target - Vector2 toTarget = attackWorldPos - (Character.AnimController.SimplePhysicsEnabled ? Character.WorldPosition : AttackingLimb.WorldPosition); + + Vector2 attackLimbPos = Character.AnimController.SimplePhysicsEnabled ? Character.WorldPosition : AttackingLimb.WorldPosition; + Vector2 toTarget = attackWorldPos - attackLimbPos; + // Add a margin when the target is moving away, because otherwise it might be difficult to reach it (the attack takes some time to perform) if (wallTarget != null) { if (wallTarget.Structure.Submarine != null) @@ -962,7 +970,6 @@ namespace Barotrauma } else if (targetCharacter != null) { - // Add a margin when the target is moving away, because otherwise it might be difficult to reach it (the attack takes some time to perform) Vector2 margin = CalculateMargin(targetCharacter.AnimController.Collider.LinearVelocity); toTarget += margin; } @@ -982,6 +989,7 @@ namespace Barotrauma return ConvertUnits.ToDisplayUnits(targetVelocity) * AttackingLimb.attack.Duration * dot; } + // Check that we can reach the target distance = toTarget.Length(); canAttack = distance < AttackingLimb.attack.Range; if (!canAttack && !IsCoolDownRunning) @@ -1366,7 +1374,7 @@ namespace Barotrauma } } - AITargetMemory targetMemory = GetTargetMemory(attacker.AiTarget); + AITargetMemory targetMemory = GetTargetMemory(attacker.AiTarget, true); targetMemory.Priority += GetRelativeDamage(attackResult.Damage, Character.Vitality) * AggressionHurt; // Only allow to react once. Otherwise would attack the target with only a fraction of a cooldown @@ -1409,7 +1417,7 @@ namespace Barotrauma var aiTarget = wallTarget.Structure.AiTarget; if (aiTarget != null && SelectedAiTarget != aiTarget) { - SelectTarget(aiTarget, GetTargetMemory(SelectedAiTarget).Priority); + SelectTarget(aiTarget, GetTargetMemory(SelectedAiTarget, true).Priority); } } IDamageable damageTarget = wallTarget != null ? wallTarget.Structure : SelectedAiTarget.Entity as IDamageable; @@ -1857,7 +1865,7 @@ namespace Barotrauma // -> just ignore the distance and attack whatever has the highest priority dist = Math.Max(dist, 100.0f); - AITargetMemory targetMemory = GetTargetMemory(aiTarget); + AITargetMemory targetMemory = GetTargetMemory(aiTarget, true); if (Character.CurrentHull != null && Math.Abs(toTarget.Y) > Character.CurrentHull.Size.Y) { // Inside the sub, treat objects that are up or down, as they were farther away. @@ -1938,12 +1946,15 @@ namespace Barotrauma return SelectedAiTarget; } - private AITargetMemory GetTargetMemory(AITarget target) + private AITargetMemory GetTargetMemory(AITarget target, bool addIfNotFound) { if (!targetMemories.TryGetValue(target, out AITargetMemory memory)) { - memory = new AITargetMemory(target, 10); - targetMemories.Add(target, memory); + if (addIfNotFound) + { + memory = new AITargetMemory(target, 10); + targetMemories.Add(target, memory); + } } return memory; } @@ -1958,8 +1969,11 @@ namespace Barotrauma } else if (CanPerceive(_selectedAiTarget, distSquared: Vector2.DistanceSquared(Character.WorldPosition, _selectedAiTarget.WorldPosition))) { - var memory = GetTargetMemory(_selectedAiTarget); - memory.Location = _selectedAiTarget.WorldPosition; + var memory = GetTargetMemory(_selectedAiTarget, false); + if (memory != null) + { + memory.Location = _selectedAiTarget.WorldPosition; + } } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveGetItem.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveGetItem.cs index 3999a332d..06af9fd06 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveGetItem.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveGetItem.cs @@ -42,6 +42,7 @@ namespace Barotrauma currSearchIndex = -1; this.equip = equip; this.targetItem = targetItem; + moveToTarget = targetItem?.GetRootInventoryOwner(); } public AIObjectiveGetItem(Character character, string itemIdentifier, AIObjectiveManager objectiveManager, bool equip = true, bool checkInventory = true, float priorityModifier = 1) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveOperateItem.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveOperateItem.cs index bd00d7734..7dba6a78c 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveOperateItem.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveOperateItem.cs @@ -61,7 +61,7 @@ namespace Barotrauma { case "shutdown": var powered = component?.Item.GetComponent(); - if (powered != null && powered.IsActive) + if (powered != null && !powered.IsActive) { Priority = 0; return Priority; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/AICharacter.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/AICharacter.cs index f6001bd17..cdd764cc6 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/AICharacter.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/AICharacter.cs @@ -47,11 +47,15 @@ namespace Barotrauma base.Update(deltaTime, cam); if (!Enabled) { return; } - if (IsDead || Vitality <= 0.0f || Stun > 0.0f || IsIncapacitated) { return; } + if (IsDead || Vitality <= 0.0f || Stun > 0.0f || IsIncapacitated) + { + //don't enable simple physics on dead/incapacitated characters + //the ragdoll controls the movement of incapacitated characters instead of the collider, + //but in simple physics mode the ragdoll would get disabled, causing the character to not move at all + AnimController.SimplePhysicsEnabled = false; + return; + } - //don't enable simple physics on dead/incapacitated characters - //the ragdoll controls the movement of incapacitated characters instead of the collider, - //but in simple physics mode the ragdoll would get disabled, causing the character to not move at all if (!IsRemotePlayer && !(AIController is HumanAIController)) { float characterDist = float.MaxValue; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs index 14de676c3..939b49ea6 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs @@ -709,7 +709,7 @@ namespace Barotrauma float impactDamage = Math.Min((impact - ImpactTolerance) * ImpactDamageMultiplayer, character.MaxVitality * MaxImpactDamage); character.LastDamageSource = null; - character.AddDamage(impactPos, new List() { AfflictionPrefab.InternalDamage.Instantiate(impactDamage) }, 0.0f, true); + character.AddDamage(impactPos, AfflictionPrefab.ImpactDamage.Instantiate(impactDamage).ToEnumerable(), 0.0f, true); strongestImpact = Math.Max(strongestImpact, impact - ImpactTolerance); character.ApplyStatusEffects(ActionType.OnImpact, 1.0f); //briefly disable impact damage diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs index 53cd51fdf..297bb4c62 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs @@ -2469,7 +2469,7 @@ namespace Barotrauma } } - private readonly float maxAIRange = 10000; + private readonly float maxAIRange = 20000; private readonly float aiTargetChangeSpeed = 5; private void UpdateSightRange(float deltaTime) @@ -2741,14 +2741,8 @@ namespace Barotrauma } if (severed) { - if (joint.LimbA == targetLimb) - { - joint.LimbB.body.LinearVelocity += targetLimb.LinearVelocity * 0.5f; - } - else - { - joint.LimbA.body.LinearVelocity += targetLimb.LinearVelocity * 0.5f; - } + Limb otherLimb = joint.LimbA == targetLimb ? joint.LimbB : joint.LimbA; + otherLimb.body.ApplyLinearImpulse(targetLimb.LinearVelocity * targetLimb.Mass); } } if (wasSevered) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionPrefab.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionPrefab.cs index 7c90aa161..39cae1adb 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionPrefab.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionPrefab.cs @@ -189,6 +189,7 @@ namespace Barotrauma } public static AfflictionPrefab InternalDamage; + public static AfflictionPrefab ImpactDamage; public static AfflictionPrefab Bleeding; public static AfflictionPrefab Burn; public static AfflictionPrefab OxygenLow; @@ -291,6 +292,7 @@ namespace Barotrauma { CPRSettings.Unload(); InternalDamage = null; + ImpactDamage = null; Bleeding = null; Burn = null; OxygenLow = null; @@ -437,6 +439,9 @@ namespace Barotrauma case "internaldamage": InternalDamage = prefab; break; + case "blunttrauma": + ImpactDamage = prefab; + break; case "bleeding": Bleeding = prefab; break; @@ -456,6 +461,8 @@ namespace Barotrauma Stun = prefab; break; } + if (ImpactDamage == null) { ImpactDamage = InternalDamage; } + if (prefab != null) { Prefabs.Add(prefab, isOverride); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Params/CharacterParams.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Params/CharacterParams.cs index 98d2eff2e..c664da6b3 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Params/CharacterParams.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Params/CharacterParams.cs @@ -46,10 +46,10 @@ namespace Barotrauma [Serialize(false, false), Editable] public bool CanSpeak { get; set; } - [Serialize(100f, true, description: "How much noise the character makes when moving?"), Editable(minValue: 0f, maxValue: 10000f)] + [Serialize(100f, true, description: "How much noise the character makes when moving?"), Editable(minValue: 0f, maxValue: 100000f)] public float Noise { get; set; } - [Serialize(100f, true, description: "How visible the character is?"), Editable(minValue: 0f, maxValue: 10000f)] + [Serialize(100f, true, description: "How visible the character is?"), Editable(minValue: 0f, maxValue: 100000f)] public float Visibility { get; set; } [Serialize("blood", true), Editable] diff --git a/Barotrauma/BarotraumaShared/SharedSource/Events/MonsterEvent.cs b/Barotrauma/BarotraumaShared/SharedSource/Events/MonsterEvent.cs index ff9a21312..41a8950ca 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Events/MonsterEvent.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Events/MonsterEvent.cs @@ -13,6 +13,9 @@ namespace Barotrauma private readonly int minAmount, maxAmount; private List monsters; + private readonly float scatter; + private readonly float offset; + private readonly bool spawnDeep; private Vector2? spawnPos; @@ -72,6 +75,8 @@ namespace Barotrauma } spawnDeep = prefab.ConfigElement.GetAttributeBool("spawndeep", false); + offset = prefab.ConfigElement.GetAttributeFloat("offset", 0); + scatter = Math.Clamp(prefab.ConfigElement.GetAttributeFloat("scatter", 1000), 0, 3000); if (GameMain.NetworkMember != null) { @@ -241,6 +246,28 @@ namespace Barotrauma spawnPos = spawnPoint.WorldPosition; } } + else if (chosenPosition.PositionType == Level.PositionType.MainPath && offset > 0) + { + Vector2 dir; + var waypoints = WayPoint.WayPointList.FindAll(wp => wp.Submarine == null); + var nearestWaypoint = waypoints.OrderBy(wp => Vector2.DistanceSquared(wp.WorldPosition, spawnPos.Value)).FirstOrDefault(); + if (nearestWaypoint != null) + { + int currentIndex = waypoints.IndexOf(nearestWaypoint); + var nextWaypoint = waypoints[Math.Min(currentIndex + 20, waypoints.Count - 1)]; + dir = Vector2.Normalize(nextWaypoint.WorldPosition - nearestWaypoint.WorldPosition); + } + else + { + dir = new Vector2(1, Rand.Range(-1, 1)); + } + Vector2 targetPos = spawnPos.Value + dir * offset; + var targetWaypoint = waypoints.OrderBy(wp => Vector2.DistanceSquared(wp.WorldPosition, targetPos)).FirstOrDefault(); + if (targetWaypoint != null) + { + spawnPos = targetWaypoint.WorldPosition; + } + } spawnPending = true; } } @@ -314,7 +341,7 @@ namespace Barotrauma //+1 because Range returns an integer less than the max value int amount = Rand.Range(minAmount, maxAmount + 1); monsters = new List(); - float offsetAmount = spawnPosType == Level.PositionType.MainPath ? 1000 : 100; + float offsetAmount = spawnPosType == Level.PositionType.MainPath ? scatter : 100; for (int i = 0; i < amount; i++) { CoroutineManager.InvokeAfter(() => @@ -324,7 +351,22 @@ namespace Barotrauma System.Diagnostics.Debug.Assert(GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer, "Clients should not create monster events."); - monsters.Add(Character.Create(speciesName, spawnPos.Value + Rand.Vector(offsetAmount), Level.Loaded.Seed + i.ToString(), null, false, true, true)); + Vector2 pos = spawnPos.Value + Rand.Vector(offsetAmount); + if (spawnPosType == Level.PositionType.MainPath) + { + if (Submarine.Loaded.Any(s => ToolBox.GetWorldBounds(s.Borders.Center, s.Borders.Size).ContainsWorld(pos))) + { + // Can't use the offset position, let's use the exact spawn position. + pos = spawnPos.Value; + } + else if (Level.Loaded.Ruins.Any(r => ToolBox.GetWorldBounds(r.Area.Center, r.Area.Size).ContainsWorld(pos))) + { + // Can't use the offset position, let's use the exact spawn position. + pos = spawnPos.Value; + } + } + + monsters.Add(Character.Create(speciesName, pos, Level.Loaded.Seed + i.ToString(), null, false, true, true)); if (monsters.Count == amount) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/RepairTool.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/RepairTool.cs index 8312209bf..3bf38223e 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/RepairTool.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/RepairTool.cs @@ -70,6 +70,12 @@ namespace Barotrauma.Items.Components [Serialize(false, false, description: "Can the item repair things through holes in walls.")] public bool RepairThroughHoles { get; set; } + [Serialize(true, false, description: "Can the item hit broken doors.")] + public bool HitItems { get; set; } + + [Serialize(false, false, description: "Can the item hit broken doors.")] + public bool HitBrokenDoors { get; set; } + [Serialize(0.0f, false, description: "The probability of starting a fire somewhere along the ray fired from the barrel (for example, 0.1 = 10% chance to start a fire during a second of use).")] public float FireProbability { get; set; } @@ -445,7 +451,9 @@ namespace Barotrauma.Items.Components return true; } else if (targetBody.UserData is Item targetItem) - { + { + if (!HitItems) { return false; } + var levelResource = targetItem.GetComponent(); if (levelResource != null && levelResource.Attached && levelResource.requiredItems.Any() && @@ -463,7 +471,15 @@ namespace Barotrauma.Items.Components } if (!targetItem.Prefab.DamagedByRepairTools) { return false; } - if (item.GetComponent() == null && item.Condition <= 0) { return false; } + + if (HitBrokenDoors) + { + if (targetItem.GetComponent() == null && targetItem.Condition <= 0) { return false; } + } + else + { + if (targetItem.Condition <= 0) { return false; } + } targetItem.IsHighlighted = true; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Projectile.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Projectile.cs index 81b272c2c..d4afdb642 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Projectile.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Projectile.cs @@ -486,6 +486,10 @@ namespace Barotrauma.Items.Components return true; } } + else if (target.Body.UserData is Item item) + { + if (item.Condition <= 0.0f) { return false; } + } //ignore character colliders (the projectile only hits limbs) if (target.CollisionCategories == Physics.CollisionCharacter && target.Body.UserData is Character) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Repairable.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Repairable.cs index 674cd8874..ece3c0323 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Repairable.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Repairable.cs @@ -309,11 +309,10 @@ namespace Barotrauma.Items.Components SkillSettings.Current.SkillIncreasePerRepair / Math.Max(characterSkillLevel, 1.0f), CurrentFixer.WorldPosition + Vector2.UnitY * 100.0f); } - SteamAchievementManager.OnItemRepaired(item, CurrentFixer); - deteriorationTimer = Rand.Range(MinDeteriorationDelay, MaxDeteriorationDelay); - wasBroken = false; } + deteriorationTimer = Rand.Range(MinDeteriorationDelay, MaxDeteriorationDelay); + wasBroken = false; StopRepairing(CurrentFixer); } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/WifiComponent.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/WifiComponent.cs index 93b88b2f3..c3dcced4a 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/WifiComponent.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/WifiComponent.cs @@ -46,7 +46,7 @@ namespace Barotrauma.Items.Components } - [Serialize(false, false, description: "Can the component communicate with wifi components in another team's submarine (e.g. enemy sub in Combat missions, respawn shuttle). Needs to be enabled on both the component transmitting the signal and the component receiving it.", alwaysUseInstanceValues: true)] + [Editable, Serialize(false, true, description: "Can the component communicate with wifi components in another team's submarine (e.g. enemy sub in Combat missions, respawn shuttle). Needs to be enabled on both the component transmitting the signal and the component receiving it.", alwaysUseInstanceValues: true)] public bool AllowCrossTeamCommunication { get; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs index 737acecc0..337a33fdc 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs @@ -707,7 +707,8 @@ namespace Barotrauma var brokenSprite = new BrokenItemSprite( new Sprite(subElement, brokenSpriteFolder, lazyLoad: true), subElement.GetAttributeFloat("maxcondition", 0.0f), - subElement.GetAttributeBool("fadein", false)); + subElement.GetAttributeBool("fadein", false), + subElement.GetAttributePoint("offset", Point.Zero)); int spriteIndex = 0; for (int i = 0; i < BrokenSprites.Count && BrokenSprites[i].MaxCondition < brokenSprite.MaxCondition; i++) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/Explosion.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/Explosion.cs index bd475290f..fedd4c35b 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/Explosion.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/Explosion.cs @@ -292,10 +292,10 @@ namespace Barotrauma if (limb.WorldPosition != worldPosition && !MathUtils.NearlyEqual(force, 0.0f)) { Vector2 limbDiff = Vector2.Normalize(limb.WorldPosition - worldPosition); - if (!MathUtils.IsValid(limbDiff)) limbDiff = Rand.Vector(1.0f); + if (!MathUtils.IsValid(limbDiff)) { limbDiff = Rand.Vector(1.0f); } Vector2 impulse = limbDiff * distFactor * force; Vector2 impulsePoint = limb.SimPosition - limbDiff * limbRadius; - limb.body.ApplyLinearImpulse(impulse, impulsePoint, maxVelocity: NetConfig.MaxPhysicsBodyVelocity); + limb.body.ApplyLinearImpulse(impulse, impulsePoint, maxVelocity: NetConfig.MaxPhysicsBodyVelocity * 0.2f); } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/Levels/CaveGenerator.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/Levels/CaveGenerator.cs index 577b7f3fd..b2403d1f7 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/Levels/CaveGenerator.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/Levels/CaveGenerator.cs @@ -182,7 +182,7 @@ namespace Barotrauma currentCell.CellType = CellType.Path; pathCells.Add(currentCell); - int currentTargetIndex = 1; + int currentTargetIndex = 0; int iterationsLeft = cells.Count; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/Levels/Level.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/Levels/Level.cs index 05648b653..cac73b3fd 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/Levels/Level.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/Levels/Level.cs @@ -1600,6 +1600,7 @@ namespace Barotrauma int attemptsLeft = maxAttempts; bool success = false; Vector2 spawnPoint = Vector2.Zero; + var allCells = Loaded.GetAllCells(); while (attemptsLeft > 0) { if (attemptsLeft < maxAttempts) @@ -1847,8 +1848,7 @@ namespace Barotrauma { return true; } - var cells = Loaded.GetAllCells().Where(c => c.Body != null && Vector2.DistanceSquared(pos, c.Center) <= maxDistance); - return cells.Any(c => c.BodyVertices.Any(v => bounds.ContainsWorld(v))); + return cells.Any(c => c.Body != null && Vector2.DistanceSquared(pos, c.Center) <= maxDistance && c.BodyVertices.Any(v => bounds.ContainsWorld(v))); } } totalSW.Stop(); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/SubmarineBody.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/SubmarineBody.cs index d36b529aa..e8ffa5a61 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/SubmarineBody.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/SubmarineBody.cs @@ -1,4 +1,5 @@ -using Barotrauma.Networking; +using Barotrauma.Extensions; +using Barotrauma.Networking; using FarseerPhysics; using FarseerPhysics.Collision; using FarseerPhysics.Common; @@ -451,7 +452,9 @@ namespace Barotrauma private void UpdateDepthDamage(float deltaTime) { if (Position.Y > DamageDepth) { return; } - +#if CLIENT + if (GameMain.GameSession.GameMode is SubTestMode) { return; } +#endif float depth = DamageDepth - Position.Y; depthDamageTimer -= deltaTime; @@ -639,7 +642,7 @@ namespace Barotrauma float damageAmount = contactDot * Body.Mass / limb.character.Mass; limb.character.LastDamageSource = submarine; limb.character.DamageLimb(ConvertUnits.ToDisplayUnits(collision.ImpactPos), limb, - new List() { AfflictionPrefab.InternalDamage.Instantiate(damageAmount) }, 0.0f, true, 0.0f); + AfflictionPrefab.ImpactDamage.Instantiate(damageAmount).ToEnumerable(), 0.0f, true, 0.0f); if (limb.character.IsDead) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/DelayedEffect.cs b/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/DelayedEffect.cs index ae67f66f2..2233141e2 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/DelayedEffect.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/DelayedEffect.cs @@ -81,7 +81,7 @@ namespace Barotrauma if (element.StartTimer > 0.0f) { continue; } - element.Parent.Apply(1.0f, element.Entity, element.Targets, element.WorldPosition); + element.Parent.Apply(deltaTime, element.Entity, element.Targets, element.WorldPosition); DelayList.Remove(element); } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/PropertyConditional.cs b/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/PropertyConditional.cs index d491eea29..5bc04a1a6 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/PropertyConditional.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/PropertyConditional.cs @@ -193,44 +193,64 @@ namespace Barotrauma string[] readTags = valStr.Split(','); int matches = 0; foreach (string tag in readTags) - if (target is Item item && item.HasTag(tag)) matches++; - + { + if (target is Item item && item.HasTag(tag)) + { + matches++; + } + } //If operator is == then it needs to match everything, otherwise if its != there must be zero matches. return Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0; } case ConditionType.HasStatusTag: if (target == null) { return Operator == OperatorType.NotEquals; } - - List durations = StatusEffect.DurationList.FindAll(d => d.Targets.Contains(target)); - List delays = DelayedEffect.DelayList.FindAll(d => d.Targets.Contains(target)); - bool success = false; - if (durations.Count > 0 || delays.Count > 0) + if (StatusEffect.DurationList.Any(d => d.Targets.Contains(target)) || DelayedEffect.DelayList.Any(d => d.Targets.Contains(target))) { string[] readTags = valStr.Split(','); - foreach (DurationListElement duration in durations) + foreach (DurationListElement duration in StatusEffect.DurationList) { + if (!duration.Targets.Contains(target)) { continue; } int matches = 0; foreach (string tag in readTags) - if (duration.Parent.HasTag(tag)) matches++; - + { + if (duration.Parent.HasTag(tag)) + { + matches++; + } + } success = Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0; if (cancelStatusEffect > 0 && success) + { StatusEffect.DurationList.Remove(duration); - if (cancelStatusEffect != 2) //cancelStatusEffect 1 = only cancel once, cancelStatusEffect 2 = cancel all of matching tags + } + if (cancelStatusEffect != 2) + { + //cancelStatusEffect 1 = only cancel once, cancelStatusEffect 2 = cancel all of matching tags return success; + } } - foreach (DelayedListElement delay in delays) + foreach (DelayedListElement delay in DelayedEffect.DelayList) { + if (!delay.Targets.Contains(target)) { continue; } int matches = 0; foreach (string tag in readTags) - if (delay.Parent.HasTag(tag)) matches++; - + { + if (delay.Parent.HasTag(tag)) + { + matches++; + } + } success = Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0; if (cancelStatusEffect > 0 && success) + { DelayedEffect.DelayList.Remove(delay); - if (cancelStatusEffect != 2) //ditto + } + if (cancelStatusEffect != 2) + { + //ditto return success; + } } } else if (Operator == OperatorType.NotEquals) diff --git a/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs b/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs index da6a3d0e8..9a30e6823 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs @@ -318,7 +318,7 @@ namespace Barotrauma break; case "conditionalcomparison": case "comparison": - if (!Enum.TryParse(attribute.Value, out conditionalComparison)) + if (!Enum.TryParse(attribute.Value, ignoreCase: true, out conditionalComparison)) { DebugConsole.ThrowError("Invalid conditional comparison type \"" + attribute.Value + "\" in StatusEffect (" + parentDebugName + ")"); } diff --git a/Barotrauma/BarotraumaShared/changelog.txt b/Barotrauma/BarotraumaShared/changelog.txt index 2d289832b..23423019b 100644 --- a/Barotrauma/BarotraumaShared/changelog.txt +++ b/Barotrauma/BarotraumaShared/changelog.txt @@ -1,3 +1,24 @@ +--------------------------------------------------------------------------------------------------------- +v0.9.1001.0 (Unstable) +--------------------------------------------------------------------------------------------------------- + +- Overhauled level layouts and events (longer and more difficult levels). +- Added two new afflictions: medical items and poisons cause organ damage instead of internal damage and explosions cause deep tissue injuries. Both are functionally identical to internal damage, and treated with the same items. +- Always draw steering indicators at the center of the display instead of the center of the sub. Fixes indicators getting offset (sometimes even outside the display) during docking. +- Added option to give all command perms with the "givecommandperm" command by using "all" as the parameter. +- Non-raycast projectiles ignore destroyed items (= destroyed thalamus organs don't block harpoons). +- Fixed monsters staying invisible if they die far away from the camera view. +- Fixed very small limbs (mudraptor's mouth tentacles, husk appendages) launching off at a very high velocity, leading to glitchy physics behavior, when hit by a non-raycast projectile or an explosion. +- Allow subs to be saved to subdirectories of the "Submarines" folder (e.g. "Submarines/Downloaded"). +- Fixed item deterioration delay not resetting when the item is repaired if the condition of the item wasn't below the repair threshold when starting to repair it. +- Fixed bots failing to use welding tools inside their toolbox when fixing leaks. +- Items that appear broken to psychotic characters revert back to normal immediately when the psychosis is healed or when switching to another character. +- Fixed wires connected to a wifi component getting moved from signal_out to set_channel in old subs. +- Fixed plasma cutter beam not going through broken doors. +- Fixed extinguishers getting blocked by broken doors. +- The explosive cargo mission that places a block of Volatile Compound N in one of the crates no longer requires delivering the volatile block to the destination. +- Disabled crush depth in the submarine test mode. + --------------------------------------------------------------------------------------------------------- v0.9.1000.0 (Unstable) ---------------------------------------------------------------------------------------------------------