diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj
index b8a2c539b..c6b93768c 100644
--- a/Subsurface/Barotrauma.csproj
+++ b/Subsurface/Barotrauma.csproj
@@ -74,10 +74,12 @@
-
+
-
+
+
+
@@ -285,13 +287,20 @@
PreserveNewest
-
+
Designer
PreserveNewest
+
+ PreserveNewest
+ Designer
+
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
diff --git a/Subsurface/Content/BackgroundSprites/BackgroundCreaturePrefabs.xml b/Subsurface/Content/BackgroundSprites/BackgroundCreaturePrefabs.xml
new file mode 100644
index 000000000..94744cc5d
--- /dev/null
+++ b/Subsurface/Content/BackgroundSprites/BackgroundCreaturePrefabs.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Subsurface/Content/BackgroundSprites/BackgroundSpritePrefabs.xml b/Subsurface/Content/BackgroundSprites/BackgroundSpritePrefabs.xml
index 389ffef44..b132e1b6f 100644
--- a/Subsurface/Content/BackgroundSprites/BackgroundSpritePrefabs.xml
+++ b/Subsurface/Content/BackgroundSprites/BackgroundSpritePrefabs.xml
@@ -1,24 +1,20 @@
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/Subsurface/Content/BackgroundSprites/vegetation.png b/Subsurface/Content/BackgroundSprites/vegetation.png
new file mode 100644
index 000000000..c104f8594
Binary files /dev/null and b/Subsurface/Content/BackgroundSprites/vegetation.png differ
diff --git a/Subsurface/Content/Characters/Coelanth/coelanth.xml b/Subsurface/Content/Characters/Coelanth/coelanth.xml
index db5ad56dd..a71ff7337 100644
--- a/Subsurface/Content/Characters/Coelanth/coelanth.xml
+++ b/Subsurface/Content/Characters/Coelanth/coelanth.xml
@@ -54,5 +54,5 @@
-
+
\ No newline at end of file
diff --git a/Subsurface/Source/Characters/AI/EnemyAIController.cs b/Subsurface/Source/Characters/AI/EnemyAIController.cs
index 2460f3c0f..5e5b97bb3 100644
--- a/Subsurface/Source/Characters/AI/EnemyAIController.cs
+++ b/Subsurface/Source/Characters/AI/EnemyAIController.cs
@@ -170,7 +170,7 @@ namespace Barotrauma
selectedTargetMemory.Priority -= deltaTime;
Vector2 attackSimPosition = Character.Submarine==null ? ConvertUnits.ToSimUnits(selectedAiTarget.WorldPosition) : selectedAiTarget.SimPosition;
- if (wallAttackPos != Vector2.Zero)
+ if (wallAttackPos != Vector2.Zero && targetEntity != null)
{
attackSimPosition = wallAttackPos;
diff --git a/Subsurface/Source/Characters/AI/HumanAIController.cs b/Subsurface/Source/Characters/AI/HumanAIController.cs
index 8a8b5c8af..55d539d1d 100644
--- a/Subsurface/Source/Characters/AI/HumanAIController.cs
+++ b/Subsurface/Source/Characters/AI/HumanAIController.cs
@@ -28,6 +28,8 @@ namespace Barotrauma
objectiveManager = new AIObjectiveManager(c);
objectiveManager.AddObjective(new AIObjectiveFindSafety(c));
objectiveManager.AddObjective(new AIObjectiveIdle(c));
+
+ updateObjectiveTimer = Rand.Range(0.0f, UpdateObjectiveInterval);
}
public override void Update(float deltaTime)
diff --git a/Subsurface/Source/Characters/AI/ÍndoorsSteeringManager.cs b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs
similarity index 97%
rename from Subsurface/Source/Characters/AI/ÍndoorsSteeringManager.cs
rename to Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs
index f0f0e90c4..cd54819d7 100644
--- a/Subsurface/Source/Characters/AI/ÍndoorsSteeringManager.cs
+++ b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs
@@ -40,6 +40,8 @@ namespace Barotrauma
this.canOpenDoors = canOpenDoors;
character = (host as AIController).Character;
+
+ findPathTimer = Rand.Range(0.0f, 1.0f);
}
public override void Update(float speed = 1)
@@ -65,9 +67,9 @@ namespace Barotrauma
if (findPathTimer > 0.0f) return Vector2.Zero;
currentTarget = target;
- currentPath = pathFinder.FindPath(host.SimPosition, target);
+ currentPath = pathFinder.FindPath(host.SimPosition+Rand.Vector(0.2f), target);
- findPathTimer = 1.0f;
+ findPathTimer = Rand.Range(1.0f,1.2f);
return DiffToCurrentNode();
}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveCombat.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveCombat.cs
index ee91e3efc..03a2078b0 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveCombat.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveCombat.cs
@@ -92,10 +92,7 @@ namespace Barotrauma
if (Vector2.Distance(character.SimPosition, enemy.SimPosition) < 3.0f)
{
- character.AIController.SteeringManager.SteeringManual(deltaTime, character.SimPosition - enemy.SimPosition);
- }
- else
- {
+ character.AIController.SteeringManager.SteeringManual(deltaTime, (character.SimPosition - enemy.SimPosition)*0.1f);
coolDownTimer = CoolDown;
}
}
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs
index ba7e16d85..38edc4aa2 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs
@@ -57,17 +57,34 @@ namespace Barotrauma
character.AIController.SteeringManager.SteeringSeek(
target != null ? target.SimPosition : targetPos);
+
+ Vector2 currTargetPos = target != null ? target.SimPosition : targetPos;
+ if (Vector2.Distance(currTargetPos, character.SimPosition) < 1.0f)
+ {
+ character.AnimController.TargetDir = currTargetPos.X > character.SimPosition.X ? Direction.Right : Direction.Left;
+ }
}
public override bool IsCompleted()
{
if (repeat) return false;
+ bool completed = false;
+
float allowedDistance = 0.5f;
var item = target as Item;
- if (item != null) allowedDistance = Math.Max(item.PickDistance,allowedDistance);
- return Vector2.Distance(target != null ? target.SimPosition : targetPos, character.SimPosition) < allowedDistance;
+ if (item != null)
+ {
+ allowedDistance = Math.Max(item.PickDistance, allowedDistance);
+ if (item.IsInsideTrigger(character.WorldPosition)) completed = true;
+ }
+
+ completed = completed || Vector2.Distance(target != null ? target.SimPosition : targetPos, character.SimPosition) < allowedDistance;
+
+ if (completed) character.AIController.SteeringManager.SteeringManual(0.0f, -character.AIController.Steering);
+
+ return completed;
}
public override bool IsDuplicate(AIObjective otherObjective)
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs
index 0017385fe..5f3f9b724 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs
@@ -63,7 +63,7 @@ namespace Barotrauma
{
if (character.Position.X < character.AnimController.CurrentHull.Rect.X + WallAvoidDistance)
{
- pathSteering.SteeringManual(deltaTime, Vector2.UnitX);
+ pathSteering.SteeringManual(deltaTime, Vector2.UnitX*5.0f);
}
else if (character.Position.X > character.AnimController.CurrentHull.Rect.Right - WallAvoidDistance)
{
diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs
index 2421a5040..e0181ce3c 100644
--- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs
+++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs
@@ -30,7 +30,7 @@ namespace Barotrauma
ItemComponent target = itemController == null ? targetItem: itemController;
if (Vector2.Distance(character.SimPosition, target.Item.SimPosition) < target.Item.PickDistance
- || target.Item.IsInsideTrigger(character.Position))
+ || target.Item.IsInsideTrigger(character.WorldPosition))
{
if (character.SelectedConstruction != target.Item && target.CanBeSelected)
{
diff --git a/Subsurface/Source/Characters/AICharacter.cs b/Subsurface/Source/Characters/AICharacter.cs
index 81522eaab..6f500ffbb 100644
--- a/Subsurface/Source/Characters/AICharacter.cs
+++ b/Subsurface/Source/Characters/AICharacter.cs
@@ -42,6 +42,7 @@ namespace Barotrauma
public AICharacter(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false)
: base(file, position, characterInfo, isNetworkPlayer)
{
+ soundInterval = Rand.Range(0.0f, soundInterval);
}
public void SetAI(AIController aiController)
@@ -113,7 +114,16 @@ namespace Barotrauma
aiController.FillNetworkData(message);
return true;
case NetworkEventType.EntityUpdate:
- if ((AnimController.RefLimb.SimPosition - Submarine.Loaded.SimPosition).Length() > NetConfig.CharacterIgnoreDistance) return false;
+ if (Submarine == null)
+ {
+ if ((AnimController.RefLimb.SimPosition - Submarine.Loaded.SimPosition).Length() > NetConfig.CharacterIgnoreDistance) return false;
+
+ }
+ else
+ {
+ if (AnimController.RefLimb.SimPosition.Length() > NetConfig.CharacterIgnoreDistance) return false;
+ }
+
message.Write(AnimController.TargetDir == Direction.Right);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.X, -1.0f, 1.0f), -1.0f, 1.0f, 8);
diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSprite.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundCreature.cs
similarity index 84%
rename from Subsurface/Source/Characters/BackgroundSprite/BackgroundSprite.cs
rename to Subsurface/Source/Characters/BackgroundSprite/BackgroundCreature.cs
index 49a5be9c9..f29e89e99 100644
--- a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSprite.cs
+++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundCreature.cs
@@ -9,7 +9,7 @@ using System.Xml.Linq;
namespace Barotrauma
{
- class BackgroundSprite : ISteerable
+ class BackgroundCreature : ISteerable
{
const float MaxDepth = 100.0f;
@@ -17,7 +17,7 @@ namespace Barotrauma
public bool Enabled;
- private BackgroundSpritePrefab prefab;
+ private BackgroundCreaturePrefab prefab;
private Vector2 position;
@@ -53,7 +53,7 @@ namespace Barotrauma
set;
}
- public BackgroundSprite(BackgroundSpritePrefab prefab, Vector2 position)
+ public BackgroundCreature(BackgroundCreaturePrefab prefab, Vector2 position)
{
this.prefab = prefab;
@@ -105,18 +105,6 @@ namespace Barotrauma
Vector2 midPoint = Swarm.MidPoint();
float midPointDist = Vector2.Distance(position, midPoint);
-
-
- //steeringManager.SteeringSeek(midPoint + Swarm.AvgVelocity()*1000.0f, prefab.Speed*0.1f);
-
- //float avgWanderAngle = 0.0f;
- //foreach (var other in Swarm.Members)
- //{
- // avgWanderAngle += other.steeringManager.WanderAngle;
- //}
- //avgWanderAngle /= Swarm.Members.Count;
- //steeringManager.WanderAngle = MathHelper.Lerp(steeringManager.WanderAngle, avgWanderAngle, 0.1f);
-
if (midPointDist > Swarm.MaxDistance)
{
steeringManager.SteeringSeek(midPoint, (midPointDist / Swarm.MaxDistance) * prefab.Speed);
@@ -169,7 +157,7 @@ namespace Barotrauma
class Swarm
{
- public List Members;
+ public List Members;
public readonly float MaxDistance;
@@ -179,7 +167,7 @@ namespace Barotrauma
Vector2 midPoint = Vector2.Zero;
- foreach (BackgroundSprite member in Members)
+ foreach (BackgroundCreature member in Members)
{
midPoint += member.SimPosition;
}
@@ -195,7 +183,7 @@ namespace Barotrauma
Vector2 avgVel = Vector2.Zero;
- foreach (BackgroundSprite member in Members)
+ foreach (BackgroundCreature member in Members)
{
avgVel += member.Velocity;
}
@@ -205,13 +193,13 @@ namespace Barotrauma
return avgVel;
}
- public Swarm(List members, float maxDistance)
+ public Swarm(List members, float maxDistance)
{
this.Members = members;
this.MaxDistance = maxDistance;
- foreach (BackgroundSprite bgSprite in members)
+ foreach (BackgroundCreature bgSprite in members)
{
bgSprite.Swarm = this;
}
diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundCreatureManager.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundCreatureManager.cs
new file mode 100644
index 000000000..1153c3b6b
--- /dev/null
+++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundCreatureManager.cs
@@ -0,0 +1,125 @@
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml.Linq;
+
+namespace Barotrauma
+{
+ class BackgroundCreatureManager
+ {
+ const int MaxSprites = 100;
+
+ const float checkActiveInterval = 1.0f;
+
+ float checkActiveTimer;
+
+ private List prefabs;
+ private List activeSprites;
+
+ public BackgroundCreatureManager(string configPath)
+ {
+ activeSprites = new List();
+ prefabs = new List();
+
+ XDocument doc = ToolBox.TryLoadXml(configPath);
+ if (doc == null || doc.Root == null) return;
+
+ foreach (XElement element in doc.Root.Elements())
+ {
+ prefabs.Add(new BackgroundCreaturePrefab(element));
+ }
+ }
+
+ public void SpawnSprites(int count, Vector2? position = null)
+ {
+ activeSprites.Clear();
+
+ if (prefabs.Count == 0) return;
+
+ count = Math.Min(count, MaxSprites);
+
+ for (int i = 0; i < count; i++ )
+ {
+ Vector2 pos = Vector2.Zero;
+
+ if (position == null)
+ {
+ var wayPoints = WayPoint.WayPointList.FindAll(wp => wp.Submarine==null);
+ if (wayPoints.Any())
+ {
+ WayPoint wp = wayPoints[Rand.Int(wayPoints.Count)];
+
+ pos = new Vector2(wp.Rect.X, wp.Rect.Y);
+ pos += Rand.Vector(200.0f);
+ }
+ else
+ {
+ pos = Rand.Vector(2000.0f);
+ }
+ }
+ else
+ {
+ pos = (Vector2)position;
+ }
+
+
+ var prefab = prefabs[Rand.Int(prefabs.Count)];
+
+ int amount = Rand.Range(prefab.SwarmMin, prefab.SwarmMax);
+ List swarmMembers = new List();
+
+ for (int n = 0; n < amount; n++)
+ {
+ var newSprite = new BackgroundCreature(prefab, pos);
+ activeSprites.Add(newSprite);
+ swarmMembers.Add(newSprite);
+ }
+ if (amount > 0)
+ {
+ new Swarm(swarmMembers, prefab.SwarmRadius);
+ }
+ }
+ }
+
+ public void ClearSprites()
+ {
+ activeSprites.Clear();
+ }
+
+ public void Update(Camera cam, float deltaTime)
+ {
+ if (checkActiveTimer<0.0f)
+ {
+ foreach (BackgroundCreature sprite in activeSprites)
+ {
+ sprite.Enabled = (Math.Abs(sprite.TransformedPosition.X - cam.WorldViewCenter.X) < 4000.0f &&
+ Math.Abs(sprite.TransformedPosition.Y - cam.WorldViewCenter.Y) < 4000.0f);
+ }
+
+ checkActiveTimer = checkActiveInterval;
+ }
+ else
+ {
+ checkActiveTimer -= deltaTime;
+ }
+
+ foreach (BackgroundCreature sprite in activeSprites)
+ {
+ if (!sprite.Enabled) continue;
+ sprite.Update(deltaTime);
+ }
+ }
+
+ public void Draw(SpriteBatch spriteBatch)
+ {
+ foreach (BackgroundCreature sprite in activeSprites)
+ {
+ if (!sprite.Enabled) continue;
+ sprite.Draw(spriteBatch);
+ }
+ }
+ }
+}
diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundCreaturePrefab.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundCreaturePrefab.cs
new file mode 100644
index 000000000..1d0de283a
--- /dev/null
+++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundCreaturePrefab.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml.Linq;
+
+namespace Barotrauma
+{
+ class BackgroundCreaturePrefab
+ {
+
+ public readonly Sprite Sprite;
+
+ public readonly float Speed;
+
+ public readonly float WanderAmount;
+
+ public readonly float WanderZAmount;
+
+ public readonly int SwarmMin, SwarmMax;
+
+ public readonly float SwarmRadius;
+
+ public readonly bool DisableRotation;
+
+ public BackgroundCreaturePrefab(XElement element)
+ {
+ Speed = ToolBox.GetAttributeFloat(element, "speed", 1.0f);
+
+ WanderAmount = ToolBox.GetAttributeFloat(element, "wanderamount", 0.0f);
+
+ WanderZAmount = ToolBox.GetAttributeFloat(element, "wanderzamount", 0.0f);
+
+ SwarmMin = ToolBox.GetAttributeInt(element, "swarmmin", 1);
+ SwarmMax = ToolBox.GetAttributeInt(element, "swarmmax", 1);
+
+ SwarmRadius = ToolBox.GetAttributeFloat(element, "swarmradius", 200.0f);
+
+ DisableRotation = ToolBox.GetAttributeBool(element, "disablerotation", false);
+
+ foreach (XElement subElement in element.Elements())
+ {
+ if (subElement.Name.ToString().ToLower() != "sprite") continue;
+
+ Sprite = new Sprite(subElement);
+ break;
+ }
+ }
+ }
+
+}
diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs
index b08753e8c..dde3c3ece 100644
--- a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs
+++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs
@@ -5,23 +5,30 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
+using Voronoi2;
namespace Barotrauma
{
+ class BackgroundSprite
+ {
+ public readonly BackgroundSpritePrefab Prefab;
+ public Vector2 Position;
+
+ public BackgroundSprite(BackgroundSpritePrefab prefab, Vector2 position)
+ {
+ this.Prefab = prefab;
+ this.Position = position;
+ }
+ }
+
class BackgroundSpriteManager
{
- const int MaxSprites = 100;
-
- const float checkActiveInterval = 1.0f;
-
- float checkActiveTimer;
-
private List prefabs;
- private List activeSprites;
+ private List sprites;
public BackgroundSpriteManager(string configPath)
{
- activeSprites = new List();
+ sprites = new List();
prefabs = new List();
XDocument doc = ToolBox.TryLoadXml(configPath);
@@ -33,93 +40,92 @@ namespace Barotrauma
}
}
- public void SpawnSprites(int count, Vector2? position = null)
+ public void PlaceSprites(Level level, int amount)
{
- activeSprites.Clear();
+ sprites.Clear();
- if (prefabs.Count == 0) return;
-
- count = Math.Min(count, MaxSprites);
-
- for (int i = 0; i < count; i++ )
+ for (int i = 0 ; i wp.Submarine==null);
- if (wayPoints.Any())
- {
- WayPoint wp = wayPoints[Rand.Int(wayPoints.Count)];
-
- pos = new Vector2(wp.Rect.X, wp.Rect.Y);
- pos += Rand.Vector(200.0f);
- }
- else
- {
- pos = Rand.Vector(2000.0f);
- }
- }
- else
- {
- pos = (Vector2)position;
- }
-
-
- var prefab = prefabs[Rand.Int(prefabs.Count)];
-
- int amount = Rand.Range(prefab.SwarmMin, prefab.SwarmMax);
- List swarmMembers = new List();
-
- for (int n = 0; n < amount; n++)
- {
- var newSprite = new BackgroundSprite(prefab, pos);
- activeSprites.Add(newSprite);
- swarmMembers.Add(newSprite);
- }
- if (amount > 0)
- {
- new Swarm(swarmMembers, prefab.SwarmRadius);
- }
+ sprites.Add(new BackgroundSprite(prefab, pos));
}
}
- public void ClearSprites()
+ private Vector2 FindSpritePosition(Level level, BackgroundSpritePrefab prefab)
{
- activeSprites.Clear();
+ Vector2 randomPos = new Vector2(Rand.Range(0.0f, level.Size.X), Rand.Range(0.0f, level.Size.Y));
+ var cells = level.GetCells(randomPos);
+
+ if (!cells.Any()) return Vector2.Zero;
+
+ VoronoiCell cell = cells[Rand.Int(cells.Count)];
+ GraphEdge bestEdge = null;
+ foreach (GraphEdge edge in cell.edges)
+ {
+ if (prefab.Alignment.HasFlag(Alignment.Bottom))
+ {
+ if (bestEdge == null || edge.Center.Y > bestEdge.Center.Y) bestEdge = edge;
+ }
+ else if (prefab.Alignment.HasFlag(Alignment.Top))
+ {
+ if (bestEdge == null || edge.Center.Y < bestEdge.Center.Y) bestEdge = edge;
+ }
+ else if (prefab.Alignment.HasFlag(Alignment.Left))
+ {
+ if (bestEdge == null || edge.Center.X > bestEdge.Center.X) bestEdge = edge;
+ }
+ else if (prefab.Alignment.HasFlag(Alignment.Right))
+ {
+ if (bestEdge == null || edge.Center.X < bestEdge.Center.X) bestEdge = edge;
+ }
+ }
+
+ Vector2 dir = Vector2.Normalize(bestEdge.point1 - bestEdge.point2);
+ Vector2 pos = bestEdge.Center;
+
+ if (prefab.Alignment.HasFlag(Alignment.Bottom))
+ {
+ pos.Y -= Math.Abs(dir.Y) * prefab.Sprite.size.X/Math.Abs(dir.X);
+ }
+ else if (prefab.Alignment.HasFlag(Alignment.Top))
+ {
+ pos.Y += Math.Abs(dir.Y) * prefab.Sprite.size.X/Math.Abs(dir.X);
+ }
+
+ return pos;
}
- public void Update(Camera cam, float deltaTime)
+ public void DrawSprites(SpriteBatch spriteBatch)
{
- if (checkActiveTimer<0.0f)
+ foreach (BackgroundSprite sprite in sprites)
{
- foreach (BackgroundSprite sprite in activeSprites)
+ sprite.Prefab.Sprite.Draw(spriteBatch, new Vector2(sprite.Position.X, -sprite.Position.Y));
+ }
+ }
+
+ private BackgroundSpritePrefab GetRandomPrefab()
+ {
+ int totalCommonness = 0;
+ foreach (BackgroundSpritePrefab prefab in prefabs)
+ {
+ totalCommonness += prefab.Commonness;
+ }
+
+ float randomNumber = Rand.Int(totalCommonness+1);
+
+ foreach (BackgroundSpritePrefab prefab in prefabs)
+ {
+ if (randomNumber <= prefab.Commonness)
{
- sprite.Enabled = (Math.Abs(sprite.TransformedPosition.X - cam.WorldViewCenter.X) < 4000.0f &&
- Math.Abs(sprite.TransformedPosition.Y - cam.WorldViewCenter.Y) < 4000.0f);
+ return prefab;
}
- checkActiveTimer = checkActiveInterval;
- }
- else
- {
- checkActiveTimer -= deltaTime;
+ randomNumber -= prefab.Commonness;
}
- foreach (BackgroundSprite sprite in activeSprites)
- {
- if (!sprite.Enabled) continue;
- sprite.Update(deltaTime);
- }
- }
-
- public void Draw(SpriteBatch spriteBatch)
- {
- foreach (BackgroundSprite sprite in activeSprites)
- {
- if (!sprite.Enabled) continue;
- sprite.Draw(spriteBatch);
- }
+ return null;
}
}
}
diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs
index de4b56c92..54f5f8264 100644
--- a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs
+++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs
@@ -10,32 +10,17 @@ namespace Barotrauma
{
public readonly Sprite Sprite;
- public readonly float Speed;
+ public readonly Alignment Alignment;
- public readonly float WanderAmount;
+ public readonly int Commonness;
- public readonly float WanderZAmount;
-
- public readonly int SwarmMin, SwarmMax;
-
- public readonly float SwarmRadius;
-
- public readonly bool DisableRotation;
-
public BackgroundSpritePrefab(XElement element)
{
- Speed = ToolBox.GetAttributeFloat(element, "speed", 1.0f);
+ string alignmentStr = ToolBox.GetAttributeString(element, "alignment", "BottomCenter");
- WanderAmount = ToolBox.GetAttributeFloat(element, "wanderamount", 0.0f);
+ if (!Enum.TryParse(alignmentStr, out Alignment)) Alignment = Alignment.BottomCenter;
- WanderZAmount = ToolBox.GetAttributeFloat(element, "wanderzamount", 0.0f);
-
- SwarmMin = ToolBox.GetAttributeInt(element, "swarmmin", 1);
- SwarmMax = ToolBox.GetAttributeInt(element, "swarmmax", 1);
-
- SwarmRadius = ToolBox.GetAttributeFloat(element, "swarmradius", 200.0f);
-
- DisableRotation = ToolBox.GetAttributeBool(element, "disablerotation", false);
+ Commonness = ToolBox.GetAttributeInt(element, "commonness", 1);
foreach (XElement subElement in element.Elements())
{
@@ -45,6 +30,6 @@ namespace Barotrauma
break;
}
}
- }
+ }
}
diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs
index bad2d1bc4..6563a8ad3 100644
--- a/Subsurface/Source/Characters/Character.cs
+++ b/Subsurface/Source/Characters/Character.cs
@@ -300,7 +300,7 @@ namespace Barotrauma
public static Character Create(CharacterInfo characterInfo, Vector2 position, bool isNetworkPlayer = false, bool hasAi=true)
{
- return Create(characterInfo.File, position, characterInfo, isNetworkPlayer);
+ return Create(characterInfo.File, position, characterInfo, isNetworkPlayer, hasAi);
}
public static Character Create(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false, bool hasAi=true)
@@ -315,17 +315,19 @@ namespace Barotrauma
}
else
{
- if (hasAi)
- {
- return new Character(file, position, characterInfo, isNetworkPlayer);
- }
- else
+ if (hasAi && !isNetworkPlayer)
{
var character = new AICharacter(file, position, characterInfo, isNetworkPlayer);
var ai = new HumanAIController(character);
character.SetAI(ai);
return character;
+
+ }
+ else
+ {
+
+ return new Character(file, position, characterInfo, isNetworkPlayer);
}
}
}
@@ -340,26 +342,12 @@ namespace Barotrauma
{
keys[i] = new Key(GameMain.Config.KeyBind((InputType)i));
}
-
- //keys[(int)InputType.Select] = new Key(GameMain.Config.KeyBind(InputType.Select));
- //keys[(int)InputType.ActionHeld] = new Key(true);
- //keys[(int)InputType.ActionHit] = new Key(false);
- //keys[(int)InputType.SecondaryHit] = new Key(false);
- //keys[(int)InputType.SecondaryHeld] = new Key(true);
-
- //keys[(int)InputType.Left] = new Key(true);
- //keys[(int)InputType.Right] = new Key(true);
- //keys[(int)InputType.Up] = new Key(true);
- //keys[(int)InputType.Down] = new Key(true);
-
- //keys[(int)InputType.Run] = new Key(true);
-
+
selectedItems = new Item[2];
IsNetworkPlayer = isNetworkPlayer;
oxygen = 100.0f;
- //blood = 100.0f;
aiTarget = new AITarget(this);
lowPassMultiplier = 1.0f;
@@ -1259,22 +1247,6 @@ namespace Barotrauma
return inventory.FillNetworkData(NetworkEventType.InventoryUpdate, message, data);
case NetworkEventType.ImportantEntityUpdate:
- //int i = 0;
- //foreach (Limb limb in AnimController.Limbs)
- //{
- // if (limb.SimPosition.Length() > NetConfig.CharacterIgnoreDistance) return false;
-
- // message.WriteRangedSingle(limb.body.SimPosition.X, -NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16);
- // message.WriteRangedSingle(limb.body.SimPosition.Y, -NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16);
-
- // //message.Write(limb.body.LinearVelocity.X);
- // //message.Write(limb.body.LinearVelocity.Y);
-
- // message.Write(limb.body.Rotation);
- // //message.WriteRangedSingle(MathHelper.Clamp(limb.body.AngularVelocity, -10.0f, 10.0f), -10.0f, 10.0f, 8);
- // i++;
- //}
-
message.Write((byte)((health / maxHealth) * 255.0f));
if (AnimController.StunTimer<=0.0f && bleeding<=0.0f && oxygen>99.0f)
@@ -1291,10 +1263,8 @@ namespace Barotrauma
bleeding = MathHelper.Clamp(bleeding, 0.0f, 5.0f);
message.WriteRangedSingle(bleeding, 0.0f, 5.0f, 8);
-
}
-
return true;
case NetworkEventType.EntityUpdate:
message.Write(keys[(int)InputType.Use].DequeueHeld);
diff --git a/Subsurface/Source/Events/MonsterEvent.cs b/Subsurface/Source/Events/MonsterEvent.cs
index 5a7110191..e4b8f1bd9 100644
--- a/Subsurface/Source/Events/MonsterEvent.cs
+++ b/Subsurface/Source/Events/MonsterEvent.cs
@@ -40,7 +40,8 @@ namespace Barotrauma
//!!!!!!!!!!!!!!!!!!
if (spawnDeep)
{
- position.Y -= 100.0f;
+
+ position.Y -= Level.Loaded.Size.Y;
}
position.X += Rand.Range(-0.5f, 0.5f);
diff --git a/Subsurface/Source/Events/Quests/SalvageQuest.cs b/Subsurface/Source/Events/Quests/SalvageQuest.cs
index 7f911a0ba..c0ce3ab6e 100644
--- a/Subsurface/Source/Events/Quests/SalvageQuest.cs
+++ b/Subsurface/Source/Events/Quests/SalvageQuest.cs
@@ -81,7 +81,7 @@ namespace Barotrauma
state = 1;
break;
case 1:
- if (!Level.Loaded.AtEndPosition && !Level.Loaded.AtStartPosition) return;
+ if (!Submarine.Loaded.AtEndPosition && !Submarine.Loaded.AtStartPosition) return;
ShowMessage(state);
state = 2;
break;
diff --git a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs
index 4b4c71f24..58c41493d 100644
--- a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs
+++ b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs
@@ -141,14 +141,12 @@ namespace Barotrauma
CrewManager.Draw(spriteBatch);
- if (Level.Loaded == null) return;
-
- if (Level.Loaded.AtEndPosition)
+ if (Submarine.Loaded.AtEndPosition)
{
endShiftButton.Text = "Enter " + Map.SelectedLocation.Name;
endShiftButton.Draw(spriteBatch);
}
- else if (Level.Loaded.AtStartPosition)
+ else if (Submarine.Loaded.AtStartPosition)
{
endShiftButton.Text = "Enter " + Map.CurrentLocation.Name;
endShiftButton.Draw(spriteBatch);
@@ -223,7 +221,7 @@ namespace Barotrauma
sb.Append("No casualties!");
}
- if (Level.Loaded.AtEndPosition)
+ if (Submarine.Loaded.AtEndPosition)
{
Map.MoveToNextLocation();
}
diff --git a/Subsurface/Source/GameSession/GameModes/TraitorMode.cs b/Subsurface/Source/GameSession/GameModes/TraitorMode.cs
index 67f191fbe..6ac1a4851 100644
--- a/Subsurface/Source/GameSession/GameModes/TraitorMode.cs
+++ b/Subsurface/Source/GameSession/GameModes/TraitorMode.cs
@@ -55,7 +55,7 @@ namespace Barotrauma
End(endMessage);
return;
}
- else if (Level.Loaded.AtEndPosition)
+ else if (Submarine.Loaded.AtEndPosition)
{
string endMessage = traitorCharacter.Name + " was a traitor! ";
endMessage += (traitorCharacter.Info.Gender == Gender.Male) ? "His" : "Her";
diff --git a/Subsurface/Source/GameSession/GameModes/TutorialMode.cs b/Subsurface/Source/GameSession/GameModes/TutorialMode.cs
index 0ad102f87..53312411e 100644
--- a/Subsurface/Source/GameSession/GameModes/TutorialMode.cs
+++ b/Subsurface/Source/GameSession/GameModes/TutorialMode.cs
@@ -85,7 +85,7 @@ namespace Barotrauma
Submarine.Loaded.SetPosition(new Vector2(Submarine.Loaded.Position.X, 38500.0f));
//spawn some fish next to the player
- GameMain.GameScreen.BackgroundSpriteManager.SpawnSprites(2,
+ GameMain.GameScreen.BackgroundCreatureManager.SpawnSprites(2,
Submarine.Loaded.Position + Character.Controlled.Position);
yield return new WaitForSeconds(4.0f);
diff --git a/Subsurface/Source/GameSession/GameSession.cs b/Subsurface/Source/GameSession/GameSession.cs
index d3ace9f02..a39764afe 100644
--- a/Subsurface/Source/GameSession/GameSession.cs
+++ b/Subsurface/Source/GameSession/GameSession.cs
@@ -119,7 +119,7 @@ namespace Barotrauma
level.Generate();
submarine.SetPosition(level.StartPosition - new Vector2(0.0f, 2000.0f));
- GameMain.GameScreen.BackgroundSpriteManager.SpawnSprites(80);
+ GameMain.GameScreen.BackgroundCreatureManager.SpawnSprites(80);
}
if (Quest!=null) Quest.Start(Level.Loaded);
diff --git a/Subsurface/Source/Items/Components/Door.cs b/Subsurface/Source/Items/Components/Door.cs
index d46eff019..ba43bf53e 100644
--- a/Subsurface/Source/Items/Components/Door.cs
+++ b/Subsurface/Source/Items/Components/Door.cs
@@ -46,6 +46,7 @@ namespace Barotrauma.Items.Components
if (linkedGap != null) return linkedGap;
}
linkedGap = new Gap(item.Rect, Item.Submarine);
+ linkedGap.Submarine = item.Submarine;
linkedGap.Open = openState;
item.linkedTo.Add(linkedGap);
return linkedGap;
diff --git a/Subsurface/Source/Items/Components/Holdable/Holdable.cs b/Subsurface/Source/Items/Components/Holdable/Holdable.cs
index 6fda8667c..dc06330cc 100644
--- a/Subsurface/Source/Items/Components/Holdable/Holdable.cs
+++ b/Subsurface/Source/Items/Components/Holdable/Holdable.cs
@@ -110,6 +110,9 @@ namespace Barotrauma.Items.Components
public override void Drop(Character dropper)
{
+ item.body.Enabled = true;
+ IsActive = false;
+
if (picker == null)
{
if (dropper==null) return;
@@ -117,8 +120,8 @@ namespace Barotrauma.Items.Components
}
if (picker.Inventory == null) return;
- item.body.Enabled = true;
- IsActive = false;
+
+ item.Submarine = picker.Submarine;
//item.Unequip();
diff --git a/Subsurface/Source/Items/Components/Holdable/Pickable.cs b/Subsurface/Source/Items/Components/Holdable/Pickable.cs
index d27a504e0..df5a0adc1 100644
--- a/Subsurface/Source/Items/Components/Holdable/Pickable.cs
+++ b/Subsurface/Source/Items/Components/Holdable/Pickable.cs
@@ -107,6 +107,8 @@ namespace Barotrauma.Items.Components
}
if (picker==null || picker.Inventory == null) return;
+
+ item.Submarine = picker.Submarine;
if (item.body!= null && !item.body.Enabled)
{
diff --git a/Subsurface/Source/Items/Components/Machines/Radar.cs b/Subsurface/Source/Items/Components/Machines/Radar.cs
index d7c805cd4..d84544a22 100644
--- a/Subsurface/Source/Items/Components/Machines/Radar.cs
+++ b/Subsurface/Source/Items/Components/Machines/Radar.cs
@@ -129,9 +129,9 @@ namespace Barotrauma.Items.Components
foreach (GraphEdge edge in cell.edges)
{
- //if (!edge.isSolid) continue;
- float cellDot = Vector2.Dot(cell.Center - item.WorldPosition, (edge.point1 + edge.point2) / 2.0f - cell.Center);
- //if (cellDot > 0) continue;
+ if (!edge.isSolid) continue;
+ float cellDot = Vector2.Dot(cell.Center - item.WorldPosition, edge.Center - cell.Center);
+ if (cellDot > 0) continue;
float facingDot = Vector2.Dot(Vector2.Normalize(edge.point1 - edge.point2), Vector2.Normalize(cell.Center-item.WorldPosition));
facingDot = 1.0f;// MathHelper.Clamp(facingDot, -1.0f, 1.0f);
@@ -150,7 +150,7 @@ namespace Barotrauma.Items.Components
if (pointDist < prevPingRadius || pointDist > pingRadius) continue;
- float step = 5.0f * (Math.Abs(facingDot) + 1.0f);
+ float step = 3.0f * (Math.Abs(facingDot) + 1.0f);
float alpha = Rand.Range(1.5f, 2.0f);
for (float z = 0; z < radius - pointDist; z += step)
{
diff --git a/Subsurface/Source/Items/Components/Power/PowerTransfer.cs b/Subsurface/Source/Items/Components/Power/PowerTransfer.cs
index 27b4fea6c..c011bb4c6 100644
--- a/Subsurface/Source/Items/Components/Power/PowerTransfer.cs
+++ b/Subsurface/Source/Items/Components/Power/PowerTransfer.cs
@@ -75,7 +75,7 @@ namespace Barotrauma.Items.Components
if (FireProbability > 0.0f && Rand.Int((int)(1.0f / FireProbability)) == 1)
{
- new FireSource(pt.item.Position);
+ new FireSource(pt.item.WorldPosition);
}
}
}
diff --git a/Subsurface/Source/Items/Components/Power/Powered.cs b/Subsurface/Source/Items/Components/Power/Powered.cs
index f571f7c6b..c6056c8b4 100644
--- a/Subsurface/Source/Items/Components/Power/Powered.cs
+++ b/Subsurface/Source/Items/Components/Power/Powered.cs
@@ -98,7 +98,7 @@ namespace Barotrauma.Items.Components
{
if (!powerOnSoundPlayed)
{
- powerOnSound.Play(1.0f, 600.0f, item.Position);
+ powerOnSound.Play(1.0f, 600.0f, item.WorldPosition);
powerOnSoundPlayed = true;
}
}
diff --git a/Subsurface/Source/Items/Components/Signal/Wire.cs b/Subsurface/Source/Items/Components/Signal/Wire.cs
index 6d4af4164..eb0fb6f54 100644
--- a/Subsurface/Source/Items/Components/Signal/Wire.cs
+++ b/Subsurface/Source/Items/Components/Signal/Wire.cs
@@ -318,7 +318,7 @@ namespace Barotrauma.Items.Components
if (item.Submarine != null) worldPos += item.Submarine.Position;
worldPos.Y = -worldPos.Y;
- GUI.DrawRectangle(spriteBatch, worldPos+new Vector2(-3,3), new Vector2(6, 6), Color.Red, true, 0.0f);
+ GUI.DrawRectangle(spriteBatch, worldPos+new Vector2(-3,-3), new Vector2(6, 6), Color.Red, true, 0.0f);
if (GUIComponent.MouseOn != null ||
Vector2.Distance(GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), Nodes[i]) > 10.0f)
@@ -326,7 +326,7 @@ namespace Barotrauma.Items.Components
continue;
}
- GUI.DrawRectangle(spriteBatch, worldPos + new Vector2(-10, 10), new Vector2(20, 20), Color.Red, false, 0.0f);
+ GUI.DrawRectangle(spriteBatch, worldPos + new Vector2(-10, -10), new Vector2(20, 20), Color.Red, false, 0.0f);
if (selectedNodeIndex == null && !MapEntity.SelectedAny)
{
diff --git a/Subsurface/Source/Items/FixRequirement.cs b/Subsurface/Source/Items/FixRequirement.cs
index 99f7228d2..de2441b78 100644
--- a/Subsurface/Source/Items/FixRequirement.cs
+++ b/Subsurface/Source/Items/FixRequirement.cs
@@ -83,7 +83,7 @@ namespace Barotrauma
int width = 400, height = 500;
int x = 0, y = 0;
- frame = new GUIFrame(new Rectangle(0, 0, width, height), Color.White * 0.8f, Alignment.Center, GUI.Style);
+ frame = new GUIFrame(new Rectangle(0, 0, width, height), null, Alignment.Center, GUI.Style);
frame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
frame.UserData = item;
diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs
index 599f2f36c..f68727942 100644
--- a/Subsurface/Source/Items/Item.cs
+++ b/Subsurface/Source/Items/Item.cs
@@ -389,15 +389,22 @@ namespace Barotrauma
if (body != null) FindHull();
}
- public Rectangle TransformTrigger(Rectangle trigger)
+ public Rectangle TransformTrigger(Rectangle trigger, bool world = false)
{
- return new Rectangle(
+ return world ?
+ new Rectangle(
+ WorldRect.X + trigger.X,
+ WorldRect.Y + trigger.Y,
+ (trigger.Width == 0) ? (int)Rect.Width : trigger.Width,
+ (trigger.Height == 0) ? (int)Rect.Height : trigger.Height)
+ :
+ new Rectangle(
Rect.X + trigger.X,
Rect.Y + trigger.Y,
(trigger.Width == 0) ? (int)Rect.Width : trigger.Width,
(trigger.Height == 0) ? (int)Rect.Height : trigger.Height);
}
-
+
///
/// goes through every item and re-checks which hull they are in
///
@@ -900,13 +907,13 @@ namespace Barotrauma
return closest;
}
- public bool IsInsideTrigger(Vector2 position)
+ public bool IsInsideTrigger(Vector2 worldPosition)
{
foreach (Rectangle trigger in prefab.Triggers)
{
- Rectangle transformedTrigger = TransformTrigger(trigger);
+ Rectangle transformedTrigger = TransformTrigger(trigger, true);
- if (Submarine.RectContains(transformedTrigger, position)) return true;
+ if (Submarine.RectContains(transformedTrigger, worldPosition)) return true;
}
return false;
@@ -1142,14 +1149,19 @@ namespace Barotrauma
element.Add(new XAttribute("name", prefab.Name),
new XAttribute("ID", ID));
-
+
if (prefab.ResizeHorizontal || prefab.ResizeVertical)
{
- element.Add(new XAttribute("rect", rect.X + "," + rect.Y + "," + rect.Width + "," + rect.Height));
+ element.Add(new XAttribute("rect",
+ (int)(rect.X - Submarine.HiddenSubPosition.X) + "," +
+ (int)(rect.Y - Submarine.HiddenSubPosition.Y) + "," +
+ rect.Width + "," + rect.Height));
}
else
{
- element.Add(new XAttribute("rect", rect.X + "," + rect.Y));
+ element.Add(new XAttribute("rect",
+ (int)(rect.X - Submarine.HiddenSubPosition.X) + "," +
+ (int)(rect.Y - Submarine.HiddenSubPosition.Y)));
}
if (linkedTo != null && linkedTo.Count>0)
diff --git a/Subsurface/Source/Map/FireSource.cs b/Subsurface/Source/Map/FireSource.cs
index 2bba83534..1abffbc2b 100644
--- a/Subsurface/Source/Map/FireSource.cs
+++ b/Subsurface/Source/Map/FireSource.cs
@@ -16,12 +16,14 @@ namespace Barotrauma
private int basicSoundIndex, largeSoundIndex;
- Hull hull;
+ private Hull hull;
- LightSource lightSource;
+ private LightSource lightSource;
- Vector2 position;
- Vector2 size;
+ private Vector2 position;
+ private Vector2 size;
+
+ private Entity Submarine;
public Vector2 Position
{
@@ -34,6 +36,11 @@ namespace Barotrauma
}
}
+ public Vector2 WorldPosition
+ {
+ get { return Submarine.Position + position; }
+ }
+
public Vector2 Size
{
get { return size; }
@@ -50,11 +57,16 @@ namespace Barotrauma
fireSoundLarge = Sound.Load("Content/Sounds/firelarge.ogg");
}
- lightSource = new LightSource(worldPosition, 50.0f, new Color(1.0f, 0.9f, 0.6f), hull == null ? null : hull.Submarine);
-
hull.AddFireSource(this, !networkEvent);
- this.position = worldPosition - new Vector2(-5.0f, 5.0f);
+ Submarine = hull.Submarine;
+
+ this.position = worldPosition - new Vector2(-5.0f, 5.0f) - Submarine.Position;
+
+
+ lightSource = new LightSource(this.position, 50.0f, new Color(1.0f, 0.9f, 0.7f), hull == null ? null : hull.Submarine);
+
+
//this.position.Y = hull.Rect.Y - hull.Rect.Height;
@@ -136,9 +148,9 @@ namespace Barotrauma
{
float normalizedPos = 0.5f-(i / count);
- Vector2 spawnPos = new Vector2(position.X + Rand.Range(0.0f, size.X), Rand.Range(position.Y - size.Y, position.Y)+10.0f);
+ Vector2 spawnPos = new Vector2(WorldPosition.X + Rand.Range(0.0f, size.X), Rand.Range(WorldPosition.Y - size.Y, WorldPosition.Y) + 10.0f);
- Vector2 speed = new Vector2((spawnPos.X - (position.X + size.X/2.0f)), (float)Math.Sqrt(size.X)*Rand.Range(10.0f,15.0f)*growModifier);
+ Vector2 speed = new Vector2((spawnPos.X - (WorldPosition.X + size.X / 2.0f)), (float)Math.Sqrt(size.X) * Rand.Range(10.0f, 15.0f) * growModifier);
var particle = GameMain.ParticleManager.CreateParticle("flame",
spawnPos, speed, 0.0f, hull);
@@ -265,8 +277,8 @@ namespace Barotrauma
{
float range = 100.0f;
- if (pos.X < position.X-range || pos.X > position.X + size.X+range) return;
- if (pos.Y < position.Y - size.Y || pos.Y > position.Y + 500.0f) return;
+ if (pos.X < WorldPosition.X - range || pos.X > WorldPosition.X + size.X + range) return;
+ if (pos.Y < WorldPosition.Y - size.Y || pos.Y > WorldPosition.Y + 500.0f) return;
float extinquishAmount = amount * deltaTime;
diff --git a/Subsurface/Source/Map/Gap.cs b/Subsurface/Source/Map/Gap.cs
index d82dcff18..6c757e85f 100644
--- a/Subsurface/Source/Map/Gap.cs
+++ b/Subsurface/Source/Map/Gap.cs
@@ -79,6 +79,13 @@ namespace Barotrauma
InsertToList();
}
+ public override void Move(Vector2 amount)
+ {
+ base.Move(amount);
+
+ FindHulls();
+ }
+
public static void UpdateHulls()
{
foreach (Gap g in Gap.GapList)
@@ -119,7 +126,7 @@ namespace Barotrauma
if (hulls[0] == null && hulls[1] == null) return;
- if (hulls[0]!=null && hulls[1]!=null)
+ if (hulls[0] != null && hulls[1] != null)
{
if ((isHorizontal && hulls[0].Rect.X > hulls[1].Rect.X) || (!isHorizontal && hulls[0].Rect.Y < hulls[1].Rect.Y))
{
@@ -537,15 +544,21 @@ namespace Barotrauma
if (soundIndex > -1) Sounds.SoundManager.Stop(soundIndex);
}
+
+ public override void OnMapLoaded()
+ {
+ UpdateHulls();
+ }
public override XElement Save(XDocument doc)
{
XElement element = new XElement("Gap");
- element.Add(new XAttribute("ID", ID),
- new XAttribute("x", rect.X),
- new XAttribute("y", rect.Y),
- new XAttribute("width", rect.Width),
- new XAttribute("height", rect.Height));
+ element.Add(new XAttribute("ID", ID));
+
+ element.Add(new XAttribute("rect",
+ (int)(rect.X - Submarine.HiddenSubPosition.X) + "," +
+ (int)(rect.Y - Submarine.HiddenSubPosition.Y) + "," +
+ rect.Width + "," + rect.Height));
//if (linkedTo != null)
//{
@@ -566,11 +579,27 @@ namespace Barotrauma
public static void Load(XElement element, Submarine submarine)
{
- Rectangle rect = new Rectangle(
- int.Parse(element.Attribute("x").Value),
- int.Parse(element.Attribute("y").Value),
- int.Parse(element.Attribute("width").Value),
- int.Parse(element.Attribute("height").Value));
+ Rectangle rect = Rectangle.Empty;
+
+ if (element.Attribute("rect") != null)
+ {
+ string rectString = ToolBox.GetAttributeString(element, "rect", "0,0,0,0");
+ string[] rectValues = rectString.Split(',');
+
+ rect = new Rectangle(
+ int.Parse(rectValues[0]),
+ int.Parse(rectValues[1]),
+ int.Parse(rectValues[2]),
+ int.Parse(rectValues[3]));
+ }
+ else
+ {
+ rect = new Rectangle(
+ int.Parse(element.Attribute("x").Value),
+ int.Parse(element.Attribute("y").Value),
+ int.Parse(element.Attribute("width").Value),
+ int.Parse(element.Attribute("height").Value));
+ }
Gap g = new Gap(rect, submarine);
g.ID = (ushort)int.Parse(element.Attribute("ID").Value);
diff --git a/Subsurface/Source/Map/Hull.cs b/Subsurface/Source/Map/Hull.cs
index 924437757..ef7ce7eb7 100644
--- a/Subsurface/Source/Map/Hull.cs
+++ b/Subsurface/Source/Map/Hull.cs
@@ -229,11 +229,11 @@ namespace Barotrauma
if (EditWater)
{
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
- if (Submarine.RectContains(rect, position))
+ if (Submarine.RectContains(WorldRect, position))
{
if (PlayerInput.LeftButtonDown())
{
- waveY[(int)(position.X - rect.X) / WaveWidth] = 100.0f;
+ //waveY[GetWaveIndex(position.X - rect.X - Submarine.Position.X) / WaveWidth] = 100.0f;
Volume = Volume + 1500.0f;
}
else if (PlayerInput.RightButtonDown())
@@ -245,7 +245,7 @@ namespace Barotrauma
else if (EditFire)
{
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
- if (Submarine.RectContains(rect, position))
+ if (Submarine.RectContains(WorldRect, position))
{
if (PlayerInput.LeftButtonClicked())
{
@@ -524,12 +524,15 @@ namespace Barotrauma
{
XElement element = new XElement("Hull");
- element.Add(new XAttribute("ID", ID),
- new XAttribute("x", rect.X),
- new XAttribute("y", rect.Y),
- new XAttribute("width", rect.Width),
- new XAttribute("height", rect.Height),
- new XAttribute("water", volume));
+ element.Add
+ (
+ new XAttribute("ID", ID),
+ new XAttribute("rect",
+ (int)(rect.X - Submarine.HiddenSubPosition.X) + "," +
+ (int)(rect.Y - Submarine.HiddenSubPosition.Y) + "," +
+ rect.Width + "," + rect.Height),
+ new XAttribute("water", volume)
+ );
doc.Root.Add(element);
@@ -538,11 +541,27 @@ namespace Barotrauma
public static void Load(XElement element, Submarine submarine)
{
- Rectangle rect = new Rectangle(
- int.Parse(element.Attribute("x").Value),
- int.Parse(element.Attribute("y").Value),
- int.Parse(element.Attribute("width").Value),
- int.Parse(element.Attribute("height").Value));
+ Rectangle rect = Rectangle.Empty;
+
+ if (element.Attribute("rect") != null)
+ {
+ string rectString = ToolBox.GetAttributeString(element, "rect", "0,0,0,0");
+ string[] rectValues = rectString.Split(',');
+
+ rect = new Rectangle(
+ int.Parse(rectValues[0]),
+ int.Parse(rectValues[1]),
+ int.Parse(rectValues[2]),
+ int.Parse(rectValues[3]));
+ }
+ else
+ {
+ rect = new Rectangle(
+ int.Parse(element.Attribute("x").Value),
+ int.Parse(element.Attribute("y").Value),
+ int.Parse(element.Attribute("width").Value),
+ int.Parse(element.Attribute("height").Value));
+ }
Hull h = new Hull(rect, submarine);
diff --git a/Subsurface/Source/Map/Levels/Level.cs b/Subsurface/Source/Map/Levels/Level.cs
index e2142f881..29a5c887a 100644
--- a/Subsurface/Source/Map/Levels/Level.cs
+++ b/Subsurface/Source/Map/Levels/Level.cs
@@ -25,7 +25,7 @@ namespace Barotrauma
private LevelRenderer renderer;
//how close the sub has to be to start/endposition to exit
- const float ExitDistance = 6000.0f;
+ public const float ExitDistance = 6000.0f;
private string seed;
@@ -56,12 +56,6 @@ namespace Barotrauma
get { return startPosition; }
}
- public bool AtStartPosition
- {
- get;
- private set;
- }
-
public Vector2 Size
{
get { return new Vector2(borders.Width, borders.Height); }
@@ -71,13 +65,7 @@ namespace Barotrauma
{
get { return endPosition; }
}
-
- public bool AtEndPosition
- {
- get;
- private set;
- }
-
+
public List PositionsOfInterest
{
get { return positionsOfInterest; }
@@ -380,6 +368,8 @@ namespace Barotrauma
endPosition = temp;
}
+ renderer.PlaceSprites(100);
+
Debug.WriteLine("**********************************************************************************");
Debug.WriteLine("Generated a map with " + sites.Count + " sites in " + sw.ElapsedMilliseconds + " ms");
Debug.WriteLine("Seed: "+seed);
@@ -967,7 +957,7 @@ namespace Barotrauma
renderer.Draw(spriteBatch);
}
- public void DrawBack(SpriteBatch spriteBatch, Camera cam, BackgroundSpriteManager backgroundSpriteManager = null)
+ public void DrawBack(SpriteBatch spriteBatch, Camera cam, BackgroundCreatureManager backgroundSpriteManager = null)
{
if (renderer == null) return;
renderer.DrawBackground(spriteBatch, cam, backgroundSpriteManager);
diff --git a/Subsurface/Source/Map/Levels/LevelRenderer.cs b/Subsurface/Source/Map/Levels/LevelRenderer.cs
index 6ed2b1640..05ee49509 100644
--- a/Subsurface/Source/Map/Levels/LevelRenderer.cs
+++ b/Subsurface/Source/Map/Levels/LevelRenderer.cs
@@ -16,6 +16,8 @@ namespace Barotrauma
private static Texture2D dustParticles;
private static Texture2D shaftTexture;
+ private static BackgroundSpriteManager backgroundSpriteManager;
+
Vector2 dustOffset;
private Level level;
@@ -43,16 +45,25 @@ namespace Barotrauma
basicEffect.Texture = TextureLoader.FromFile("Content/Map/iceWall.png");
}
+ if (backgroundSpriteManager==null)
+ {
+ backgroundSpriteManager = new BackgroundSpriteManager("Content/BackgroundSprites/BackgroundSpritePrefabs.xml");
+ }
+
this.level = level;
}
+ public void PlaceSprites(int amount)
+ {
+ backgroundSpriteManager.PlaceSprites(level, amount);
+ }
+
public void Update(float deltaTime)
{
-
dustOffset -= Vector2.UnitY * 10.0f * (float)deltaTime;
}
- public void DrawBackground(SpriteBatch spriteBatch, Camera cam, BackgroundSpriteManager backgroundSpriteManager = null)
+ public void DrawBackground(SpriteBatch spriteBatch, Camera cam, BackgroundCreatureManager backgroundCreatureManager = null)
{
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearWrap);
@@ -87,7 +98,9 @@ namespace Barotrauma
SamplerState.LinearWrap, DepthStencilState.Default, null, null,
cam.Transform);
- if (backgroundSpriteManager!=null) backgroundSpriteManager.Draw(spriteBatch);
+ backgroundSpriteManager.DrawSprites(spriteBatch);
+
+ if (backgroundCreatureManager!=null) backgroundCreatureManager.Draw(spriteBatch);
spriteBatch.End();
@@ -118,12 +131,10 @@ namespace Barotrauma
public void Draw(SpriteBatch spriteBatch)
{
Vector2 pos = new Vector2(0.0f, -level.StartPosition.Y);// level.EndPosition;
- //pos.Y = -pos.Y - level.Position.Y;
if (GameMain.GameScreen.Cam.WorldView.Y < -pos.Y - 512) return;
pos.X = GameMain.GameScreen.Cam.WorldView.X -512.0f;
- //pos.X += Position.X % 512;
int width = (int)(Math.Ceiling(GameMain.GameScreen.Cam.WorldView.Width / 512.0f + 2.0f) * 512.0f);
diff --git a/Subsurface/Source/Map/MapEntity.cs b/Subsurface/Source/Map/MapEntity.cs
index 4f0633b3e..eada87ff6 100644
--- a/Subsurface/Source/Map/MapEntity.cs
+++ b/Subsurface/Source/Map/MapEntity.cs
@@ -236,8 +236,6 @@ namespace Barotrauma
///
public static void UpdateSelecting(Camera cam)
{
- if (GUIComponent.MouseOn != null) return;
-
if (DisableSelect)
{
DisableSelect = false;
@@ -250,6 +248,10 @@ namespace Barotrauma
e.isSelected = false;
}
+ if (GUIComponent.MouseOn != null) return;
+
+
+
if (MapEntityPrefab.Selected != null)
{
selectionPos = Vector2.Zero;
@@ -278,8 +280,7 @@ namespace Barotrauma
e.isSelected = false;
}
- if (highLightedEntity != null)
- highLightedEntity.isHighlighted = true;
+ if (highLightedEntity != null) highLightedEntity.isHighlighted = true;
foreach (MapEntity e in selectedList)
{
@@ -304,7 +305,6 @@ namespace Barotrauma
startMovingPos = Vector2.Zero;
}
-
}
//started dragging a "selection rectangle"
else if (selectionPos != Vector2.Zero)
@@ -397,7 +397,7 @@ namespace Barotrauma
{
foreach (MapEntity e in selectedList)
GUI.DrawRectangle(spriteBatch,
- new Vector2(e.rect.X, -e.rect.Y) + moveAmount,
+ new Vector2(e.WorldRect.X, -e.WorldRect.Y) + moveAmount,
new Vector2(e.rect.Width, e.rect.Height),
Color.DarkRed);
@@ -502,8 +502,7 @@ namespace Barotrauma
{
MapEntity linked = FindEntityByID(i) as MapEntity;
- if (linked != null)
- e.linkedTo.Add(linked);
+ if (linked != null) e.linkedTo.Add(linked);
}
}
diff --git a/Subsurface/Source/Map/Structure.cs b/Subsurface/Source/Map/Structure.cs
index 7f60d88e2..903885616 100644
--- a/Subsurface/Source/Map/Structure.cs
+++ b/Subsurface/Source/Map/Structure.cs
@@ -289,7 +289,7 @@ namespace Barotrauma
{
if (prefab.sprite == null) return;
- Color color = (isHighlighted) ? Color.Green : Color.White;
+ Color color = (isHighlighted) ? Color.Orange : Color.White;
if (isSelected && editing) color = Color.Red;
Vector2 drawOffset = Submarine == null ? Vector2.Zero : Submarine.DrawPosition;
@@ -583,8 +583,11 @@ namespace Barotrauma
element.Add(new XAttribute("name", prefab.Name),
new XAttribute("ID", ID),
- new XAttribute("rect", rect.X + "," + rect.Y+","+rect.Width+","+rect.Height));
-
+ new XAttribute("rect",
+ (int)(rect.X - Submarine.HiddenSubPosition.X) + "," +
+ (int)(rect.Y - Submarine.HiddenSubPosition.Y) + "," +
+ rect.Width + "," + rect.Height));
+
for (int i = 0; i < sections.Count(); i++)
{
if (sections[i].damage == 0.0f) continue;
diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs
index b8d17dce4..13189fd1b 100644
--- a/Subsurface/Source/Map/Submarine.cs
+++ b/Subsurface/Source/Map/Submarine.cs
@@ -104,6 +104,24 @@ namespace Barotrauma
get { return subBody==null ? Vector2.Zero : subBody.Position - HiddenSubPosition; }
}
+ public bool AtEndPosition
+ {
+ get
+ {
+ if (Level.Loaded == null) return false;
+ return (Vector2.Distance(Position + HiddenSubPosition, Level.Loaded.EndPosition) < Level.ExitDistance);
+ }
+ }
+
+ public bool AtStartPosition
+ {
+ get
+ {
+ if (Level.Loaded == null) return false;
+ return (Vector2.Distance(Position + HiddenSubPosition, Level.Loaded.StartPosition) < Level.ExitDistance);
+ }
+ }
+
public new Vector2 DrawPosition
{
get;
@@ -283,6 +301,8 @@ namespace Barotrauma
public static Body PickBody(Vector2 rayStart, Vector2 rayEnd, List ignoredBodies = null, Category? collisionCategory = null)
{
+ if (Vector2.DistanceSquared(rayStart, rayEnd) < 0.0f) return null;
+
float closestFraction = 1.0f;
Body closestBody = null;
GameMain.World.RayCast((fixture, point, normal, fraction) =>
@@ -397,8 +417,8 @@ namespace Barotrauma
{
if (subBody == null) return false;
- message.Write(Position.X);
- message.Write(Position.Y);
+ message.Write(subBody.Position.X);
+ message.Write(subBody.Position.Y);
message.Write(Velocity.X);
message.Write(Velocity.Y);
diff --git a/Subsurface/Source/Map/SubmarineBody.cs b/Subsurface/Source/Map/SubmarineBody.cs
index 7bf92e0a9..ef7f34881 100644
--- a/Subsurface/Source/Map/SubmarineBody.cs
+++ b/Subsurface/Source/Map/SubmarineBody.cs
@@ -15,7 +15,7 @@ namespace Barotrauma
{
class SubmarineBody
{
- public const float DamageDepth = -10000.0f;
+ public const float DamageDepth = -30000.0f;
const float PressureDamageMultiplier = 0.001f;
//structure damage = impact * damageMultiplier
@@ -115,7 +115,27 @@ namespace Barotrauma
foreach (Hull hull in Hull.hullList)
{
- FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits(hull.Rect.Width), ConvertUnits.ToSimUnits(hull.Rect.Height), 5.0f, hull.SimPosition, body, this);
+ Rectangle rect = hull.Rect;
+ foreach (Structure wall in Structure.WallList)
+ {
+ if (!Submarine.RectsOverlap(wall.Rect, hull.Rect)) continue;
+
+ Rectangle wallRect = wall.IsHorizontal ?
+ new Rectangle(hull.Rect.X, wall.Rect.Y, hull.Rect.Width, wall.Rect.Height) :
+ new Rectangle(wall.Rect.X, hull.Rect.Y, wall.Rect.Width, hull.Rect.Height);
+
+ rect = Rectangle.Union(
+ new Rectangle(wallRect.X, wallRect.Y-wallRect.Height, wallRect.Width, wallRect.Height),
+ new Rectangle(rect.X, rect.Y - rect.Height, rect.Width, rect.Height));
+ rect.Y = rect.Y + rect.Height;
+ }
+
+ FixtureFactory.AttachRectangle(
+ ConvertUnits.ToSimUnits(rect.Width),
+ ConvertUnits.ToSimUnits(rect.Height),
+ 5.0f,
+ ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width/2, rect.Y - rect.Height/2)),
+ body, this);
}
body.BodyType = BodyType.Dynamic;
@@ -189,36 +209,26 @@ namespace Barotrauma
}
public void Update(float deltaTime)
- {
- if (Position!=Vector2.Zero)
+ {
+ if (targetPosition != Vector2.Zero && targetPosition != Position)
{
- //!!!!!!!!!!!!!!!!
- //UpdateColliding();
+ float dist = Vector2.Distance(targetPosition, Position);
+
+ if (dist > 1000.0f)
+ {
+ body.SetTransform(ConvertUnits.ToSimUnits(targetPosition), 0.0f);
+ targetPosition = Vector2.Zero;
+ }
+ else if (dist > 50.0f)
+ {
+ body.SetTransform((ConvertUnits.ToSimUnits(targetPosition) - body.Position) * 0.01f, 0.0f);
+ }
+ }
+ else
+ {
+ targetPosition = Vector2.Zero;
}
- //Vector2 translateAmount = speed * deltaTime;
- //translateAmount += ConvertUnits.ToDisplayUnits(Position) * collisionRigidness;
-
- //if (targetPosition != Vector2.Zero && targetPosition != Position)
- //{
- // float dist = Vector2.Distance(targetPosition, Position);
-
- // if (dist>1000.0f)
- // {
- // sub.SetPosition(targetPosition);
- // targetPosition = Vector2.Zero;
- // }
- // else if (dist>50.0f)
- // {
- // translateAmount += (targetPosition - Position) * 0.01f;
- // }
- //}
- //else
- //{
- // targetPosition = Vector2.Zero;
- //}
-
- //sub.Translate(translateAmount);
//-------------------------
@@ -236,13 +246,8 @@ namespace Barotrauma
ApplyForce(totalForce);
- //UpdateDepthDamage(deltaTime);
+ UpdateDepthDamage(deltaTime);
- //hullBodies[0].body.LinearVelocity = -hullBodies[0].body.Position;
-
- //hullBody.SetTransform(Vector2.Zero , 0.0f);
- //body.SetTransform(Vector2.Zero, 0.0f);// .LinearVelocity = -body.Position / (float)Physics.step;
- //body.LinearVelocity = Vector2.Zero;
}
private Vector2 CalculateBuoyancy()
@@ -311,80 +316,15 @@ namespace Barotrauma
GameMain.GameScreen.Cam.Shake = depth * PressureDamageMultiplier * 0.1f;
+ damagePos += submarine.Position + Submarine.HiddenSubPosition;
Explosion.RangedStructureDamage(damagePos, depth * PressureDamageMultiplier * 50.0f, depth * PressureDamageMultiplier);
//SoundPlayer.PlayDamageSound(DamageSoundType.StructureBlunt, Rand.Range(0.0f, 100.0f), damagePos, 5000.0f);
depthDamageTimer = 10.0f;
}
- //private void UpdateColliding()
- //{
-
- // return;
-
- // if (body.Position.LengthSquared()<0.00001f) return;
-
- // Vector2 normal = Vector2.Normalize(body.Position);
- // Vector2 simSpeed = ConvertUnits.ToSimUnits(body.LinearVelocity);
-
- // float impact = Vector2.Dot(simSpeed, -normal);
-
- // if (impact < 0.0f) return;
-
- // Vector2 u = Vector2.Dot(simSpeed, -normal) * normal;
- // Vector2 w = (simSpeed + u);
-
- // //speed = ConvertUnits.ToDisplayUnits(w * (1.0f - Friction) + u * Restitution);
-
- // if (lastContactPoint == null || lastContactCell==null || impact < 3.0f) return;
-
- // SoundPlayer.PlayDamageSound(DamageSoundType.StructureBlunt, impact * 10.0f, ConvertUnits.ToDisplayUnits((Vector2)lastContactPoint));
- // GameMain.GameScreen.Cam.Shake = impact * 2.0f;
-
- // Vector2 limbForce = -normal * impact*0.5f;
-
- // float length = limbForce.Length();
- // if (length > 10.0f) limbForce = (limbForce / length) * 10.0f;
-
- // foreach (Character c in Character.CharacterList)
- // {
- // if (c.AnimController.CurrentHull == null) continue;
-
- // if (impact > 2.0f) c.AnimController.StunTimer = (impact - 2.0f) * 0.1f;
-
- // foreach (Limb limb in c.AnimController.Limbs)
- // {
- // if (c.AnimController.LowestLimb == limb) continue;
- // limb.body.ApplyLinearImpulse(limb.Mass * limbForce);
- // }
- // }
-
- // Explosion.RangedStructureDamage(ConvertUnits.ToDisplayUnits((Vector2)lastContactPoint), impact*50.0f, impact*DamageMultiplier);
-
- // //Body wallBody = Submarine.PickBody(
- // // (Vector2)lastContactPoint - body.Position,
- // // (Vector2)lastContactPoint + body.Position * 10.0f,
- // // new List() { lastContactCell.body });
-
- // //if (wallBody == null || wallBody.UserData == null) return;
-
- // //var damageable = wallBody.UserData as IDamageable;
- // //Structure structure = wallBody.UserData as Structure;
-
- // //if (structure == null) return;
-
- // //int sectionIndex = structure.FindSectionIndex(ConvertUnits.ToDisplayUnits(Submarine.LastPickedPosition));
-
- // //for (int i = sectionIndex - (int)(impact / 5.0f); i < sectionIndex + (int)(impact / 5.0f); i++)
- // //{
- // // structure.AddDamage(i, impact * DamageMultiplier);
- // //}
- //}
-
public bool OnCollision(Fixture f1, Fixture f2, Contact contact)
{
-
-
VoronoiCell cell = f2.Body.UserData as VoronoiCell;
if (cell == null)
@@ -396,7 +336,9 @@ namespace Barotrauma
FixedArray2 points;
contact.GetWorldManifold(out normal2, out points);
- if (Submarine.PickBody(points[0] - ConvertUnits.ToSimUnits(submarine.Position) + normal2, points[0] - ConvertUnits.ToSimUnits(submarine.Position) - normal2, null, Physics.CollisionWall) != null)
+ 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)
{
return true;
@@ -441,7 +383,7 @@ namespace Barotrauma
{
if (c.AnimController.CurrentHull == null) continue;
- if (impact > 2.0f) c.AnimController.StunTimer = (impact - 2.0f) * 0.1f;
+ if (impact > 2.0f) c.StartStun((impact - 2.0f) * 0.1f);
foreach (Limb limb in c.AnimController.Limbs)
{
diff --git a/Subsurface/Source/Map/WayPoint.cs b/Subsurface/Source/Map/WayPoint.cs
index 3477a6a89..772f6641b 100644
--- a/Subsurface/Source/Map/WayPoint.cs
+++ b/Subsurface/Source/Map/WayPoint.cs
@@ -420,8 +420,8 @@ namespace Barotrauma
XElement element = new XElement("WayPoint");
element.Add(new XAttribute("ID", ID),
- new XAttribute("x", rect.X),
- new XAttribute("y", rect.Y),
+ new XAttribute("x", (int)(rect.X - Submarine.HiddenSubPosition.X)),
+ new XAttribute("y", (int)(rect.Y - Submarine.HiddenSubPosition.Y)),
new XAttribute("spawn", spawnType));
if (idCardTags.Length > 0)
diff --git a/Subsurface/Source/Map/azreey13.hzj b/Subsurface/Source/Map/azreey13.hzj
new file mode 100644
index 000000000..78791a947
--- /dev/null
+++ b/Subsurface/Source/Map/azreey13.hzj
@@ -0,0 +1,404 @@
+using FarseerPhysics;
+using FarseerPhysics.Collision;
+using FarseerPhysics.Common;
+using FarseerPhysics.Common.Decomposition;
+using FarseerPhysics.Dynamics;
+using FarseerPhysics.Dynamics.Contacts;
+using FarseerPhysics.Factories;
+using Microsoft.Xna.Framework;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Voronoi2;
+
+namespace Barotrauma
+{
+ class SubmarineBody
+ {
+ public const float DamageDepth = -30000.0f;
+ const float PressureDamageMultiplier = 0.001f;
+
+ //structure damage = impact * damageMultiplier
+ const float DamageMultiplier = 50.0f;
+
+ const float Friction = 0.2f, Restitution = 0.0f;
+
+ public List HullVertices
+ {
+ get;
+ private set;
+ }
+
+ private float depthDamageTimer;
+
+ private Submarine submarine;
+
+ private Body body;
+
+ private Vector2 targetPosition;
+
+ float mass = 10000.0f;
+
+ //private Vector2? lastContactPoint;
+ //private VoronoiCell lastContactCell;
+
+ public Rectangle Borders
+ {
+ get;
+ private set;
+ }
+
+ public Vector2 Velocity
+ {
+ get { return body.LinearVelocity; }
+ set
+ {
+ if (!MathUtils.IsValid(value)) return;
+ body.LinearVelocity = value;
+ }
+ }
+
+ public Vector2 TargetPosition
+ {
+ get { return targetPosition; }
+ set
+ {
+ if (!MathUtils.IsValid(value)) return;
+ targetPosition = value;
+ }
+ }
+
+ public Vector2 Position
+ {
+ get { return ConvertUnits.ToDisplayUnits(body.Position); }
+ }
+
+ public Vector2 Center
+ {
+ get { return new Vector2(Borders.X + Borders.Width / 2, Borders.Y - Borders.Height / 2); }
+ }
+
+ public bool AtDamageDepth
+ {
+ get { return Position.Y < DamageDepth; }
+ }
+
+ public SubmarineBody(Submarine sub)
+ {
+ this.submarine = sub;
+
+
+ List convexHull = GenerateConvexHull();
+ HullVertices = convexHull;
+
+ for (int i = 0; i < convexHull.Count; i++)
+ {
+ convexHull[i] = ConvertUnits.ToSimUnits(convexHull[i]);
+ }
+
+ convexHull.Reverse();
+
+ //get farseer 'vertices' from vectors
+ Vertices shapevertices = new Vertices(convexHull);
+
+ AABB hullAABB = shapevertices.GetAABB();
+
+ Borders = new Rectangle(
+ (int)ConvertUnits.ToDisplayUnits(hullAABB.LowerBound.X),
+ (int)ConvertUnits.ToDisplayUnits(hullAABB.UpperBound.Y),
+ (int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.X * 2.0f),
+ (int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.Y * 2.0f));
+
+ //var triangulatedVertices = Triangulate.ConvexPartition(shapevertices, TriangulationAlgorithm.Bayazit);
+
+ body = BodyFactory.CreateBody(GameMain.World, this);
+
+ foreach (Hull hull in Hull.hullList)
+ {
+ Rectangle rect = hull.Rect;
+ foreach (Structure wall in Structure.WallList)
+ {
+ if (!Submarine.RectsOverlap(wall.Rect, hull.Rect)) continue;
+
+ if (wall.IsHorizontal)
+ {
+ if (wall.Rect.Y >= hull.Rect.Y)
+ {
+ rect = new Rectangle(rect.X, wall.Rect.Y, rect.Width, rect.Height + (wall.Rect.Y - rect.Y));
+ }
+ else
+ {
+ rect = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height + (rect.Y - rect.Height - (wall.Rect.Y - wall.Rect.Height)));
+ }
+ }
+ }
+
+ FixtureFactory.AttachRectangle(
+ ConvertUnits.ToSimUnits(rect.Width),
+ ConvertUnits.ToSimUnits(rect.Height),
+ 5.0f,
+ ConvertUnits.ToSimUnits(rect.Center.ToVector2()),
+ body, this);
+ }
+
+ body.BodyType = BodyType.Dynamic;
+ body.CollisionCategories = Physics.CollisionMisc | Physics.CollisionWall;
+ body.CollidesWith = Physics.CollisionLevel | Physics.CollisionCharacter;
+ body.Restitution = Restitution;
+ body.Friction = Friction;
+ body.FixedRotation = true;
+ body.Mass = mass;
+ body.Awake = true;
+ body.SleepingAllowed = false;
+ body.IgnoreGravity = true;
+ body.OnCollision += OnCollision;
+ //body.UserData = this;
+ }
+
+
+ private List GenerateConvexHull()
+ {
+ if (!Structure.WallList.Any())
+ {
+ return new List() { new Vector2(-1.0f, 1.0f), new Vector2(1.0f, 1.0f), new Vector2(0.0f, -1.0f) };
+ }
+
+ List points = new List();
+
+ Vector2 leftMost = Vector2.Zero;
+
+ foreach (Structure wall in Structure.WallList)
+ {
+ for (int x = -1; x <= 1; x += 2)
+ {
+ for (int y = -1; y <= 1; y += 2)
+ {
+ Vector2 corner = new Vector2(wall.Rect.X + wall.Rect.Width / 2.0f, wall.Rect.Y - wall.Rect.Height / 2.0f);
+ corner.X += x * wall.Rect.Width / 2.0f;
+ corner.Y += y * wall.Rect.Height / 2.0f;
+
+ if (points.Contains(corner)) continue;
+
+ points.Add(corner);
+ if (leftMost == Vector2.Zero || corner.X < leftMost.X) leftMost = corner;
+ }
+ }
+ }
+
+ List hullPoints = new List();
+
+ Vector2 currPoint = leftMost;
+ Vector2 endPoint;
+ do
+ {
+ hullPoints.Add(currPoint);
+ endPoint = points[0];
+
+ for (int i = 1; i < points.Count; i++)
+ {
+ if ((currPoint == endPoint)
+ || (MathUtils.VectorOrientation(currPoint, endPoint, points[i]) == -1))
+ {
+ endPoint = points[i];
+ }
+ }
+
+ currPoint = endPoint;
+
+ }
+ while (endPoint != hullPoints[0]);
+
+ return hullPoints;
+ }
+
+ public void Update(float deltaTime)
+ {
+ if (targetPosition != Vector2.Zero && targetPosition != Position)
+ {
+ float dist = Vector2.Distance(targetPosition, Position);
+
+ if (dist > 1000.0f)
+ {
+ body.SetTransform(ConvertUnits.ToSimUnits(targetPosition), 0.0f);
+ targetPosition = Vector2.Zero;
+ }
+ else if (dist > 50.0f)
+ {
+ body.SetTransform((ConvertUnits.ToSimUnits(targetPosition) - body.Position) * 0.01f, 0.0f);
+ }
+ }
+ else
+ {
+ targetPosition = Vector2.Zero;
+ }
+
+
+ //-------------------------
+
+ Vector2 totalForce = CalculateBuoyancy();
+
+ if (body.LinearVelocity.LengthSquared() > 0.000001f)
+ {
+ float dragCoefficient = 0.01f;
+
+ float speedLength = (body.LinearVelocity == Vector2.Zero) ? 0.0f : body.LinearVelocity.Length();
+ float drag = speedLength * speedLength * dragCoefficient * mass;
+
+ totalForce += -Vector2.Normalize(body.LinearVelocity) * drag;
+ }
+
+ ApplyForce(totalForce);
+
+ UpdateDepthDamage(deltaTime);
+
+ }
+
+ private Vector2 CalculateBuoyancy()
+ {
+ float waterVolume = 0.0f;
+ float volume = 0.0f;
+ foreach (Hull hull in Hull.hullList)
+ {
+ waterVolume += hull.Volume;
+ volume += hull.FullVolume;
+ }
+
+ float waterPercentage = waterVolume / volume;
+
+ float neutralPercentage = 0.07f;
+
+ float buoyancy = Math.Max(neutralPercentage - waterPercentage, -neutralPercentage*2.0f);
+ buoyancy *= mass;
+
+ return new Vector2(0.0f, buoyancy*10.0f);
+ }
+
+ public void ApplyForce(Vector2 force)
+ {
+ body.ApplyForce(force);
+ }
+
+ public void SetPosition(Vector2 position)
+ {
+ body.SetTransform(ConvertUnits.ToSimUnits(position), 0.0f);
+ }
+
+ private void UpdateDepthDamage(float deltaTime)
+ {
+ if (Position.Y > DamageDepth) return;
+
+ float depth = DamageDepth - Position.Y;
+ depth = Math.Min(depth, 40000.0f);
+
+ // float prevTimer = depthDamageTimer;
+
+ depthDamageTimer -= deltaTime*Math.Min(depth,20000)*PressureDamageMultiplier;
+
+ //if (prevTimer>5.0f && depthDamageTimer<=5.0f)
+ //{
+ // SoundPlayer.PlayDamageSound(DamageSoundType.Pressure, 50.0f,);
+ //}
+
+ if (depthDamageTimer > 0.0f) return;
+
+ Vector2 damagePos = Vector2.Zero;
+ if (Rand.Int(2)==0)
+ {
+ damagePos = new Vector2(
+ (Rand.Int(2) == 0) ? Borders.X : Borders.X+Borders.Width,
+ Rand.Range(Borders.Y - Borders.Height, Borders.Y));
+ }
+ else
+ {
+ damagePos = new Vector2(
+ Rand.Range(Borders.X, Borders.X + Borders.Width),
+ (Rand.Int(2) == 0) ? Borders.Y : Borders.Y - Borders.Height);
+ }
+
+ SoundPlayer.PlayDamageSound(DamageSoundType.Pressure, 50.0f, damagePos, 10000.0f);
+
+ GameMain.GameScreen.Cam.Shake = depth * PressureDamageMultiplier * 0.1f;
+
+ damagePos += submarine.Position + Submarine.HiddenSubPosition;
+ Explosion.RangedStructureDamage(damagePos, depth * PressureDamageMultiplier * 50.0f, depth * PressureDamageMultiplier);
+ //SoundPlayer.PlayDamageSound(DamageSoundType.StructureBlunt, Rand.Range(0.0f, 100.0f), damagePos, 5000.0f);
+
+ depthDamageTimer = 10.0f;
+ }
+
+ public bool OnCollision(Fixture f1, Fixture f2, Contact contact)
+ {
+ VoronoiCell cell = f2.Body.UserData as VoronoiCell;
+
+ if (cell == null)
+ {
+ Limb limb = f2.Body.UserData as Limb;
+ if (limb!=null && limb.character.Submarine==null)
+ {
+ 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)
+ {
+
+ return true;
+ }
+
+ var ragdoll = limb.character.AnimController;
+ ragdoll.FindHull();
+
+ return false;
+
+ }
+
+ return true;
+ }
+
+ Vector2 normal;
+ FarseerPhysics.Common.FixedArray2 worldPoints;
+ contact.GetWorldManifold(out normal, out worldPoints);
+
+ Vector2 lastContactPoint = worldPoints[0];
+
+ normal = Vector2.Normalize(ConvertUnits.ToDisplayUnits(body.Position) - cell.Center);
+
+ float impact = Vector2.Dot(Velocity, -normal);
+
+ //Vector2 u = Vector2.Dot(Velocity, -normal) * normal;
+ //Vector2 w = (Velocity + u);
+
+ //speed = ConvertUnits.ToDisplayUnits(w * (1.0f - Friction) + u * Restitution);
+
+ if (impact < 3.0f) return true;
+
+ SoundPlayer.PlayDamageSound(DamageSoundType.StructureBlunt, impact * 10.0f, ConvertUnits.ToDisplayUnits(lastContactPoint));
+ GameMain.GameScreen.Cam.Shake = impact * 2.0f;
+
+ Vector2 limbForce = -normal * impact * 0.5f;
+
+ float length = limbForce.Length();
+ if (length > 10.0f) limbForce = (limbForce / length) * 10.0f;
+
+ foreach (Character c in Character.CharacterList)
+ {
+ if (c.AnimController.CurrentHull == null) continue;
+
+ if (impact > 2.0f) c.StartStun((impact - 2.0f) * 0.1f);
+
+ foreach (Limb limb in c.AnimController.Limbs)
+ {
+ if (c.AnimController.LowestLimb == limb) continue;
+ limb.body.ApplyLinearImpulse(limb.Mass * limbForce);
+ }
+ }
+
+ Explosion.RangedStructureDamage(ConvertUnits.ToDisplayUnits(lastContactPoint), impact * 50.0f, impact * DamageMultiplier);
+
+ return true;
+ }
+
+ }
+}
diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs
index dfd784553..5300c7070 100644
--- a/Subsurface/Source/Networking/GameClient.cs
+++ b/Subsurface/Source/Networking/GameClient.cs
@@ -611,7 +611,7 @@ namespace Barotrauma.Networking
(float)Math.Cos(camAngle) * (Submarine.Borders.Width / 2.0f),
(float)Math.Sin(camAngle) * (Submarine.Borders.Height / 2.0f)));
- GameMain.GameScreen.Cam.TargetPos = offset * 0.8f;
+ GameMain.GameScreen.Cam.TargetPos = Submarine.Loaded.Position + offset * 0.8f;
//Game1.GameScreen.Cam.MoveCamera((float)deltaTime);
messageBox.Text = endMessage + "\nReturning to lobby in " + (int)secondsLeft + " s";
@@ -751,7 +751,7 @@ namespace Barotrauma.Networking
continue;
}
- Character character = Character.Create(ch, position, !isMyCharacter);
+ Character character = Character.Create(ch, position, !isMyCharacter, false);
character.ID = ID;
diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs
index 17b01c8fd..18cdf275b 100644
--- a/Subsurface/Source/Networking/GameServer.cs
+++ b/Subsurface/Source/Networking/GameServer.cs
@@ -709,12 +709,21 @@ namespace Barotrauma.Networking
return false;
}
- GameMain.ShowLoading(StartGame(selectedSub), false);
+ GameModePreset selectedMode = Voting.HighestVoted(VoteType.Mode, ConnectedClients);
+ if (selectedMode == null) selectedMode = GameMain.NetLobbyScreen.SelectedMode;
+
+ if (selectedMode==null)
+ {
+ GameMain.NetLobbyScreen.ModeList.Flash();
+ return false;
+ }
+
+ GameMain.ShowLoading(StartGame(selectedSub, selectedMode), false);
return true;
}
- private IEnumerable