From c7e7b3909f6dc1d1185d02ba05610a07986c82fb Mon Sep 17 00:00:00 2001 From: Regalis11 Date: Wed, 23 Dec 2015 00:10:02 +0200 Subject: [PATCH] Autopilot waypoint skipping, AI finds and equips diving gear when the sub is flooding, progress on AI welding, equipping items in AIObjectiveGetItem, wire node coordinate bugfixes, EntityGrid.RemoveEntity fix --- .vs/Subsurface_Solution/v14/.suo | Bin 748544 -> 757760 bytes .../Content/Characters/Endworm/endworm.xml | 8 +- .../Content/Items/Diving/divinggear.xml | 3 +- Subsurface/Source/Camera.cs | 11 +-- .../Source/Characters/AI/EnemyAIController.cs | 62 +++--------- .../Source/Characters/AI/HumanAIController.cs | 8 +- .../Characters/AI/IndoorsSteeringManager.cs | 4 +- .../Characters/AI/Objectives/AIObjective.cs | 6 +- .../AI/Objectives/AIObjectiveContainItem.cs | 44 ++++++--- .../AI/Objectives/AIObjectiveFindSafety.cs | 56 ++++++++++- .../AI/Objectives/AIObjectiveFixLeak.cs | 61 ++++++++++-- .../AI/Objectives/AIObjectiveGetItem.cs | 92 ++++++++++++++---- .../AI/Objectives/AIObjectiveManager.cs | 16 ++- .../AI/Objectives/AIObjectiveOperateItem.cs | 64 ++++++++---- Subsurface/Source/Characters/AICharacter.cs | 22 +---- .../Source/Characters/Animation/Ragdoll.cs | 5 +- Subsurface/Source/Characters/Character.cs | 22 ++--- Subsurface/Source/Items/CharacterInventory.cs | 4 +- .../Items/Components/Holdable/RepairTool.cs | 30 +++--- .../Source/Items/Components/ItemComponent.cs | 2 +- .../Items/Components/Machines/Controller.cs | 10 +- .../Items/Components/Machines/Reactor.cs | 3 +- .../Items/Components/Machines/Steering.cs | 32 +++--- .../Items/Components/Power/PowerContainer.cs | 2 +- .../Items/Components/Signal/Connection.cs | 32 +++--- .../Source/Items/Components/Signal/Wire.cs | 13 +-- Subsurface/Source/Items/Components/Turret.cs | 2 +- Subsurface/Source/Items/Inventory.cs | 7 +- Subsurface/Source/Map/EntityGrid.cs | 4 +- Subsurface/Source/Map/Gap.cs | 8 ++ Subsurface/Source/Map/Hull.cs | 3 +- Subsurface/Source/Map/Levels/LevelRenderer.cs | 1 + Subsurface/Source/Map/Submarine.cs | 5 +- Subsurface/Source/Map/SubmarineBody.cs | 12 ++- Subsurface/Source/Networking/GameClient.cs | 5 +- 35 files changed, 402 insertions(+), 257 deletions(-) diff --git a/.vs/Subsurface_Solution/v14/.suo b/.vs/Subsurface_Solution/v14/.suo index 37658a661bf39f8dfcc729cf7ec2f60810a6df46..7351f4633f5a56af9727443c2c82cbedf8e51778 100644 GIT binary patch delta 43138 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 z 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 - + + - + + - + 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();