diff --git a/.vs/Subsurface_Solution/v14/.suo b/.vs/Subsurface_Solution/v14/.suo index 37658a661..7351f4633 100644 Binary files a/.vs/Subsurface_Solution/v14/.suo and b/.vs/Subsurface_Solution/v14/.suo differ diff --git a/Subsurface/Content/Characters/Endworm/endworm.xml b/Subsurface/Content/Characters/Endworm/endworm.xml index cad1443fa..a944deec0 100644 --- a/Subsurface/Content/Characters/Endworm/endworm.xml +++ b/Subsurface/Content/Characters/Endworm/endworm.xml @@ -42,14 +42,16 @@ - + + - + + - + diff --git a/Subsurface/Content/Items/Diving/divinggear.xml b/Subsurface/Content/Items/Diving/divinggear.xml index f4d2d2caf..6f14ab05e 100644 --- a/Subsurface/Content/Items/Diving/divinggear.xml +++ b/Subsurface/Content/Items/Diving/divinggear.xml @@ -19,7 +19,7 @@ @@ -46,6 +46,7 @@ diff --git a/Subsurface/Source/Camera.cs b/Subsurface/Source/Camera.cs index 021093842..86c2cb5b1 100644 --- a/Subsurface/Source/Camera.cs +++ b/Subsurface/Source/Camera.cs @@ -117,9 +117,7 @@ namespace Barotrauma public Vector2 TargetPos { get { return targetPos; } - set { - targetPos = value; - } + set { targetPos = value; } } // Auxiliary function to move the camera @@ -149,10 +147,7 @@ namespace Barotrauma -interpolatedPosition.Y - resolution.Y / interpolatedZoom / 2.0f, 0)) * Matrix.CreateScale(new Vector3(interpolatedZoom, interpolatedZoom, 1)) * viewMatrix; - - - - + Sound.CameraPos = new Vector3(WorldViewCenter.X, WorldViewCenter.Y, 0.0f); } @@ -166,7 +161,7 @@ namespace Barotrauma Vector2 moveCam = Vector2.Zero; if (targetPos == Vector2.Zero) { - if (GUITextBox.KeyboardDispatcher.Subscriber == null) + if (GUIComponent.KeyboardDispatcher.Subscriber == null) { if (PlayerInput.KeyDown(Keys.LeftShift)) moveSpeed *= 2.0f; if (PlayerInput.KeyDown(Keys.LeftControl)) moveSpeed *= 0.5f; diff --git a/Subsurface/Source/Characters/AI/EnemyAIController.cs b/Subsurface/Source/Characters/AI/EnemyAIController.cs index 5e5b97bb3..7460e2c3b 100644 --- a/Subsurface/Source/Characters/AI/EnemyAIController.cs +++ b/Subsurface/Source/Characters/AI/EnemyAIController.cs @@ -109,7 +109,6 @@ namespace Barotrauma } else { - System.Diagnostics.Debug.WriteLine("updatetargets"); UpdateTargets(Character); updateTargetsTimer = UpdateTargetsInterval; @@ -160,7 +159,6 @@ namespace Barotrauma private void UpdateAttack(float deltaTime) { - if (selectedAiTarget == null) { state = AiState.None; @@ -219,9 +217,7 @@ namespace Barotrauma { coolDownTimer -= deltaTime; attackingLimb = null; - - //System.Diagnostics.Debug.WriteLine("cooldown"); - + if (selectedAiTarget.Entity is Hull || Vector2.Distance(attackPosition, Character.AnimController.Limbs[0].SimPosition) < ConvertUnits.ToSimUnits(500.0f)) { @@ -238,10 +234,7 @@ namespace Barotrauma private void GetTargetEntity() { targetEntity = null; - - - - + //check if there's a wall between the target and the Character Vector2 rayStart = Character.SimPosition; Vector2 rayEnd = selectedAiTarget.SimPosition; @@ -329,10 +322,6 @@ namespace Barotrauma limb.soundTimer = Limb.SoundInterval; } - else - { - //limb.body.ApplyTorque(limb.Mass * -20.0f * Character.animController.Dir * dir); - } Vector2 diff = attackPosition - limb.SimPosition; if (diff.LengthSquared() > 0.00001f) @@ -363,7 +352,7 @@ namespace Barotrauma //sight/hearing range public void UpdateTargets(Character character) { - if (distanceAccumulator<5.0f && Rand.Range(1,3, false)==1) + if (distanceAccumulator<5.0f && Rand.Range(1,3)==1) { selectedAiTarget = null; character.AnimController.TargetMovement = -character.AnimController.TargetMovement; @@ -426,49 +415,30 @@ namespace Barotrauma Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd); Structure closestStructure = (closestBody == null) ? null : closestBody.UserData as Structure; - - //if (targetCharacter != null) - //{ - // //if target is a Character that isn't visible, ignore - // if (closestStructure != null) continue; - // //prefer targets with low health - // valueModifier = valueModifier / targetCharacter.Health; - //} - //else - //{ - if (targetDamageable != null) - { - valueModifier = valueModifier / targetDamageable.Health; - } - else if (closestStructure!=null) - { - valueModifier = valueModifier / (closestStructure as IDamageable).Health; - } - else - { - valueModifier = valueModifier / 1000.0f; - } + if (targetDamageable != null) + { + valueModifier = valueModifier / targetDamageable.Health; + } + else if (closestStructure!=null) + { + valueModifier = valueModifier / (closestStructure as IDamageable).Health; + } + else + { + valueModifier = valueModifier / 1000.0f; + } - //} - - - - //float newTargetValue = valueModifier/dist; if (selectedAiTarget == null || Math.Abs(valueModifier) > Math.Abs(targetValue)) { selectedAiTarget = target; selectedTargetMemory = targetMemory; targetValue = valueModifier; - Debug.WriteLine(selectedAiTarget.Entity+": "+targetValue); } } } - - //selectedTarget = bestTarget; - //selectedTargetMemory = targetMemory; - //this.targetValue = bestTargetValue; + } //find the targetMemory that corresponds to some AItarget or create if there isn't one yet diff --git a/Subsurface/Source/Characters/AI/HumanAIController.cs b/Subsurface/Source/Characters/AI/HumanAIController.cs index 5b694e096..55f64059b 100644 --- a/Subsurface/Source/Characters/AI/HumanAIController.cs +++ b/Subsurface/Source/Characters/AI/HumanAIController.cs @@ -112,16 +112,16 @@ namespace Barotrauma if (pathSteering == null || pathSteering.CurrentPath == null || pathSteering.CurrentPath.CurrentNode==null) return; GUI.DrawLine(spriteBatch, - new Vector2(Character.Position.X, -Character.Position.Y), - new Vector2(pathSteering.CurrentPath.CurrentNode.Position.X, -pathSteering.CurrentPath.CurrentNode.Position.Y), + new Vector2(Character.WorldPosition.X, -Character.WorldPosition.Y), + new Vector2(pathSteering.CurrentPath.CurrentNode.Position.X+Submarine.Loaded.Position.X, -(pathSteering.CurrentPath.CurrentNode.Position.Y+Submarine.Loaded.Position.Y)), Color.LightGreen); for (int i = 1; i < pathSteering.CurrentPath.Nodes.Count; i++) { GUI.DrawLine(spriteBatch, - new Vector2(pathSteering.CurrentPath.Nodes[i].Position.X, -pathSteering.CurrentPath.Nodes[i].Position.Y), - new Vector2(pathSteering.CurrentPath.Nodes[i - 1].Position.X, -pathSteering.CurrentPath.Nodes[i-1].Position.Y), + new Vector2(pathSteering.CurrentPath.Nodes[i].Position.X + Submarine.Loaded.Position.X, -(pathSteering.CurrentPath.Nodes[i].Position.Y + Submarine.Loaded.Position.Y)), + new Vector2(pathSteering.CurrentPath.Nodes[i - 1].Position.X + Submarine.Loaded.Position.X, -(pathSteering.CurrentPath.Nodes[i-1].Position.Y + Submarine.Loaded.Position.Y)), Color.LightGreen); } } diff --git a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs index cd54819d7..e37a5b0bb 100644 --- a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs +++ b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs @@ -62,12 +62,12 @@ namespace Barotrauma protected override Vector2 DoSteeringSeek(Vector2 target, float speed = 1) { //find a new path if one hasn't been found yet or the target is different from the current target - if (currentPath == null || Vector2.Distance(target, currentTarget)>1.0f || findPathTimer < -10.0f) + if (currentPath == null || Vector2.Distance(target, currentTarget)>1.0f || findPathTimer < -5.0f) { if (findPathTimer > 0.0f) return Vector2.Zero; currentTarget = target; - currentPath = pathFinder.FindPath(host.SimPosition+Rand.Vector(0.2f), target); + currentPath = pathFinder.FindPath(host.SimPosition, target); findPathTimer = Rand.Range(1.0f,1.2f); diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjective.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjective.cs index 48d815f6c..d749eb214 100644 --- a/Subsurface/Source/Characters/AI/Objectives/AIObjective.cs +++ b/Subsurface/Source/Characters/AI/Objectives/AIObjective.cs @@ -22,7 +22,7 @@ namespace Barotrauma public virtual bool CanBeCompleted { - get { return false; } + get { return true; } } public string Option @@ -51,7 +51,7 @@ namespace Barotrauma /// the character who's trying to achieve the objective public void TryComplete(float deltaTime) { - subObjectives.RemoveAll(s => s.IsCompleted()); + subObjectives.RemoveAll(s => s.IsCompleted() || !s.CanBeCompleted); foreach (AIObjective objective in subObjectives) { @@ -66,7 +66,7 @@ namespace Barotrauma public void AddSubObjective(AIObjective objective) { - if (subObjectives.Find(o => o.IsDuplicate(objective)) != null) return; + if (subObjectives.Any(o => o.IsDuplicate(objective))) return; subObjectives.Add(objective); } diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveContainItem.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveContainItem.cs index de32a9fbc..9b34badea 100644 --- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveContainItem.cs +++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveContainItem.cs @@ -12,13 +12,11 @@ namespace Barotrauma private string itemName; private ItemContainer container; - - bool canBeCompleted; - + bool isCompleted; public bool IgnoreAlreadyContainedItems; - + public AIObjectiveContainItem(Character character, string itemName, ItemContainer container) : base (character, "") { @@ -26,13 +24,13 @@ namespace Barotrauma this.container = container; //check if the container has room for more items - canBeCompleted = false; - foreach (Item contained in container.inventory.Items) - { - if (contained != null) continue; - canBeCompleted = true; - break; - } + //canBeCompleted = false; + //foreach (Item contained in container.inventory.Items) + //{ + // if (contained != null) continue; + // canBeCompleted = true; + // break; + //} } public override bool IsCompleted() @@ -54,14 +52,28 @@ namespace Barotrauma return; } - if (Vector2.Distance(character.SimPosition, container.Item.SimPosition) > container.Item.PickDistance - && !container.Item.IsInsideTrigger(character.Position)) + if (container.Item.inventory == character.Inventory) { - AddSubObjective(new AIObjectiveGoTo(container.Item, character)); - return; + var containedItems = container.inventory.Items; + //if there's already something in the mask (empty oxygen tank?), drop it + var existingItem = containedItems.FirstOrDefault(i => i != null); + if (existingItem != null) existingItem.Drop(character); + + character.Inventory.RemoveItem(itemToContain); + container.inventory.TryPutItem(itemToContain, null, false); + } + else + { + if (Vector2.Distance(character.SimPosition, container.Item.SimPosition) > container.Item.PickDistance + && !container.Item.IsInsideTrigger(character.Position)) + { + AddSubObjective(new AIObjectiveGoTo(container.Item, character)); + return; + } + + container.Combine(itemToContain); } - container.Combine(itemToContain); isCompleted = true; } diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs index 431692602..29ab15d4e 100644 --- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs +++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs @@ -1,4 +1,5 @@ -using Microsoft.Xna.Framework; +using Barotrauma.Items.Components; +using Microsoft.Xna.Framework; using System; using System.Collections.Generic; using System.Linq; @@ -19,6 +20,8 @@ namespace Barotrauma private float searchHullTimer; + private AIObjective divingGearObjective; + public float? OverrideCurrentHullSafety; public AIObjectiveFindSafety(Character character) @@ -43,6 +46,12 @@ namespace Barotrauma return; } + var currentHull = character.AnimController.CurrentHull; + if (currentHull.Volume / currentHull.FullVolume > 0.5f) + { + if (!FindDivingGear(deltaTime)) return; + } + if (searchHullTimer>0.0f) { searchHullTimer -= deltaTime; @@ -50,6 +59,8 @@ namespace Barotrauma } else { + + var pathSteering = character.AIController.SteeringManager as IndoorsSteeringManager; Hull bestHull = null; @@ -104,6 +115,46 @@ namespace Barotrauma } } + private bool FindDivingGear(float deltaTime) + { + + + var item = character.Inventory.FindItem("diving"); + if (item == null) + { + //get a diving mask/suit first + if (!(divingGearObjective is AIObjectiveGetItem)) + { + divingGearObjective = new AIObjectiveGetItem(character, "diving", true); + } + } + else + { + var containedItems = item.ContainedItems; + if (containedItems == null) return true; + + //check if there's an oxygen tank in the mask + var oxygenTank = Array.Find(containedItems, i => i.Name == "Oxygen Tank" && i.Condition > 0.0f); + + if (oxygenTank != null) return true; + + + if (!(divingGearObjective is AIObjectiveContainItem)) + { + divingGearObjective = new AIObjectiveContainItem(character, "Oxygen Tank", item.GetComponent()); + + } + } + + if (divingGearObjective != null) + { + divingGearObjective.TryComplete(deltaTime); + return divingGearObjective.IsCompleted(); + } + + return false; + } + public override bool IsDuplicate(AIObjective otherObjective) { return (otherObjective is AIObjectiveFindSafety); @@ -128,7 +179,8 @@ namespace Barotrauma } float safety = 100.0f - fireAmount; - if (waterPercentage > 30.0f) safety -= waterPercentage; + + if (waterPercentage > 30.0f && character.Oxygen<80.0f) safety -= waterPercentage; if (hull.OxygenPercentage < 30.0f) safety -= (30.0f-hull.OxygenPercentage)*5.0f; return safety; diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs index 0d4011b9e..fc6ea845e 100644 --- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs +++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs @@ -1,4 +1,6 @@ -using Microsoft.Xna.Framework; +using Barotrauma.Items.Components; +using FarseerPhysics; +using Microsoft.Xna.Framework; using System; using System.Collections.Generic; using System.Linq; @@ -8,17 +10,26 @@ namespace Barotrauma { class AIObjectiveFixLeak : AIObjective { - Gap leak; + private Gap leak; + + public Gap Leak + { + get { return leak; } + } public AIObjectiveFixLeak(Gap leak, Character character) - :base (character, "") + : base (character, "") { this.leak = leak; } public override float GetPriority(Character character) { - return leak.isHorizontal ? leak.Rect.Height * leak.Open : leak.Rect.Width * leak.Open; + float leakSize = (leak.isHorizontal ? leak.Rect.Height : leak.Rect.Width) * leak.Open; + + float dist = Vector2.DistanceSquared(character.SimPosition, leak.SimPosition); + dist = Math.Max(dist/1000.0f, 1.0f); + return Math.Min(leakSize/dist, 40.0f); } public override bool IsDuplicate(AIObjective otherObjective) @@ -34,15 +45,51 @@ namespace Barotrauma if (weldingTool == null) { - subObjectives.Add(new AIObjectiveGetItem(character, "Welding Tool")); + subObjectives.Add(new AIObjectiveGetItem(character, "Welding Tool", true)); + return; } else { - if (Vector2.Distance(character.Position, leak.Position)>10.0f) + var containedItems = weldingTool.ContainedItems; + if (containedItems == null) return; + + var fuelTank = Array.Find(containedItems, i => i.Name == "Welding Fuel Tank" && i.Condition > 0.0f); + + if (fuelTank == null) { - subObjectives.Add(new AIObjectiveGoTo(leak.Position,character)); + AddSubObjective(new AIObjectiveContainItem(character, "Welding Fuel Tank", weldingTool.GetComponent())); } } + + if (Vector2.Distance(character.Position, leak.Position) > 300.0f) + { + AddSubObjective(new AIObjectiveGoTo(ConvertUnits.ToSimUnits(GetStandPosition()), character)); + } + else + { + var repairTool = weldingTool.GetComponent(); + if (repairTool == null) return; + AddSubObjective(new AIObjectiveOperateItem(repairTool, character, "")); + } + } + + private Vector2 GetStandPosition() + { + Vector2 standPos = leak.Position; + var hull = leak.linkedTo[0]; + + if (hull == null) return standPos; + + if (leak.isHorizontal) + { + standPos += Vector2.UnitX * Math.Sign(hull.Position.X - leak.Position.X) * leak.Rect.Width; + } + else + { + standPos += Vector2.UnitY * Math.Sign(hull.Position.Y - leak.Position.Y) * leak.Rect.Height; + } + + return standPos; } } } diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGetItem.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGetItem.cs index 1c1542067..fbda8a9b8 100644 --- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGetItem.cs +++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGetItem.cs @@ -1,4 +1,5 @@ -using Microsoft.Xna.Framework; +using Barotrauma.Items.Components; +using Microsoft.Xna.Framework; using System; using System.Collections.Generic; using System.Linq; @@ -18,17 +19,32 @@ namespace Barotrauma public bool IgnoreContainedItems; + private bool equip; + public override bool CanBeCompleted { get { return canBeCompleted; } } + public AIObjectiveGetItem(Character character, Item targetItem, bool equip = false) + : base(character, "") + { + canBeCompleted = true; - public AIObjectiveGetItem(Character character, string itemName) + this.equip = equip; + + currSearchIndex = 0; + + this.targetItem = targetItem; + } + + public AIObjectiveGetItem(Character character, string itemName, bool equip=false) : base (character, "") { canBeCompleted = true; + this.equip = equip; + currSearchIndex = 0; this.itemName = itemName; @@ -40,32 +56,68 @@ namespace Barotrauma { if (Vector2.Distance(character.SimPosition, targetItem.SimPosition) < targetItem.PickDistance) { + int targetSlot = -1; + if (equip) + { + var pickable = targetItem.GetComponent(); + //check if all the slots required by the item are free + foreach (LimbSlot slots in pickable.AllowedSlots) + { + if (slots.HasFlag(LimbSlot.Any)) continue; + + for (int i = 0; i() { LimbSlot.Any }, false)) continue; + + //if everything else fails, simply drop the existing item + character.Inventory.Items[i].Drop(); + } + } + } + targetItem.Pick(character, false, true); + + if (targetSlot>-1 && character.Inventory.IsInLimbSlot(targetItem, LimbSlot.Any)) + { + character.Inventory.TryPutItem(targetItem, targetSlot, false); + } } + + return; } - if (currSearchIndex >= Item.ItemList.Count) + + for (int i = 0; i<10 && currSearchIndex= Item.ItemList.Count) canBeCompleted = false; } public override bool IsDuplicate(AIObjective otherObjective) diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveManager.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveManager.cs index 9cb2e6225..c648355c8 100644 --- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveManager.cs +++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveManager.cs @@ -49,27 +49,23 @@ namespace Barotrauma { if (!objectives.Any()) return; - //remove completed objectives - objectives = objectives.FindAll(o => !o.IsCompleted()); + //remove completed objectives and ones that can't be completed + objectives = objectives.FindAll(o => !o.IsCompleted() && o.CanBeCompleted); //sort objectives according to priority objectives.Sort((x, y) => y.GetPriority(character).CompareTo(x.GetPriority(character))); - if (character.AnimController.CurrentHull!=null) + foreach (Gap gap in Gap.GapList) { - var gaps = character.AnimController.CurrentHull.FindGaps(); + if (gap.IsRoomToRoom || gap.ConnectedDoor != null || gap.Open<0.1f) continue; - foreach (Gap gap in gaps) - { - if (gap.linkedTo.Count > 1) continue; - AddObjective(new AIObjectiveFixLeak(gap, character)); - } + AddObjective(new AIObjectiveFixLeak(gap, character)); } } public void DoCurrentObjective(float deltaTime) { - if (currentObjective != null && (!objectives.Any() || objectives[0].GetPriority(character)(); - if (controllers.Any()) itemController = controllers[0]; + if (controllers.Any()) component = controllers[0]; + + canBeCompleted = true; } protected override void Act(float deltaTime) { - ItemComponent target = itemController == null ? targetItem: itemController; - - if (Vector2.Distance(character.SimPosition, target.Item.SimPosition) < target.Item.PickDistance - || target.Item.IsInsideTrigger(character.WorldPosition)) - { - if (character.SelectedConstruction != target.Item && target.CanBeSelected) + if (component.CanBeSelected) + { + if (Vector2.Distance(character.SimPosition, component.Item.SimPosition) < component.Item.PickDistance + || component.Item.IsInsideTrigger(character.WorldPosition)) { - target.Item.Pick(character, false, true); + if (character.SelectedConstruction != component.Item && component.CanBeSelected) + { + component.Item.Pick(character, false, true); + } + + if (component.AIOperate(deltaTime, character, this)) isCompleted = true; + return; } - if (targetItem.AIOperate(deltaTime, character, this)) isCompleted = true; - return; + AddSubObjective(new AIObjectiveGoTo(component.Item, character)); + } + else + { + if (!character.Inventory.Items.Contains(component.Item)) + { + AddSubObjective(new AIObjectiveGetItem(character, component.Item, true)); + } + else + { + if (component.AIOperate(deltaTime, character, this)) isCompleted = true; + } } - - subObjectives.Add(new AIObjectiveGoTo(target.Item, character)); } public override bool IsCompleted() @@ -54,7 +84,7 @@ namespace Barotrauma AIObjectiveOperateItem operateItem = otherObjective as AIObjectiveOperateItem; if (operateItem == null) return false; - return (operateItem.targetItem == targetItem); + return (operateItem.component == component); } } } diff --git a/Subsurface/Source/Characters/AICharacter.cs b/Subsurface/Source/Characters/AICharacter.cs index 8eb8acad8..4dc2dd162 100644 --- a/Subsurface/Source/Characters/AICharacter.cs +++ b/Subsurface/Source/Characters/AICharacter.cs @@ -18,27 +18,7 @@ namespace Barotrauma { get { return aiController; } } - - //public AICharacter(string file) : this(file, Vector2.Zero, null) - //{ - //} - - //public AICharacter(string file, Vector2 position) - // : this(file, position, null) - //{ - //} - - //public AICharacter(CharacterInfo characterInfo, WayPoint spawnPoint, bool isNetworkPlayer = false) - // : this(characterInfo.File, spawnPoint.SimPosition, characterInfo, isNetworkPlayer) - //{ - - //} - - //public AICharacter(CharacterInfo characterInfo, Vector2 position, bool isNetworkPlayer = false) - // : this(characterInfo.File, position, characterInfo, isNetworkPlayer) - //{ - //} - + public AICharacter(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false) : base(file, position, characterInfo, isNetworkPlayer) { diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index 0ef960ab9..c07551fce 100644 --- a/Subsurface/Source/Characters/Animation/Ragdoll.cs +++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs @@ -561,7 +561,10 @@ namespace Barotrauma } CurrentHull = newHull; - + + character.Submarine = CurrentHull == null ? null : Submarine.Loaded; + + UpdateCollisionCategories(); } diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 2191914d0..2ea2b63b8 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -866,8 +866,6 @@ namespace Barotrauma { if (!Enabled) return; - Submarine = AnimController.CurrentHull == null ? null : Submarine.Loaded; - obstructVisionAmount = Math.Max(obstructVisionAmount - deltaTime, 0.0f); float dist = Vector2.Distance(cam.WorldViewCenter, WorldPosition); @@ -1125,13 +1123,9 @@ namespace Barotrauma { timer += 1.0f / 60.0f; - if (Character.controlled == this) + if (controlled == this) { - if (cam != null) - { - cam.TargetPos = ConvertUnits.ToDisplayUnits(AnimController.Limbs[0].SimPosition); - cam.OffsetAmount = 0.0f; - } + if (cam != null) cam.OffsetAmount = 0.0f; GameMain.LightManager.AmbientLight = Color.Lerp(prevAmbientLight, darkLight, timer / dimDuration); } @@ -1139,7 +1133,7 @@ namespace Barotrauma yield return CoroutineStatus.Running; } - while (Character.Controlled == this) + while (controlled == this) { yield return CoroutineStatus.Running; } @@ -1381,7 +1375,7 @@ namespace Barotrauma data = causeOfDeath; - if (causeOfDeath==CauseOfDeath.Pressure) + if (causeOfDeath == CauseOfDeath.Pressure) { Implode(true); } @@ -1525,13 +1519,11 @@ namespace Barotrauma if (controlled == this) controlled = null; - if (GameMain.Client!=null && GameMain.Client.Character == this) GameMain.Client.Character = null; + if (GameMain.Client != null && GameMain.Client.Character == this) GameMain.Client.Character = null; - if (aiTarget != null) - aiTarget.Remove(); + if (aiTarget != null) aiTarget.Remove(); - if (AnimController!=null) - AnimController.Remove(); + if (AnimController!=null) AnimController.Remove(); } } diff --git a/Subsurface/Source/Items/CharacterInventory.cs b/Subsurface/Source/Items/CharacterInventory.cs index f3e2ec843..9788fade3 100644 --- a/Subsurface/Source/Items/CharacterInventory.cs +++ b/Subsurface/Source/Items/CharacterInventory.cs @@ -20,7 +20,7 @@ namespace Barotrauma private Character character; - private static LimbSlot[] limbSlots = new LimbSlot[] { + public static LimbSlot[] limbSlots = new LimbSlot[] { LimbSlot.Head, LimbSlot.Torso, LimbSlot.Legs, LimbSlot.LeftHand, LimbSlot.RightHand, LimbSlot.Any, LimbSlot.Any, LimbSlot.Any, LimbSlot.Any, LimbSlot.Any, LimbSlot.Any, LimbSlot.Any, LimbSlot.Any, LimbSlot.Any, LimbSlot.Any}; @@ -83,7 +83,7 @@ namespace Barotrauma { for (int i = 0; i < Items.Length; i++) { - if ( limbSlots[i] == limbSlot) return i; + if (limbSlots[i] == limbSlot) return i; } return -1; } diff --git a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs index 47a36bb99..5fe798ac4 100644 --- a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs +++ b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs @@ -5,7 +5,6 @@ using FarseerPhysics; using FarseerPhysics.Dynamics; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using Barotrauma.Particles; namespace Barotrauma.Items.Components { @@ -200,23 +199,30 @@ namespace Barotrauma.Items.Components } //ApplyStatusEffects(ActionType.OnUse, 1.0f, null, targ); } - //if (Character.SecondaryKeyDown.State) - //{ - // IPropertyObject propertyObject = targetBody.UserData as IPropertyObject; - // if (propertyObject!=null) ApplyStatusEffects(ActionType.OnUse, 1.0f, item.SimPosition, propertyObject); - // //isActive = true; - //} + //if (Character.SecondaryKeyDown.State) + //{ + // IPropertyObject propertyObject = targetBody.UserData as IPropertyObject; + // if (propertyObject!=null) ApplyStatusEffects(ActionType.OnUse, 1.0f, item.SimPosition, propertyObject); + // //isActive = true; + //} return true; } - - public override void Update(float deltaTime, Camera cam) + + public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective) { - base.Update(deltaTime, cam); + Gap leak = objective.OperateTarget as Gap; + if (leak == null) return true; + + character.CursorPosition = leak.Position; + character.SetInput(InputType.Aim, false, true); + + Use(deltaTime, character); + + return leak.Open <= 0.0f; - //isActive = true; } - + public override void Draw(SpriteBatch spriteBatch, bool editing) { if (!IsActive) return; diff --git a/Subsurface/Source/Items/Components/ItemComponent.cs b/Subsurface/Source/Items/Components/ItemComponent.cs index 4d16074e7..7275c2df4 100644 --- a/Subsurface/Source/Items/Components/ItemComponent.cs +++ b/Subsurface/Source/Items/Components/ItemComponent.cs @@ -411,7 +411,7 @@ namespace Barotrauma.Items.Components /// true if the operation was completed - public virtual bool AIOperate(float deltaTime, Character character, AIObjective objective) + public virtual bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective) { return false; } diff --git a/Subsurface/Source/Items/Components/Machines/Controller.cs b/Subsurface/Source/Items/Components/Machines/Controller.cs index 5775cac99..0e8716283 100644 --- a/Subsurface/Source/Items/Components/Machines/Controller.cs +++ b/Subsurface/Source/Items/Components/Machines/Controller.cs @@ -16,16 +16,16 @@ namespace Barotrauma.Items.Components class Controller : ItemComponent { //where the limbs of the user should be positioned when using the controller - List limbPositions; + private List limbPositions; - Direction dir; + private Direction dir; //the x-position where the user walks to when using the controller - float userPos; + private float userPos; - Camera cam; + private Camera cam; - Character character; + private Character character; [HasDefaultValue(0.0f, false)] public float UserPos diff --git a/Subsurface/Source/Items/Components/Machines/Reactor.cs b/Subsurface/Source/Items/Components/Machines/Reactor.cs index 78355ed1e..9c3946c51 100644 --- a/Subsurface/Source/Items/Components/Machines/Reactor.cs +++ b/Subsurface/Source/Items/Components/Machines/Reactor.cs @@ -192,6 +192,7 @@ namespace Barotrauma.Items.Components { foreach (Connection connection in connections) { + if (!connection.IsPower) continue; foreach (Connection recipient in connection.Recipients) { Item it = recipient.Item as Item; @@ -311,7 +312,7 @@ namespace Barotrauma.Items.Components new Vector2(10, 40 * (temperature / 10000.0f)), new Color(temperature / 10000.0f, 1.0f - (temperature / 10000.0f), 0.0f, 1.0f), true); } - public override bool AIOperate(float deltaTime, Character character, AIObjective objective) + public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective) { switch (objective.Option.ToLower()) { diff --git a/Subsurface/Source/Items/Components/Machines/Steering.cs b/Subsurface/Source/Items/Components/Machines/Steering.cs index d14179c52..02a5d1bca 100644 --- a/Subsurface/Source/Items/Components/Machines/Steering.cs +++ b/Subsurface/Source/Items/Components/Machines/Steering.cs @@ -166,25 +166,25 @@ namespace Barotrauma.Items.Components { Vector2 diff = ConvertUnits.ToSimUnits(steeringPath.NextNode.Position - item.WorldPosition); - //bool nextVisible = true; - //for (int x = -1; x < 2; x += 2) - //{ - // for (int y = -1; y < 2; y += 2) - // { - // Vector2 cornerPos = - // new Vector2(Submarine.Borders.Width * x, Submarine.Borders.Height * y) / 2.0f; + bool nextVisible = true; + for (int x = -1; x < 2; x += 2) + { + for (int y = -1; y < 2; y += 2) + { + Vector2 cornerPos = + new Vector2(Submarine.Borders.Width * x, Submarine.Borders.Height * y) / 2.0f; - // cornerPos = ConvertUnits.ToSimUnits(cornerPos*1.2f); + cornerPos = ConvertUnits.ToSimUnits(cornerPos * 1.2f + Submarine.Loaded.Position); - // if (Submarine.PickBody(cornerPos, cornerPos + diff, null, Physics.CollisionLevel) == null) continue; - - // nextVisible = false; - // x = 2; - // y = 2; - // } - //} + if (Submarine.PickBody(cornerPos, cornerPos + diff, null, Physics.CollisionLevel) == null) continue; - //if (nextVisible) steeringPath.SkipToNextNode(); + nextVisible = false; + x = 2; + y = 2; + } + } + + if (nextVisible) steeringPath.SkipToNextNode(); autopilotRayCastTimer = AutopilotRayCastInterval; } diff --git a/Subsurface/Source/Items/Components/Power/PowerContainer.cs b/Subsurface/Source/Items/Components/Power/PowerContainer.cs index 47612f831..cc41d1ad8 100644 --- a/Subsurface/Source/Items/Components/Power/PowerContainer.cs +++ b/Subsurface/Source/Items/Components/Power/PowerContainer.cs @@ -156,7 +156,7 @@ namespace Barotrauma.Items.Components voltage = 0.0f; } - public override bool AIOperate(float deltaTime, Character character, AIObjective objective) + public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective) { RechargeSpeed = maxRechargeSpeed * 0.5f; diff --git a/Subsurface/Source/Items/Components/Signal/Connection.cs b/Subsurface/Source/Items/Components/Signal/Connection.cs index 60bde8f79..b604bc0ba 100644 --- a/Subsurface/Source/Items/Components/Signal/Connection.cs +++ b/Subsurface/Source/Items/Components/Signal/Connection.cs @@ -29,9 +29,7 @@ namespace Barotrauma.Items.Components private List effects; public readonly ushort[] wireId; - - private List recipients; - + public bool IsPower { get; @@ -40,7 +38,17 @@ namespace Barotrauma.Items.Components public List Recipients { - get { return recipients; } + get + { + List recipients = new List(); + for (int i = 0; i < MaxLinked; i++) + { + if (Wires[i] == null) continue; + Connection recipient = Wires[i].OtherConnection(this); + if (recipient != null) recipients.Add(recipient); + } + return recipients; + } } public Item Item @@ -63,9 +71,7 @@ namespace Barotrauma.Items.Components //recipient = new Connection[MaxLinked]; Wires = new Wire[MaxLinked]; - - recipients = new List(); - + IsOutput = (element.Name.ToString() == "output"); Name = ToolBox.GetAttributeString(element, "name", (IsOutput) ? "output" : "input"); @@ -139,13 +145,7 @@ namespace Barotrauma.Items.Components public void UpdateRecipients() { - recipients.Clear(); - for (int i = 0; i < MaxLinked; i++) - { - if (Wires[i] == null) continue; - Connection recipient = Wires[i].OtherConnection(this); - if (recipient != null) recipients.Add(recipient); - } + } public void SendSignal(string signal, Item sender, float power) @@ -180,9 +180,7 @@ namespace Barotrauma.Items.Components Wires[i].RemoveConnection(this); Wires[i] = null; - } - - recipients.Clear(); + } } diff --git a/Subsurface/Source/Items/Components/Signal/Wire.cs b/Subsurface/Source/Items/Components/Signal/Wire.cs index 593668fbd..4236a6f7d 100644 --- a/Subsurface/Source/Items/Components/Signal/Wire.cs +++ b/Subsurface/Source/Items/Components/Signal/Wire.cs @@ -103,16 +103,16 @@ namespace Barotrauma.Items.Components if (!addNode) break; - if (Nodes.Count>0&&Nodes[0] == newConnection.Item.Position) break; - if (Nodes.Count > 1 && Nodes[Nodes.Count-1] == newConnection.Item.Position) break; + if (Nodes.Count > 0 && Nodes[0] == newConnection.Item.Position - Submarine.HiddenSubPosition) break; + if (Nodes.Count > 1 && Nodes[Nodes.Count-1] == newConnection.Item.Position - Submarine.HiddenSubPosition) break; if (i == 0) { - Nodes.Insert(0, newConnection.Item.Position); + Nodes.Insert(0, newConnection.Item.Position - Submarine.HiddenSubPosition); } else { - Nodes.Add(newConnection.Item.Position); + Nodes.Add(newConnection.Item.Position - Submarine.HiddenSubPosition); } break; @@ -121,8 +121,6 @@ namespace Barotrauma.Items.Components if (connections[0] != null && connections[1] != null) { //List prevNodes = new List(Nodes); - - foreach (ItemComponent ic in item.components) { if (ic == this) continue; @@ -130,7 +128,6 @@ namespace Barotrauma.Items.Components } if (item.container != null) item.container.RemoveContained(this.item); - item.body.Enabled = false; IsActive = false; @@ -182,7 +179,7 @@ namespace Barotrauma.Items.Components position.Y += item.CurrentHull.Rect.Y - item.CurrentHull.Rect.Height; } - newNodePos = RoundNode(item.Position, item.CurrentHull); + newNodePos = RoundNode(item.Position, item.CurrentHull)-Submarine.HiddenSubPosition; //if (Vector2.Distance(position, nodes[nodes.Count - 1]) > nodeDistance*10) //{ diff --git a/Subsurface/Source/Items/Components/Turret.cs b/Subsurface/Source/Items/Components/Turret.cs index 225c389f3..3515b3062 100644 --- a/Subsurface/Source/Items/Components/Turret.cs +++ b/Subsurface/Source/Items/Components/Turret.cs @@ -161,7 +161,7 @@ namespace Barotrauma.Items.Components return true; } - public override bool AIOperate(float deltaTime, Character character, AIObjective objective) + public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective) { var projectiles = GetLoadedProjectiles(); diff --git a/Subsurface/Source/Items/Inventory.cs b/Subsurface/Source/Items/Inventory.cs index 40e1a6f8a..571a6d621 100644 --- a/Subsurface/Source/Items/Inventory.cs +++ b/Subsurface/Source/Items/Inventory.cs @@ -118,7 +118,7 @@ namespace Barotrauma { if (Owner == null) return; - if (item.inventory != null && removeItem) + if (removeItem) { item.Drop(null, false); if (item.inventory != null) item.inventory.RemoveItem(item); @@ -268,7 +268,6 @@ namespace Barotrauma if (!isSubSlot && selectedSlot == -1) { - System.Diagnostics.Debug.WriteLine("DSFG"); selectedSlot = slotIndex; } } @@ -284,7 +283,7 @@ namespace Barotrauma #if DEBUG System.Diagnostics.Debug.Assert(slotIndex >= 0 && slotIndex < Items.Length); #else - if (slotIndex<0 || slotIndex>=Items.Length) return; + if (slotIndex < 0 || slotIndex >= Items.Length) return; #endif Rectangle containerRect = new Rectangle(rect.X - 5, rect.Y - (40 + 10) * itemCapacity - 5, @@ -293,9 +292,7 @@ namespace Barotrauma Rectangle subRect = rect; subRect.Height = 40; - selectedSlot = containerRect.Contains(PlayerInput.MousePosition) ? slotIndex : -1; - System.Diagnostics.Debug.WriteLine(selectedSlot); GUI.DrawRectangle(spriteBatch, containerRect, Color.Black * 0.8f, true); GUI.DrawRectangle(spriteBatch, containerRect, Color.White); diff --git a/Subsurface/Source/Map/EntityGrid.cs b/Subsurface/Source/Map/EntityGrid.cs index 679ee9098..6641c2a82 100644 --- a/Subsurface/Source/Map/EntityGrid.cs +++ b/Subsurface/Source/Map/EntityGrid.cs @@ -50,9 +50,9 @@ namespace Barotrauma public void RemoveEntity(MapEntity entity) { - for (int x = 0; x <= entities.GetLength(0); x++) + for (int x = 0; x < entities.GetLength(0); x++) { - for (int y = 0; y <= entities.GetLength(1); y++) + for (int y = 0; y < entities.GetLength(1); y++) { if (entities[x,y].Contains(entity)) entities[x, y].Remove(entity); } diff --git a/Subsurface/Source/Map/Gap.cs b/Subsurface/Source/Map/Gap.cs index 6c757e85f..b5efdea99 100644 --- a/Subsurface/Source/Map/Gap.cs +++ b/Subsurface/Source/Map/Gap.cs @@ -57,6 +57,14 @@ namespace Barotrauma get { return flowTargetHull; } } + public bool IsRoomToRoom + { + get + { + return linkedTo.Count == 2; + } + } + public Gap(Rectangle newRect, Submarine submarine) : this(newRect, newRect.Width < newRect.Height, submarine) { } diff --git a/Subsurface/Source/Map/Hull.cs b/Subsurface/Source/Map/Hull.cs index af0969fc0..a84bebfef 100644 --- a/Subsurface/Source/Map/Hull.cs +++ b/Subsurface/Source/Map/Hull.cs @@ -503,7 +503,8 @@ namespace Barotrauma if (Submarine.RectContains(useWorldCoordinates ? guess.WorldRect : guess.rect, position)) return guess; } - var entities = entityGrid.GetEntities(useWorldCoordinates ? position-Submarine.Loaded.Position : position); + var entities = entityGrid.GetEntities( + useWorldCoordinates && Submarine.Loaded!=null ? position-Submarine.Loaded.Position : position); foreach (Hull hull in entities) { diff --git a/Subsurface/Source/Map/Levels/LevelRenderer.cs b/Subsurface/Source/Map/Levels/LevelRenderer.cs index 7e07bc8d3..d74c6c64f 100644 --- a/Subsurface/Source/Map/Levels/LevelRenderer.cs +++ b/Subsurface/Source/Map/Levels/LevelRenderer.cs @@ -181,6 +181,7 @@ namespace Barotrauma for (int side = 0; side < 2; side++) { + for (int i = 0; i < 2; i++) { graphicsDevice.SetVertexBuffer(level.WrappingWalls[side, i].BodyVertices); diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index 13189fd1b..9eaa1f72d 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -257,8 +257,8 @@ namespace Barotrauma public static Vector2 VectorToWorldGrid(Vector2 position) { - position.X = (float)Math.Floor(Convert.ToDouble(position.X / GridSize.X)) * GridSize.X; - position.Y = (float)Math.Ceiling(Convert.ToDouble(position.Y / GridSize.Y)) * GridSize.Y; + position.X = (float)Math.Floor(position.X / GridSize.X) * GridSize.X; + position.Y = (float)Math.Ceiling(position.Y / GridSize.Y) * GridSize.Y; return position; } @@ -329,6 +329,7 @@ namespace Barotrauma lastPickedPosition = rayStart + (rayEnd - rayStart) * closestFraction; lastPickedFraction = closestFraction; + return closestBody; } diff --git a/Subsurface/Source/Map/SubmarineBody.cs b/Subsurface/Source/Map/SubmarineBody.cs index ef7f34881..7eba2e664 100644 --- a/Subsurface/Source/Map/SubmarineBody.cs +++ b/Subsurface/Source/Map/SubmarineBody.cs @@ -330,15 +330,19 @@ namespace Barotrauma if (cell == null) { Limb limb = f2.Body.UserData as Limb; - if (limb!=null && limb.character.Submarine==null) + if (limb!=null) { + if (limb.character.Submarine != null) return false; + Vector2 normal2; FixedArray2 points; contact.GetWorldManifold(out normal2, out points); - if (Submarine.PickBody( - points[0] - limb.LinearVelocity * ((float)Physics.step) - ConvertUnits.ToSimUnits(submarine.Position) - submarine.Velocity * ((float)Physics.step) + normal2, - points[0] - ConvertUnits.ToSimUnits(submarine.Position) - normal2, null, Physics.CollisionWall) != null) + var pickedBody = Submarine.PickBody( + points[0] - limb.LinearVelocity * ((float)Physics.step) - ConvertUnits.ToSimUnits(submarine.Position) - submarine.Velocity * ((float)Physics.step), + points[0] - ConvertUnits.ToSimUnits(submarine.Position), null, Physics.CollisionWall); + + if (pickedBody != null) { return true; diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 5300c7070..992cae94e 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -420,8 +420,7 @@ namespace Barotrauma.Networking while ((inc = client.ReadMessage()) != null) { if (inc.MessageType != NetIncomingMessageType.Data) continue; - - //todo: exception handling + byte packetType = inc.ReadByte(); if (packetType == (byte)PacketTypes.ReliableMessage) @@ -522,7 +521,7 @@ namespace Barotrauma.Networking private IEnumerable StartGame(NetIncomingMessage inc) { - if (this.Character != null) Character.Remove(); + if (Character != null) Character.Remove(); int seed = inc.ReadInt32();