From 7d74b5bd52c529fd3e585d8c3b6069c961e87226 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Mon, 25 Mar 2019 19:49:20 +0200 Subject: [PATCH] (2c717d761) Enable wall targets also inside the sub, so that enemies can get through multiple layers of walls. Don't target walls (intentionally), when the character is already inside the sub. Fix attack world position being calculated wrong when the character is targeting walls inside the sub. Take the sub position into account when assigning the wall target position. Makes things a bit simpler. --- .../Source/Characters/AI/EnemyAIController.cs | 1 - .../Source/Characters/AI/EnemyAIController.cs | 121 +++++++++++------- 2 files changed, 73 insertions(+), 49 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/Characters/AI/EnemyAIController.cs b/Barotrauma/BarotraumaClient/Source/Characters/AI/EnemyAIController.cs index cb2c213d0..c18e14dee 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/AI/EnemyAIController.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/AI/EnemyAIController.cs @@ -21,7 +21,6 @@ namespace Barotrauma if (wallTarget != null) { Vector2 wallTargetPos = wallTarget.Position; - if (wallTarget.Structure.Submarine != null) wallTargetPos += wallTarget.Structure.Submarine.Position; wallTargetPos.Y = -wallTargetPos.Y; GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Red, false); GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5); diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs index 19904cd90..75fabb3e9 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs @@ -447,10 +447,6 @@ namespace Barotrauma { attackWorldPos = wallTarget.Position; attackSimPos = ConvertUnits.ToSimUnits(attackWorldPos); - if (Character.Submarine == null && wallTarget.Structure.Submarine != null) - { - attackWorldPos += wallTarget.Structure.Submarine.Position; - } } else if (SelectedAiTarget.Entity is Character c) { @@ -471,15 +467,6 @@ namespace Barotrauma // Take the sub position into account in the sim pos if (Character.Submarine == null && SelectedAiTarget.Entity.Submarine != null) - { - attackSimPos += SelectedAiTarget.Entity.Submarine.SimPosition; - } - else if (Character.Submarine != null && SelectedAiTarget.Entity.Submarine == null) - { - attackSimPos -= Character.Submarine.SimPosition; - } - - if (Math.Abs(Character.AnimController.movement.X) > 0.1f && !Character.AnimController.InWater) { Character.AnimController.TargetDir = Character.WorldPosition.X < attackWorldPos.X ? Direction.Right : Direction.Left; } @@ -490,32 +477,26 @@ namespace Barotrauma if (wallTarget != null && wallTarget.SectionIndex > -1 && CanPassThroughHole(wallTarget.Structure, wallTarget.SectionIndex)) { WallSection section = wallTarget.Structure.GetSection(wallTarget.SectionIndex); - Hull targetHull = section.gap?.FlowTargetHull; - if (targetHull != null && !section.gap.IsRoomToRoom) + Vector2 targetPos = wallTarget.Structure.SectionPosition(wallTarget.SectionIndex, true); + if (section?.gap != null && section.gap.IsRoomToRoom && SteerThroughGap(wallTarget.Structure, section, targetPos, deltaTime)) { - Vector2 targetPos = wallTarget.Structure.SectionPosition(wallTarget.SectionIndex, true); - if (wallTarget.Structure.IsHorizontal) - { - targetPos.Y = targetHull.WorldRect.Y - targetHull.Rect.Height / 2; - } - else - { - targetPos.X = targetHull.WorldRect.Center.X; - } - - latchOntoAI?.DeattachFromBody(); - Character.AnimController.ReleaseStuckLimbs(); - if (steeringManager is IndoorsSteeringManager) - { - steeringManager.SteeringManual(deltaTime, Vector2.Normalize(targetPos - Character.WorldPosition)); - } - else - { - steeringManager.SteeringSeek(ConvertUnits.ToSimUnits(targetPos)); - } return; } } + else if (SelectedAiTarget.Entity is Structure wall) + { + for (int i = 0; i < wall.Sections.Length; i++) + { + WallSection section = wall.Sections[i]; + if (CanPassThroughHole(wall, i) && section?.gap != null) + { + if (SteerThroughGap(wall, section, section.gap.WorldPosition, deltaTime)) + { + return; + } + } + } + } else if (SelectedAiTarget.Entity is Item i) { var door = i.GetComponent(); @@ -528,6 +509,8 @@ namespace Barotrauma if (Character.WorldPosition.Y < door.Item.WorldRect.Y && Character.WorldPosition.Y > door.Item.WorldRect.Y - door.Item.Rect.Height) { velocity.Y = 0; + latchOntoAI?.DeattachFromBody(); + Character.AnimController.ReleaseStuckLimbs(); steeringManager.SteeringManual(deltaTime, velocity); return; } @@ -537,6 +520,8 @@ namespace Barotrauma if (Character.WorldPosition.X < door.Item.WorldRect.X && Character.WorldPosition.X > door.Item.WorldRect.Right) { velocity.X = 0; + latchOntoAI?.DeattachFromBody(); + Character.AnimController.ReleaseStuckLimbs(); steeringManager.SteeringManual(deltaTime, velocity); return; } @@ -702,6 +687,34 @@ namespace Barotrauma } } + private bool SteerThroughGap(Structure wall, WallSection section, Vector2 targetWorldPos, float deltaTime) + { + Hull targetHull = section.gap?.FlowTargetHull; + if (targetHull != null) // && !section.gap.IsRoomToRoom + { + if (wall.IsHorizontal) + { + targetWorldPos.Y = targetHull.WorldRect.Y - targetHull.Rect.Height / 2; + } + else + { + targetWorldPos.X = targetHull.WorldRect.Center.X; + } + latchOntoAI?.DeattachFromBody(); + Character.AnimController.ReleaseStuckLimbs(); + if (steeringManager is IndoorsSteeringManager) + { + steeringManager.SteeringManual(deltaTime, Vector2.Normalize(targetWorldPos - Character.WorldPosition)); + } + else + { + steeringManager.SteeringSeek(ConvertUnits.ToSimUnits(targetWorldPos)); + } + return true; + } + return false; + } + private Limb GetAttackLimb(Vector2 attackWorldPos, Limb ignoredLimb = null) { AttackContext currentContext = Character.GetAttackContext(); @@ -725,11 +738,6 @@ namespace Barotrauma { wallTarget = null; - if (Character.AnimController.CurrentHull != null) - { - return; - } - //check if there's a wall between the target and the Character Vector2 rayStart = SimPosition; Vector2 rayEnd = SelectedAiTarget.SimPosition; @@ -737,10 +745,10 @@ namespace Barotrauma if (offset) { - rayStart -= ConvertUnits.ToSimUnits(SelectedAiTarget.Entity.Submarine.Position); + rayStart -= SelectedAiTarget.Entity.Submarine.SimPosition; } - Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd); + Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd, ignoreSubs: true); if (Submarine.LastPickedFraction == 1.0f || closestBody == null) { @@ -785,8 +793,12 @@ namespace Barotrauma sectionPos.X += (wall.BodyWidth <= 0.0f ? wall.Rect.Width : wall.BodyWidth) / 2 * attachTargetNormal.X; } + latchOntoAI?.SetAttachTarget(wall.Submarine.PhysicsBody.FarseerBody, wall.Submarine, sectionPos, attachTargetNormal); + if (wall.Submarine != null) + { + sectionPos += wall.Submarine.Position; + } wallTarget = new WallTarget(sectionPos, wall, sectionIndex); - latchOntoAI?.SetAttachTarget(wall.Submarine.PhysicsBody.FarseerBody, wall.Submarine, ConvertUnits.ToSimUnits(sectionPos), attachTargetNormal); } } @@ -1002,14 +1014,27 @@ namespace Barotrauma else if (target.Entity is Structure s) { targetingTag = "wall"; - if (character.CurrentHull == null && aggressiveBoarding) + if (aggressiveBoarding) { - valueModifier = s.HasBody ? 2 : 0; - foreach (var section in s.Sections) + // Ignore walls when inside. + valueModifier = character.CurrentHull == null ? 2 : 0; + if (valueModifier > 0) { - if (section.gap != null) + // Ignore structures that doesn't have a body (not walls) + valueModifier *= s.HasBody ? 1 : 0; + } + for (int i = 0; i < s.Sections.Length; i++) + { + var section = s.Sections[i]; + if (CanPassThroughHole(s, i)) { - // up to 100% more priority for every gap in the wall + // Ignore walls that can be passed through + valueModifier = 0; + break; + } + else if (section.gap != null) + { + // up to 100% priority increase for every gap in the wall valueModifier *= 1 + section.gap.Open; } }