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 StartGame(Submarine selectedSub) + private IEnumerable StartGame(Submarine selectedSub, GameModePreset selectedMode) { GUIMessageBox.CloseAll(); @@ -722,10 +731,7 @@ namespace Barotrauma.Networking roundStartSeed = DateTime.Now.Millisecond; Rand.SetSyncedSeed(roundStartSeed); - - GameModePreset selectedMode = Voting.HighestVoted(VoteType.Mode, ConnectedClients); - if (selectedMode==null) selectedMode=GameMain.NetLobbyScreen.SelectedMode; - + GameMain.GameSession = new GameSession(selectedSub, "", selectedMode); GameMain.GameSession.StartShift(GameMain.NetLobbyScreen.LevelSeed); @@ -757,13 +763,13 @@ namespace Barotrauma.Networking for (int i = 0; i < ConnectedClients.Count; i++) { ConnectedClients[i].Character = Character.Create( - ConnectedClients[i].characterInfo, assignedWayPoints[i].WorldPosition, true); + ConnectedClients[i].characterInfo, assignedWayPoints[i].WorldPosition, true, false); ConnectedClients[i].Character.GiveJobItems(assignedWayPoints[i]); } if (characterInfo != null) { - myCharacter = Character.Create(characterInfo, assignedWayPoints[assignedWayPoints.Length - 1].WorldPosition); + myCharacter = Character.Create(characterInfo, assignedWayPoints[assignedWayPoints.Length - 1].WorldPosition, false, false); Character.Controlled = myCharacter; myCharacter.GiveJobItems(assignedWayPoints[assignedWayPoints.Length - 1]); @@ -782,7 +788,7 @@ namespace Barotrauma.Networking gameStarted = true; - GameMain.GameScreen.Cam.TargetPos = Vector2.Zero; + GameMain.GameScreen.Cam.TargetPos = Submarine.Loaded.Position; GameMain.GameScreen.Select(); @@ -876,7 +882,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"; diff --git a/Subsurface/Source/Physics/PhysicsBody.cs b/Subsurface/Source/Physics/PhysicsBody.cs index 1f1a81d1e..ccb60628d 100644 --- a/Subsurface/Source/Physics/PhysicsBody.cs +++ b/Subsurface/Source/Physics/PhysicsBody.cs @@ -115,6 +115,11 @@ namespace Barotrauma get { return body.Position; } } + public Vector2 PrevPosition + { + get { return prevPosition; } + } + public float Rotation { get { return body.Rotation; } diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index 1e8195cf7..56d0073f9 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -15,7 +15,7 @@ namespace Barotrauma readonly RenderTarget2D renderTargetWater; readonly RenderTarget2D renderTargetAir; - public BackgroundSpriteManager BackgroundSpriteManager; + public BackgroundCreatureManager BackgroundCreatureManager; public Camera Cam { @@ -32,13 +32,15 @@ namespace Barotrauma renderTargetAir = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight); - BackgroundSpriteManager = new BackgroundSpriteManager("Content/BackgroundSprites/BackgroundSpritePrefabs.xml"); + BackgroundCreatureManager = new BackgroundCreatureManager("Content/BackgroundSprites/BackgroundCreaturePrefabs.xml"); } public override void Select() { base.Select(); + if (Submarine.Loaded != null) cam.TargetPos = Submarine.Loaded.Position; + foreach (MapEntity entity in MapEntity.mapEntityList) entity.IsHighlighted = false; } @@ -83,7 +85,7 @@ namespace Barotrauma Character.UpdateAll(cam, (float)deltaTime); - BackgroundSpriteManager.Update(cam, (float)deltaTime); + BackgroundCreatureManager.Update(cam, (float)deltaTime); GameMain.ParticleManager.Update((float)deltaTime); @@ -180,7 +182,7 @@ namespace Barotrauma graphics.SetRenderTarget(renderTarget); graphics.Clear(new Color(11, 18, 26, 255)); - if (Level.Loaded != null) Level.Loaded.DrawBack(spriteBatch, cam, BackgroundSpriteManager); + if (Level.Loaded != null) Level.Loaded.DrawBack(spriteBatch, cam, BackgroundCreatureManager); spriteBatch.Begin(SpriteSortMode.BackToFront, diff --git a/Subsurface/Source/Screens/NetLobbyScreen.cs b/Subsurface/Source/Screens/NetLobbyScreen.cs index 6d8ca83df..0f3b75914 100644 --- a/Subsurface/Source/Screens/NetLobbyScreen.cs +++ b/Subsurface/Source/Screens/NetLobbyScreen.cs @@ -101,9 +101,9 @@ namespace Barotrauma private set { if (levelSeed == value) return; - backgroundSprite = LocationType.Random(LevelSeed).Background; levelSeed = value; + backgroundSprite = LocationType.Random(levelSeed).Background; seedBox.Text = levelSeed; } } @@ -277,8 +277,6 @@ namespace Barotrauma public override void Deselect() { textBox.Deselect(); - - seedBox.Text = ToolBox.RandomSeed(8); } public override void Select() @@ -326,18 +324,18 @@ namespace Barotrauma banListButton.OnClicked = GameMain.Server.BanList.ToggleBanFrame; banListButton.UserData = "banListButton"; - if (subList.CountChildren > 0 && subList.Selected == null) subList.Select(-1); - if (GameModePreset.list.Count > 0 && modeList.Selected == null) modeList.Select(-1); + if (subList.CountChildren > 0 && subList.Selected == null) subList.Select(0); + if (GameModePreset.list.Count > 0 && modeList.Selected == null) modeList.Select(0); if (myPlayerFrame.children.Find(c => c.UserData as string == "playyourself") == null) { - var playYourself = new GUITickBox(new Rectangle(-10, -10, 20, 20), "Play yourself", Alignment.TopLeft, myPlayerFrame); + var playYourself = new GUITickBox(new Rectangle(0, -10, 20, 20), "Play yourself", Alignment.TopLeft, myPlayerFrame); playYourself.Selected = GameMain.Server.CharacterInfo != null; playYourself.OnSelected = TogglePlayYourself; playYourself.UserData = "playyourself"; } - if (GameMain.Server.RandomizeSeed) seedBox.Text = ToolBox.RandomSeed(8); + if (GameMain.Server.RandomizeSeed) LevelSeed = ToolBox.RandomSeed(8); if (GameMain.Server.SubSelectionMode == SelectionMode.Random) subList.Select(Rand.Range(0,subList.CountChildren)); if (GameMain.Server.ModeSelectionMode == SelectionMode.Random) modeList.Select(Rand.Range(0, modeList.CountChildren)); } @@ -364,7 +362,7 @@ namespace Barotrauma if (IsServer && GameMain.Server != null) { - var playYourself = new GUITickBox(new Rectangle(-10, -10, 20, 20), "Play yourself", Alignment.TopLeft, myPlayerFrame); + var playYourself = new GUITickBox(new Rectangle(0, -10, 20, 20), "Play yourself", Alignment.TopLeft, myPlayerFrame); playYourself.Selected = GameMain.Server.CharacterInfo != null; playYourself.OnSelected = TogglePlayYourself; playYourself.UserData = "playyourself"; @@ -743,6 +741,8 @@ namespace Barotrauma GameModePreset modePreset = obj as GameModePreset; if (modePreset == null) return false; + if (GameMain.Server != null) GameMain.Server.UpdateNetLobby(obj); + return true; } @@ -886,11 +886,11 @@ namespace Barotrauma //msg.Write(AllowSubVoting); //msg.Write(AllowModeVoting); - msg.Write(modeList.SelectedIndex-1); + msg.Write(modeList.SelectedIndex); //msg.Write(durationBar.BarScroll); msg.Write(LevelSeed); - msg.Write(GameMain.Server==null ? false : GameMain.Server.AutoRestart); + msg.Write(GameMain.Server == null ? false : GameMain.Server.AutoRestart); msg.Write(GameMain.Server == null ? 0.0f : GameMain.Server.AutoRestartTimer); msg.Write((byte)(playerList.CountChildren)); @@ -907,7 +907,7 @@ namespace Barotrauma int modeIndex = 0; //float durationScroll = 0.0f; - string levelSeed = ""; + string newSeed = ""; bool autoRestart = false; @@ -928,7 +928,7 @@ namespace Barotrauma //durationScroll = msg.ReadFloat(); - levelSeed = msg.ReadString(); + newSeed = msg.ReadString(); autoRestart = msg.ReadBoolean(); restartTimer = msg.ReadFloat(); @@ -956,7 +956,7 @@ namespace Barotrauma //durationBar.BarScroll = durationScroll; - LevelSeed = levelSeed; + LevelSeed = newSeed; } } diff --git a/Subsurface/Source/Sounds/Sound.cs b/Subsurface/Source/Sounds/Sound.cs index 219e9b7f6..694d053c0 100644 --- a/Subsurface/Source/Sounds/Sound.cs +++ b/Subsurface/Source/Sounds/Sound.cs @@ -183,7 +183,6 @@ namespace Barotrauma public int Loop(int sourceIndex, float baseVolume, Vector2 position, float range) { - Vector2 relativePos = GetRelativePosition(position); float volume = GetVolume(relativePos, range, baseVolume); @@ -258,7 +257,7 @@ namespace Barotrauma if (s.oggSound == oggSound) return; } - System.Diagnostics.Debug.WriteLine("Removing sound " + filePath + " (buffer id" + AlBufferId + ")"); + //System.Diagnostics.Debug.WriteLine("Removing sound " + filePath + " (buffer id" + AlBufferId + ")"); SoundManager.ClearAlSource(AlBufferId); oggSound.Dispose(); diff --git a/Subsurface/Source/Utils/MathUtils.cs b/Subsurface/Source/Utils/MathUtils.cs index 1f2135e57..edf3d6a6a 100644 --- a/Subsurface/Source/Utils/MathUtils.cs +++ b/Subsurface/Source/Utils/MathUtils.cs @@ -205,7 +205,7 @@ namespace Barotrauma return (cornerDistanceSq <= (radius * radius)); } - + /// /// divide a convex hull into triangles /// diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index 6e06c07fa..8be54eb46 100644 Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ