diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj
index f75ce7183..4d256f821 100644
--- a/Subsurface/Barotrauma.csproj
+++ b/Subsurface/Barotrauma.csproj
@@ -62,7 +62,10 @@
+
+
+
diff --git a/Subsurface/Source/Characters/AI/AITarget.cs b/Subsurface/Source/Characters/AI/AITarget.cs
index 46e006afa..b4f0f3af6 100644
--- a/Subsurface/Source/Characters/AI/AITarget.cs
+++ b/Subsurface/Source/Characters/AI/AITarget.cs
@@ -27,7 +27,7 @@ namespace Barotrauma
set { sightRange = value; }
}
- public Vector2 Position
+ public Vector2 SimPosition
{
get { return Entity.SimPosition; }
}
diff --git a/Subsurface/Source/Characters/AI/EnemyAIController.cs b/Subsurface/Source/Characters/AI/EnemyAIController.cs
index 8e57c410e..e777daa91 100644
--- a/Subsurface/Source/Characters/AI/EnemyAIController.cs
+++ b/Subsurface/Source/Characters/AI/EnemyAIController.cs
@@ -21,10 +21,7 @@ namespace Barotrauma
//0.0 = doesn't attack targets of the type
//positive values = attacks targets of this type
//negative values = escapes targets of this type
- private float attackRooms;
- private float attackHumans;
- private float attackWeaker;
- private float attackStronger;
+ private float attackRooms, attackHumans, attackWeaker, attackStronger;
private float updateTargetsTimer;
@@ -165,7 +162,7 @@ namespace Barotrauma
selectedTargetMemory.Priority -= deltaTime;
- Vector2 attackPosition = selectedAiTarget.Position;
+ Vector2 attackPosition = selectedAiTarget.SimPosition;
if (wallAttackPos != Vector2.Zero) attackPosition = wallAttackPos;
if (coolDownTimer>0.0f)
@@ -230,7 +227,7 @@ namespace Barotrauma
targetEntity = null;
//check if there's a wall between the target and the Character
Vector2 rayStart = Character.AnimController.Limbs[0].SimPosition;
- Vector2 rayEnd = selectedAiTarget.Position;
+ Vector2 rayEnd = selectedAiTarget.SimPosition;
Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd);
if (Submarine.LastPickedFraction == 1.0f || closestBody == null)
@@ -391,7 +388,7 @@ namespace Barotrauma
dist = Vector2.Distance(
character.AnimController.Limbs[0].SimPosition,
- target.Position);
+ target.SimPosition);
dist = ConvertUnits.ToDisplayUnits(dist);
AITargetMemory targetMemory = FindTargetMemory(target);
@@ -402,7 +399,7 @@ namespace Barotrauma
if (Math.Abs(valueModifier) > Math.Abs(targetValue) && (dist < target.SightRange * sight || dist < target.SoundRange * hearing))
{
Vector2 rayStart = character.AnimController.Limbs[0].SimPosition;
- Vector2 rayEnd = target.Position;
+ Vector2 rayEnd = target.SimPosition;
Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd);
Structure closestStructure = (closestBody == null) ? null : closestBody.UserData as Structure;
@@ -493,7 +490,7 @@ namespace Barotrauma
if (selectedAiTarget!=null)
{
- GUI.DrawLine(spriteBatch, pos, ConvertUnits.ToDisplayUnits(new Vector2(selectedAiTarget.Position.X, -selectedAiTarget.Position.Y)), Color.Red);
+ GUI.DrawLine(spriteBatch, pos, ConvertUnits.ToDisplayUnits(new Vector2(selectedAiTarget.SimPosition.X, -selectedAiTarget.SimPosition.Y)), Color.Red);
if (wallAttackPos!=Vector2.Zero)
{
diff --git a/Subsurface/Source/Characters/AI/HumanAIController.cs b/Subsurface/Source/Characters/AI/HumanAIController.cs
index e67a0d049..b092bd76c 100644
--- a/Subsurface/Source/Characters/AI/HumanAIController.cs
+++ b/Subsurface/Source/Characters/AI/HumanAIController.cs
@@ -13,20 +13,27 @@ namespace Barotrauma
private AIObjectiveManager objectiveManager;
+ private IndoorsSteeringManager indoorsSteeringManager;
+ private SteeringManager outdoorsSteeringManager;
+
private AITarget selectedAiTarget;
private float updateObjectiveTimer;
public HumanAIController(Character c) : base(c)
{
- steeringManager = new PathSteeringManager(this);
+ indoorsSteeringManager = new IndoorsSteeringManager(this, true);
+ outdoorsSteeringManager = new SteeringManager(this);
objectiveManager = new AIObjectiveManager(c);
- objectiveManager.AddObjective(new AIObjectiveFindSafety());
+ objectiveManager.AddObjective(new AIObjectiveFindSafety(c));
+ objectiveManager.AddObjective(new AIObjectiveIdle(c));
}
public override void Update(float deltaTime)
{
+ steeringManager = Character.AnimController.CurrentHull == null ? outdoorsSteeringManager : indoorsSteeringManager;
+
if (updateObjectiveTimer>0.0f)
{
updateObjectiveTimer -= deltaTime;
@@ -46,12 +53,15 @@ namespace Barotrauma
Character.AnimController.IgnorePlatforms = (-Character.AnimController.TargetMovement.Y > Math.Abs(Character.AnimController.TargetMovement.X));
- if (Math.Abs(Character.AnimController.TargetMovement.X)>0.1f)
+ if (Math.Abs(Character.AnimController.TargetMovement.X) > 0.1f && !Character.AnimController.InWater)
{
Character.AnimController.TargetDir = Character.AnimController.TargetMovement.X > 0.0f ? Direction.Right : Direction.Left;
}
- steeringManager.Update();
+ float currObjectivePriority = objectiveManager.CurrentObjective == null ? 0.0f : objectiveManager.CurrentObjective.GetPriority(Character);
+ float moveSpeed = MathHelper.Clamp(currObjectivePriority/10.0f, 1.0f, 3.0f);
+
+ steeringManager.Update(moveSpeed);
}
public override void SelectTarget(AITarget target)
@@ -61,13 +71,12 @@ namespace Barotrauma
public override void DebugDraw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
{
-
if (selectedAiTarget != null)
{
- GUI.DrawLine(spriteBatch, new Vector2(Character.Position.X, -Character.Position.Y), ConvertUnits.ToDisplayUnits(new Vector2(selectedAiTarget.Position.X, -selectedAiTarget.Position.Y)), Color.Red);
+ GUI.DrawLine(spriteBatch, new Vector2(Character.Position.X, -Character.Position.Y), ConvertUnits.ToDisplayUnits(new Vector2(selectedAiTarget.SimPosition.X, -selectedAiTarget.SimPosition.Y)), Color.Red);
}
- PathSteeringManager pathSteering = steeringManager as PathSteeringManager;
+ IndoorsSteeringManager pathSteering = steeringManager as IndoorsSteeringManager;
if (pathSteering == null || pathSteering.CurrentPath == null || pathSteering.CurrentPath.CurrentNode==null) return;
GUI.DrawLine(spriteBatch,
@@ -83,7 +92,6 @@ namespace Barotrauma
new Vector2(pathSteering.CurrentPath.Nodes[i - 1].Position.X, -pathSteering.CurrentPath.Nodes[i-1].Position.Y),
Color.LightGreen);
}
-
}
}
}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjective.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjective.cs
index 420d1441c..5da96ddf8 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjective.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjective.cs
@@ -11,14 +11,23 @@ namespace Barotrauma
protected float priority;
+ protected Character character;
+
public virtual bool IsCompleted()
{
return false;
}
- public AIObjective()
+ public virtual bool CanBeCompleted
+ {
+ get { return false; }
+ }
+
+ public AIObjective(Character character)
{
subObjectives = new List();
+
+ this.character = character;
}
///
@@ -26,20 +35,20 @@ namespace Barotrauma
/// need to be completed before this one
///
/// the character who's trying to achieve the objective
- public void TryComplete(float deltaTime, Character character)
+ public void TryComplete(float deltaTime)
{
foreach (AIObjective objective in subObjectives)
{
if (objective.IsCompleted()) continue;
- objective.TryComplete(deltaTime, character);
+ objective.TryComplete(deltaTime);
return;
}
- Act(deltaTime, character);
+ Act(deltaTime);
}
- protected virtual void Act(float deltaTime, Character character) { }
+ protected virtual void Act(float deltaTime) { }
public virtual float GetPriority(Character character)
{
@@ -48,7 +57,7 @@ namespace Barotrauma
public virtual bool IsDuplicate(AIObjective otherObjective)
{
- return true;
+ throw new NotImplementedException();
}
}
}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs
index e79d065a3..2fec74906 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs
@@ -12,16 +12,26 @@ namespace Barotrauma
const float MinSafety = 50.0f;
AIObjectiveGoTo gotoObjective;
+
+ private List unreachable;
float currenthullSafety;
float searchHullTimer;
- protected override void Act(float deltaTime, Character character)
+ public AIObjectiveFindSafety(Character character)
+ : base(character)
+ {
+ unreachable = new List();
+ }
+
+ protected override void Act(float deltaTime)
{
if (character.AnimController.CurrentHull == null || GetHullSafety(character.AnimController.CurrentHull) > MinSafety)
{
- character.AIController.SteeringManager.SteeringSeek(character.AnimController.CurrentHull.Position);
+ character.AIController.SteeringManager.SteeringSeek(character.AnimController.CurrentHull.SimPosition);
+
+ character.AIController.SelectTarget(null);
gotoObjective = null;
return;
@@ -32,34 +42,56 @@ namespace Barotrauma
searchHullTimer -= deltaTime;
return;
}
-
- searchHullTimer = SearchHullInterval;
-
- Hull bestHull = null;
- float bestValue = currenthullSafety;
-
- foreach (Hull hull in Hull.hullList)
+ else
{
- if (hull == character.AnimController.CurrentHull) continue;
- float hullValue = GetHullSafety(hull);
- hullValue -= (float)Math.Sqrt(Math.Abs(character.Position.X- hull.Position.X));
- hullValue -= (float)Math.Sqrt(Math.Abs(character.Position.Y - hull.Position.Y)*2.0f);
+ Hull bestHull = null;
+ float bestValue = currenthullSafety;
- if (bestHull==null || hullValue > bestValue)
+ foreach (Hull hull in Hull.hullList)
{
- bestHull = hull;
- bestValue = hullValue;
+ if (hull == character.AnimController.CurrentHull) continue;
+ if (unreachable.Contains(hull.AiTarget)) continue;
+
+ float hullValue = GetHullSafety(hull);
+ hullValue -= (float)Math.Sqrt(Math.Abs(character.Position.X- hull.Position.X));
+ hullValue -= (float)Math.Sqrt(Math.Abs(character.Position.Y - hull.Position.Y)*2.0f);
+
+ if (bestHull==null || hullValue > bestValue)
+ {
+ bestHull = hull;
+ bestValue = hullValue;
+ }
+ }
+
+ if (bestHull != null)
+ {
+ gotoObjective = new AIObjectiveGoTo(bestHull.AiTarget, character);
+ //character.AIController.SelectTarget(bestHull.AiTarget);
+ }
+
+
+ searchHullTimer = SearchHullInterval;
+ }
+
+ if (gotoObjective != null)
+ {
+ var pathSteering = character.AIController.SteeringManager as IndoorsSteeringManager;
+ if (pathSteering!=null && pathSteering.CurrentPath!= null &&
+ pathSteering.CurrentPath.Unreachable && !unreachable.Contains(gotoObjective.Target))
+ {
+ unreachable.Add(gotoObjective.Target);
}
}
- if (bestHull != null)
- {
- gotoObjective = new AIObjectiveGoTo(bestHull.AiTarget, character);
- //character.AIController.SelectTarget(bestHull.AiTarget);
- }
- gotoObjective.TryComplete(deltaTime, character);
+
+ gotoObjective.TryComplete(deltaTime);
+ }
+
+ public override bool IsDuplicate(AIObjective otherObjective)
+ {
+ return (otherObjective is AIObjectiveFindSafety);
}
public override float GetPriority(Character character)
@@ -77,10 +109,11 @@ namespace Barotrauma
foreach (FireSource fireSource in hull.FireSources)
{
- fireAmount += fireSource.Size.X;
+ fireAmount += Math.Max(fireSource.Size.X,50.0f);
}
- float safety = 100.0f - fireAmount - waterPercentage;
+ float safety = 100.0f - fireAmount;
+ if (waterPercentage > 30.0f) safety -= waterPercentage;
if (hull.OxygenPercentage < 30.0f) safety -= (30.0f-hull.OxygenPercentage)*3.0f;
return safety;
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs
new file mode 100644
index 000000000..0d23d7de4
--- /dev/null
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs
@@ -0,0 +1,48 @@
+using Microsoft.Xna.Framework;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Barotrauma
+{
+ class AIObjectiveFixLeak : AIObjective
+ {
+ Gap leak;
+
+ public AIObjectiveFixLeak(Gap leak, Character 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;
+ }
+
+ public override bool IsDuplicate(AIObjective otherObjective)
+ {
+ AIObjectiveFixLeak fixLeak = otherObjective as AIObjectiveFixLeak;
+ if (fixLeak == null) return false;
+ return fixLeak.leak == leak;
+ }
+
+ protected override void Act(float deltaTime)
+ {
+ var weldingTool = character.Inventory.FindItem("Welding Tool");
+
+ if (weldingTool == null)
+ {
+ subObjectives.Add(new AIObjectiveGetItem(character, "Welding Tool"));
+ }
+ else
+ {
+ if (Vector2.Distance(character.Position, leak.Position)>10.0f)
+ {
+ subObjectives.Add(new AIObjectiveGoTo(leak.Position,character));
+ }
+ }
+ }
+ }
+}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGetItem.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGetItem.cs
new file mode 100644
index 000000000..f2e1dc6ba
--- /dev/null
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGetItem.cs
@@ -0,0 +1,78 @@
+using Microsoft.Xna.Framework;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Barotrauma
+{
+ class AIObjectiveGetItem : AIObjective
+ {
+ private string itemName;
+
+ private Item targetItem;
+
+ private int currSearchIndex;
+
+ private bool canBeCompleted;
+
+ public override bool CanBeCompleted
+ {
+ get { return canBeCompleted; }
+ }
+
+ public AIObjectiveGetItem(Character character, string itemName)
+ : base (character)
+ {
+ canBeCompleted = true;
+
+ currSearchIndex = 0;
+
+ this.itemName = itemName;
+ }
+
+ protected override void Act(float deltaTime)
+ {
+ if (targetItem != null)
+ {
+ if (Vector2.Distance(character.SimPosition, targetItem.SimPosition) < targetItem.PickDistance)
+ {
+ targetItem.Pick(character, false, true);
+ }
+ return;
+ }
+
+ if (currSearchIndex >= Item.ItemList.Count)
+ {
+ canBeCompleted = false;
+ return;
+ }
+
+ if (Item.ItemList[currSearchIndex].HasTag(itemName) || Item.ItemList[currSearchIndex].Name == itemName)
+ {
+ targetItem = Item.ItemList[currSearchIndex];
+
+ while (targetItem.container != null)
+ {
+ targetItem = targetItem.container;
+ }
+
+ subObjectives.Add(new AIObjectiveGoTo(targetItem.Position, character));
+ }
+
+ currSearchIndex++;
+ }
+
+ public override bool IsDuplicate(AIObjective otherObjective)
+ {
+ AIObjectiveGetItem getItem = otherObjective as AIObjectiveGetItem;
+ if (getItem == null) return false;
+ return (getItem.itemName == itemName);
+ }
+
+ public override bool IsCompleted()
+ {
+ return character.Inventory.Items.FirstOrDefault(i => i != null && (i.HasTag(itemName) || i.Name == itemName)) != null;
+ }
+ }
+}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs
index e8bd7d3ff..63e6a1614 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs
@@ -12,22 +12,46 @@ namespace Barotrauma
{
AITarget target;
- private Character character;
+ Vector2 targetPos;
- public AIObjectiveGoTo(AITarget target, Character character)
+ public override bool CanBeCompleted
{
- this.character = character;
- this.target = target;
-
+ get
+ {
+ var pathSteering = character.AIController.SteeringManager as IndoorsSteeringManager;
+ return (pathSteering.CurrentPath == null || !pathSteering.CurrentPath.Unreachable);
+ }
}
- protected override void Act(float deltaTime, Character character)
+ public AITarget Target
{
- if (target == null) return;
+ get { return target; }
+ }
+ public AIObjectiveGoTo(AITarget target, Character character)
+ : base (character)
+ {
+ this.target = target;
+ }
+
+
+ public AIObjectiveGoTo(Vector2 targetPos, Character character)
+ : base(character)
+ {
+ this.targetPos = targetPos;
+ }
+
+ protected override void Act(float deltaTime)
+ {
character.AIController.SelectTarget(target);
- character.AIController.SteeringManager.SteeringSeek(ConvertUnits.ToDisplayUnits(target.Position));
+ character.AIController.SteeringManager.SteeringSeek(
+ target != null ? target.SimPosition : targetPos);
+ }
+
+ public override bool IsCompleted()
+ {
+ return Vector2.Distance(target != null ? target.SimPosition : ConvertUnits.ToDisplayUnits(targetPos), character.SimPosition) < 0.5f;
}
}
}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs
new file mode 100644
index 000000000..1d24d7f78
--- /dev/null
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs
@@ -0,0 +1,90 @@
+using Microsoft.Xna.Framework;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Barotrauma
+{
+ class AIObjectiveIdle : AIObjective
+ {
+ AITarget currentTarget;
+ private float newTargetTimer;
+
+
+
+ public AIObjectiveIdle(Character character) : base(character)
+ {
+
+ }
+
+ public override float GetPriority(Character character)
+ {
+ return 1.0f;
+ }
+
+
+ protected override void Act(float deltaTime)
+ {
+ if (newTargetTimer <= 0.0f)
+ {
+ currentTarget = FindRandomTarget();
+
+ newTargetTimer = currentTarget == null ? 5.0f : 10.0f;
+ }
+ else
+ {
+ newTargetTimer -= deltaTime;
+ }
+
+
+ if (currentTarget == null) return;
+
+ character.AIController.SteeringManager.SteeringSeek(currentTarget.SimPosition);
+
+ var pathSteering = character.AIController.SteeringManager as IndoorsSteeringManager;
+ if (pathSteering!=null && pathSteering.CurrentPath != null)
+ {
+ if (pathSteering.CurrentPath.NextNode==null || pathSteering.CurrentPath.Unreachable)
+ {
+ character.AIController.SteeringManager.SteeringWander(1.0f);
+ }
+ }
+ }
+
+ private AITarget FindRandomTarget()
+ {
+ if (Rand.Int(5)==1)
+ {
+ var idCard = character.Inventory.FindItem("ID Card");
+ if (idCard==null) return null;
+
+ foreach (WayPoint wp in WayPoint.WayPointList)
+ {
+ if (wp.SpawnType != SpawnType.Human) continue;
+
+ foreach (string tag in wp.IdCardTags)
+ {
+ if (idCard.HasTag(tag)) return wp.CurrentHull.AiTarget;
+ }
+ }
+ }
+ else
+ {
+ List targetHulls = new List(Hull.hullList);
+ //ignore all hulls with fires or water in them
+ targetHulls.RemoveAll(h => h.FireSources.Any() || (h.Volume/h.FullVolume)>0.1f);
+ if (!targetHulls.Any()) return null;
+
+ return targetHulls[Rand.Range(0, targetHulls.Count)].AiTarget;
+ }
+
+ return null;
+ }
+
+ public override bool IsDuplicate(AIObjective otherObjective)
+ {
+ return true;
+ }
+ }
+}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveManager.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveManager.cs
index 68d4f82ea..3f413d27f 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveManager.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveManager.cs
@@ -10,6 +10,14 @@ namespace Barotrauma
private List objectives;
private Character character;
+
+ public AIObjective CurrentObjective
+ {
+ get
+ {
+ return objectives.Any() ? objectives[0] : null;
+ }
+ }
public AIObjectiveManager(Character character)
{
@@ -33,14 +41,24 @@ namespace Barotrauma
objectives = objectives.FindAll(o => !o.IsCompleted());
//sort objectives according to priority
- objectives.Sort((x, y) => x.GetPriority(character).CompareTo(y.GetPriority(character)));
-
+ objectives.Sort((x, y) => y.GetPriority(character).CompareTo(x.GetPriority(character)));
+
+ if (character.AnimController.CurrentHull!=null)
+ {
+ var gaps = character.AnimController.CurrentHull.FindGaps();
+
+ foreach (Gap gap in gaps)
+ {
+ if (gap.linkedTo.Count > 1) continue;
+ AddObjective(new AIObjectiveFixLeak(gap, character));
+ }
+ }
}
public void DoCurrentObjective(float deltaTime)
{
if (!objectives.Any()) return;
- objectives[0].TryComplete(deltaTime, character);
+ objectives[0].TryComplete(deltaTime);
}
}
}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs
index 8da97fd54..fe4107793 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs
@@ -9,12 +9,13 @@ namespace Barotrauma
{
private Item targetItem;
- public AIObjectiveOperateItem(Item item)
+ public AIObjectiveOperateItem(Item item, Character character)
+ :base (character)
{
targetItem = item;
}
- protected override void Act(float deltaTime, Character character)
+ protected override void Act(float deltaTime)
{
//item.AIOperate(float deltaTime, Character character) or something
}
diff --git a/Subsurface/Source/Characters/AI/PathFinder.cs b/Subsurface/Source/Characters/AI/PathFinder.cs
index f6fe77c3a..5af610785 100644
--- a/Subsurface/Source/Characters/AI/PathFinder.cs
+++ b/Subsurface/Source/Characters/AI/PathFinder.cs
@@ -77,8 +77,8 @@ namespace Barotrauma
class PathFinder
{
- public delegate float GetNodePenaltyHandler(PathNode node, PathNode prevNode);
- public GetNodePenaltyHandler GetNodePriority;
+ public delegate float? GetNodePenaltyHandler(PathNode node, PathNode prevNode);
+ public GetNodePenaltyHandler GetNodePenalty;
List nodes;
@@ -95,12 +95,14 @@ namespace Barotrauma
{
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
-
+
float closestDist = 0.0f;
PathNode startNode = null;
foreach (PathNode node in nodes)
{
- float dist = Vector2.Distance(start,node.Position);
+ float dist = System.Math.Abs(start.X-node.Position.X)+
+ System.Math.Abs(start.Y - node.Position.Y)*10.0f +
+ Vector2.Distance(end,node.Position)/2.0f;
if (dist openableButtons;
+ private Character character;
public SteeringPath CurrentPath
{
@@ -31,15 +31,15 @@ namespace Barotrauma
private float findPathTimer;
- public PathSteeringManager(ISteerable host)
+ public IndoorsSteeringManager(ISteerable host, bool canOpenDoors)
: base(host)
{
pathFinder = new PathFinder(WayPoint.WayPointList.FindAll(wp => wp.SpawnType == SpawnType.Path), true);
- pathFinder.GetNodePriority = GetNodePriority;
+ pathFinder.GetNodePenalty = GetNodePenalty;
+
+ this.canOpenDoors = canOpenDoors;
character = (host as AIController).Character;
-
- openableButtons = new List();
}
public override void Update(float speed = 1)
@@ -53,37 +53,22 @@ 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.DistanceSquared(target, currentTarget)>10.0f)
+ if (currentPath == null || Vector2.Distance(target, currentTarget)>1.0f || findPathTimer < -10.0f)
{
if (findPathTimer > 0.0f) return Vector2.Zero;
currentTarget = target;
- currentPath = pathFinder.FindPath(host.SimPosition, ConvertUnits.ToSimUnits(target));
-
+ currentPath = pathFinder.FindPath(host.SimPosition, target);
+
findPathTimer = 1.0f;
return DiffToCurrentNode();
}
-
- //if (pathSteering == null || pathSteering.CurrentPath == null || pathSteering.CurrentPath.CurrentNode == null) return;
-
- //if (currentPath.CurrentNode.ConnectedGap != null && currentPath.CurrentNode.ConnectedGap.Open < 0.9f)
- //{
- foreach (Controller controller in openableButtons)
- {
- if (Vector2.Distance(controller.Item.SimPosition, character.SimPosition) > controller.Item.PickDistance) continue;
-
- controller.Item.Pick(character, false, true);
- }
- //}
-
-
-
Vector2 diff = DiffToCurrentNode();
if (diff == Vector2.Zero) return -host.Steering;
-
+
return (diff == Vector2.Zero) ? Vector2.Zero : Vector2.Normalize(diff)*speed;
}
@@ -91,61 +76,77 @@ namespace Barotrauma
{
if (currentPath == null) return Vector2.Zero;
- currentPath.CheckProgress(host.SimPosition, 0.45f);
+ if (canOpenDoors) CheckDoorsInPath();
+
+ currentPath.CheckProgress(host.SimPosition, character.AnimController.InWater ? 1.0f : 0.6f);
if (currentPath.CurrentNode == null) return Vector2.Zero;
return currentPath.CurrentNode.SimPosition - host.SimPosition;
}
- private float GetNodePriority(PathNode node, PathNode nextNode)
+ private void CheckDoorsInPath()
{
- if (character==null) return 0.0f;
- if (nextNode.Waypoint.ConnectedGap!=null)
+ for (int i = 0; i < 2; i++)
+ {
+ WayPoint node = i == 0 ? currentPath.CurrentNode : currentPath.PrevNode;
+
+ if (node == null || node.ConnectedGap == null || node.ConnectedGap.ConnectedDoor == null) continue;
+
+ var door = node.ConnectedGap.ConnectedDoor;
+
+ bool open = currentPath.CurrentNode != null &&
+ Math.Sign(door.Item.SimPosition.X - host.SimPosition.X) == Math.Sign(currentPath.CurrentNode.SimPosition.X - host.SimPosition.X);
+
+ //toggle the door if it's the previous node and open, or if it's current node and closed
+ if (door.IsOpen != open)
+ {
+ var buttons = door.GetButtons();
+ foreach (Controller controller in buttons)
+ {
+ if (Vector2.Distance(controller.Item.SimPosition, character.SimPosition) > controller.Item.PickDistance * 2.0f) continue;
+
+ controller.Item.Pick(character, false, true);
+ break;
+ }
+ }
+ }
+ }
+
+ private float? GetNodePenalty(PathNode node, PathNode nextNode)
+ {
+ if (character == null) return 0.0f;
+ if (nextNode.Waypoint.ConnectedGap != null)
{
if (nextNode.Waypoint.ConnectedGap.Open > 0.9f) return 0.0f;
if (nextNode.Waypoint.ConnectedGap.ConnectedDoor == null) return 100.0f;
- var doorButtons = GetDoorButtons(nextNode.Waypoint.ConnectedGap.ConnectedDoor);
+ if (!canOpenDoors) return null;
+
+ var doorButtons = nextNode.Waypoint.ConnectedGap.ConnectedDoor.GetButtons();
foreach (Controller button in doorButtons)
{
if (Math.Sign(button.Item.Position.X - nextNode.Waypoint.Position.X) !=
Math.Sign(node.Position.X - nextNode.Position.X)) continue;
- if (!button.HasRequiredItems(character, false)) return 1000.0f;
+ if (!button.HasRequiredItems(character, false)) return null;
}
}
+ if (node.Waypoint!=null && node.Waypoint.CurrentHull!=null)
+ {
+ var hull = node.Waypoint.CurrentHull;
+
+ float penalty = hull.FireSources.Any() ? 1000.0f : 0.0f;
+
+ if (character.NeedsAir && hull.Volume / hull.Rect.Width > 100.0f) penalty += 500.0f;
+ if (character.PressureProtection < 10.0f && hull.Volume > hull.FullVolume) penalty += 1000.0f;
+ }
+
return 0.0f;
}
- private List GetDoorButtons(Door door)
- {
- if (door == null) return new List();
- ConnectionPanel connectionPanel = door.Item.GetComponent();
- List doorButtons = new List();
-
- foreach (Connection c in connectionPanel.Connections)
- {
- foreach (Wire w in c.Wires)
- {
- if (w == null) continue;
- var otherConnection = w.OtherConnection(c);
-
- if (otherConnection.Item == door.Item || otherConnection == null) continue;
-
- var controller = otherConnection.Item.GetComponent();
- if (controller != null)
- {
- doorButtons.Add(controller);
- if (!openableButtons.Contains(controller)) openableButtons.Add(controller);
- }
- }
- }
-
- return doorButtons;
- }
}
}
diff --git a/Subsurface/Source/Characters/AI/SteeringPath.cs b/Subsurface/Source/Characters/AI/SteeringPath.cs
index e52f748a7..d508da2d8 100644
--- a/Subsurface/Source/Characters/AI/SteeringPath.cs
+++ b/Subsurface/Source/Characters/AI/SteeringPath.cs
@@ -9,9 +9,16 @@ namespace Barotrauma
int currentIndex;
- public SteeringPath()
+ public bool Unreachable
+ {
+ get;
+ private set;
+ }
+
+ public SteeringPath(bool unreachable = false)
{
nodes = new List();
+ Unreachable = unreachable;
}
public void AddNode(WayPoint node)
@@ -20,6 +27,20 @@ namespace Barotrauma
nodes.Add(node);
}
+ public int CurrentIndex
+ {
+ get { return currentIndex; }
+ }
+
+ public WayPoint PrevNode
+ {
+ get
+ {
+ if (currentIndex-1 < 0 || currentIndex-1 > nodes.Count - 1) return null;
+ return nodes[currentIndex-1];
+ }
+ }
+
public WayPoint CurrentNode
{
get
diff --git a/Subsurface/Source/Characters/AICharacter.cs b/Subsurface/Source/Characters/AICharacter.cs
index e4563302b..ba52cab67 100644
--- a/Subsurface/Source/Characters/AICharacter.cs
+++ b/Subsurface/Source/Characters/AICharacter.cs
@@ -75,7 +75,7 @@ namespace Barotrauma
{
base.DrawFront(spriteBatch);
- if (GameMain.DebugDraw) aiController.DebugDraw(spriteBatch);
+ if (GameMain.DebugDraw && !isDead) aiController.DebugDraw(spriteBatch);
}
public override AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, float deltaTime, bool playSound = false)
diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs
index 6c0a21867..f75d75bfe 100644
--- a/Subsurface/Source/Characters/Character.cs
+++ b/Subsurface/Source/Characters/Character.cs
@@ -84,6 +84,17 @@ namespace Barotrauma
//the name of the species (e.q. human)
public readonly string SpeciesName;
+ protected float soundTimer;
+ protected float soundInterval;
+
+ private float bleeding;
+
+ private Sound[] sounds;
+ private float[] soundRange;
+ //which AIstate each sound is for
+ private AIController.AiState[] soundStates;
+
+
private CharacterInfo info;
public CharacterInfo Info
@@ -99,16 +110,6 @@ namespace Barotrauma
}
}
- protected float soundTimer;
- protected float soundInterval;
-
- private float bleeding;
-
- private Sound[] sounds;
- private float[] soundRange;
- //which AIstate each sound is for
- private AIController.AiState[] soundStates;
-
public string Name
{
get
@@ -171,6 +172,7 @@ namespace Barotrauma
{
get { return aiTarget.SightRange; }
}
+
private float pressureProtection;
public float PressureProtection
{
@@ -181,11 +183,17 @@ namespace Barotrauma
}
}
+ public bool NeedsAir
+ {
+ get { return needsAir; }
+ }
+
public float Oxygen
{
get { return oxygen; }
set
{
+ if (!MathUtils.IsValid(value)) return;
oxygen = MathHelper.Clamp(value, 0.0f, 100.0f);
if (oxygen == 0.0f) Kill(CauseOfDeath.Suffocation);
}
@@ -567,6 +575,8 @@ namespace Barotrauma
AnimController.TargetMovement = targetMovement;
AnimController.IsStanding = true;
+ AnimController.IgnorePlatforms = targetMovement.Y < 0.0f;
+
if (AnimController.onGround &&
!AnimController.InWater &&
AnimController.Anim != AnimController.Animation.UsingConstruction)
@@ -877,7 +887,7 @@ namespace Barotrauma
if (isDead) return;
- if (!(this is AICharacter))
+ if (!(AnimController is FishAnimController))
{
bool protectedFromPressure = PressureProtection > 0.0f;
@@ -993,7 +1003,7 @@ namespace Barotrauma
AnimController.DebugDraw(spriteBatch);
}
- Vector2 healthBarPos = new Vector2(Position.X - 50, -Position.Y - 50.0f);
+ Vector2 healthBarPos = new Vector2(Position.X - 50, -Position.Y - 100.0f);
GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X - 2, (int)healthBarPos.Y - 2, 100 + 4, 15 + 4), Color.Black, false);
GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X, (int)healthBarPos.Y, (int)(100.0f * (health / maxHealth)), 15), Color.Red, true);
}
diff --git a/Subsurface/Source/Characters/CharacterInfo.cs b/Subsurface/Source/Characters/CharacterInfo.cs
index 162931585..cc6b805d0 100644
--- a/Subsurface/Source/Characters/CharacterInfo.cs
+++ b/Subsurface/Source/Characters/CharacterInfo.cs
@@ -219,7 +219,7 @@ namespace Barotrauma
public void UpdateCharacterItems()
{
pickedItems.Clear();
- foreach (Item item in Character.Inventory.items)
+ foreach (Item item in Character.Inventory.Items)
{
pickedItems.Add(item == null ? (ushort)0 : item.ID);
}
diff --git a/Subsurface/Source/Characters/HumanoidAnimController.cs b/Subsurface/Source/Characters/HumanoidAnimController.cs
index 8244d80e6..3fea8f485 100644
--- a/Subsurface/Source/Characters/HumanoidAnimController.cs
+++ b/Subsurface/Source/Characters/HumanoidAnimController.cs
@@ -133,11 +133,7 @@ namespace Barotrauma
stunTimer -= deltaTime;
return;
}
-
- IgnorePlatforms = (TargetMovement.Y < 0.0f);
-
-
-
+
if (Anim != Animation.UsingConstruction) ResetPullJoints();
if (TargetDir != dir) Flip();
diff --git a/Subsurface/Source/DebugConsole.cs b/Subsurface/Source/DebugConsole.cs
index b245b55df..8226cec06 100644
--- a/Subsurface/Source/DebugConsole.cs
+++ b/Subsurface/Source/DebugConsole.cs
@@ -269,6 +269,12 @@ namespace Barotrauma
case "edit":
GameMain.EditMapScreen.Select();
break;
+ case "test":
+ Submarine.Load("aegir mark ii");
+ GameMain.DebugDraw = true;
+ GameMain.LightManager.LosEnabled = false;
+ GameMain.EditMapScreen.Select();
+ break;
case "editcharacter":
case "editchar":
GameMain.EditCharacterScreen.Select();
diff --git a/Subsurface/Source/GUI/GUIButton.cs b/Subsurface/Source/GUI/GUIButton.cs
index 235bbecbf..8973d95eb 100644
--- a/Subsurface/Source/GUI/GUIButton.cs
+++ b/Subsurface/Source/GUI/GUIButton.cs
@@ -63,8 +63,8 @@ namespace Barotrauma
}
set
{
- if (textBlock == null) return;
base.Font = value;
+ if (textBlock != null) textBlock.Font = value;
}
}
diff --git a/Subsurface/Source/GameSession/CrewManager.cs b/Subsurface/Source/GameSession/CrewManager.cs
index c81d87ffb..e7c30ad55 100644
--- a/Subsurface/Source/GameSession/CrewManager.cs
+++ b/Subsurface/Source/GameSession/CrewManager.cs
@@ -98,7 +98,8 @@ namespace Barotrauma
name,
Color.Transparent, Color.White,
Alignment.Left, Alignment.Left,
- null, frame);
+ null, frame, false);
+ textBlock.Font = GUI.SmallFont;
textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
new GUIImage(new Rectangle(-10, -10, 0, 0), character.AnimController.Limbs[0].sprite, Alignment.Left, frame);
diff --git a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs
index 5178374bb..5a6fe2582 100644
--- a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs
+++ b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs
@@ -52,6 +52,7 @@ namespace Barotrauma
CargoManager = new CargoManager();
endShiftButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 220, 20, 200, 25), "End shift", Alignment.TopLeft, GUI.Style);
+ endShiftButton.Font = GUI.SmallFont;
endShiftButton.OnClicked = EndShift;
for (int i = 0; i < 3; i++)
@@ -142,14 +143,12 @@ namespace Barotrauma
if (Level.Loaded.AtEndPosition)
{
- endShiftButton.Text = "Enter " + Map.SelectedLocation.Name;
- endShiftButton.Font = GUI.SmallFont;
+ endShiftButton.Text = "Enter " + Map.SelectedLocation.Name;
endShiftButton.Draw(spriteBatch);
}
else if (Level.Loaded.AtStartPosition)
{
endShiftButton.Text = "Enter " + Map.CurrentLocation.Name;
- endShiftButton.Font = GUI.SmallFont;
endShiftButton.Draw(spriteBatch);
}
diff --git a/Subsurface/Source/GameSession/GameModes/TutorialMode.cs b/Subsurface/Source/GameSession/GameModes/TutorialMode.cs
index 96d6fec8b..b9854f2ff 100644
--- a/Subsurface/Source/GameSession/GameModes/TutorialMode.cs
+++ b/Subsurface/Source/GameSession/GameModes/TutorialMode.cs
@@ -50,16 +50,10 @@ namespace Barotrauma
Character character = Character.Create(charInfo, wayPoint.SimPosition);
Character.Controlled = character;
character.GiveJobItems(null);
-
- foreach (Item item in character.Inventory.items)
- {
- if (item == null || item.Name != "ID Card") continue;
- item.AddTag("com");
- item.AddTag("eng");
-
- break;
- }
+ var idCard = character.Inventory.FindItem("ID Card");
+ idCard.AddTag("com");
+ idCard.AddTag("eng");
CrewManager.AddCharacter(character);
@@ -495,7 +489,7 @@ namespace Barotrauma
do
{
- var weldingTool = Character.Controlled.Inventory.items.FirstOrDefault(i => i != null && i.Name == "Welding Tool");
+ var weldingTool = Character.Controlled.Inventory.Items.FirstOrDefault(i => i != null && i.Name == "Welding Tool");
if (weldingTool != null &&
weldingTool.ContainedItems.FirstOrDefault(contained => contained != null && contained.Name == "Welding Fuel Tank") != null) break;
@@ -604,7 +598,7 @@ namespace Barotrauma
private bool HasItem(string itemName)
{
if (Character.Controlled == null) return false;
- return Character.Controlled.Inventory.items.FirstOrDefault(i => i != null && i.Name == itemName)!=null;
+ return Character.Controlled.Inventory.Items.FirstOrDefault(i => i != null && i.Name == itemName)!=null;
}
///
diff --git a/Subsurface/Source/Items/CharacterInventory.cs b/Subsurface/Source/Items/CharacterInventory.cs
index 95c3fed58..8bdf72dfb 100644
--- a/Subsurface/Source/Items/CharacterInventory.cs
+++ b/Subsurface/Source/Items/CharacterInventory.cs
@@ -81,7 +81,7 @@ namespace Barotrauma
public int FindLimbSlot(LimbSlot limbSlot)
{
- for (int i = 0; i < items.Length; i++)
+ for (int i = 0; i < Items.Length; i++)
{
if ( limbSlots[i] == limbSlot) return i;
}
@@ -90,9 +90,9 @@ namespace Barotrauma
public bool IsInLimbSlot(Item item, LimbSlot limbSlot)
{
- for (int i = 0; i 4);
+ UpdateSlot(spriteBatch, slotRect, i, Items[i], i > 4);
- if (draggingItem!=null && draggingItem == items[i]) draggingItemSlot = slotRect;
+ if (draggingItem!=null && draggingItem == Items[i]) draggingItemSlot = slotRect;
}
@@ -406,7 +406,7 @@ namespace Barotrauma
bool multiSlot = false;
//check if the item is in multiple slots
- if (items[i] != null)
+ if (Items[i] != null)
{
slotRect.X = (int)slotPositions[i].X;
slotRect.Y = (int)slotPositions[i].Y;
@@ -415,7 +415,7 @@ namespace Barotrauma
for (int n = 0; n < capacity; n++)
{
- if (items[n] != items[i]) continue;
+ if (Items[n] != Items[i]) continue;
if (!multiSlot && i > n) break;
@@ -430,7 +430,7 @@ namespace Barotrauma
if (!multiSlot) continue;
- UpdateSlot(spriteBatch, slotRect, i, items[i], i > 4);
+ UpdateSlot(spriteBatch, slotRect, i, Items[i], i > 4);
//if (multiSlot && i == first)
//{
@@ -469,7 +469,7 @@ namespace Barotrauma
{
for (int i = 0; i < capacity; i++)
{
- message.Write(items[i]==null ? (ushort)0 : (ushort)items[i].ID);
+ message.Write(Items[i]==null ? (ushort)0 : (ushort)Items[i].ID);
}
return true;
@@ -486,14 +486,14 @@ namespace Barotrauma
ushort itemId = message.ReadUInt16();
if (itemId==0)
{
- if (items[i] != null) items[i].Drop(character, false);
+ if (Items[i] != null) Items[i].Drop(character, false);
}
else
{
Item item = Entity.FindEntityByID(itemId) as Item;
if (item == null) continue;
- if (items[i] != item && items[i] != null) items[i].Drop(character, false);
+ if (Items[i] != item && Items[i] != null) Items[i].Drop(character, false);
TryPutItem(item, i, false);
}
}
diff --git a/Subsurface/Source/Items/Components/Door.cs b/Subsurface/Source/Items/Components/Door.cs
index eb83c9986..c6e60c2d3 100644
--- a/Subsurface/Source/Items/Components/Door.cs
+++ b/Subsurface/Source/Items/Components/Door.cs
@@ -7,6 +7,7 @@ using FarseerPhysics.Factories;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Lights;
+using System.Collections.Generic;
namespace Barotrauma.Items.Components
{
@@ -41,8 +42,7 @@ namespace Barotrauma.Items.Components
if (linkedGap != null) return linkedGap;
foreach (MapEntity e in item.linkedTo)
{
- linkedGap = e as Gap;
- linkedGap.ConnectedDoor = this;
+ linkedGap = e as Gap;
if (linkedGap != null) return linkedGap;
}
linkedGap = new Gap(item.Rect);
@@ -256,6 +256,30 @@ namespace Barotrauma.Items.Components
linkedGap.Open = 1.0f;
}
+ public List GetButtons()
+ {
+ ConnectionPanel connectionPanel = Item.GetComponent();
+ if (connectionPanel == null) return new List();
+
+ List buttons = new List();
+
+ foreach (Connection c in connectionPanel.Connections)
+ {
+ foreach (Wire w in c.Wires)
+ {
+ if (w == null) continue;
+ var otherConnection = w.OtherConnection(c);
+
+ if (otherConnection.Item == Item || otherConnection == null) continue;
+
+ var controller = otherConnection.Item.GetComponent();
+ if (controller != null) buttons.Add(controller);
+ }
+ }
+
+ return buttons;
+ }
+
public override void Draw(SpriteBatch spriteBatch, bool editing)
{
Color color = (item.IsSelected) ? Color.Green : Color.White;
@@ -272,38 +296,43 @@ namespace Barotrauma.Items.Components
if (openState == 1.0f)
{
body.Enabled = false;
+ return;
+ }
+
+ spriteBatch.Draw(doorSprite.Texture, new Vector2(item.Rect.Center.X, -item.Rect.Y),
+ new Rectangle(doorSprite.SourceRect.X, (int)(doorSprite.size.Y * openState),
+ (int)doorSprite.size.X, (int)(doorSprite.size.Y * (1.0f - openState))),
+ color, 0.0f, doorSprite.Origin, 1.0f, SpriteEffects.None, doorSprite.Depth);
+
+ if (openState == 0.0f)
+ {
+ body.Enabled = true;
}
else
{
- spriteBatch.Draw(doorSprite.Texture, new Vector2(item.Rect.Center.X, -item.Rect.Y),
- new Rectangle(doorSprite.SourceRect.X, (int)(doorSprite.size.Y * openState),
- (int)doorSprite.size.X, (int)(doorSprite.size.Y * (1.0f - openState))),
- color, 0.0f, doorSprite.Origin, 1.0f, SpriteEffects.None, doorSprite.Depth);
+ //push characters out of the doorway when the door is closing/opening
+ Vector2 simPos = ConvertUnits.ToSimUnits(new Vector2(item.Rect.X, item.Rect.Y));
+ Vector2 simSize = ConvertUnits.ToSimUnits(new Vector2(item.Rect.Width,
+ item.Rect.Height * (1.0f - openState)));
- if (openState == 0.0f)
+ foreach (Character c in Character.CharacterList)
{
- body.Enabled = true;
- }
- else
- {
- //push characters out of the doorway when the door is closing/opening
- Vector2 simPos = ConvertUnits.ToSimUnits(new Vector2(item.Rect.X, item.Rect.Y));
- Vector2 simSize = ConvertUnits.ToSimUnits(new Vector2(item.Rect.Width,
- item.Rect.Height * (1.0f - openState)));
-
- foreach (Character c in Character.CharacterList)
+ int dir = Math.Sign(c.AnimController.Limbs[0].SimPosition.X - simPos.X);
+ foreach (Limb l in c.AnimController.Limbs)
{
- int dir = Math.Sign(c.AnimController.Limbs[0].SimPosition.X - simPos.X);
- foreach (Limb l in c.AnimController.Limbs)
- {
- if (l.SimPosition.Y < simPos.Y || l.SimPosition.Y > simPos.Y - simSize.Y) continue;
- if (Math.Abs(l.SimPosition.X - simPos.X) > simSize.X * 2.0f) continue;
+ if (l.SimPosition.Y < simPos.Y || l.SimPosition.Y > simPos.Y - simSize.Y) continue;
+ if (Math.Abs(l.SimPosition.X - simPos.X) > simSize.X * 2.0f) continue;
- l.body.ApplyForce(new Vector2(dir * 10.0f, 0.0f));
- }
+ l.body.ApplyForce(new Vector2(dir * 10.0f, 0.0f));
}
}
}
+
+ }
+
+ public override void OnMapLoaded()
+ {
+ LinkedGap.ConnectedDoor = this;
}
public override void Remove()
diff --git a/Subsurface/Source/Items/Components/ItemComponent.cs b/Subsurface/Source/Items/Components/ItemComponent.cs
index 2550ce4b6..7f4f750f8 100644
--- a/Subsurface/Source/Items/Components/ItemComponent.cs
+++ b/Subsurface/Source/Items/Components/ItemComponent.cs
@@ -551,7 +551,7 @@ namespace Barotrauma.Items.Components
}
if (!hasItem && ri.Type.HasFlag(RelatedItem.RelationType.Picked))
{
- if (character.Inventory.items.FirstOrDefault(x => x!=null && x.Condition>0.0f && ri.MatchesItem(x))!=null) hasItem = true;
+ if (character.Inventory.Items.FirstOrDefault(x => x!=null && x.Condition>0.0f && ri.MatchesItem(x))!=null) hasItem = true;
}
if (!hasItem)
{
diff --git a/Subsurface/Source/Items/Components/ItemContainer.cs b/Subsurface/Source/Items/Components/ItemContainer.cs
index 3cb9cfad4..0babebb28 100644
--- a/Subsurface/Source/Items/Components/ItemContainer.cs
+++ b/Subsurface/Source/Items/Components/ItemContainer.cs
@@ -127,7 +127,7 @@ namespace Barotrauma.Items.Components
{
if (!hasStatusEffects) return;
- foreach (Item contained in inventory.items)
+ foreach (Item contained in inventory.Items)
{
if (contained == null || contained.Condition <= 0.0f) continue;
//if (contained.body != null) contained.body.Enabled = false;
@@ -179,7 +179,7 @@ namespace Barotrauma.Items.Components
currentRotation += item.body.Rotation;
}
- foreach (Item containedItem in inventory.items)
+ foreach (Item containedItem in inventory.Items)
{
if (containedItem == null) continue;
@@ -243,7 +243,7 @@ namespace Barotrauma.Items.Components
{
base.Remove();
- foreach (Item item in inventory.items)
+ foreach (Item item in inventory.Items)
{
if (item == null) continue;
item.Remove();
@@ -274,10 +274,10 @@ namespace Barotrauma.Items.Components
{
XElement componentElement = base.Save(parentElement);
- string[] itemIdStrings = new string[inventory.items.Length];
- for (int i = 0; i < inventory.items.Length; i++)
+ string[] itemIdStrings = new string[inventory.Items.Length];
+ for (int i = 0; i < inventory.Items.Length; i++)
{
- itemIdStrings[i] = (inventory.items[i]==null) ? "0" : inventory.items[i].ID.ToString();
+ itemIdStrings[i] = (inventory.Items[i]==null) ? "0" : inventory.Items[i].ID.ToString();
}
componentElement.Add(new XAttribute("contained", string.Join(",",itemIdStrings)));
diff --git a/Subsurface/Source/Items/Components/Machines/Fabricator.cs b/Subsurface/Source/Items/Components/Machines/Fabricator.cs
index ffde50cc3..70b302f71 100644
--- a/Subsurface/Source/Items/Components/Machines/Fabricator.cs
+++ b/Subsurface/Source/Items/Components/Machines/Fabricator.cs
@@ -162,7 +162,7 @@ namespace Barotrauma.Items.Components
ItemContainer container = item.GetComponent();
foreach (ItemPrefab ip in fabricatedItem.RequiredItems)
{
- var requiredItem = Array.Find(container.inventory.items, it => it != null && it.Prefab == ip);
+ var requiredItem = container.inventory.Items.FirstOrDefault(it => it != null && it.Prefab == ip);
container.inventory.RemoveItem(requiredItem);
}
@@ -182,7 +182,7 @@ namespace Barotrauma.Items.Components
ItemContainer container = item.GetComponent();
foreach (ItemPrefab ip in targetItem.RequiredItems)
{
- if (Array.Find(container.inventory.items, it => it != null && it.Prefab == ip) != null) continue;
+ if (Array.Find(container.inventory.Items, it => it != null && it.Prefab == ip) != null) continue;
selectedItemFrame.GetChild().Enabled = false;
break;
}
diff --git a/Subsurface/Source/Items/Components/Turret.cs b/Subsurface/Source/Items/Components/Turret.cs
index ff617ef98..142ce006c 100644
--- a/Subsurface/Source/Items/Components/Turret.cs
+++ b/Subsurface/Source/Items/Components/Turret.cs
@@ -139,12 +139,12 @@ namespace Barotrauma.Items.Components
ItemContainer containerComponent = projectileContainer.GetComponent();
if (containerComponent == null) continue;
- for (int i = 0; i < containerComponent.inventory.items.Length; i++)
+ for (int i = 0; i < containerComponent.inventory.Items.Length; i++)
{
- if (containerComponent.inventory.items[i] == null) continue;
- if ((projectileComponent = containerComponent.inventory.items[i].GetComponent()) != null)
+ if (containerComponent.inventory.Items[i] == null) continue;
+ if ((projectileComponent = containerComponent.inventory.Items[i].GetComponent()) != null)
{
- projectile = containerComponent.inventory.items[i];
+ projectile = containerComponent.inventory.Items[i];
break;
}
}
diff --git a/Subsurface/Source/Items/FixRequirement.cs b/Subsurface/Source/Items/FixRequirement.cs
index f740473be..99f7228d2 100644
--- a/Subsurface/Source/Items/FixRequirement.cs
+++ b/Subsurface/Source/Items/FixRequirement.cs
@@ -54,7 +54,7 @@ namespace Barotrauma
GUIComponent component = reqFrame.children.Find(c => c.UserData as string == itemName);
GUITextBlock text = component as GUITextBlock;
- Item item = character.Inventory.items.FirstOrDefault(i => i !=null && (i.Name == itemName || i.HasTag(itemName)));
+ Item item = character.Inventory.FindItem(itemName);
bool itemFound = (item != null);
if (!itemFound) success = false;
diff --git a/Subsurface/Source/Items/Inventory.cs b/Subsurface/Source/Items/Inventory.cs
index 6f431a12b..33e73244a 100644
--- a/Subsurface/Source/Items/Inventory.cs
+++ b/Subsurface/Source/Items/Inventory.cs
@@ -42,7 +42,7 @@ namespace Barotrauma
protected int selectedSlot;
- public Item[] items;
+ public Item[] Items;
public Inventory(Entity owner, int capacity, Vector2? centerPos = null, int slotsPerRow=5)
{
@@ -52,7 +52,7 @@ namespace Barotrauma
this.slotsPerRow = slotsPerRow;
- items = new Item[capacity];
+ Items = new Item[capacity];
CenterPos = (centerPos==null) ? new Vector2(0.5f, 0.5f) : (Vector2)centerPos;
}
@@ -61,7 +61,7 @@ namespace Barotrauma
{
for (int i = 0; i < capacity; i++)
{
- if (items[i] == item) return i;
+ if (Items[i] == item) return i;
}
return -1;
}
@@ -71,12 +71,12 @@ namespace Barotrauma
for (int i = 0; i < capacity; i++)
{
//item is already in the inventory!
- if (items[i] == item) return -1;
+ if (Items[i] == item) return -1;
}
for (int i = 0; i < capacity; i++)
{
- if (items[i] == null) return i;
+ if (Items[i] == null) return i;
}
return -1;
@@ -84,8 +84,8 @@ namespace Barotrauma
public virtual bool CanBePut(Item item, int i)
{
- if (i < 0 || i >= items.Length) return false;
- return (items[i] == null);
+ if (i < 0 || i >= Items.Length) return false;
+ return (Items[i] == null);
}
///
@@ -124,7 +124,7 @@ namespace Barotrauma
if (item.inventory != null) item.inventory.RemoveItem(item);
}
- items[i] = item;
+ Items[i] = item;
item.inventory = this;
if (item.body != null)
{
@@ -134,13 +134,18 @@ namespace Barotrauma
if (createNetworkEvent) new NetworkEvent(NetworkEventType.InventoryUpdate, Owner.ID, true, true);
}
+ public Item FindItem(string itemName)
+ {
+ return Items.FirstOrDefault(i => i != null && (i.Name == itemName || i.HasTag(itemName)));
+ }
+
public void RemoveItem(Item item)
{
//go through the inventory and remove the item from all slots
for (int n = 0; n < capacity; n++)
{
- if (items[n] != item) continue;
- items[n] = null;
+ if (Items[n] != item) continue;
+ Items[n] = null;
item.inventory = null;
}
}
@@ -177,9 +182,9 @@ namespace Barotrauma
slotRect.X = startX + (rectWidth + spacing) * (i % slotsPerRow);
slotRect.Y = startY + (rectHeight + spacing) * ((int)Math.Floor((double)i / slotsPerRow));
- if (draggingItem == items[i]) draggingItemSlot = slotRect;
+ if (draggingItem == Items[i]) draggingItemSlot = slotRect;
- UpdateSlot(spriteBatch, slotRect, i, items[i], false);
+ UpdateSlot(spriteBatch, slotRect, i, Items[i], false);
}
if (draggingItem != null && !draggingItemSlot.Contains(PlayerInput.MousePosition) && draggingItem.container == this.Owner)
@@ -247,7 +252,7 @@ namespace Barotrauma
{
#if DEBUG
- System.Diagnostics.Debug.Assert(slotIndex >= 0 && slotIndex < items.Length);
+ System.Diagnostics.Debug.Assert(slotIndex >= 0 && slotIndex < Items.Length);
#else
if (slotIndex<0 || slotIndex>=items.Length) return;
#endif
@@ -266,7 +271,7 @@ namespace Barotrauma
GUI.DrawRectangle(spriteBatch, containerRect, Color.White);
Item[] containedItems = null;
- if (items[slotIndex] != null) containedItems = items[slotIndex].ContainedItems;
+ if (Items[slotIndex] != null) containedItems = Items[slotIndex].ContainedItems;
if (containedItems != null)
{
@@ -316,7 +321,7 @@ namespace Barotrauma
public virtual bool FillNetworkData(NetworkEventType type, NetBuffer message, object data)
{
- var foundItems = Array.FindAll(items, i => i != null);
+ var foundItems = Array.FindAll(Items, i => i != null);
message.Write((byte)foundItems.Count());
foreach (Item item in foundItems)
{
@@ -340,10 +345,10 @@ namespace Barotrauma
for (int i = 0; i < capacity; i++)
{
- if (items[i] == null) continue;
- if (!newItemIDs.Contains(items[i].ID))
+ if (Items[i] == null) continue;
+ if (!newItemIDs.Contains(Items[i].ID))
{
- items[i].Drop(null, false);
+ Items[i].Drop(null, false);
continue;
}
}
diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs
index 3a9e957a5..7609969bc 100644
--- a/Subsurface/Source/Items/Item.cs
+++ b/Subsurface/Source/Items/Item.cs
@@ -219,7 +219,7 @@ namespace Barotrauma
get
{
ItemContainer c = GetComponent();
- return (c == null) ? null : Array.FindAll(c.inventory.items, i=>i!=null);
+ return (c == null) ? null : Array.FindAll(c.inventory.Items, i=>i!=null);
}
}
diff --git a/Subsurface/Source/Items/ItemInventory.cs b/Subsurface/Source/Items/ItemInventory.cs
index 3acbf3209..712f46c97 100644
--- a/Subsurface/Source/Items/ItemInventory.cs
+++ b/Subsurface/Source/Items/ItemInventory.cs
@@ -25,14 +25,14 @@ namespace Barotrauma
for (int i = 0; i < capacity; i++)
{
//item is already in the inventory!
- if (items[i] == item) return -1;
+ if (Items[i] == item) return -1;
}
if (!container.CanBeContained(item)) return -1;
for (int i = 0; i < capacity; i++)
{
- if (items[i] == null) return i;
+ if (Items[i] == null) return i;
}
return -1;
@@ -40,8 +40,8 @@ namespace Barotrauma
public override bool CanBePut(Item item, int i)
{
- if (i < 0 || i >= items.Length) return false;
- return (item!=null && items[i]==null && container.CanBeContained(item));
+ if (i < 0 || i >= Items.Length) return false;
+ return (item!=null && Items[i]==null && container.CanBeContained(item));
}
public override bool TryPutItem(Item item, int i, bool createNetworkEvent)
diff --git a/Subsurface/Source/Items/ItemPrefab.cs b/Subsurface/Source/Items/ItemPrefab.cs
index 76c2658d2..8f9bd920d 100644
--- a/Subsurface/Source/Items/ItemPrefab.cs
+++ b/Subsurface/Source/Items/ItemPrefab.cs
@@ -161,8 +161,8 @@ namespace Barotrauma
name = ToolBox.GetAttributeString(element, "name", "");
if (name == "") DebugConsole.ThrowError("Unnamed item in "+filePath+"!");
- pickThroughWalls = ToolBox.GetAttributeBool(element, "pickthroughwalls", false);
- pickDistance = ConvertUnits.ToSimUnits(ToolBox.GetAttributeFloat(element, "pickdistance", 0.0f));
+ pickThroughWalls = ToolBox.GetAttributeBool(element, "pickthroughwalls", false);
+ pickDistance = ConvertUnits.ToSimUnits(ToolBox.GetAttributeFloat(element, "pickdistance", 0.0f));
isLinkable = ToolBox.GetAttributeBool(element, "linkable", false);
diff --git a/Subsurface/Source/Items/RelatedItem.cs b/Subsurface/Source/Items/RelatedItem.cs
index 2bccf83cc..c0c9db549 100644
--- a/Subsurface/Source/Items/RelatedItem.cs
+++ b/Subsurface/Source/Items/RelatedItem.cs
@@ -93,7 +93,7 @@ namespace Barotrauma
break;
case RelationType.Picked:
if (character == null || character.Inventory==null) return false;
- foreach (Item pickedItem in character.Inventory.items)
+ foreach (Item pickedItem in character.Inventory.Items)
{
if (pickedItem == null) continue;
diff --git a/Subsurface/Source/Map/Map.cs b/Subsurface/Source/Map/Map.cs
index 9e7e68a5e..1a9c9a407 100644
--- a/Subsurface/Source/Map/Map.cs
+++ b/Subsurface/Source/Map/Map.cs
@@ -328,7 +328,16 @@ namespace Barotrauma
Location location = locations[i];
Vector2 pos = rectCenter + (location.MapPosition + offset) * scale;
- if (!rect.Contains(pos)) continue;
+
+
+
+
+ Rectangle drawRect = location.Type.Sprite.SourceRect;
+ Rectangle sourceRect = drawRect;
+ drawRect.X = (int)pos.X - drawRect.Width/2;
+ drawRect.Y = (int)pos.Y - drawRect.Width/2;
+
+ if (!rect.Intersects(drawRect)) continue;
Color color = location.Connections.Find(c => c.Locations.Contains(currentLocation))==null ? Color.White : Color.Green;
@@ -336,16 +345,32 @@ namespace Barotrauma
if (location == currentLocation) color = Color.Orange;
- location.Type.Sprite.Draw(spriteBatch, pos, color, 0.0f, scale/3.0f);
+ if (drawRect.X < rect.X)
+ {
+ sourceRect.X += rect.X - drawRect.X;
+ sourceRect.Width -= sourceRect.X;
+ drawRect.X = rect.X;
+ }
+ else if (drawRect.Right > rect.Right)
+ {
+ sourceRect.Width -= (drawRect.Right - rect.Right);
+ }
- //int imgIndex = i % 16;
- //int xCell = imgIndex % 4;
- //int yCell = (int)Math.Floor(imgIndex / 4.0f);
- //spriteBatch.Draw(iceCraters, pos,
- // new Rectangle(xCell * 64, yCell * 64, 64, 64),
- // Color.White, i,
- // new Vector2(32, 32), 0.5f*scale, SpriteEffects.None, 0.0f);
+ if (drawRect.Y < rect.Y)
+ {
+ sourceRect.Y += rect.Y - drawRect.Y;
+ sourceRect.Height -= sourceRect.Y;
+ drawRect.Y = rect.Y;
+ }
+ else if (drawRect.Bottom > rect.Bottom)
+ {
+ sourceRect.Height -= drawRect.Bottom - rect.Bottom;
+ }
+ drawRect.Width = sourceRect.Width;
+ drawRect.Height = sourceRect.Height;
+
+ spriteBatch.Draw(location.Type.Sprite.Texture, drawRect, sourceRect, color);
}
for (int i = 0; i < 3; i++ )
diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs
index a05debddb..9fd5853ed 100644
--- a/Subsurface/Source/Map/Submarine.cs
+++ b/Subsurface/Source/Map/Submarine.cs
@@ -636,6 +636,8 @@ namespace Barotrauma
}
}
+ WayPoint.GenerateSubWaypoints();
+
GameMain.LightManager.OnMapLoaded();
ID = ushort.MaxValue-10;
diff --git a/Subsurface/Source/Map/WayPoint.cs b/Subsurface/Source/Map/WayPoint.cs
index d825fc3bd..b34ba97af 100644
--- a/Subsurface/Source/Map/WayPoint.cs
+++ b/Subsurface/Source/Map/WayPoint.cs
@@ -23,12 +23,19 @@ namespace Barotrauma
//only characters with this job will be spawned at the waypoint
private JobPrefab assignedJob;
+ private Hull currentHull;
+
public Gap ConnectedGap
{
get;
private set;
}
+ public Hull CurrentHull
+ {
+ get { return currentHull; }
+ }
+
public SpawnType SpawnType
{
get { return spawnType; }
@@ -396,10 +403,14 @@ namespace Barotrauma
return assignedWayPoints;
}
+ public override void OnMapLoaded()
+ {
+ currentHull = Hull.FindHull(this.Position);
+ }
public override XElement Save(XDocument doc)
{
- if (MoveWithLevel) return null;
+ if (MoveWithLevel || spawnType == SpawnType.Path) return null;
XElement element = new XElement("WayPoint");
element.Add(new XAttribute("ID", ID),
diff --git a/Subsurface/Source/Physics/PhysicsBody.cs b/Subsurface/Source/Physics/PhysicsBody.cs
index 1e42e05a9..cb01c7a18 100644
--- a/Subsurface/Source/Physics/PhysicsBody.cs
+++ b/Subsurface/Source/Physics/PhysicsBody.cs
@@ -315,8 +315,6 @@ namespace Barotrauma
sprite.Draw(spriteBatch, new Vector2(drawPosition.X, -drawPosition.Y), color, -drawRotation, 1.0f, spriteEffect, depth);
- //prevPosition = body.Position;
- //prevRotation = body.Rotation;
}
///
@@ -331,20 +329,6 @@ namespace Barotrauma
float torque = body.Mass * angle * 60.0f * (force/100.0f);
body.ApplyTorque(torque);
-
- //float nextAngle = bodyAngle + body->GetAngularVelocity() / 60.0;
- //float totalRotation = desiredAngle - nextAngle;
- //while (totalRotation < -180 * DEGTORAD) totalRotation += 360 * DEGTORAD;
- //while (totalRotation > 180 * DEGTORAD) totalRotation -= 360 * DEGTORAD;
- //float desiredAngularVelocity = totalRotation * 60;
- //float torque = body->GetInertia() * desiredAngularVelocity / (1 / 60.0);
- //body->ApplyTorque(torque);
-
-
-
-
- //body.ApplyTorque((Math.Sign(angle) + Math.Max(Math.Min(angle * force, force / 2.0f), -force / 2.0f)) * body.Mass);
- //body.ApplyTorque(-body.AngularVelocity * 0.5f * body.Mass);
}
@@ -352,53 +336,7 @@ namespace Barotrauma
{
list.Remove(this);
GameMain.World.RemoveBody(body);
-
}
- public void FillNetworkData(NetworkEventType type, NetOutgoingMessage message)
- {
- message.Write(body.Position.X);
- message.Write(body.Position.Y);
- message.Write(body.LinearVelocity.X);
- message.Write(body.LinearVelocity.Y);
-
- message.Write(body.Rotation);
- message.Write(body.AngularVelocity);
- }
-
- public void ReadNetworkData(NetworkEventType type, NetIncomingMessage message)
- {
- Vector2 newTargetPos = Vector2.Zero;
- Vector2 newTargetVel = Vector2.Zero;
-
- float newTargetRotation = 0.0f, newTargetAngularVel = 0.0f;
- try
- {
- newTargetPos = new Vector2(message.ReadFloat(),message.ReadFloat());
- newTargetVel = new Vector2(message.ReadFloat(),message.ReadFloat());
-
- newTargetRotation = message.ReadFloat();
- newTargetAngularVel = message.ReadFloat();
- }
-
- catch (Exception e)
- {
-#if DEBUG
- DebugConsole.ThrowError("invalid network message", e);
-#endif
- return;
- }
-
- if (!MathUtils.IsValid(newTargetPos) || !MathUtils.IsValid(newTargetVel) ||
- !MathUtils.IsValid(newTargetRotation) || !MathUtils.IsValid(newTargetAngularVel)) return;
-
- targetPosition = newTargetPos;
- targetVelocity = newTargetVel;
-
- targetRotation = newTargetRotation;
- targetAngularVelocity = newTargetAngularVel;
-
-
- }
}
}
diff --git a/Subsurface/Source/Screens/EditMapScreen.cs b/Subsurface/Source/Screens/EditMapScreen.cs
index 7ff101292..c55633494 100644
--- a/Subsurface/Source/Screens/EditMapScreen.cs
+++ b/Subsurface/Source/Screens/EditMapScreen.cs
@@ -181,7 +181,7 @@ namespace Barotrauma
}
else if (dummyCharacter != null)
{
- foreach (Item item in dummyCharacter.Inventory.items)
+ foreach (Item item in dummyCharacter.Inventory.Items)
{
if (item == null) continue;
diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo
index 54ca7c8c8..1bffe684d 100644
Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ