diff --git a/.vs/Subsurface_Solution/v14/.suo b/.vs/Subsurface_Solution/v14/.suo index da95ab367..7133c7cba 100644 Binary files a/.vs/Subsurface_Solution/v14/.suo and b/.vs/Subsurface_Solution/v14/.suo differ 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 1f9407652..a71ff7337 100644 --- a/Subsurface/Content/Characters/Coelanth/coelanth.xml +++ b/Subsurface/Content/Characters/Coelanth/coelanth.xml @@ -15,7 +15,7 @@ - + @@ -54,5 +54,5 @@ - + \ No newline at end of file diff --git a/Subsurface/Content/Map/iceWall.png b/Subsurface/Content/Map/iceWall.png new file mode 100644 index 000000000..e5ad5fd10 Binary files /dev/null and b/Subsurface/Content/Map/iceWall.png differ diff --git a/Subsurface/Content/UI/style.xml b/Subsurface/Content/UI/style.xml index 0a0b09c89..0f7a74e6e 100644 --- a/Subsurface/Content/UI/style.xml +++ b/Subsurface/Content/UI/style.xml @@ -9,8 +9,7 @@ hovercolor="0.8, 0.8, 0.8, 1.0" selectedcolor="1.0, 0.82, 0.05, 1.0" - outlinecolor="0.5, 0.57, 0.6, 1.0"> - + outlinecolor="0.5, 0.57, 0.6, 1.0"> + + + \ No newline at end of file diff --git a/Subsurface/Source/Camera.cs b/Subsurface/Source/Camera.cs index d483da785..c17ff9d94 100644 --- a/Subsurface/Source/Camera.cs +++ b/Subsurface/Source/Camera.cs @@ -148,16 +148,17 @@ namespace Barotrauma Matrix.CreateScale(new Vector3(interpolatedZoom, interpolatedZoom, 1)) * viewMatrix; - prevPosition = position; - prevZoom = zoom; + Sound.CameraPos = new Vector3(WorldViewCenter.X, WorldViewCenter.Y, 0.0f); - } - + public void MoveCamera(float deltaTime) - { + { + prevPosition = position; + prevZoom = zoom; + float moveSpeed = 20.0f/zoom; Vector2 moveCam = Vector2.Zero; @@ -173,6 +174,11 @@ namespace Barotrauma if (PlayerInput.KeyDown(Keys.S)) moveCam.Y -= moveSpeed; if (PlayerInput.KeyDown(Keys.W)) moveCam.Y += moveSpeed; + if (Submarine.Loaded!=null && Screen.Selected == GameMain.GameScreen) + { + moveCam += FarseerPhysics.ConvertUnits.ToDisplayUnits(Submarine.Loaded.Velocity*deltaTime); + } + moveCam = moveCam * deltaTime * 60.0f; } @@ -210,6 +216,7 @@ namespace Barotrauma public Vector2 Position { get { return position; } + set { position = value; } } public Vector2 ScreenToWorld(Vector2 coords) diff --git a/Subsurface/Source/Characters/AI/AITarget.cs b/Subsurface/Source/Characters/AI/AITarget.cs index b4f0f3af6..868468704 100644 --- a/Subsurface/Source/Characters/AI/AITarget.cs +++ b/Subsurface/Source/Characters/AI/AITarget.cs @@ -27,6 +27,11 @@ namespace Barotrauma set { sightRange = value; } } + public Vector2 WorldPosition + { + get { return Entity.WorldPosition; } + } + public Vector2 SimPosition { get { return Entity.SimPosition; } diff --git a/Subsurface/Source/Characters/AI/EnemyAIController.cs b/Subsurface/Source/Characters/AI/EnemyAIController.cs index 3c6d2c4b4..5e5b97bb3 100644 --- a/Subsurface/Source/Characters/AI/EnemyAIController.cs +++ b/Subsurface/Source/Characters/AI/EnemyAIController.cs @@ -64,6 +64,8 @@ namespace Barotrauma public EnemyAIController(Character c, string file) : base(c) { + if (GameMain.Client != null && GameMain.Server == null) c.Enabled = false; + targetMemories = new Dictionary(); XDocument doc = ToolBox.TryLoadXml(file); @@ -167,12 +169,17 @@ namespace Barotrauma selectedTargetMemory.Priority -= deltaTime; - Vector2 attackPosition = selectedAiTarget.SimPosition; - if (wallAttackPos != Vector2.Zero) attackPosition = wallAttackPos; + Vector2 attackSimPosition = Character.Submarine==null ? ConvertUnits.ToSimUnits(selectedAiTarget.WorldPosition) : selectedAiTarget.SimPosition; + if (wallAttackPos != Vector2.Zero && targetEntity != null) + { + attackSimPosition = wallAttackPos; + + if (selectedAiTarget.Entity != null && Character.Submarine==null && selectedAiTarget.Entity.Submarine != null) attackSimPosition += ConvertUnits.ToSimUnits(selectedAiTarget.Entity.Submarine.Position); + } if (coolDownTimer>0.0f) { - UpdateCoolDown(attackPosition, deltaTime); + UpdateCoolDown(attackSimPosition, deltaTime); return; } @@ -187,7 +194,8 @@ namespace Barotrauma raycastTimer = RaycastInterval; } - steeringManager.SteeringSeek(attackPosition); + steeringManager.SteeringAvoid(deltaTime, 1.0f); + steeringManager.SteeringSeek(attackSimPosition); //check if any of the limbs is close enough to attack the target if (attackingLimb == null) @@ -195,7 +203,7 @@ namespace Barotrauma foreach (Limb limb in Character.AnimController.Limbs) { if (limb.attack==null || limb.attack.Type == AttackType.None) continue; - if (Vector2.Distance(limb.SimPosition, attackPosition) > limb.attack.Range) continue; + if (ConvertUnits.ToDisplayUnits(Vector2.Distance(limb.SimPosition, attackSimPosition)) > limb.attack.Range) continue; attackingLimb = limb; break; @@ -203,7 +211,7 @@ namespace Barotrauma return; } - UpdateLimbAttack(deltaTime, attackingLimb, attackPosition); + UpdateLimbAttack(deltaTime, attackingLimb, attackSimPosition); } @@ -230,9 +238,19 @@ namespace Barotrauma private void GetTargetEntity() { targetEntity = null; + + + + //check if there's a wall between the target and the Character - Vector2 rayStart = Character.AnimController.Limbs[0].SimPosition; + Vector2 rayStart = Character.SimPosition; Vector2 rayEnd = selectedAiTarget.SimPosition; + + if (selectedAiTarget.Entity.Submarine!=null && Character.Submarine==null) + { + rayStart -= ConvertUnits.ToSimUnits(selectedAiTarget.Entity.Submarine.Position); + } + Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd); if (Submarine.LastPickedFraction == 1.0f || closestBody == null) @@ -245,6 +263,8 @@ namespace Barotrauma if (wall == null) { wallAttackPos = Submarine.LastPickedPosition; + if (selectedAiTarget.Entity.Submarine!=null) wallAttackPos -= ConvertUnits.ToSimUnits(selectedAiTarget.Entity.Submarine.Position); + } else { @@ -261,6 +281,7 @@ namespace Barotrauma if (wall.SectionDamage(i) > sectionDamage) sectionIndex = i; } wallAttackPos = wall.SectionPosition(sectionIndex); + //if (wall.Submarine != null) wallAttackPos += wall.Submarine.Position; wallAttackPos = ConvertUnits.ToSimUnits(wallAttackPos); } @@ -288,15 +309,8 @@ namespace Barotrauma float dir = (limb.attack.Type == AttackType.PinchCW) ? 1.0f : -1.0f; - if (wallAttackPos != Vector2.Zero && targetEntity != null) - { - damageTarget = targetEntity as IDamageable; - } - else - { - damageTarget = selectedAiTarget.Entity as IDamageable; - } - + damageTarget = (wallAttackPos != Vector2.Zero && targetEntity != null) ? targetEntity : selectedAiTarget.Entity as IDamageable; + attackTimer += deltaTime*0.05f; if (damageTarget == null) @@ -305,13 +319,13 @@ namespace Barotrauma break; } - float dist = Vector2.Distance(limb.SimPosition, damageTarget.SimPosition); + float dist = ConvertUnits.ToDisplayUnits(Vector2.Distance(limb.SimPosition, attackPosition)); if (dist < limb.attack.Range * 0.5f) { attackTimer += deltaTime; limb.body.ApplyTorque(limb.Mass * 50.0f * Character.AnimController.Dir * dir); - - limb.attack.DoDamage(Character, damageTarget, limb.SimPosition, deltaTime, (limb.soundTimer <= 0.0f)); + + limb.attack.DoDamage(Character, damageTarget, limb.WorldPosition, deltaTime, (limb.soundTimer <= 0.0f)); limb.soundTimer = Limb.SoundInterval; } @@ -392,9 +406,8 @@ namespace Barotrauma } dist = Vector2.Distance( - character.AnimController.Limbs[0].SimPosition, - target.SimPosition); - dist = ConvertUnits.ToDisplayUnits(dist); + character.WorldPosition, + target.WorldPosition); AITargetMemory targetMemory = FindTargetMemory(target); @@ -406,6 +419,11 @@ namespace Barotrauma Vector2 rayStart = character.AnimController.Limbs[0].SimPosition; Vector2 rayEnd = target.SimPosition; + if (target.Entity.Submarine != null && character.Submarine==null) + { + rayStart -= ConvertUnits.ToSimUnits(target.Entity.Submarine.Position); + } + Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd); Structure closestStructure = (closestBody == null) ? null : closestBody.UserData as Structure; @@ -490,12 +508,12 @@ namespace Barotrauma { if (Character.IsDead) return; - Vector2 pos = Character.Position; + Vector2 pos = Character.WorldPosition; pos.Y = -pos.Y; if (selectedAiTarget!=null) { - GUI.DrawLine(spriteBatch, pos, ConvertUnits.ToDisplayUnits(new Vector2(selectedAiTarget.SimPosition.X, -selectedAiTarget.SimPosition.Y)), Color.Red); + GUI.DrawLine(spriteBatch, pos, new Vector2(selectedAiTarget.WorldPosition.X, -selectedAiTarget.WorldPosition.Y), Color.Red); if (wallAttackPos!=Vector2.Zero) { diff --git a/Subsurface/Source/Characters/AI/HumanAIController.cs b/Subsurface/Source/Characters/AI/HumanAIController.cs index 6ab49fa46..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) @@ -87,7 +89,9 @@ namespace Barotrauma { if (selectedAiTarget != null) { - GUI.DrawLine(spriteBatch, new Vector2(Character.Position.X, -Character.Position.Y), ConvertUnits.ToDisplayUnits(new Vector2(selectedAiTarget.SimPosition.X, -selectedAiTarget.SimPosition.Y)), Color.Red); + GUI.DrawLine(spriteBatch, + new Vector2(Character.WorldPosition.X, -Character.WorldPosition.Y), + new Vector2(selectedAiTarget.WorldPosition.X, -selectedAiTarget.WorldPosition.Y), Color.Red); } IndoorsSteeringManager pathSteering = steeringManager as IndoorsSteeringManager; diff --git a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs index f0f0e90c4..cd54819d7 100644 --- a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.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 1c2b2c4cb..5f3f9b724 100644 --- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs +++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs @@ -31,6 +31,11 @@ namespace Barotrauma var pathSteering = character.AIController.SteeringManager as IndoorsSteeringManager; + if (pathSteering==null) + { + return; + } + if (newTargetTimer <= 0.0f) { currentTarget = FindRandomTarget(); @@ -54,15 +59,19 @@ namespace Barotrauma (pathSteering.CurrentPath.NextNode == null || pathSteering.CurrentPath.Unreachable))) { //steer away from edges of the hull - if (character.Position.X < character.AnimController.CurrentHull.Rect.X + WallAvoidDistance) + if (character.AnimController.CurrentHull!=null) { - pathSteering.SteeringManual(deltaTime, Vector2.UnitX); - } - else if (character.Position.X > character.AnimController.CurrentHull.Rect.Right - WallAvoidDistance) - { - pathSteering.SteeringManual(deltaTime, -Vector2.UnitX); + if (character.Position.X < character.AnimController.CurrentHull.Rect.X + WallAvoidDistance) + { + pathSteering.SteeringManual(deltaTime, Vector2.UnitX*5.0f); + } + else if (character.Position.X > character.AnimController.CurrentHull.Rect.Right - WallAvoidDistance) + { + pathSteering.SteeringManual(deltaTime, -Vector2.UnitX); + } } + character.AIController.SteeringManager.SteeringWander(1.0f); return; } @@ -80,8 +89,8 @@ namespace Barotrauma foreach (WayPoint wp in WayPoint.WayPointList) { - if (wp.SpawnType != SpawnType.Human) continue; - + if (wp.SpawnType != SpawnType.Human || wp.CurrentHull==null) continue; + foreach (string tag in wp.IdCardTags) { if (idCard.HasTag(tag)) return wp.CurrentHull.AiTarget; 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/AI/PathFinder.cs b/Subsurface/Source/Characters/AI/PathFinder.cs index 9f8b8cb5d..d6ccf8b9e 100644 --- a/Subsurface/Source/Characters/AI/PathFinder.cs +++ b/Subsurface/Source/Characters/AI/PathFinder.cs @@ -218,7 +218,7 @@ namespace Barotrauma //a node that hasn't been searched yet if (nextNode.state==0) { - nextNode.H = Vector2.DistanceSquared(nextNode.Position,end.Position); + nextNode.H = Vector2.Distance(nextNode.Position,end.Position); if (GetNodePenalty != null) { diff --git a/Subsurface/Source/Characters/AI/SteeringManager.cs b/Subsurface/Source/Characters/AI/SteeringManager.cs index 92962fbc6..d523e492e 100644 --- a/Subsurface/Source/Characters/AI/SteeringManager.cs +++ b/Subsurface/Source/Characters/AI/SteeringManager.cs @@ -144,11 +144,14 @@ namespace Barotrauma avoidSteering = Vector2.Normalize(Submarine.LastPickedPosition - obstaclePosition); } - else + else if (closestBody.UserData is Item) { Item item = closestBody.UserData as Item; - if (item != null) avoidSteering = Vector2.Normalize(Submarine.LastPickedPosition - item.SimPosition); - + avoidSteering = Vector2.Normalize(Submarine.LastPickedPosition - item.SimPosition); + } + else + { + avoidSteering = Vector2.Normalize(host.SimPosition - Submarine.LastPickedPosition); } } diff --git a/Subsurface/Source/Characters/AICharacter.cs b/Subsurface/Source/Characters/AICharacter.cs index ba52cab67..6f500ffbb 100644 --- a/Subsurface/Source/Characters/AICharacter.cs +++ b/Subsurface/Source/Characters/AICharacter.cs @@ -42,7 +42,7 @@ namespace Barotrauma public AICharacter(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false) : base(file, position, characterInfo, isNetworkPlayer) { - if (GameMain.Client != null && GameMain.Server == null) Enabled = false; + soundInterval = Rand.Range(0.0f, soundInterval); } public void SetAI(AIController aiController) @@ -94,15 +94,14 @@ namespace Barotrauma case NetworkEventType.KillCharacter: return true; case NetworkEventType.ImportantEntityUpdate: - int i = 0; //foreach (Limb limb in AnimController.Limbs) //{ //if (RefLimb.ignoreCollisions) continue; - if (AnimController.RefLimb.SimPosition.Length() > NetConfig.CharacterIgnoreDistance) return false; + if ((AnimController.RefLimb.SimPosition - Submarine.Loaded.SimPosition).Length() > NetConfig.CharacterIgnoreDistance) return false; - message.WriteRangedSingle(AnimController.RefLimb.SimPosition.X, -NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16); - message.WriteRangedSingle(AnimController.RefLimb.SimPosition.Y, -NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16); + message.Write(AnimController.RefLimb.SimPosition.X); + message.Write(AnimController.RefLimb.SimPosition.Y); message.Write(AnimController.RefLimb.Rotation); @@ -115,14 +114,23 @@ namespace Barotrauma aiController.FillNetworkData(message); return true; case NetworkEventType.EntityUpdate: - if (AnimController.RefLimb.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); message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.X, -1.0f, 1.0f), -1.0f, 1.0f, 8); - message.WriteRangedSingle(AnimController.RefLimb.SimPosition.X, -NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16); - message.WriteRangedSingle(AnimController.RefLimb.SimPosition.Y, -NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16); + message.Write(AnimController.RefLimb.SimPosition.X); + message.Write(AnimController.RefLimb.SimPosition.Y); return true; } @@ -150,8 +158,8 @@ namespace Barotrauma try { - limbPos.X = message.ReadRangedSingle(-NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16); - limbPos.Y = message.ReadRangedSingle(-NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16); + limbPos.X = message.ReadFloat(); + limbPos.Y = message.ReadFloat(); rotation = message.ReadFloat(); } @@ -197,8 +205,8 @@ namespace Barotrauma targetMovement.X = message.ReadRangedSingle(-1.0f, 1.0f, 8); targetMovement.Y = message.ReadRangedSingle(-1.0f, 1.0f, 8); - pos.X = message.ReadRangedSingle(-NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16); - pos.Y = message.ReadRangedSingle(-NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16); + pos.X = message.ReadFloat(); + pos.Y = message.ReadFloat(); //vel.X = message.ReadFloat(); //vel.Y = message.ReadFloat(); diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index 8d3ab1458..513b08e6a 100644 --- a/Subsurface/Source/Characters/Animation/Ragdoll.cs +++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs @@ -152,7 +152,17 @@ namespace Barotrauma public Hull CurrentHull { - get { return currentHull;} + get { return currentHull; } + set + { + if (value == currentHull) return; + + currentHull = value; + foreach (Limb limb in Limbs) + { + limb.body.Submarine = currentHull == null ? null : Submarine.Loaded; + } + } } public bool IgnorePlatforms @@ -378,14 +388,14 @@ namespace Barotrauma float volume = stairs == null ? impact/5.0f : impact; volume= Math.Min(impact, 1.0f); - if (impact > 0.8f && l.HitSound != null && l.soundTimer <= 0.0f) l.HitSound.Play(volume, impact * 100.0f, l.body.FarseerBody); + if (impact > 0.8f && l.HitSound != null && l.soundTimer <= 0.0f) l.HitSound.Play(volume, impact * 100.0f, l.WorldPosition); if (impact > l.impactTolerance) { character.Health -= (impact - l.impactTolerance * 0.1f); strongestImpact = Math.Max(strongestImpact, impact - l.impactTolerance); - SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, strongestImpact, l.body.FarseerBody); + SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, strongestImpact, l.body); if (Character.Controlled == character) GameMain.GameScreen.Cam.Shake = strongestImpact; } @@ -526,16 +536,28 @@ namespace Barotrauma } } - public void FindHull() + public void FindHull(Vector2? worldPosition = null, bool setSubmarine = true) { - Hull newHull = Hull.FindHull( - ConvertUnits.ToDisplayUnits(refLimb.SimPosition), - currentHull); + Vector2 findPos = worldPosition==null ? refLimb.WorldPosition : (Vector2)worldPosition; + Hull newHull = Hull.FindHull(findPos, currentHull); + if (newHull == currentHull) return; - currentHull = newHull; - + if (setSubmarine) + { + if (newHull == null && currentHull.Submarine != null) + { + SetPosition(refLimb.SimPosition + ConvertUnits.ToSimUnits(currentHull.Submarine.Position)); + } + else if (currentHull == null && newHull != null && newHull.Submarine != null) + { + SetPosition(refLimb.SimPosition - ConvertUnits.ToSimUnits(newHull.Submarine.Position)); + } + } + + CurrentHull = newHull; + UpdateCollisionCategories(); } @@ -597,11 +619,9 @@ namespace Barotrauma foreach (Limb limb in Limbs) { - Vector2 limbPosition = ConvertUnits.ToDisplayUnits(limb.SimPosition); - //find the room which the limb is in //the room where the ragdoll is in is used as the "guess", meaning that it's checked first - Hull limbHull = Hull.FindHull(limbPosition, currentHull); + Hull limbHull = Hull.FindHull(limb.WorldPosition, currentHull); bool prevInWater = limb.inWater; limb.inWater = false; @@ -611,9 +631,9 @@ namespace Barotrauma //limb isn't in any room -> it's in the water limb.inWater = true; } - else if (limbHull.Volume > 0.0f && Submarine.RectContains(limbHull.Rect, limbPosition)) - { - if (limbPosition.Y < limbHull.Surface) + else if (limbHull.Volume > 0.0f && Submarine.RectContains(limbHull.Rect, limb.Position)) + { + if (limb.Position.Y < limbHull.Surface) { limb.inWater = true; @@ -637,12 +657,12 @@ namespace Barotrauma //create a splash particle GameMain.ParticleManager.CreateParticle("watersplash", - new Vector2(limb.Position.X, limbHull.Surface), + new Vector2(limb.Position.X, limbHull.Surface) + limbHull.Submarine.Position, new Vector2(0.0f, Math.Abs(-limb.LinearVelocity.Y * 10.0f)), 0.0f, limbHull); - + GameMain.ParticleManager.CreateParticle("bubbles", - new Vector2(limb.Position.X, limbHull.Surface), + new Vector2(limb.Position.X, limbHull.Surface) + limbHull.Submarine.Position, limb.LinearVelocity*0.001f, 0.0f, limbHull); @@ -656,7 +676,7 @@ namespace Barotrauma float parallel = (float)Math.Abs(Math.Sin(limb.Rotation)); Vector2 impulse = Vector2.Multiply(limb.LinearVelocity, -parallel * limb.Mass); //limb.body.ApplyLinearImpulse(impulse); - int n = (int)((limbPosition.X - limbHull.Rect.X) / Hull.WaveWidth); + int n = (int)((limb.Position.X - limbHull.Rect.X) / Hull.WaveWidth); limbHull.WaveVel[n] = Math.Min(impulse.Y * 1.0f, 5.0f); StrongestImpact = ((impulse.Length() * 0.5f) - limb.impactTolerance); } diff --git a/Subsurface/Source/Characters/Attack.cs b/Subsurface/Source/Characters/Attack.cs index fd7f06ce2..530981cc7 100644 --- a/Subsurface/Source/Characters/Attack.cs +++ b/Subsurface/Source/Characters/Attack.cs @@ -109,7 +109,7 @@ namespace Barotrauma sound = Sound.Load(soundPath); } - Range = FarseerPhysics.ConvertUnits.ToSimUnits(ToolBox.GetAttributeFloat(element, "range", 0.0f)); + Range = ToolBox.GetAttributeFloat(element, "range", 0.0f); Duration = ToolBox.GetAttributeFloat(element, "duration", 0.0f); @@ -122,7 +122,7 @@ namespace Barotrauma } - public AttackResult DoDamage(IDamageable attacker, IDamageable target, Vector2 position, float deltaTime, bool playSound = true) + public AttackResult DoDamage(IDamageable attacker, IDamageable target, Vector2 worldPosition, float deltaTime, bool playSound = true) { float damageAmount = 0.0f; //DamageSoundType damageSoundType = DamageSoundType.None; @@ -139,15 +139,15 @@ namespace Barotrauma if (particleEmitterPrefab != null) { - particleEmitterPrefab.Emit(position); + particleEmitterPrefab.Emit(worldPosition); } if (sound != null) { - sound.Play(1.0f, 500.0f, position); + sound.Play(1.0f, 500.0f, worldPosition); } - return target.AddDamage(attacker, position, this, deltaTime, playSound); + return target.AddDamage(attacker, worldPosition, this, deltaTime, playSound); } } diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSprite.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundCreature.cs similarity index 80% rename from Subsurface/Source/Characters/BackgroundSprite/BackgroundSprite.cs rename to Subsurface/Source/Characters/BackgroundSprite/BackgroundCreature.cs index a13f75f2d..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,13 +53,13 @@ namespace Barotrauma set; } - public BackgroundSprite(BackgroundSpritePrefab prefab, Vector2 position) + public BackgroundCreature(BackgroundCreaturePrefab prefab, Vector2 position) { this.prefab = prefab; this.position = position; - drawPosition = position + Level.Loaded.Position; + drawPosition = position; steeringManager = new SteeringManager(this); @@ -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); @@ -153,15 +141,15 @@ namespace Barotrauma if (velocity.X < 0.0f) rotation -= MathHelper.Pi; } - if (Level.Loaded != null) drawPosition = position + Level.Loaded.Position; + drawPosition = position;// +Level.Loaded.Position; if (depth > 0.0f) { Vector2 camOffset = drawPosition - GameMain.GameScreen.Cam.WorldViewCenter; - drawPosition = drawPosition - camOffset * (depth / MaxDepth) * 0.05f; + drawPosition -= camOffset * (depth / MaxDepth) * 0.05f; } - + prefab.Sprite.Draw(spriteBatch, new Vector2(drawPosition.X, -drawPosition.Y), Color.Lerp(Color.White, Color.DarkBlue, (depth/MaxDepth)*0.3f), rotation, 1.0f - (depth / MaxDepth) * 0.2f, velocity.X > 0.0f ? SpriteEffects.None : SpriteEffects.FlipHorizontally, (depth / MaxDepth)); } @@ -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 410b119c2..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,92 +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 0) - { - WayPoint wp = WayPoint.WayPointList[Rand.Int(WayPoint.WayPointList.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 7918dbd66..6563a8ad3 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -138,6 +138,11 @@ namespace Barotrauma } } + public Vector2 CursorWorldPosition + { + get { return Submarine == null ? cursorPosition : cursorPosition + Submarine.Position; } + } + public Character ClosestCharacter { get { return closestCharacter; } @@ -273,38 +278,32 @@ namespace Barotrauma get { return AnimController.RefLimb.SimPosition; } } - public Vector2 Position + public override Vector2 Position { - get { return ConvertUnits.ToDisplayUnits(AnimController.RefLimb.SimPosition); } + get { return AnimController.RefLimb.Position; } } - + static Character() { - DeathMsg[(int)CauseOfDeath.Damage] = "succumbed to your injuries"; - DeathMsg[(int)CauseOfDeath.Bloodloss] = "bled out"; - DeathMsg[(int)CauseOfDeath.Drowning] = "drowned"; + DeathMsg[(int)CauseOfDeath.Damage] = "succumbed to your injuries"; + DeathMsg[(int)CauseOfDeath.Bloodloss] = "bled out"; + DeathMsg[(int)CauseOfDeath.Drowning] = "drowned"; DeathMsg[(int)CauseOfDeath.Suffocation] = "suffocated"; - DeathMsg[(int)CauseOfDeath.Pressure] = "been crushed by water pressure"; - DeathMsg[(int)CauseOfDeath.Burn] = "burnt to death"; + DeathMsg[(int)CauseOfDeath.Pressure] = "been crushed by water pressure"; + DeathMsg[(int)CauseOfDeath.Burn] = "burnt to death"; } public static Character Create(string file, Vector2 position) { return Create(file, position, null); } - - public static Character Create(CharacterInfo characterInfo, WayPoint spawnPoint, bool isNetworkPlayer = false) + + public static Character Create(CharacterInfo characterInfo, Vector2 position, bool isNetworkPlayer = false, bool hasAi=true) { - return Create(characterInfo.File, spawnPoint.SimPosition, characterInfo, isNetworkPlayer); + return Create(characterInfo.File, position, characterInfo, isNetworkPlayer, hasAi); } - - public static Character Create(CharacterInfo characterInfo, Vector2 position, bool isNetworkPlayer = false) - { - return Create(characterInfo.File, position, characterInfo, isNetworkPlayer); - } - - public static Character Create(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false) + public static Character Create(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false, bool hasAi=true) { if (file != humanConfigFile) { @@ -316,24 +315,25 @@ namespace Barotrauma } else { - if (isNetworkPlayer) - { - var netCharacter = new Character(file, position, characterInfo, isNetworkPlayer); - - return netCharacter; - } - 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); } } } protected Character(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false) + : base(null) { keys = new Key[Enum.GetNames(typeof(InputType)).Length]; @@ -342,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; @@ -392,7 +378,7 @@ namespace Barotrauma foreach (Limb limb in AnimController.Limbs) { - limb.body.SetTransform(position+limb.SimPosition, 0.0f); + limb.body.SetTransform(ConvertUnits.ToSimUnits(position)+limb.SimPosition, 0.0f); //limb.prevPosition = ConvertUnits.ToDisplayUnits(position); } @@ -442,7 +428,8 @@ namespace Barotrauma } } - AnimController.FindHull(); + AnimController.FindHull(null); + if (AnimController.CurrentHull != null) Submarine = AnimController.CurrentHull.Submarine; CharacterList.Add(this); @@ -522,7 +509,7 @@ namespace Barotrauma continue; } - Item item = new Item(itemPrefab, Position); + Item item = new Item(itemPrefab, Position, null); if (info.Job.EquipSpawnItem[i]) { @@ -734,7 +721,7 @@ namespace Barotrauma { Limb head = AnimController.GetLimb(LimbType.Head); - Lights.LightManager.ViewPos = ConvertUnits.ToDisplayUnits(head.SimPosition); + //Lights.LightManager.ViewPos = WorldPosition; if (!DisableControls) { @@ -757,8 +744,11 @@ namespace Barotrauma cam.OffsetAmount = MathHelper.Lerp(cam.OffsetAmount, 250.0f, 0.05f); } - cursorPosition = cam.ScreenToWorld(PlayerInput.MousePosition); + cursorPosition = cam.ScreenToWorld(PlayerInput.MousePosition); + if (AnimController.CurrentHull != null) cursorPosition -= Submarine.Loaded.Position; + Vector2 mouseSimPos = ConvertUnits.ToSimUnits(cursorPosition); + if (Vector2.Distance(AnimController.Limbs[0].SimPosition, mouseSimPos)>1.0f) { Body body = Submarine.PickBody(AnimController.Limbs[0].SimPosition, mouseSimPos); @@ -876,9 +866,11 @@ namespace Barotrauma { if (!Enabled) return; + Submarine = AnimController.CurrentHull == null ? null : Submarine.Loaded; + obstructVisionAmount = Math.Max(obstructVisionAmount - deltaTime, 0.0f); - AnimController.SimplePhysicsEnabled = (Character.controlled != this && Vector2.Distance(cam.WorldViewCenter, Position) > 5000.0f); + AnimController.SimplePhysicsEnabled = (Character.controlled != this && Vector2.Distance(cam.WorldViewCenter, WorldPosition) > 5000.0f); if (isDead) return; @@ -888,7 +880,7 @@ namespace Barotrauma if (Submarine.Loaded!=null && Level.Loaded !=null) { - protectedFromPressure = protectedFromPressure && (Position-Level.Loaded.Position).Y > SubmarineBody.DamageDepth; + protectedFromPressure = protectedFromPressure && Position.Y > SubmarineBody.DamageDepth; } if (!protectedFromPressure && @@ -976,7 +968,7 @@ namespace Barotrauma { if (!Enabled) return; - Vector2 pos = ConvertUnits.ToDisplayUnits(AnimController.Limbs[0].SimPosition); + Vector2 pos = AnimController.Limbs[0].WorldPosition; pos.Y = -pos.Y; if (this == controlled) return; @@ -998,7 +990,7 @@ namespace Barotrauma AnimController.DebugDraw(spriteBatch); } - Vector2 healthBarPos = new Vector2(Position.X - 50, -Position.Y - 100.0f); + Vector2 healthBarPos = new Vector2(DrawPosition.X - 50, -DrawPosition.Y - 100.0f); GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X - 2, (int)healthBarPos.Y - 2, 100 + 4, 15 + 4), Color.Black, false); GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X, (int)healthBarPos.Y, (int)(100.0f * (health / maxHealth)), 15), Color.Red, true); } @@ -1016,17 +1008,16 @@ namespace Barotrauma if (soundStates[i] != state) continue; if (n == selectedSound && sounds[i]!=null) { - sounds[i].Play(1.0f, 2000.0f, - AnimController.Limbs[0].body.FarseerBody); + sounds[i].Play(1.0f, 2000.0f, AnimController.Limbs[0].WorldPosition); return; } n++; } } - public virtual AttackResult AddDamage(IDamageable attacker, Vector2 simPosition, Attack attack, float deltaTime, bool playSound = false) + public virtual AttackResult AddDamage(IDamageable attacker, Vector2 worldPosition, Attack attack, float deltaTime, bool playSound = false) { - return AddDamage(simPosition, attack.DamageType, attack.GetDamage(deltaTime), attack.GetBleedingDamage(deltaTime), attack.Stun, playSound); + return AddDamage(worldPosition, attack.DamageType, attack.GetDamage(deltaTime), attack.GetBleedingDamage(deltaTime), attack.Stun, playSound); } public AttackResult AddDamage(Vector2 simPosition, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound) @@ -1091,17 +1082,17 @@ namespace Barotrauma // limb.Damage = 100.0f; } - SoundPlayer.PlayDamageSound(DamageSoundType.Implode, 50.0f, AnimController.RefLimb.body.FarseerBody); + SoundPlayer.PlayDamageSound(DamageSoundType.Implode, 50.0f, AnimController.RefLimb.body); for (int i = 0; i < 10; i++) { Particle p = GameMain.ParticleManager.CreateParticle("waterblood", - centerOfMass + Rand.Vector(50.0f), + ConvertUnits.ToDisplayUnits(centerOfMass) + Rand.Vector(50.0f), Vector2.Zero); if (p!=null) p.Size *= 2.0f; GameMain.ParticleManager.CreateParticle("bubbles", - centerOfMass + Rand.Vector(50.0f), + ConvertUnits.ToDisplayUnits(centerOfMass) + Rand.Vector(50.0f), new Vector2(Rand.Range(-50f, 50f), Rand.Range(-100f,50f))); } @@ -1256,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) @@ -1288,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); @@ -1324,10 +1297,14 @@ namespace Barotrauma message.Write(AnimController.Dir > 0.0f); } - if (AnimController.RefLimb.SimPosition.Length() > NetConfig.CharacterIgnoreDistance) return true; - - message.WriteRangedSingle(AnimController.RefLimb.SimPosition.X, -NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16); - message.WriteRangedSingle(AnimController.RefLimb.SimPosition.Y, -NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16); + message.Write(Submarine != null); + + //Vector2 position = Submarine == null ? SimPosition : SimPosition - Submarine.SimPosition; + + //if ((AnimController.RefLimb.SimPosition - Submarine.Loaded.SimPosition).Length() > NetConfig.CharacterIgnoreDistance) return true; + + message.Write(SimPosition.X); + message.Write(SimPosition.Y); return true; default: @@ -1492,17 +1469,21 @@ namespace Barotrauma #endif return; } - try - { - pos.X = message.ReadRangedSingle(-NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16); - pos.Y = message.ReadRangedSingle(-NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16); - } - catch + bool inSub = message.ReadBoolean(); + + pos.X = message.ReadFloat(); + pos.Y = message.ReadFloat(); + + if (inSub) { - //failed to read position, Character may be further than NetConfig.CharacterIgnoreDistance - pos = SimPosition; - } + Hull newHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(pos), AnimController.CurrentHull, false); + if (newHull != null) + { + AnimController.CurrentHull = newHull; + Submarine = newHull.Submarine; + } + } if (secondaryKeyState) { @@ -1514,7 +1495,8 @@ namespace Barotrauma cursorPosition = Position + new Vector2(1000.0f, 0.0f) * dir; } - AnimController.RefLimb.body.TargetPosition = AnimController.EstimateCurrPosition(pos, (float)(NetTime.Now + message.SenderConnection.RemoteTimeOffset) - sendingTime); + AnimController.RefLimb.body.TargetPosition = + AnimController.EstimateCurrPosition(pos, (float)(NetTime.Now + message.SenderConnection.RemoteTimeOffset) - sendingTime); LastNetworkUpdate = sendingTime; diff --git a/Subsurface/Source/Characters/CharacterHUD.cs b/Subsurface/Source/Characters/CharacterHUD.cs index d57d1e94c..6ffbf8868 100644 --- a/Subsurface/Source/Characters/CharacterHUD.cs +++ b/Subsurface/Source/Characters/CharacterHUD.cs @@ -54,7 +54,7 @@ namespace Barotrauma if (character.ClosestCharacter != null && (character.ClosestCharacter.IsDead || character.ClosestCharacter.Stun > 0.0f)) { - Vector2 startPos = character.Position + (character.ClosestCharacter.Position - character.Position) * 0.7f; + Vector2 startPos = character.DrawPosition + (character.ClosestCharacter.DrawPosition - character.DrawPosition) * 0.7f; startPos = cam.WorldToScreen(startPos); Vector2 textPos = startPos; @@ -67,7 +67,7 @@ namespace Barotrauma else if (character.SelectedCharacter == null && character.ClosestItem != null && character.SelectedConstruction == null) { - Vector2 startPos = character.Position + (character.ClosestItem.Position - character.Position) * 0.7f; + Vector2 startPos = character.DrawPosition + (character.ClosestItem.DrawPosition - character.DrawPosition) * 0.7f; startPos = cam.WorldToScreen(startPos); Vector2 textPos = startPos; @@ -96,10 +96,10 @@ namespace Barotrauma { int width = 100, height = 20; - drowningBar = new GUIProgressBar(new Rectangle(30, GameMain.GraphicsHeight - 200, width, height), Color.Blue, 1.0f); + drowningBar = new GUIProgressBar(new Rectangle(30, GameMain.GraphicsHeight - 200, width, height), Color.Blue, GUI.Style, 1.0f, Alignment.TopLeft); new GUIImage(new Rectangle(-27, -7, 20, 20), new Rectangle(17, 0, 20, 24), statusIcons, Alignment.TopLeft, drowningBar); - healthBar = new GUIProgressBar(new Rectangle(30, GameMain.GraphicsHeight - 230, width, height), Color.Red, 1.0f); + healthBar = new GUIProgressBar(new Rectangle(30, GameMain.GraphicsHeight - 230, width, height), Color.Red, GUI.Style, 1.0f, Alignment.TopLeft); new GUIImage(new Rectangle(-26, -7, 20, 20), new Rectangle(0, 0, 13, 24), statusIcons, Alignment.TopLeft, healthBar); } diff --git a/Subsurface/Source/Characters/Limb.cs b/Subsurface/Source/Characters/Limb.cs index f3e20b861..15ae58311 100644 --- a/Subsurface/Source/Characters/Limb.cs +++ b/Subsurface/Source/Characters/Limb.cs @@ -79,6 +79,11 @@ namespace Barotrauma get { return doesFlip; } } + public Vector2 WorldPosition + { + get { return character.Submarine == null ? Position : Position + character.Submarine.Position; } + } + public Vector2 Position { get { return ConvertUnits.ToDisplayUnits(body.SimPosition); } @@ -352,13 +357,13 @@ namespace Barotrauma if (particleVel != Vector2.Zero) particleVel = Vector2.Normalize(particleVel); GameMain.ParticleManager.CreateParticle("blood", - Position, + WorldPosition, particleVel * Rand.Range(100.0f, 300.0f), 0.0f, character.AnimController.CurrentHull); } for (int i = 0; i < bloodAmount / 2; i++) { - GameMain.ParticleManager.CreateParticle("waterblood", Position, Vector2.Zero, 0.0f, character.AnimController.CurrentHull); + GameMain.ParticleManager.CreateParticle("waterblood", WorldPosition, Vector2.Zero, 0.0f, character.AnimController.CurrentHull); } damage += Math.Max(amount,bleedingAmount) / character.MaxHealth * 100.0f; diff --git a/Subsurface/Source/Characters/StatusEffect.cs b/Subsurface/Source/Characters/StatusEffect.cs index da6786d54..0a0d3f6da 100644 --- a/Subsurface/Source/Characters/StatusEffect.cs +++ b/Subsurface/Source/Characters/StatusEffect.cs @@ -212,10 +212,10 @@ namespace Barotrauma protected virtual void Apply(float deltaTime, Entity entity, List targets) { - if (explosion != null) explosion.Explode(entity.SimPosition); + if (explosion != null) explosion.Explode(entity.WorldPosition); if (Fire) new FireSource(ConvertUnits.ToDisplayUnits(entity.SimPosition)); - if (sound != null) sound.Play(1.0f, 1000.0f, ConvertUnits.ToDisplayUnits(entity.SimPosition)); + if (sound != null) sound.Play(1.0f, 1000.0f, entity.WorldPosition); for (int i = 0; i < propertyNames.Count(); i++) { diff --git a/Subsurface/Source/CoroutineManager.cs b/Subsurface/Source/CoroutineManager.cs index a9bb06ee5..861124e70 100644 --- a/Subsurface/Source/CoroutineManager.cs +++ b/Subsurface/Source/CoroutineManager.cs @@ -66,18 +66,18 @@ namespace Barotrauma } } - try - { + //try + //{ Coroutines[i].MoveNext(); - } +// } - catch (Exception e) - { -#if DEBUG - DebugConsole.ThrowError("Coroutine " + Coroutines[i] + " threw an exception: " + e.Message); -#endif - Coroutines.RemoveAt(i); - } +// catch (Exception e) +// { +//#if DEBUG +// DebugConsole.ThrowError("Coroutine " + Coroutines[i] + " threw an exception: " + e.Message); +//#endif +// Coroutines.RemoveAt(i); +// } } } diff --git a/Subsurface/Source/DebugConsole.cs b/Subsurface/Source/DebugConsole.cs index 54e6a579d..0404cb653 100644 --- a/Subsurface/Source/DebugConsole.cs +++ b/Subsurface/Source/DebugConsole.cs @@ -225,7 +225,7 @@ namespace Barotrauma if (commands[1].ToLower()=="human") { WayPoint spawnPoint = WayPoint.GetRandom(SpawnType.Human); - Character.Controlled = Character.Create(Character.HumanConfigFile, (spawnPoint == null) ? Vector2.Zero : spawnPoint.SimPosition); + Character.Controlled = Character.Create(Character.HumanConfigFile, (spawnPoint == null) ? Vector2.Zero : spawnPoint.WorldPosition); if (GameMain.GameSession != null) { SinglePlayerMode mode = GameMain.GameSession.gameMode as SinglePlayerMode; @@ -237,7 +237,7 @@ namespace Barotrauma else { WayPoint spawnPoint = WayPoint.GetRandom(SpawnType.Enemy); - Character.Create("Content/Characters/" + commands[1] + "/" + commands[1] + ".xml", (spawnPoint == null) ? Vector2.Zero : spawnPoint.SimPosition); + Character.Create("Content/Characters/" + commands[1] + "/" + commands[1] + ".xml", (spawnPoint == null) ? Vector2.Zero : spawnPoint.WorldPosition); } break; @@ -287,6 +287,9 @@ namespace Barotrauma commands[1] = commands[1].ToLower(); Character.Controlled = Character.CharacterList.Find(c => !c.IsNetworkPlayer && c.Name.ToLower() == commands[1]); break; + case "godmode": + Submarine.Loaded.GodMode = !Submarine.Loaded.GodMode; + break; case "heal": if (Character.Controlled != null) { @@ -320,7 +323,7 @@ namespace Barotrauma break; case "fixhull": case "fixwalls": - foreach (Structure w in Structure.wallList) + foreach (Structure w in Structure.WallList) { for (int i = 0 ; i < w.SectionCount; i++) { diff --git a/Subsurface/Source/Events/MonsterEvent.cs b/Subsurface/Source/Events/MonsterEvent.cs index e16939bf2..e4b8f1bd9 100644 --- a/Subsurface/Source/Events/MonsterEvent.cs +++ b/Subsurface/Source/Events/MonsterEvent.cs @@ -35,12 +35,13 @@ namespace Barotrauma for (int i = 0; i < amount; i++) { - Vector2 position = (randomWayPoint == null) ? Vector2.Zero : FarseerPhysics.ConvertUnits.ToSimUnits(randomWayPoint.Position + Level.Loaded.Position); - + Vector2 position = (randomWayPoint == null) ? Vector2.Zero : randomWayPoint.Position; + //!!!!!!!!!!!!!!!!!! if (spawnDeep) { - position.Y = FarseerPhysics.ConvertUnits.ToSimUnits(Level.Loaded.Position.Y); + + position.Y -= Level.Loaded.Size.Y; } position.X += Rand.Range(-0.5f, 0.5f); diff --git a/Subsurface/Source/Events/Quests/MonsterQuest.cs b/Subsurface/Source/Events/Quests/MonsterQuest.cs index 860d926ed..7693d0a97 100644 --- a/Subsurface/Source/Events/Quests/MonsterQuest.cs +++ b/Subsurface/Source/Events/Quests/MonsterQuest.cs @@ -31,7 +31,7 @@ namespace Barotrauma { Vector2 position = level.PositionsOfInterest[Rand.Int(level.PositionsOfInterest.Count, false)]; - monster = Character.Create(monsterFile, ConvertUnits.ToSimUnits(position+level.Position)); + monster = Character.Create(monsterFile, position); } public override void Update(float deltaTime) diff --git a/Subsurface/Source/Events/Quests/SalvageQuest.cs b/Subsurface/Source/Events/Quests/SalvageQuest.cs index aaba18db4..c0ce3ab6e 100644 --- a/Subsurface/Source/Events/Quests/SalvageQuest.cs +++ b/Subsurface/Source/Events/Quests/SalvageQuest.cs @@ -47,8 +47,8 @@ namespace Barotrauma Vector2 tryPos = level.PositionsOfInterest[Rand.Int(level.PositionsOfInterest.Count, false)]; if (Submarine.PickBody( - tryPos + level.Position, - tryPos + level.Position - Vector2.UnitY*level.Size.Y, + tryPos, + tryPos - Vector2.UnitY*level.Size.Y, null, Physics.CollisionLevel) != null) { position = tryPos; @@ -65,7 +65,7 @@ namespace Barotrauma } while (tries < 10); - item = new Item(itemPrefab, position + level.Position); + item = new Item(itemPrefab, position, null); item.MoveWithLevel = true; item.body.FarseerBody.GravityScale = 0.5f; //item.MoveWithLevel = true; @@ -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/GUI/GUIProgressBar.cs b/Subsurface/Source/GUI/GUIProgressBar.cs index 53e33d6e4..a0b8dfcb1 100644 --- a/Subsurface/Source/GUI/GUIProgressBar.cs +++ b/Subsurface/Source/GUI/GUIProgressBar.cs @@ -37,12 +37,18 @@ namespace Barotrauma } public GUIProgressBar(Rectangle rect, Color color, float barSize, Alignment alignment, GUIComponent parent = null) - : base(null) + : this(rect,color,null, barSize,alignment, parent) + { + + } + + public GUIProgressBar(Rectangle rect, Color color, GUIStyle style, float barSize, Alignment alignment, GUIComponent parent = null) + : base(style) { this.rect = rect; this.color = color; isHorizontal = (rect.Width > rect.Height); - + this.alignment = alignment; margin = 5; @@ -50,19 +56,36 @@ namespace Barotrauma if (parent != null) parent.AddChild(this); - frame = new GUIFrame(new Rectangle(0,0,0,0), Color.White, null, this); + frame = new GUIFrame(new Rectangle(0, 0, 0, 0), Color.Black, null, this); this.barSize = barSize; UpdateRect(); + + if (style != null) style.Apply(this); + } + + public override void ApplyStyle(GUIComponentStyle style) + { + if (frame == null) return; + + frame.Color = style.Color; + frame.HoverColor = style.HoverColor; + frame.SelectedColor = style.SelectedColor; + + Padding = style.Padding; + + frame.OutlineColor = style.OutlineColor; + + this.style = style; } private void UpdateRect() { rect = new Rectangle( - frame.Rect.X + margin, - frame.Rect.Y + margin, - isHorizontal ? (int)((frame.Rect.Width - margin * 2) * barSize) : (frame.Rect.Width - margin * 2), - isHorizontal ? (frame.Rect.Height - margin * 2) : (int)((frame.Rect.Height - margin * 2) * barSize)); + (int)(frame.Rect.X + padding.X), + (int)(frame.Rect.Y + padding.Y), + isHorizontal ? (int)((frame.Rect.Width - padding.X - padding.Z) * barSize) : (frame.Rect.Width - margin * 2), + isHorizontal ? (int)(frame.Rect.Height - padding.Y - padding.W) : (int)((frame.Rect.Height - margin * 2) * barSize)); } public override void Draw(SpriteBatch spriteBatch) diff --git a/Subsurface/Source/GameSession/CargoManager.cs b/Subsurface/Source/GameSession/CargoManager.cs index 3e106d654..0f6dea546 100644 --- a/Subsurface/Source/GameSession/CargoManager.cs +++ b/Subsurface/Source/GameSession/CargoManager.cs @@ -30,7 +30,7 @@ namespace Barotrauma return; } - Hull cargoRoom = Hull.FindHull(wp.Position); + Hull cargoRoom = Hull.FindHull(wp.WorldPosition); if (cargoRoom == null) { @@ -44,7 +44,7 @@ namespace Barotrauma Rand.Range(cargoRoom.Rect.X + 20, cargoRoom.Rect.Right - 20), Rand.Range(cargoRoom.Rect.Y - cargoRoom.Rect.Height + 20.0f, cargoRoom.Rect.Y)); - new Item(prefab as ItemPrefab, position); + new Item(prefab as ItemPrefab, position, wp.Submarine); } purchasedItems.Clear(); diff --git a/Subsurface/Source/GameSession/CrewManager.cs b/Subsurface/Source/GameSession/CrewManager.cs index 3c0c51a56..b946c5e1a 100644 --- a/Subsurface/Source/GameSession/CrewManager.cs +++ b/Subsurface/Source/GameSession/CrewManager.cs @@ -113,7 +113,7 @@ namespace Barotrauma { guiFrame.Update(deltaTime); - if (PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.I)) + if (PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.C)) { commander.ToggleGUIFrame(); } @@ -213,7 +213,7 @@ namespace Barotrauma //WayPoint randomWayPoint = WayPoint.GetRandom(SpawnType.Human); //Vector2 position = (randomWayPoint == null) ? Vector2.Zero : randomWayPoint.SimPosition; - Character character = Character.Create(characterInfos[i], waypoints[i]); + Character character = Character.Create(characterInfos[i], waypoints[i].WorldPosition); Character.Controlled = character; if (!character.Info.StartItemsGiven) 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 b9854f2ff..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); @@ -333,7 +333,7 @@ namespace Barotrauma infoBox = CreateInfoFrame("Uh-oh... Something enormous just appeared on the radar."); List windows = new List(); - foreach (Structure s in Structure.wallList) + foreach (Structure s in Structure.WallList) { if (s.CastShadow || !s.HasBody) continue; @@ -343,7 +343,7 @@ namespace Barotrauma bool broken = false; do { - Submarine.Loaded.Speed = Vector2.Zero; + Submarine.Loaded.Velocity = Vector2.Zero; moloch.AIController.SelectTarget(steering.Item.CurrentHull.AiTarget); Vector2 steeringDir = windows[0].Position - moloch.Position; 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 210d4cc9c..ba43bf53e 100644 --- a/Subsurface/Source/Items/Components/Door.cs +++ b/Subsurface/Source/Items/Components/Door.cs @@ -45,7 +45,8 @@ namespace Barotrauma.Items.Components linkedGap = e as Gap; if (linkedGap != null) return linkedGap; } - linkedGap = new Gap(item.Rect); + linkedGap = new Gap(item.Rect, Item.Submarine); + linkedGap.Submarine = item.Submarine; linkedGap.Open = openState; item.linkedTo.Add(linkedGap); return linkedGap; @@ -144,8 +145,8 @@ namespace Barotrauma.Items.Components Vector2[] corners = GetConvexHullCorners(doorRect); - convexHull = new ConvexHull(corners, Color.Black); - if (window!=Rectangle.Empty) convexHull2 = new ConvexHull(corners, Color.Black); + convexHull = new ConvexHull(corners, Color.Black, item.CurrentHull == null ? null : item.CurrentHull.Submarine); + if (window!=Rectangle.Empty) convexHull2 = new ConvexHull(corners, Color.Black, item.CurrentHull == null ? null : item.CurrentHull.Submarine); UpdateConvexHulls(); @@ -262,7 +263,7 @@ namespace Barotrauma.Items.Components if (Math.Sign(l.SimPosition.X - item.SimPosition.X) != dir) { l.body.SetTransform(new Vector2(item.SimPosition.X + dir * simSize.X*1.2f, item.SimPosition.Y), l.body.Rotation); - SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, 1.0f, l.body.FarseerBody); + SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, 1.0f, l.body); //c.AddDamage(item.SimPosition, DamageType.Blunt, 1.0f, 0.0f, 0.0f, true); l.body.ApplyLinearImpulse(new Vector2(dir * 0.5f, isOpen ? 0.0f : -1.0f)); @@ -303,7 +304,12 @@ namespace Barotrauma.Items.Components if (stuck>0.0f && weldedSprite!=null) { - weldedSprite.Draw(spriteBatch, new Vector2(item.Rect.X, -item.Rect.Y), Color.White*(stuck/100.0f), 0.0f, 1.0f); + Vector2 weldSpritePos = new Vector2(item.Rect.X, item.Rect.Y); + if (item.Submarine != null) weldSpritePos += item.Submarine.Position; + weldSpritePos.Y = -weldSpritePos.Y; + + weldedSprite.Draw(spriteBatch, + weldSpritePos, Color.White*(stuck/100.0f), 0.0f, 1.0f); } if (openState == 1.0f) @@ -311,8 +317,12 @@ namespace Barotrauma.Items.Components body.Enabled = false; return; } - - spriteBatch.Draw(doorSprite.Texture, new Vector2(item.Rect.Center.X, -item.Rect.Y), + + Vector2 pos = new Vector2(item.Rect.Center.X, item.Rect.Y); + if (item.Submarine != null) pos += item.Submarine.DrawPosition; + pos.Y = -pos.Y; + + spriteBatch.Draw(doorSprite.Texture, pos, new Rectangle(doorSprite.SourceRect.X, (int)(doorSprite.size.Y * openState), (int)doorSprite.size.X, (int)(doorSprite.size.Y * (1.0f - openState))), color, 0.0f, doorSprite.Origin, 1.0f, SpriteEffects.None, doorSprite.Depth); @@ -344,12 +354,12 @@ namespace Barotrauma.Items.Components if (connection.Name=="toggle") { isOpen = !isOpen; - PlaySound(ActionType.OnUse, item.Position); + PlaySound(ActionType.OnUse, item.WorldPosition); } else if (connection.Name == "set_state") { bool newState = (signal!="0"); - if (isOpen!=newState) PlaySound(ActionType.OnUse, item.Position); + if (isOpen!=newState) PlaySound(ActionType.OnUse, item.WorldPosition); isOpen = newState; } diff --git a/Subsurface/Source/Items/Components/Holdable/Holdable.cs b/Subsurface/Source/Items/Components/Holdable/Holdable.cs index 3ab8b457b..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(); @@ -236,6 +239,8 @@ namespace Barotrauma.Items.Components AnimController ac = picker.AnimController; + item.Submarine = picker.Submarine; + //item.sprite.Depth = picker.AnimController.GetLimb(LimbType.RightHand).sprite.Depth + 0.01f; ac.HoldItem(deltaTime, item, handlePos, holdPos, aimPos, picker.IsKeyDown(InputType.Aim), holdAngle); diff --git a/Subsurface/Source/Items/Components/Holdable/MeleeWeapon.cs b/Subsurface/Source/Items/Components/Holdable/MeleeWeapon.cs index e4252a6cd..b06348507 100644 --- a/Subsurface/Source/Items/Components/Holdable/MeleeWeapon.cs +++ b/Subsurface/Source/Items/Components/Holdable/MeleeWeapon.cs @@ -194,7 +194,7 @@ namespace Barotrauma.Items.Components if (target == null) return false; - if (attack!=null) attack.DoDamage(user, target, item.Position, 1.0f); + if (attack!=null) attack.DoDamage(user, target, item.WorldPosition, 1.0f); RestoreCollision(); hitting = false; 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/Holdable/Propulsion.cs b/Subsurface/Source/Items/Components/Holdable/Propulsion.cs index 525f9adcc..4455d4638 100644 --- a/Subsurface/Source/Items/Components/Holdable/Propulsion.cs +++ b/Subsurface/Source/Items/Components/Holdable/Propulsion.cs @@ -88,7 +88,7 @@ namespace Barotrauma.Items.Components if (!string.IsNullOrWhiteSpace(particles)) { - GameMain.ParticleManager.CreateParticle(particles, item.Position, + GameMain.ParticleManager.CreateParticle(particles, item.WorldPosition, item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi), 0.0f, item.CurrentHull); } diff --git a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs index cdcbaac48..47a36bb99 100644 --- a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs +++ b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs @@ -24,8 +24,8 @@ namespace Barotrauma.Items.Components [HasDefaultValue(0.0f, false)] public float Range { - get { return ConvertUnits.ToDisplayUnits(range); } - set { range = ConvertUnits.ToSimUnits(value); } + get { return range; } + set { range = value; } } [HasDefaultValue(0.0f, false)] @@ -61,8 +61,8 @@ namespace Barotrauma.Items.Components [HasDefaultValue("0.0,0.0", false)] public string BarrelPos { - get { return ToolBox.Vector2ToString(ConvertUnits.ToDisplayUnits(barrelPos)); } - set { barrelPos = ConvertUnits.ToSimUnits(ToolBox.ParseToVector2(value)); } + get { return ToolBox.Vector2ToString(barrelPos); } + set { barrelPos = ToolBox.ParseToVector2(value); } } public Vector2 TransformedBarrelPos @@ -72,7 +72,7 @@ namespace Barotrauma.Items.Components Matrix bodyTransform = Matrix.CreateRotationZ(item.body.Rotation); Vector2 flippedPos = barrelPos; if (item.body.Dir < 0.0f) flippedPos.X = -flippedPos.X; - return (Vector2.Transform(flippedPos, bodyTransform) + item.body.SimPosition); + return (Vector2.Transform(flippedPos, bodyTransform)); } } @@ -115,7 +115,6 @@ namespace Barotrauma.Items.Components IsActive = true; - Vector2 targetPosition = item.body.SimPosition; //targetPosition = targetPosition.X, -targetPosition.Y); float degreeOfSuccess = DegreeOfSuccess(character)/100.0f; @@ -126,6 +125,7 @@ namespace Barotrauma.Items.Components return false; } + Vector2 targetPosition = item.WorldPosition; targetPosition += new Vector2( (float)Math.Cos(item.body.Rotation), (float)Math.Sin(item.body.Rotation)) * range * item.body.Dir; @@ -137,14 +137,18 @@ namespace Barotrauma.Items.Components ignoredBodies.Add(limb.body.FarseerBody); } + Vector2 rayStart = item.WorldPosition + TransformedBarrelPos; + Vector2 rayEnd = targetPosition; + Body targetBody = Submarine.PickBody( + ConvertUnits.ToSimUnits(rayStart - Submarine.Loaded.Position), + ConvertUnits.ToSimUnits(rayEnd - Submarine.Loaded.Position), ignoredBodies); - Body targetBody = Submarine.PickBody(TransformedBarrelPos, targetPosition, ignoredBodies); pickedPosition = Submarine.LastPickedPosition; if (ExtinquishAmount > 0.0f) { - Vector2 displayPos = ConvertUnits.ToDisplayUnits(TransformedBarrelPos + (targetPosition-TransformedBarrelPos)*Submarine.LastPickedFraction*0.9f); + Vector2 displayPos = rayStart + (rayEnd-rayStart)*Submarine.LastPickedFraction*0.9f; Hull hull = Hull.FindHull(displayPos, item.CurrentHull); if (hull != null) hull.Extinquish(deltaTime, ExtinquishAmount, displayPos); } @@ -224,7 +228,7 @@ namespace Barotrauma.Items.Components if (!string.IsNullOrWhiteSpace(particles)) { - GameMain.ParticleManager.CreateParticle(particles, ConvertUnits.ToDisplayUnits(TransformedBarrelPos), + GameMain.ParticleManager.CreateParticle(particles, item.WorldPosition+TransformedBarrelPos, -item.body.Rotation + ((item.body.Dir>0.0f) ? 0.0f : MathHelper.Pi), ParticleSpeed); } diff --git a/Subsurface/Source/Items/Components/ItemComponent.cs b/Subsurface/Source/Items/Components/ItemComponent.cs index 7476bc20c..90658eb4a 100644 --- a/Subsurface/Source/Items/Components/ItemComponent.cs +++ b/Subsurface/Source/Items/Components/ItemComponent.cs @@ -322,6 +322,8 @@ namespace Barotrauma.Items.Components if (itemSound.Loop) { loopingSound = itemSound; + + loopingSoundIndex = loopingSound.Sound.Loop(loopingSoundIndex, GetSoundVolume(loopingSound), position, loopingSound.Range); } else { diff --git a/Subsurface/Source/Items/Components/ItemContainer.cs b/Subsurface/Source/Items/Components/ItemContainer.cs index 8021ae386..777cb1e94 100644 --- a/Subsurface/Source/Items/Components/ItemContainer.cs +++ b/Subsurface/Source/Items/Components/ItemContainer.cs @@ -163,6 +163,7 @@ namespace Barotrauma.Items.Components if (item.body == null) { transformedItemPos = new Vector2(item.Rect.X, item.Rect.Y); + if (item.Submarine != null) transformedItemPos += item.Submarine.DrawPosition; transformedItemPos = transformedItemPos + itemPos; } else @@ -179,7 +180,7 @@ namespace Barotrauma.Items.Components transformedItemPos = Vector2.Transform(transformedItemPos, transform); transformedItemInterval = Vector2.Transform(transformedItemInterval, transform); - transformedItemPos += ConvertUnits.ToDisplayUnits(item.body.SimPosition); + transformedItemPos += item.DrawPosition; currentRotation += item.body.Rotation; } diff --git a/Subsurface/Source/Items/Components/ItemLabel.cs b/Subsurface/Source/Items/Components/ItemLabel.cs index 2fca7a515..133b5e3ec 100644 --- a/Subsurface/Source/Items/Components/ItemLabel.cs +++ b/Subsurface/Source/Items/Components/ItemLabel.cs @@ -61,6 +61,7 @@ namespace Barotrauma.Items.Components { base.Draw(spriteBatch, editing); + textBlock.Rect = new Rectangle((int)item.DrawPosition.X - item.Rect.Width/2, -(int)(item.DrawPosition.Y + item.Rect.Height/2), item.Rect.Width, item.Rect.Height); textBlock.Draw(spriteBatch); } } diff --git a/Subsurface/Source/Items/Components/Machines/Controller.cs b/Subsurface/Source/Items/Components/Machines/Controller.cs index ea21d683e..5775cac99 100644 --- a/Subsurface/Source/Items/Components/Machines/Controller.cs +++ b/Subsurface/Source/Items/Components/Machines/Controller.cs @@ -118,7 +118,7 @@ namespace Barotrauma.Items.Components fmj.WorldAnchorB = position; } - item.SendSignal(ToolBox.Vector2ToString(character.CursorPosition), "position_out"); + item.SendSignal(ToolBox.Vector2ToString(character.CursorWorldPosition), "position_out"); } public override bool Use(float deltaTime, Character activator = null) @@ -152,12 +152,12 @@ namespace Barotrauma.Items.Components { if (c2 == null || c2.Item==null || !c2.Item.Prefab.FocusOnSelected) continue; - Vector2 centerPos = c2.Item.Position; + Vector2 centerPos = c2.Item.WorldPosition; if (character == Character.Controlled && cam != null) { Lights.LightManager.ViewPos = centerPos; - cam.TargetPos = c2.Item.Position; + cam.TargetPos = c2.Item.WorldPosition; } break; @@ -169,7 +169,7 @@ namespace Barotrauma.Items.Components { item.SendSignal("1", "signal_out"); - PlaySound(ActionType.OnUse, item.Position); + PlaySound(ActionType.OnUse, item.WorldPosition); return true; } diff --git a/Subsurface/Source/Items/Components/Machines/Engine.cs b/Subsurface/Source/Items/Components/Machines/Engine.cs index d86d955fc..238d92a38 100644 --- a/Subsurface/Source/Items/Components/Machines/Engine.cs +++ b/Subsurface/Source/Items/Components/Machines/Engine.cs @@ -74,7 +74,7 @@ namespace Barotrauma.Items.Components for (int i = 0; i < 5; i++) { - GameMain.ParticleManager.CreateParticle("bubbles", item.Position, + GameMain.ParticleManager.CreateParticle("bubbles", item.WorldPosition, -currForce / 5.0f + new Vector2(Rand.Range(-100.0f, 100.0f), Rand.Range(-50f, 50f)), 0.0f, item.CurrentHull); } diff --git a/Subsurface/Source/Items/Components/Machines/Pump.cs b/Subsurface/Source/Items/Components/Machines/Pump.cs index bce4c90ae..d58a9c465 100644 --- a/Subsurface/Source/Items/Components/Machines/Pump.cs +++ b/Subsurface/Source/Items/Components/Machines/Pump.cs @@ -103,7 +103,7 @@ namespace Barotrauma.Items.Components private void GetHull() { - hull1 = Hull.FindHull(item.Position, item.CurrentHull); + hull1 = Hull.FindHull(item.WorldPosition, item.CurrentHull); } public override void DrawHUD(SpriteBatch spriteBatch, Character character) diff --git a/Subsurface/Source/Items/Components/Machines/Radar.cs b/Subsurface/Source/Items/Components/Machines/Radar.cs index 05a3e460b..d84544a22 100644 --- a/Subsurface/Source/Items/Components/Machines/Radar.cs +++ b/Subsurface/Source/Items/Components/Machines/Radar.cs @@ -50,6 +50,8 @@ namespace Barotrauma.Items.Components public override void Update(float deltaTime, Camera cam) { + currPowerConsumption = powerConsumption; + base.Update(deltaTime, cam); for (int i = radarBlips.Count - 1; i >= 0; i-- ) @@ -71,6 +73,8 @@ namespace Barotrauma.Items.Components { pingState = 0.0f; } + + voltage = 0.0f; } public override bool Use(float deltaTime, Character character = null) @@ -115,67 +119,67 @@ namespace Barotrauma.Items.Components float radius = rect.Width / 2.0f; float simScale = 1.5f; - + if (Level.Loaded != null) { - List cells = Level.Loaded.GetCells(-Level.Loaded.Position, 7); + List cells = Level.Loaded.GetCells(item.WorldPosition, 7); foreach (VoronoiCell cell in cells) { foreach (GraphEdge edge in cell.edges) { - //if (!edge.isSolid) continue; - float cellDot = Vector2.Dot(cell.Center + Level.Loaded.Position, (edge.point1 + edge.point2) / 2.0f - cell.Center); + 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 + Level.Loaded.Position)); - facingDot = MathHelper.Clamp(facingDot, -1.0f, 1.0f); + 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); - Vector2 point1 = (edge.point1 + Level.Loaded.Position); - Vector2 point2 = (edge.point2 + Level.Loaded.Position); + Vector2 point1 = (edge.point1); + Vector2 point2 = (edge.point2); float length = (point1 - point2).Length(); - for (float x=0; x radius) continue; 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) continue; @@ -195,7 +198,7 @@ namespace Barotrauma.Items.Components if (pointDist > radius) continue; if (pointDist > prevPingRadius && pointDist < pingRadius) { - var blip = new RadarBlip(pos - Level.Loaded.Position, 1.0f); + var blip = new RadarBlip(limb.WorldPosition, 1.0f); radarBlips.Add(blip); } } @@ -203,14 +206,14 @@ namespace Barotrauma.Items.Components foreach (RadarBlip radarBlip in radarBlips) { - DrawBlip(spriteBatch,radarBlip, center, Color.Green * radarBlip.FadeTimer, radius); + DrawBlip(spriteBatch, radarBlip, center, Color.Green * radarBlip.FadeTimer, radius); } prevPingRadius = pingRadius; - if (screenOverlay!=null) + if (screenOverlay != null) { - screenOverlay.Draw(spriteBatch, center, 0.0f, rect.Width/screenOverlay.size.X); + screenOverlay.Draw(spriteBatch, center, 0.0f, rect.Width / screenOverlay.size.X); } //prevPingRadius = pingRadius; @@ -220,11 +223,11 @@ namespace Barotrauma.Items.Components DrawMarker(spriteBatch, (GameMain.GameSession.Map == null) ? "Start" : GameMain.GameSession.Map.CurrentLocation.Name, - (Level.Loaded.StartPosition + Level.Loaded.Position), displayScale, center, (rect.Width * 0.55f)); + (Level.Loaded.StartPosition), displayScale, center, (rect.Width * 0.55f)); DrawMarker(spriteBatch, (GameMain.GameSession.Map == null) ? "End" : GameMain.GameSession.Map.SelectedLocation.Name, - (Level.Loaded.EndPosition + Level.Loaded.Position), displayScale, center, (rect.Width * 0.55f)); + (Level.Loaded.EndPosition), displayScale, center, (rect.Width * 0.55f)); if (GameMain.GameSession.Quest != null) { @@ -247,15 +250,15 @@ namespace Barotrauma.Items.Components foreach (WayPoint wp in steering.SteeringPath.Nodes) { - Vector2 pos = (wp.Position - Submarine.Loaded.Position) * displayScale; + Vector2 pos = (wp.Position - item.WorldPosition) * displayScale; if (pos.Length() > radius) continue; pos.Y = -pos.Y; pos += center; - GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X -3 / 2, (int)pos.Y - 3, 6, 6), (steering.SteeringPath.CurrentNode==wp) ? Color.LightGreen : Color.Green, false); + GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X - 3 / 2, (int)pos.Y - 3, 6, 6), (steering.SteeringPath.CurrentNode == wp) ? Color.LightGreen : Color.Green, false); - if (prevPos!=Vector2.Zero) + if (prevPos != Vector2.Zero) { GUI.DrawLine(spriteBatch, pos, prevPos, Color.Green); } @@ -263,12 +266,12 @@ namespace Barotrauma.Items.Components prevPos = pos; } - voltage = 0.0f; } private void DrawBlip(SpriteBatch spriteBatch, RadarBlip blip, Vector2 center, Color color, float radius) { - Vector2 pos = (blip.Position + Level.Loaded.Position) * displayScale; + + Vector2 pos = (blip.Position-item.WorldPosition) * displayScale; pos.Y = -pos.Y; if (pos.Length() > radius) diff --git a/Subsurface/Source/Items/Components/Machines/Reactor.cs b/Subsurface/Source/Items/Components/Machines/Reactor.cs index 1f3ee98fa..78355ed1e 100644 --- a/Subsurface/Source/Items/Components/Machines/Reactor.cs +++ b/Subsurface/Source/Items/Components/Machines/Reactor.cs @@ -163,7 +163,7 @@ namespace Barotrauma.Items.Components Vector2 baseVel = Rand.Vector(300.0f); for (int i = 0; i < 10; i++) { - var particle = GameMain.ParticleManager.CreateParticle("spark", item.Position, + var particle = GameMain.ParticleManager.CreateParticle("spark", item.WorldPosition, baseVel + Rand.Vector(100.0f), 0.0f, item.CurrentHull); if (particle != null) particle.Size *= Rand.Range(0.5f, 1.0f); diff --git a/Subsurface/Source/Items/Components/Machines/Steering.cs b/Subsurface/Source/Items/Components/Machines/Steering.cs index d938a96b9..d14179c52 100644 --- a/Subsurface/Source/Items/Components/Machines/Steering.cs +++ b/Subsurface/Source/Items/Components/Machines/Steering.cs @@ -41,7 +41,7 @@ namespace Barotrauma.Items.Components { if (pathFinder==null) pathFinder = new PathFinder(WayPoint.WayPointList, false); steeringPath = pathFinder.FindPath( - ConvertUnits.ToSimUnits(Submarine.Loaded.Position), + ConvertUnits.ToSimUnits(item.WorldPosition), ConvertUnits.ToSimUnits(Level.Loaded.EndPosition)); } } @@ -160,31 +160,31 @@ namespace Barotrauma.Items.Components { autopilotRayCastTimer -= deltaTime; - steeringPath.CheckProgress(ConvertUnits.ToSimUnits(Submarine.Loaded.Position), 10.0f); + steeringPath.CheckProgress(ConvertUnits.ToSimUnits(item.WorldPosition), 10.0f); if (autopilotRayCastTimer<=0.0f && steeringPath.NextNode != null) { - Vector2 diff = ConvertUnits.ToSimUnits(steeringPath.NextNode.Position - Submarine.Loaded.Position); + Vector2 diff = ConvertUnits.ToSimUnits(steeringPath.NextNode.Position - item.WorldPosition); - bool nextVisible = true; - for (int x = -1; x < 2; x += 2) - { - for (int y = -1; y < 2; y += 2) - { - Vector2 cornerPos = - new Vector2(Submarine.Borders.Width * x, Submarine.Borders.Height * y) / 2.0f; + //bool nextVisible = true; + //for (int x = -1; x < 2; x += 2) + //{ + // for (int y = -1; y < 2; y += 2) + // { + // Vector2 cornerPos = + // new Vector2(Submarine.Borders.Width * x, Submarine.Borders.Height * y) / 2.0f; - cornerPos = ConvertUnits.ToSimUnits(cornerPos*1.2f); + // cornerPos = ConvertUnits.ToSimUnits(cornerPos*1.2f); - if (Submarine.PickBody(cornerPos, cornerPos + diff, null, Physics.CollisionLevel) == null) continue; + // if (Submarine.PickBody(cornerPos, cornerPos + diff, null, Physics.CollisionLevel) == null) continue; - nextVisible = false; - x = 2; - y = 2; - } - } + // nextVisible = false; + // x = 2; + // y = 2; + // } + //} - if (nextVisible) steeringPath.SkipToNextNode(); + //if (nextVisible) steeringPath.SkipToNextNode(); autopilotRayCastTimer = AutopilotRayCastInterval; } @@ -193,8 +193,8 @@ namespace Barotrauma.Items.Components { float prediction = 5.0f; - Vector2 futurePosition = Submarine.Loaded.Speed * prediction; - Vector2 targetSpeed = ((steeringPath.CurrentNode.Position - Submarine.Loaded.Position) - futurePosition); + Vector2 futurePosition = ConvertUnits.ToDisplayUnits(item.Submarine.Velocity) * prediction; + Vector2 targetSpeed = ((steeringPath.CurrentNode.WorldPosition - item.WorldPosition) - futurePosition); targetSpeed = Vector2.Normalize(targetSpeed); TargetVelocity = targetSpeed * 100.0f; diff --git a/Subsurface/Source/Items/Components/Power/PowerTransfer.cs b/Subsurface/Source/Items/Components/Power/PowerTransfer.cs index 62c650871..c011bb4c6 100644 --- a/Subsurface/Source/Items/Components/Power/PowerTransfer.cs +++ b/Subsurface/Source/Items/Components/Power/PowerTransfer.cs @@ -62,12 +62,12 @@ namespace Barotrauma.Items.Components if (pt.item.Condition<=0.0f && prevCondition > 0.0f) { - sparkSounds[Rand.Int(sparkSounds.Length)].Play(1.0f, 600.0f, pt.item.Position); + sparkSounds[Rand.Int(sparkSounds.Length)].Play(1.0f, 600.0f, pt.item.WorldPosition); Vector2 baseVel = Rand.Vector(300.0f); for (int i = 0; i < 10; i++) { - var particle = GameMain.ParticleManager.CreateParticle("spark", pt.item.Position, + var particle = GameMain.ParticleManager.CreateParticle("spark", pt.item.WorldPosition, baseVel + Rand.Vector(100.0f), 0.0f, item.CurrentHull); if (particle != null) particle.Size *= Rand.Range(0.5f, 1.0f); @@ -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/Projectile.cs b/Subsurface/Source/Items/Components/Projectile.cs index 719dac46c..3f94f2d36 100644 --- a/Subsurface/Source/Items/Components/Projectile.cs +++ b/Subsurface/Source/Items/Components/Projectile.cs @@ -169,11 +169,11 @@ namespace Barotrauma.Items.Components Structure structure; if ((limb = (f2.Body.UserData as Limb)) != null) { - attackResult = attack.DoDamage(User, limb.character, item.SimPosition, 1.0f); + attackResult = attack.DoDamage(User, limb.character, item.WorldPosition, 1.0f); } else if ((structure = (f2.Body.UserData as Structure)) != null) { - attackResult = attack.DoDamage(User, structure, item.SimPosition, 1.0f); + attackResult = attack.DoDamage(User, structure, item.WorldPosition, 1.0f); } } diff --git a/Subsurface/Source/Items/Components/Signal/LightComponent.cs b/Subsurface/Source/Items/Components/Signal/LightComponent.cs index 8f84865f7..6ab43eafa 100644 --- a/Subsurface/Source/Items/Components/Signal/LightComponent.cs +++ b/Subsurface/Source/Items/Components/Signal/LightComponent.cs @@ -88,7 +88,7 @@ namespace Barotrauma.Items.Components // break; //} - light = new LightSource(item.Position, 100.0f, Color.White); + light = new LightSource(item.Position, 100.0f, Color.White, item.CurrentHull == null ? null : item.CurrentHull.Submarine); IsActive = true; @@ -98,6 +98,12 @@ namespace Barotrauma.Items.Components public override void Update(float deltaTime, Camera cam) { base.Update(deltaTime, cam); + if (item.CurrentHull != null) + { + light.Submarine = item.CurrentHull.Submarine; + } + + if (item.container != null) { @@ -107,7 +113,7 @@ namespace Barotrauma.Items.Components if (item.body != null) { - light.Position = ConvertUnits.ToDisplayUnits(item.body.SimPosition); + light.Position = item.WorldPosition; } if (powerConsumption == 0.0f) @@ -121,7 +127,7 @@ namespace Barotrauma.Items.Components if (Rand.Range(0.0f, 1.0f) < 0.05f && voltage < Rand.Range(0.0f, minVoltage)) { - if (voltage > 0.1f) sparkSounds[Rand.Int(sparkSounds.Length)].Play(1.0f, 400.0f, item.Position); + if (voltage > 0.1f) sparkSounds[Rand.Int(sparkSounds.Length)].Play(1.0f, 400.0f, item.WorldPosition); lightBrightness = 0.0f; } else diff --git a/Subsurface/Source/Items/Components/Signal/OxygenDetector.cs b/Subsurface/Source/Items/Components/Signal/OxygenDetector.cs index 918d64241..1a06ccf46 100644 --- a/Subsurface/Source/Items/Components/Signal/OxygenDetector.cs +++ b/Subsurface/Source/Items/Components/Signal/OxygenDetector.cs @@ -4,31 +4,17 @@ namespace Barotrauma.Items.Components { class OxygenDetector : ItemComponent { - private Hull hull; - public OxygenDetector(Item item, XElement element) : base (item, element) { - hull = Hull.FindHull(item.Position); - IsActive = true; } - public override void OnMapLoaded() - { - hull = Hull.FindHull(item.Position); - } - - public override void Move(Microsoft.Xna.Framework.Vector2 amount) - { - hull = Hull.FindHull(item.Position); - } - public override void Update(float deltaTime, Camera cam) { - if (hull == null) return; - - item.SendSignal(((int)hull.OxygenPercentage).ToString(), "signal_out"); + if (item.CurrentHull == null) return; + + item.SendSignal(((int)item.CurrentHull.OxygenPercentage).ToString(), "signal_out"); } diff --git a/Subsurface/Source/Items/Components/Signal/Wire.cs b/Subsurface/Source/Items/Components/Signal/Wire.cs index 771b2e4ee..eb0fb6f54 100644 --- a/Subsurface/Source/Items/Components/Signal/Wire.cs +++ b/Subsurface/Source/Items/Components/Signal/Wire.cs @@ -41,11 +41,10 @@ namespace Barotrauma.Items.Components public override void Move(Vector2 amount) { - //amount = FarseerPhysics.ConvertUnits.ToDisplayUnits(amount); - //for (int i = 0; i 10.0f) @@ -323,7 +326,7 @@ namespace Barotrauma.Items.Components continue; } - GUI.DrawRectangle(spriteBatch, new Rectangle((int)Nodes[i].X - 10, (int)-Nodes[i].Y - 10, 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) { @@ -348,9 +351,11 @@ namespace Barotrauma.Items.Components MapEntity.DisableSelect = true; Nodes[(int)selectedNodeIndex] = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition); - Vector2 pos = Nodes[(int)selectedNodeIndex]; + Vector2 nodeWorldPos = Nodes[(int)selectedNodeIndex]; - Nodes[(int)selectedNodeIndex] = RoundNode(Nodes[(int)selectedNodeIndex], Hull.FindHull(Nodes[(int)selectedNodeIndex])); + if (item.Submarine != null) nodeWorldPos += item.Submarine.Position; + + Nodes[(int)selectedNodeIndex] = RoundNode(Nodes[(int)selectedNodeIndex], Hull.FindHull(nodeWorldPos)); MapEntity.SelectEntity(item); } } @@ -362,6 +367,12 @@ namespace Barotrauma.Items.Components private void DrawSection(SpriteBatch spriteBatch, Vector2 start, Vector2 end, Color color) { + if (item.Submarine!=null) + { + start += item.Submarine.DrawPosition; + end += item.Submarine.DrawPosition; + } + start.Y = -start.Y; end.Y = -end.Y; diff --git a/Subsurface/Source/Items/Components/Turret.cs b/Subsurface/Source/Items/Components/Turret.cs index b7f820669..225c389f3 100644 --- a/Subsurface/Source/Items/Components/Turret.cs +++ b/Subsurface/Source/Items/Components/Turret.cs @@ -81,8 +81,12 @@ namespace Barotrauma.Items.Components public override void Draw(SpriteBatch spriteBatch, bool editing) { + Vector2 drawPos = new Vector2(item.Rect.X, item.Rect.Y); + if (item.Submarine != null) drawPos += item.Submarine.DrawPosition; + drawPos.Y = -drawPos.Y; + barrelSprite.Draw(spriteBatch, - new Vector2(item.Rect.X, -item.Rect.Y) + barrelPos, Color.White, + drawPos + barrelPos, Color.White, rotation + MathHelper.PiOver2, 1.0f, SpriteEffects.None, item.Sprite.Depth+0.01f); } @@ -149,7 +153,7 @@ namespace Barotrauma.Items.Components projectile.body.ResetDynamics(); projectile.body.Enabled = true; - projectile.SetTransform(ConvertUnits.ToSimUnits(new Vector2(item.Rect.X + barrelPos.X, item.Rect.Y - barrelPos.Y)), -rotation); + projectile.SetTransform(ConvertUnits.ToSimUnits(new Vector2(item.WorldRect.X + barrelPos.X, item.WorldRect.Y - barrelPos.Y)), -rotation); projectiles[0].Use(deltaTime); if (projectile.container != null) projectile.container.RemoveContained(projectile); @@ -297,7 +301,7 @@ namespace Barotrauma.Items.Components case "position_in": Vector2 receivedPos = ToolBox.ParseToVector2(signal, false); - Vector2 centerPos = new Vector2(item.Rect.X + barrelPos.X, item.Rect.Y - barrelPos.Y); + Vector2 centerPos = new Vector2(item.WorldRect.X + barrelPos.X, item.WorldRect.Y - barrelPos.Y); Vector2 offset = receivedPos - centerPos; offset.Y = -offset.Y; diff --git a/Subsurface/Source/Items/Components/Wearable.cs b/Subsurface/Source/Items/Components/Wearable.cs index f052172f1..7aba939e4 100644 --- a/Subsurface/Source/Items/Components/Wearable.cs +++ b/Subsurface/Source/Items/Components/Wearable.cs @@ -165,7 +165,7 @@ namespace Barotrauma.Items.Components ApplyStatusEffects(ActionType.OnWearing, deltaTime, picker); - PlaySound(ActionType.OnWearing, picker.Position); + PlaySound(ActionType.OnWearing, picker.WorldPosition); if (containedItems == null) return; for (int j = 0; j /// goes through every item and re-checks which hull they are in /// @@ -408,7 +415,11 @@ namespace Barotrauma public virtual Hull FindHull() { - CurrentHull = Hull.FindHull((body == null) ? Position : ConvertUnits.ToDisplayUnits(body.SimPosition), CurrentHull); + CurrentHull = Hull.FindHull(WorldPosition, CurrentHull); + if (body!=null) + { + body.Submarine = CurrentHull == null ? null : Submarine.Loaded; + } return CurrentHull; } @@ -545,7 +556,7 @@ namespace Barotrauma { ic.Update(deltaTime, cam); - ic.PlaySound(ActionType.OnActive, Position); + ic.PlaySound(ActionType.OnActive, WorldPosition); //ic.ApplyStatusEffects(ActionType.OnActive, deltaTime, null); } else @@ -598,7 +609,16 @@ namespace Barotrauma { if (body == null) { - prefab.sprite.DrawTiled(spriteBatch, new Vector2(rect.X, -rect.Y), new Vector2(rect.Width, rect.Height), color); + if (prefab.ResizeHorizontal || prefab.ResizeVertical) + { + + prefab.sprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X-rect.Width/2, -(DrawPosition.Y+rect.Height/2)), new Vector2(rect.Width, rect.Height), color); + } + else + { + prefab.sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y), color); + } + } else if (body.Enabled) { @@ -615,7 +635,7 @@ namespace Barotrauma depth = holdable.Picker.AnimController.GetLimb(LimbType.LeftArm).sprite.Depth - 0.000001f; } - body.Draw(spriteBatch, prefab.sprite, color, depth); + body.Draw(spriteBatch, prefab.sprite, color, depth); } else { @@ -632,13 +652,18 @@ namespace Barotrauma return; } - GUI.DrawRectangle(spriteBatch, new Vector2(rect.X, -rect.Y), new Vector2(rect.Width, rect.Height), Color.Green); + GUI.DrawRectangle(spriteBatch, new Vector2(DrawPosition.X - rect.Width / 2, -(DrawPosition.Y+rect.Height/2)), new Vector2(rect.Width, rect.Height), Color.Green); foreach (Rectangle t in prefab.Triggers) { Rectangle transformedTrigger = TransformTrigger(t); + + Vector2 rectWorldPos = new Vector2(transformedTrigger.X, transformedTrigger.Y); + if (Submarine!=null) rectWorldPos += Submarine.Position; + rectWorldPos.Y = -rectWorldPos.Y; + GUI.DrawRectangle(spriteBatch, - new Vector2(transformedTrigger.X, -transformedTrigger.Y), + rectWorldPos, new Vector2(transformedTrigger.Width, transformedTrigger.Height), Color.Green); } @@ -646,8 +671,8 @@ namespace Barotrauma foreach (MapEntity e in linkedTo) { GUI.DrawLine(spriteBatch, - new Vector2(rect.X + rect.Width / 2, -rect.Y + rect.Height / 2), - new Vector2(e.Rect.X + e.Rect.Width / 2, -e.Rect.Y + e.Rect.Height / 2), + new Vector2(WorldPosition.X, -WorldPosition.Y), + new Vector2(e.WorldPosition.X, -e.WorldPosition.Y), Color.Red*0.3f); } } @@ -882,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; @@ -989,7 +1014,7 @@ namespace Barotrauma { ic.WasUsed = true; - ic.PlaySound(ActionType.OnUse, body==null ? Position : ConvertUnits.ToDisplayUnits(body.SimPosition)); + ic.PlaySound(ActionType.OnUse, WorldPosition); ic.ApplyStatusEffects(ActionType.OnUse, deltaTime, character); @@ -1124,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) @@ -1159,8 +1189,8 @@ namespace Barotrauma return element; } - public static void Load(XElement element) - { + public static void Load(XElement element, Submarine submarine) + { string rectString = ToolBox.GetAttributeString(element, "rect", "0,0,0,0"); string[] rectValues = rectString.Split(','); Rectangle rect = Rectangle.Empty; @@ -1196,7 +1226,8 @@ namespace Barotrauma rect.Height = (int)ip.Size.Y; } - Item item = new Item(rect, ip); + Item item = new Item(rect, ip, submarine); + item.Submarine = submarine; item.ID = (ushort)int.Parse(element.Attribute("ID").Value); item.linkedToID = new List(); @@ -1243,6 +1274,16 @@ namespace Barotrauma } } + + public override void OnMapLoaded() + { + FindHull(); + + foreach (ItemComponent ic in components) + { + ic.OnMapLoaded(); + } + } public void NewComponentEvent(ItemComponent ic, bool isClient, bool isImportant) diff --git a/Subsurface/Source/Items/ItemPrefab.cs b/Subsurface/Source/Items/ItemPrefab.cs index 8f9bd920d..23541fbea 100644 --- a/Subsurface/Source/Items/ItemPrefab.cs +++ b/Subsurface/Source/Items/ItemPrefab.cs @@ -83,7 +83,7 @@ namespace Barotrauma { if (PlayerInput.LeftButtonClicked()) { - new Item(new Rectangle((int)position.X, (int)position.Y, (int)sprite.size.X, (int)sprite.size.Y), this); + new Item(new Rectangle((int)position.X, (int)position.Y, (int)sprite.size.X, (int)sprite.size.Y), this, Submarine.Loaded); //constructor.Invoke(lobject); placePosition = Vector2.Zero; @@ -112,7 +112,7 @@ namespace Barotrauma if (PlayerInput.GetMouseState.LeftButton == ButtonState.Released) { - new Item(new Rectangle((int)placePosition.X, (int)placePosition.Y, (int)placeSize.X, (int)placeSize.Y), this); + new Item(new Rectangle((int)placePosition.X, (int)placePosition.Y, (int)placeSize.X, (int)placeSize.Y), this, Submarine.Loaded); placePosition = Vector2.Zero; //selected = null; return; diff --git a/Subsurface/Source/Items/ItemSpawner.cs b/Subsurface/Source/Items/ItemSpawner.cs index 7c73b7407..4de33a80f 100644 --- a/Subsurface/Source/Items/ItemSpawner.cs +++ b/Subsurface/Source/Items/ItemSpawner.cs @@ -30,7 +30,8 @@ namespace Barotrauma { var itemInfo = spawnQueue.Dequeue(); - new Item(itemInfo.First, itemInfo.Second); + //!!!!!!!!!!!!!!!!!!!!!! + new Item(itemInfo.First, itemInfo.Second, null); } } } diff --git a/Subsurface/Source/Map/Entity.cs b/Subsurface/Source/Map/Entity.cs index c447765c2..51f3ce6dc 100644 --- a/Subsurface/Source/Map/Entity.cs +++ b/Subsurface/Source/Map/Entity.cs @@ -45,14 +45,37 @@ namespace Barotrauma { get { return Vector2.Zero; } } + + public virtual Vector2 Position + { + get { return Vector2.Zero; } + } + + public Vector2 WorldPosition + { + get { return Submarine == null ? Position : Submarine.Position + Position; } + } + + public Vector2 DrawPosition + { + get { return Submarine == null ? Position : Submarine.DrawPosition + Position; } + } + + public Submarine Submarine + { + get; + set; + } public AITarget AiTarget { get { return aiTarget; } } - public Entity() + public Entity(Submarine submarine) { + this.Submarine = submarine; + //give an unique ID bool IDfound; id = 1;//Rand.Int(int.MaxValue); diff --git a/Subsurface/Source/Map/Explosion.cs b/Subsurface/Source/Map/Explosion.cs index 5c88f7e01..91dbfe117 100644 --- a/Subsurface/Source/Map/Explosion.cs +++ b/Subsurface/Source/Map/Explosion.cs @@ -10,8 +10,6 @@ namespace Barotrauma { class Explosion { - private Vector2 position; - private Attack attack; private float force; @@ -32,58 +30,52 @@ namespace Barotrauma shockwave = ToolBox.GetAttributeBool(element, "shockwave", true); flames = ToolBox.GetAttributeBool(element, "flames", true); - CameraShake = ToolBox.GetAttributeFloat(element, "camerashake", attack.Range*10.0f); + CameraShake = ToolBox.GetAttributeFloat(element, "camerashake", attack.Range); } - public void Explode() + public void Explode(Vector2 worldPosition) { - Explode(position); - } - - public void Explode(Vector2 simPosition) - { - Vector2 displayPosition = ConvertUnits.ToDisplayUnits(simPosition); - - Hull hull = Hull.FindHull(displayPosition); + Hull hull = Hull.FindHull(worldPosition); if (shockwave) { - GameMain.ParticleManager.CreateParticle("shockwave", displayPosition, + GameMain.ParticleManager.CreateParticle("shockwave", worldPosition, Vector2.Zero, 0.0f, hull); } - for (int i = 0; i < attack.Range * 10; i++) + for (int i = 0; i < attack.Range * 0.1f; i++) { if (sparks) { - GameMain.ParticleManager.CreateParticle("spark", displayPosition, + GameMain.ParticleManager.CreateParticle("spark", worldPosition, Rand.Vector(Rand.Range(500.0f, 800.0f)), 0.0f, hull); } if (flames) { - GameMain.ParticleManager.CreateParticle("explosionfire", displayPosition + Rand.Vector(50f), + GameMain.ParticleManager.CreateParticle("explosionfire", worldPosition + Rand.Vector(50f), Rand.Vector(Rand.Range(50f, 100.0f)), 0.0f, hull); } } - float displayRange = ConvertUnits.ToDisplayUnits(attack.Range); + float displayRange = attack.Range; + if (displayRange < 0.1f) return; - light = new LightSource(displayPosition, displayRange, Color.LightYellow); + light = new LightSource(worldPosition, displayRange, Color.LightYellow, hull != null ? hull.Submarine : null); CoroutineManager.StartCoroutine(DimLight()); - float cameraDist = Vector2.Distance(GameMain.GameScreen.Cam.Position, displayPosition)/2.0f; - GameMain.GameScreen.Cam.Shake = CameraShake * Math.Max((displayRange - cameraDist)/displayRange, 0.0f); + float cameraDist = Vector2.Distance(GameMain.GameScreen.Cam.Position, worldPosition)/2.0f; + GameMain.GameScreen.Cam.Shake = CameraShake * Math.Max((displayRange - cameraDist) / displayRange, 0.0f); if (attack.GetStructureDamage(1.0f) > 0.0f) { - RangedStructureDamage(displayPosition, displayRange, attack.GetStructureDamage(1.0f)); + RangedStructureDamage(worldPosition, displayRange, attack.GetStructureDamage(1.0f)); } if (force == 0.0f && attack.Stun == 0.0f && attack.GetDamage(1.0f) == 0.0f) return; foreach (Character c in Character.CharacterList) { - float dist = Vector2.Distance(c.SimPosition, simPosition); + float dist = Vector2.Distance(c.WorldPosition, worldPosition); if (dist > attack.Range) continue; @@ -91,14 +83,14 @@ namespace Barotrauma foreach (Limb limb in c.AnimController.Limbs) { - if (limb.SimPosition == simPosition) continue; - distFactor = 1.0f - Vector2.Distance(limb.SimPosition, simPosition)/attack.Range; + if (limb.WorldPosition == worldPosition) continue; + distFactor = 1.0f - Vector2.Distance(limb.WorldPosition, worldPosition)/attack.Range; c.AddDamage(limb.SimPosition, DamageType.None, attack.GetDamage(1.0f) / c.AnimController.Limbs.Length * distFactor, 0.0f, attack.Stun * distFactor, false); - if (force>0.0f) + if (force > 0.0f) { - limb.body.ApplyLinearImpulse(Vector2.Normalize(limb.SimPosition - simPosition) * distFactor * force); + limb.body.ApplyLinearImpulse(Vector2.Normalize(limb.WorldPosition - worldPosition) * distFactor * force); } } } @@ -124,7 +116,7 @@ namespace Barotrauma yield return CoroutineStatus.Success; } - public static void RangedStructureDamage(Vector2 displayPosition, float displayRange, float damage) + public static void RangedStructureDamage(Vector2 worldPosition, float worldRange, float damage) { List structureList = new List(); @@ -137,7 +129,7 @@ namespace Barotrauma if (structure.HasBody && !structure.IsPlatform && - Vector2.Distance(structure.Position, displayPosition) < dist * 3.0f) + Vector2.Distance(structure.WorldPosition, worldPosition) < dist * 3.0f) { structureList.Add(structure); } @@ -147,7 +139,7 @@ namespace Barotrauma { for (int i = 0; i < structure.SectionCount; i++) { - float distFactor = 1.0f - (Vector2.Distance(structure.SectionPosition(i), displayPosition) / displayRange); + float distFactor = 1.0f - (Vector2.Distance(structure.SectionPosition(i, true), worldPosition) / worldRange); if (distFactor > 0.0f) structure.AddDamage(i, damage * distFactor); } } diff --git a/Subsurface/Source/Map/FireSource.cs b/Subsurface/Source/Map/FireSource.cs index 41dfc3d87..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,14 +36,19 @@ namespace Barotrauma } } + public Vector2 WorldPosition + { + get { return Submarine.Position + position; } + } + public Vector2 Size { get { return size; } } - public FireSource(Vector2 position, Hull spawningHull = null, bool networkEvent=false) + public FireSource(Vector2 worldPosition, Hull spawningHull = null, bool networkEvent=false) { - hull = Hull.FindHull(position, spawningHull); + hull = Hull.FindHull(worldPosition, spawningHull); if (hull == null || (!networkEvent && GameMain.Client!=null)) return; if (fireSoundBasic==null) @@ -50,11 +57,16 @@ namespace Barotrauma fireSoundLarge = Sound.Load("Content/Sounds/firelarge.ogg"); } - lightSource = new LightSource(position, 50.0f, new Color(1.0f, 0.9f, 0.6f)); - hull.AddFireSource(this, !networkEvent); - this.position = position - 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 3a62159f0..6c757e85f 100644 --- a/Subsurface/Source/Map/Gap.cs +++ b/Subsurface/Source/Map/Gap.cs @@ -57,12 +57,12 @@ namespace Barotrauma get { return flowTargetHull; } } - public Gap(Rectangle newRect) - : this(newRect, (newRect.Width < newRect.Height)) - { - } + public Gap(Rectangle newRect, Submarine submarine) + : this(newRect, newRect.Width < newRect.Height, submarine) + { } - public Gap(Rectangle newRect, bool isHorizontal) + public Gap(Rectangle newRect, bool isHorizontal, Submarine submarine) + : base (submarine) { rect = newRect; linkedTo = new ObservableCollection(); @@ -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) @@ -89,8 +96,8 @@ namespace Barotrauma public override bool Contains(Vector2 position) { - return (Submarine.RectContains(rect, position) && - !Submarine.RectContains(new Rectangle(rect.X + 4, rect.Y - 4, rect.Width - 8, rect.Height - 8), position)); + return (Submarine.RectContains(WorldRect, position) && + !Submarine.RectContains(MathUtils.ExpandRect(WorldRect, -5), position)); } private void FindHulls() @@ -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)) { @@ -142,7 +149,7 @@ namespace Barotrauma { if (GameMain.DebugDraw) { - Vector2 center = new Vector2(rect.X + rect.Width / 2.0f, -(rect.Y - rect.Width / 2.0f)); + Vector2 center = new Vector2(WorldRect.X + rect.Width / 2.0f, -(WorldRect.Y - rect.Width / 2.0f)); GUI.DrawLine(sb, center, center + flowForce/10.0f, Color.Red); GUI.DrawLine(sb, center + Vector2.One * 5.0f, center + lerpedFlowForce / 10.0f + Vector2.One * 5.0f, Color.Orange); @@ -152,7 +159,7 @@ namespace Barotrauma Color clr = (open == 0.0f) ? Color.Red : Color.Cyan; - GUI.DrawRectangle(sb, new Rectangle(rect.X, -rect.Y, rect.Width, rect.Height), clr*0.5f, true); + GUI.DrawRectangle(sb, new Rectangle(WorldRect.X, -WorldRect.Y, rect.Width, rect.Height), clr * 0.5f, true); if (isHorizontal) { @@ -160,11 +167,11 @@ namespace Barotrauma { if (linkedTo[i].Rect.Center.X > rect.Center.X) { - GUI.DrawRectangle(sb, new Rectangle(rect.Right, -rect.Y, 10, rect.Height), Color.Green * 0.3f, true); + GUI.DrawRectangle(sb, new Rectangle(WorldRect.Right, -WorldRect.Y, 10, rect.Height), Color.Green * 0.3f, true); } else { - GUI.DrawRectangle(sb, new Rectangle(rect.X - 10, -rect.Y, 10, rect.Height), Color.Green * 0.3f, true); + GUI.DrawRectangle(sb, new Rectangle(WorldRect.X - 10, -WorldRect.Y, 10, rect.Height), Color.Green * 0.3f, true); } } } @@ -172,13 +179,13 @@ namespace Barotrauma { for (int i = 0; i < linkedTo.Count; i++) { - if (linkedTo[i].Rect.Y - linkedTo[i].Rect.Height/2.0f > rect.Y) + if (linkedTo[i].Rect.Y - linkedTo[i].Rect.Height / 2.0f > WorldRect.Y) { - GUI.DrawRectangle(sb, new Rectangle(rect.X, -rect.Y - 10, rect.Width, 10), Color.Green * 0.3f, true); + GUI.DrawRectangle(sb, new Rectangle(WorldRect.X, -WorldRect.Y - 10, rect.Width, 10), Color.Green * 0.3f, true); } else { - GUI.DrawRectangle(sb, new Rectangle(rect.X, -rect.Y + rect.Height, rect.Width, 10), Color.Green * 0.3f, true); + GUI.DrawRectangle(sb, new Rectangle(WorldRect.X, -WorldRect.Y + rect.Height, rect.Width, 10), Color.Green * 0.3f, true); } } } @@ -186,7 +193,7 @@ namespace Barotrauma if (isSelected) { GUI.DrawRectangle(sb, - new Vector2(rect.X - 5, -rect.Y - 5), + new Vector2(WorldRect.X - 5, -WorldRect.Y - 5), new Vector2(rect.Width + 10, rect.Height + 10), Color.Red); } @@ -200,7 +207,7 @@ namespace Barotrauma int index = (int)Math.Floor(flowForce.Length() / 100.0f); index = Math.Min(index,2); - soundIndex = SoundPlayer.flowSounds[index].Loop(soundIndex, soundVolume, Position, 2000.0f); + soundIndex = SoundPlayer.flowSounds[index].Loop(soundIndex, soundVolume, WorldPosition, 2000.0f); flowForce = Vector2.Zero; lerpedFlowForce = Vector2.Lerp(lerpedFlowForce, flowForce, 0.05f); @@ -229,7 +236,7 @@ namespace Barotrauma { pos.X += Math.Sign(flowForce.X); pos.Y = MathHelper.Clamp((higherSurface+lowerSurface)/2.0f, rect.Y - rect.Height, rect.Y); - + Vector2 velocity = new Vector2( MathHelper.Clamp(flowForce.X, -5000.0f, 5000.0f) * Rand.Range(0.5f, 0.7f), flowForce.Y * Rand.Range(0.5f, 0.7f)); @@ -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) //{ @@ -564,15 +577,31 @@ namespace Barotrauma } - public static void Load(XElement element) + 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; - Gap g = new Gap(rect); + 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); g.linkedToID = new List(); diff --git a/Subsurface/Source/Map/Hull.cs b/Subsurface/Source/Map/Hull.cs index 5573385fa..ef7ce7eb7 100644 --- a/Subsurface/Source/Map/Hull.cs +++ b/Subsurface/Source/Map/Hull.cs @@ -133,7 +133,8 @@ namespace Barotrauma get { return fireSources; } } - public Hull(Rectangle rectangle) + public Hull(Rectangle rectangle, Submarine submarine) + : base (submarine) { rect = rectangle; @@ -155,7 +156,7 @@ namespace Barotrauma surface = rect.Y - rect.Height; aiTarget = new AITarget(this); - aiTarget.SightRange = (rect.Width + rect.Height)*10.0f; + aiTarget.SightRange = (rect.Width + rect.Height)*5.0f; hullList.Add(this); @@ -169,8 +170,8 @@ namespace Barotrauma public override bool Contains(Vector2 position) { - return (Submarine.RectContains(rect, position) && - !Submarine.RectContains(new Rectangle(rect.X + 8, rect.Y - 8, rect.Width - 16, rect.Height - 16), position)); + return (Submarine.RectContains(WorldRect, position) && + !Submarine.RectContains(MathUtils.ExpandRect(WorldRect, -8), position)); } public int GetWaveIndex(Vector2 position) @@ -228,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()) @@ -244,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()) { @@ -269,8 +270,11 @@ namespace Barotrauma float maxDelta = Math.Max(Math.Abs(rightDelta[i]), Math.Abs(leftDelta[i])); if (maxDelta > Rand.Range(1.0f,10.0f)) { + Vector2 particlePos = new Vector2(rect.X + WaveWidth * i, surface + waveY[i]); + if (Submarine != null) particlePos += Submarine.Position; + GameMain.ParticleManager.CreateParticle("mist", - new Vector2(rect.X + WaveWidth * i,surface + waveY[i]), + particlePos, new Vector2(0.0f, -50.0f), 0.0f, this); } @@ -349,25 +353,28 @@ namespace Barotrauma { if (!editing && !GameMain.DebugDraw) return; - GUI.DrawRectangle(spriteBatch, - new Vector2(rect.X, -rect.Y), - new Vector2(rect.Width, rect.Height), - isHighlighted ? Color.Green : Color.Blue); + Rectangle drawRect = + Submarine == null ? rect : new Rectangle((int)(Submarine.DrawPosition.X + rect.X), (int)(Submarine.DrawPosition.Y + rect.Y), rect.Width, rect.Height); GUI.DrawRectangle(spriteBatch, - new Rectangle(rect.X, -rect.Y, rect.Width, rect.Height), + new Vector2(drawRect.X, -drawRect.Y), + new Vector2(rect.Width, rect.Height), + Color.Blue); + + GUI.DrawRectangle(spriteBatch, + new Rectangle(drawRect.X, -drawRect.Y, rect.Width, rect.Height), Color.Red*((100.0f-OxygenPercentage)/400.0f), true); spriteBatch.DrawString(GUI.Font, "Pressure: " + ((int)pressure - rect.Y).ToString() + - " - Oxygen: "+((int)OxygenPercentage), new Vector2(rect.X+10, -rect.Y+10), Color.Black); - spriteBatch.DrawString(GUI.Font, volume +" / "+ FullVolume, new Vector2(rect.X+10, -rect.Y+30), Color.Black); + " - Oxygen: " + ((int)OxygenPercentage), new Vector2(drawRect.X + 10, -drawRect.Y + 10), Color.Black); + spriteBatch.DrawString(GUI.Font, volume + " / " + FullVolume, new Vector2(drawRect.X + 10, -drawRect.Y + 30), Color.Black); - if (isSelected && editing) + if ((isSelected || isHighlighted) && editing) { GUI.DrawRectangle(spriteBatch, - new Vector2(rect.X - 5, -rect.Y - 5), - new Vector2(rect.Width + 10, rect.Height + 10), - Color.Red); + new Vector2(drawRect.X + 5, -drawRect.Y + 5), + new Vector2(rect.Width - 10, rect.Height - 10), + isHighlighted ? Color.LightBlue*0.5f : Color.Red*0.5f, true); } } @@ -376,12 +383,13 @@ namespace Barotrauma if (renderer.PositionInBuffer > renderer.vertices.Length - 6) return; //calculate where the surface should be based on the water volume - float top = rect.Y; - float bottom = rect.Y - rect.Height; + float top = rect.Y+Submarine.DrawPosition.Y; + float bottom = top - rect.Height; float surfaceY = bottom + Volume / rect.Width; //interpolate the position of the rendered surface towards the "target surface" - surface = surface + (surfaceY - surface) / 10.0f; + surface = surface + ((surfaceY - Submarine.DrawPosition.Y) - surface) / 10.0f; + float drawSurface = surface + Submarine.DrawPosition.Y; Matrix transform = cam.Transform * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f; @@ -393,15 +401,16 @@ namespace Barotrauma Vector3[] corners = new Vector3[4]; - corners[0] = new Vector3(rect.X, top, 0.0f); - corners[1] = new Vector3(rect.X + rect.Width, top, 0.0f); + corners[0] = new Vector3(rect.X, rect.Y, 0.0f); + corners[1] = new Vector3(rect.X + rect.Width, rect.Y, 0.0f); - corners[2] = new Vector3(corners[1].X, bottom, 0.0f); - corners[3] = new Vector3(corners[0].X, bottom, 0.0f); + corners[2] = new Vector3(corners[1].X, rect.Y-rect.Height, 0.0f); + corners[3] = new Vector3(corners[0].X, corners[2].Y, 0.0f); Vector2[] uvCoords = new Vector2[4]; for (int i = 0; i < 4; i++ ) { + corners[i] += new Vector3(Submarine.DrawPosition, 0.0f); uvCoords[i] = Vector2.Transform(new Vector2(corners[i].X, -corners[i].Y), transform); } @@ -418,8 +427,8 @@ namespace Barotrauma return; } - int x = rect.X; - int start = (int)Math.Floor((float)(cam.WorldView.X - x) / WaveWidth); + float x = rect.X + Submarine.DrawPosition.X; + int start = (int)Math.Floor((cam.WorldView.X - x) / WaveWidth); start = Math.Max(start, 0); int end = (waveY.Length - 1) @@ -435,7 +444,7 @@ namespace Barotrauma Vector3[] corners = new Vector3[4]; corners[0] = new Vector3(x, top, 0.0f); - corners[3] = new Vector3(corners[0].X, surface + waveY[i], 0.0f); + corners[3] = new Vector3(corners[0].X, drawSurface + waveY[i], 0.0f); //skip adjacent "water rects" if the surface of the water is roughly at the same position int width = WaveWidth; @@ -446,7 +455,7 @@ namespace Barotrauma } corners[1] = new Vector3(x + width, top, 0.0f); - corners[2] = new Vector3(corners[1].X, surface + waveY[i+1], 0.0f); + corners[2] = new Vector3(corners[1].X, drawSurface + waveY[i + 1], 0.0f); Vector2[] uvCoords = new Vector2[4]; for (int n = 0; n < 4; n++) @@ -470,21 +479,21 @@ namespace Barotrauma } //returns the water block which contains the point (or null if it isn't inside any) - public static Hull FindHull(Vector2 position, Hull guess = null) + public static Hull FindHull(Vector2 position, Hull guess = null, bool useWorldCoordinates = true) { - return FindHull(position, hullList, guess); + return FindHull(position, hullList, guess, useWorldCoordinates); } - public static Hull FindHull(Vector2 position, List hulls, Hull guess = null) + public static Hull FindHull(Vector2 position, List hulls, Hull guess = null, bool useWorldCoordinates = true) { if (guess != null && hulls.Contains(guess)) { - if (Submarine.RectContains(guess.rect, position)) return guess; + if (Submarine.RectContains(useWorldCoordinates ? guess.WorldRect : guess.rect, position)) return guess; } - foreach (Hull w in hulls) + foreach (Hull hull in hulls) { - if (Submarine.RectContains(w.rect, position)) return w; + if (Submarine.RectContains(useWorldCoordinates ? hull.WorldRect : hull.rect, position)) return hull; } return null; @@ -515,27 +524,46 @@ 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); return element; } - public static void Load(XElement element) + 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; - Hull h = new Hull(rect); + 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); h.volume = ToolBox.GetAttributeFloat(element, "pressure", 0.0f); diff --git a/Subsurface/Source/Map/IDamageable.cs b/Subsurface/Source/Map/IDamageable.cs index 995c3121f..9b56fc410 100644 --- a/Subsurface/Source/Map/IDamageable.cs +++ b/Subsurface/Source/Map/IDamageable.cs @@ -9,6 +9,11 @@ namespace Barotrauma get; } + Vector2 WorldPosition + { + get; + } + float Health { get; diff --git a/Subsurface/Source/Map/Levels/Level.cs b/Subsurface/Source/Map/Levels/Level.cs index 8d8fc3c50..29a5c887a 100644 --- a/Subsurface/Source/Map/Levels/Level.cs +++ b/Subsurface/Source/Map/Levels/Level.cs @@ -6,6 +6,7 @@ using Lidgren.Network; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; +using System.Linq; using System.Collections.Generic; using System.Diagnostics; using Voronoi2; @@ -24,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; @@ -40,7 +41,6 @@ namespace Barotrauma //List bodies; private List cells; - private VertexPositionTexture[] vertices; //private VertexBuffer vertexBuffer; private Vector2 startPosition, endPosition; @@ -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,21 +65,7 @@ namespace Barotrauma { get { return endPosition; } } - - public bool AtEndPosition - { - get; - private set; - } - - public Vector2 Position - { - get - { - return cells==null ? Vector2.Zero : ConvertUnits.ToDisplayUnits(cells[0].body.Position); - } - } - + public List PositionsOfInterest { get { return positionsOfInterest; } @@ -247,7 +227,7 @@ namespace Barotrauma for (int i = 0; i <3 ; i++ ) { Vector2 position = pathCells[Rand.Range((int)(pathCells.Count * 0.5f), pathCells.Count - 2, false)].Center; - WayPoint wayPoint = new WayPoint(new Rectangle((int)position.X, (int)position.Y, 10, 10)); + WayPoint wayPoint = new WayPoint(new Rectangle((int)position.X, (int)position.Y, 10, 10), null); wayPoint.MoveWithLevel = true; wayPoint.SpawnType = SpawnType.Enemy; } @@ -321,7 +301,9 @@ namespace Barotrauma startPosition.Y = borders.Height; endPosition.Y = borders.Height; - vertices = GeneratePolygons(cells, pathCells); + renderer.BodyVertices = GeneratePolygons(cells, pathCells); + renderer.WallVertices = GenerateWallShapes(cells); + wrappingWalls = new WrappingWall[2, 2]; @@ -332,7 +314,13 @@ namespace Barotrauma wrappingWalls[side, i] = new WrappingWall(pathCells, cells, borders.Height * 0.5f, (side == 0 ? -1 : 1) * (i == 0 ? 1 : 2)); - wrappingWalls[side, i].Vertices = GeneratePolygons(wrappingWalls[side, i].Cells, new List()); + wrappingWalls[side, i].BodyVertices = GeneratePolygons(wrappingWalls[side, i].Cells, new List(), false); + wrappingWalls[side, i].WallVertices = GenerateWallShapes(wrappingWalls[side, i].Cells); + //wrappingWalls[side, i].Cells[0].edges[1].isSolid = false; + //wrappingWalls[side, i].Cells[0].edges[3].isSolid = false; + + //wrappingWalls[side, i].Cells[wrappingWalls[side, i].Cells.Count-1].edges[1].isSolid = false; + //wrappingWalls[side, i].Cells[wrappingWalls[side, i].Cells.Count - 1].edges[3].isSolid = false; } } @@ -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); @@ -462,7 +452,7 @@ namespace Barotrauma if (placeWaypoints) { - WayPoint newWaypoint = new WayPoint(new Rectangle((int)pathCells[0].Center.X, (int)(borders.Height + shaftHeight), 10, 10)); + WayPoint newWaypoint = new WayPoint(new Rectangle((int)pathCells[0].Center.X, (int)(borders.Height + shaftHeight), 10, 10), null); newWaypoint.MoveWithLevel = true; WayPoint prevWaypoint = newWaypoint; @@ -479,7 +469,7 @@ namespace Barotrauma } if (i >= pathCells.Count) break; - newWaypoint = new WayPoint(new Rectangle((int)pathCells[i].Center.X, (int)pathCells[i].Center.Y, 10, 10)); + newWaypoint = new WayPoint(new Rectangle((int)pathCells[i].Center.X, (int)pathCells[i].Center.Y, 10, 10), null); newWaypoint.MoveWithLevel = true; if (prevWaypoint != null) { @@ -489,7 +479,7 @@ namespace Barotrauma prevWaypoint = newWaypoint; } - newWaypoint = new WayPoint(new Rectangle((int)pathCells[pathCells.Count - 1].Center.X, (int)(borders.Height + shaftHeight), 10, 10)); + newWaypoint = new WayPoint(new Rectangle((int)pathCells[pathCells.Count - 1].Center.X, (int)(borders.Height + shaftHeight), 10, 10), null); newWaypoint.MoveWithLevel = true; prevWaypoint.linkedTo.Add(newWaypoint); @@ -624,9 +614,9 @@ namespace Barotrauma } - private VertexPositionTexture[] GeneratePolygons(List cells, List emptyCells) + private VertexPositionColor[] GeneratePolygons(List cells, List emptyCells, bool setSolid=true) { - List verticeList = new List(); + List verticeList = new List(); //bodies = new List(); List tempVertices = new List(); @@ -647,7 +637,7 @@ namespace Barotrauma VoronoiCell adjacentCell = ge.AdjacentCell(cell); if (adjacentCell!=null && cells.Contains(adjacentCell)) continue; - ge.isSolid = true; + if (setSolid) ge.isSolid = true; if (!bodyPoints.Contains(ge.point1)) bodyPoints.Add(ge.point1); if (!bodyPoints.Contains(ge.point2)) bodyPoints.Add(ge.point2); @@ -664,11 +654,10 @@ namespace Barotrauma { foreach (Vector2 vertex in triangles[i]) { - verticeList.Add(new VertexPositionTexture(new Vector3(vertex, 0.0f), vertex/1000.0f)); + verticeList.Add(new VertexPositionColor(new Vector3(vertex, 0.0f), Color.Black)); } } - if (bodyPoints.Count < 2) continue; if (bodyPoints.Count < 3) @@ -712,117 +701,266 @@ namespace Barotrauma return verticeList.ToArray(); } - public void SetPosition(Vector2 pos) + private VertexPositionTexture[] GenerateWallShapes(List cells) { - Vector2 amount = pos - Position; - Vector2 simAmount = ConvertUnits.ToSimUnits(amount); - //foreach (VoronoiCell cell in cells) - //{ - // if (cell.body == null) continue; - // cell.body.SleepingAllowed = false; - // cell.body.SetTransform(cell.body.Position + simAmount, cell.body.Rotation); - //} + float inwardThickness = 500.0f, outWardThickness = 30.0f; - foreach (Body body in bodies) - { - body.SetTransform(body.Position + simAmount, body.Rotation); - } + List verticeList = new List(); - foreach (MapEntity mapEntity in MapEntity.mapEntityList) + foreach (VoronoiCell cell in cells) { - Item item = mapEntity as Item; - if (item == null) + if (cell.body == null) continue; + foreach (GraphEdge edge in cell.edges) { - //if (!mapEntity.MoveWithLevel) continue; - //mapEntity.Move(amount); - } - else if (item.body != null) - { - if (item.CurrentHull != null) continue; - item.SetTransform(item.SimPosition+amount, item.body.Rotation); + if (edge.cell1 != null && edge.cell1.body == null) edge.cell1 = null; + if (edge.cell2 != null && edge.cell2.body == null) edge.cell2 = null; + + CompareCCW compare = new CompareCCW(cell.Center); + if (compare.Compare(edge.point1, edge.point2) == -1) + { + var temp = edge.point1; + edge.point1 = edge.point2; + edge.point2 = temp; + } } } - //WrappingWall.UpdateWallShift(Position, wrappingWalls); - } - - Vector2 prevVelocity; - public void Move(Vector2 amount) - { - Vector2 simVelocity = ConvertUnits.ToSimUnits(amount / (float)Physics.step); - - foreach (Body body in bodies) + foreach (VoronoiCell cell in cells) { - body.LinearVelocity = simVelocity; - } - - foreach (Character character in Character.CharacterList) - { - foreach (Limb limb in character.AnimController.Limbs) + if (cell.body == null) continue; + foreach (GraphEdge edge in cell.edges) { - if (character.AnimController.CurrentHull != null) continue; + if (!edge.isSolid) continue; + + GraphEdge leftEdge = null, rightEdge = null; + + foreach (GraphEdge edge2 in cell.edges) + { + if (edge == edge2) continue; + if (edge.point1 == edge2.point1 || + edge.point1 == edge2.point2) + { + leftEdge = edge2; + } + else if(edge.point2 == edge2.point2 || edge.point2 == edge2.point1) + { + rightEdge = edge2; + } + } - limb.body.LinearVelocity += simVelocity; + Vector2 leftNormal = Vector2.Zero, rightNormal = Vector2.Zero; + + if (leftEdge == null) + { + leftNormal = GetEdgeNormal(edge, cell); + } + else + { + leftNormal = (leftEdge.isSolid) ? + Vector2.Normalize(GetEdgeNormal(leftEdge) + GetEdgeNormal(edge, cell)) : + Vector2.Normalize(leftEdge.Center - edge.point1); + } + + + if (rightEdge == null) + { + rightNormal = GetEdgeNormal(edge, cell); + } + else + { + rightNormal = (rightEdge.isSolid) ? + Vector2.Normalize(GetEdgeNormal(rightEdge) + GetEdgeNormal(edge, cell)) : + Vector2.Normalize(rightEdge.Center - edge.point2); + } + + + + + for (int i = 0; i < 2; i++) + { + Vector2[] verts = new Vector2[3]; + VertexPositionTexture[] vertPos = new VertexPositionTexture[3]; + + + if (i==0) + { + verts[0] = edge.point1 - leftNormal * outWardThickness; + verts[1] = edge.point2 - rightNormal * outWardThickness; + verts[2] = edge.point1 + leftNormal * inwardThickness; + + vertPos[0] = new VertexPositionTexture(new Vector3(verts[0], 0.0f), Vector2.Zero); + vertPos[1] = new VertexPositionTexture(new Vector3(verts[1], 0.0f), Vector2.UnitX); + vertPos[2] = new VertexPositionTexture(new Vector3(verts[2], 0.0f), new Vector2(0, 0.5f)); + } + else + { + verts[0] = edge.point1 + leftNormal * inwardThickness; + verts[1] = edge.point2 - rightNormal * outWardThickness; + verts[2] = edge.point2 + rightNormal * inwardThickness; + + vertPos[0] = new VertexPositionTexture(new Vector3(verts[0], 0.0f), new Vector2(0.0f, 0.5f)); + vertPos[1] = new VertexPositionTexture(new Vector3(verts[1], 0.0f), Vector2.UnitX); + vertPos[2] = new VertexPositionTexture(new Vector3(verts[2], 0.0f), new Vector2(1.0f, 0.5f)); + } + + var comparer = new CompareCCW((verts[0] + verts[1] + verts[2]) / 3.0f); + Array.Sort(verts, vertPos, comparer); + + for (int j = 0; j<3; j++) + { + verticeList.Add(vertPos[j]); + } + } } } - foreach (Item item in Item.ItemList) - { - if (item.body==null || item.CurrentHull != null) continue; - item.body.LinearVelocity += simVelocity; + return verticeList.ToArray(); + } + + private Vector2 GetEdgeNormal(GraphEdge edge, VoronoiCell cell = null) + { + if (cell == null) cell = edge.AdjacentCell(null); + if (cell == null) return Vector2.UnitX; + + CompareCCW compare = new CompareCCW(cell.Center); + if (compare.Compare(edge.point1, edge.point2) == -1) + { + var temp = edge.point1; + edge.point1 = edge.point2; + edge.point2 = temp; } - AtStartPosition = Vector2.Distance(startPosition, -Position) < ExitDistance; - AtEndPosition = Vector2.Distance(endPosition, -Position) < ExitDistance; + Vector2 normal = Vector2.Zero; + + normal = Vector2.Normalize(edge.point2 - edge.point1); + Vector2 diffToCell = Vector2.Normalize(cell.Center - edge.point2); + + normal = new Vector2(-normal.Y, normal.X); + + if (Vector2.Dot(normal, diffToCell) < 0) + { + normal = -normal; + } - prevVelocity = simVelocity; - - WrappingWall.UpdateWallShift(-Position, wrappingWalls); + return normal; } - public static void AfterWorldStep() + //public void SetPosition(Vector2 pos) + //{ + // Vector2 amount = pos - Position; + // Vector2 simAmount = ConvertUnits.ToSimUnits(amount); + // //foreach (VoronoiCell cell in cells) + // //{ + // // if (cell.body == null) continue; + // // cell.body.SleepingAllowed = false; + // // cell.body.SetTransform(cell.body.Position + simAmount, cell.body.Rotation); + // //} + + // foreach (Body body in bodies) + // { + // body.SetTransform(body.Position + simAmount, body.Rotation); + // } + + // foreach (MapEntity mapEntity in MapEntity.mapEntityList) + // { + // Item item = mapEntity as Item; + // if (item == null) + // { + // //if (!mapEntity.MoveWithLevel) continue; + // //mapEntity.Move(amount); + // } + // else if (item.body != null) + // { + // if (item.CurrentHull != null) continue; + // item.SetTransform(item.SimPosition+amount, item.body.Rotation); + // } + // } + + // //WrappingWall.UpdateWallShift(Position, wrappingWalls); + //} + + //Vector2 prevVelocity; + //public void Move(Vector2 amount) + //{ + // Vector2 simVelocity = ConvertUnits.ToSimUnits(amount / (float)Physics.step); + + // foreach (Body body in bodies) + // { + // body.LinearVelocity = simVelocity; + // } + + // foreach (Character character in Character.CharacterList) + // { + // foreach (Limb limb in character.AnimController.Limbs) + // { + // if (character.AnimController.CurrentHull != null) continue; + + // limb.body.LinearVelocity += simVelocity; + // } + // } + + // foreach (Item item in Item.ItemList) + // { + // if (item.body==null || item.CurrentHull != null) continue; + // item.body.LinearVelocity += simVelocity; + // } + + // AtStartPosition = Vector2.Distance(startPosition, -Position) < ExitDistance; + // AtEndPosition = Vector2.Distance(endPosition, -Position) < ExitDistance; + + // prevVelocity = simVelocity; + + // WrappingWall.UpdateWallShift(-Position, wrappingWalls); + //} + + //public static void AfterWorldStep() + //{ + // if (loaded == null) return; + + // loaded.ResetBodyVelocities(); + //} + + //private void ResetBodyVelocities() + //{ + // if (prevVelocity == Vector2.Zero) return; + // if (!MathUtils.IsValid(prevVelocity)) + // { + // prevVelocity = Vector2.Zero; + // return; + // } + + // foreach (Character character in Character.CharacterList) + // { + // if (character.AnimController.CurrentHull != null) continue; + + // foreach (Limb limb in character.AnimController.Limbs) + // { + // limb.body.LinearVelocity -= prevVelocity; + // } + // } + + // foreach (Item item in Item.ItemList) + // { + // if (item.body == null || item.CurrentHull != null) continue; + // item.body.LinearVelocity -= prevVelocity; + // } + //} + + public void Update (float deltaTime) { - if (loaded == null) return; - - loaded.ResetBodyVelocities(); + renderer.Update(deltaTime); } - private void ResetBodyVelocities() - { - if (prevVelocity == Vector2.Zero) return; - if (!MathUtils.IsValid(prevVelocity)) - { - prevVelocity = Vector2.Zero; - return; - } - - foreach (Character character in Character.CharacterList) - { - if (character.AnimController.CurrentHull != null) continue; - - foreach (Limb limb in character.AnimController.Limbs) - { - limb.body.LinearVelocity -= prevVelocity; - } - } - - foreach (Item item in Item.ItemList) - { - if (item.body == null || item.CurrentHull != null) continue; - item.body.LinearVelocity -= prevVelocity; - } - } - - public void Draw(SpriteBatch spriteBatch) + public void DrawFront(SpriteBatch spriteBatch) { if (renderer == null) return; renderer.Draw(spriteBatch); } - public void Render(GraphicsDevice graphicsDevice, Camera cam) + public void DrawBack(SpriteBatch spriteBatch, Camera cam, BackgroundCreatureManager backgroundSpriteManager = null) { if (renderer == null) return; - renderer.Render(graphicsDevice, cam, vertices); + renderer.DrawBackground(spriteBatch, cam, backgroundSpriteManager); } @@ -841,7 +979,7 @@ namespace Barotrauma System.Diagnostics.Debug.WriteLine("avgpos: " + avgPos / cells.Count); - System.Diagnostics.Debug.WriteLine("pos: " + Position); + //System.Diagnostics.Debug.WriteLine("pos: " + Position); } public List GetCells(Vector2 pos, int searchDepth = 2) @@ -911,10 +1049,10 @@ namespace Barotrauma { if (onlySolid && !cell.edges[i].isSolid) continue; - Vector2 start = cell.edges[i].point1 + Position; + Vector2 start = cell.edges[i].point1; start.Y = -start.Y; - Vector2 end = cell.edges[i].point2 + Position; + Vector2 end = cell.edges[i].point2; end.Y = -end.Y; edges.Add(new Vector2[] { start, end }); @@ -932,7 +1070,7 @@ namespace Barotrauma foreach (VoronoiCell cell in wrappingWalls[side, n].Cells) { - Vector2 offset = wrappingWalls[side, n].Offset + Position; + Vector2 offset = wrappingWalls[side, n].Offset; for (int i = 0; i < cell.edges.Count; i++) { if (onlySolid && !cell.edges[i].isSolid) continue; @@ -954,9 +1092,7 @@ namespace Barotrauma private void Unload() { renderer = null; - - vertices = null; - + cells = null; bodies.Clear(); diff --git a/Subsurface/Source/Map/Levels/LevelRenderer.cs b/Subsurface/Source/Map/Levels/LevelRenderer.cs index c51393cae..05ee49509 100644 --- a/Subsurface/Source/Map/Levels/LevelRenderer.cs +++ b/Subsurface/Source/Map/Levels/LevelRenderer.cs @@ -2,6 +2,7 @@ using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; @@ -9,44 +10,136 @@ namespace Barotrauma { class LevelRenderer { - private static BasicEffect basicEffect; + private static Sprite background, backgroundTop; + private static Texture2D dustParticles; private static Texture2D shaftTexture; - private Level level; + private static BackgroundSpriteManager backgroundSpriteManager; + Vector2 dustOffset; + + private Level level; + + public VertexPositionTexture[] WallVertices; + public VertexPositionColor[] BodyVertices; + public LevelRenderer(Level level) { if (shaftTexture == null) shaftTexture = TextureLoader.FromFile("Content/Map/shaft.png"); + if (background==null) + { + background = new Sprite("Content/Map/background.png", Vector2.Zero); + backgroundTop = new Sprite("Content/Map/background2.png", Vector2.Zero); + dustParticles = Sprite.LoadTexture("Content/Map/dustparticles.png"); + } + if (basicEffect == null) { - basicEffect = new BasicEffect(GameMain.CurrGraphicsDevice); basicEffect.VertexColorEnabled = false; basicEffect.TextureEnabled = true; - basicEffect.Texture = TextureLoader.FromFile("Content/Map/iceSurface.png"); + 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, BackgroundCreatureManager backgroundCreatureManager = null) + { + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearWrap); + + Vector2 backgroundPos = cam.Position; + //if (Level.Loaded != null) backgroundPos -= Level.Loaded.Position; + backgroundPos.Y = -backgroundPos.Y; + backgroundPos /= 20.0f; + + if (backgroundPos.Y < 1024) + { + if (backgroundPos.Y > -1024) + { + background.SourceRect = new Rectangle((int)backgroundPos.X, (int)Math.Max(backgroundPos.Y, 0), 1024, 1024); + background.DrawTiled(spriteBatch, + (backgroundPos.Y < 0) ? new Vector2(0.0f, -backgroundPos.Y) : Vector2.Zero, + new Vector2(GameMain.GraphicsWidth, 1024 - backgroundPos.Y), + Vector2.Zero, Color.White); + } + + if (backgroundPos.Y < 0) + { + backgroundTop.SourceRect = new Rectangle((int)backgroundPos.X, (int)backgroundPos.Y, 1024, (int)Math.Min(-backgroundPos.Y, 1024)); + backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, Math.Min(-backgroundPos.Y, GameMain.GraphicsHeight)), + Vector2.Zero, Color.White); + } + } + + spriteBatch.End(); + + spriteBatch.Begin(SpriteSortMode.BackToFront, + BlendState.AlphaBlend, + SamplerState.LinearWrap, DepthStencilState.Default, null, null, + cam.Transform); + + backgroundSpriteManager.DrawSprites(spriteBatch); + + if (backgroundCreatureManager!=null) backgroundCreatureManager.Draw(spriteBatch); + + spriteBatch.End(); + + spriteBatch.Begin(SpriteSortMode.BackToFront, + BlendState.AlphaBlend, + SamplerState.LinearWrap); + + backgroundPos = new Vector2(cam.WorldView.X, cam.WorldView.Y) + dustOffset; + //if (Level.Loaded != null) backgroundPos -= Level.Loaded.Position; + + Rectangle viewRect = cam.WorldView; + viewRect.Y = -viewRect.Y; + + float multiplier = 0.8f; + for (int i = 1; i < 5; i++) + { + spriteBatch.Draw(dustParticles, new Rectangle(0,0,GameMain.GraphicsWidth,GameMain.GraphicsHeight), + new Rectangle((int)((backgroundPos.X * multiplier)), (int)((-backgroundPos.Y * multiplier)), cam.WorldView.Width*2, cam.WorldView.Height*2), + Color.White * multiplier, 0.0f, Vector2.Zero, SpriteEffects.None, 1.0f - multiplier); + multiplier -= 0.1f; + } + + spriteBatch.End(); + + RenderWalls(GameMain.CurrGraphicsDevice, cam); + } + public void Draw(SpriteBatch spriteBatch) { - Vector2 pos = level.EndPosition; - pos.Y = -pos.Y - level.Position.Y; + Vector2 pos = new Vector2(0.0f, -level.StartPosition.Y);// level.EndPosition; if (GameMain.GameScreen.Cam.WorldView.Y < -pos.Y - 512) return; - pos.X = GameMain.GameScreen.Cam.WorldView.X - 512.0f; - //pos.X += Position.X % 512; + pos.X = GameMain.GameScreen.Cam.WorldView.X -512.0f; int width = (int)(Math.Ceiling(GameMain.GameScreen.Cam.WorldView.Width / 512.0f + 2.0f) * 512.0f); spriteBatch.Draw(shaftTexture, - new Rectangle((int)(MathUtils.Round(pos.X, 512.0f) + level.Position.X % 512), (int)pos.Y, width, 512), + new Rectangle((int)(MathUtils.Round(pos.X, 512.0f)), (int)pos.Y, width, 512), new Rectangle(0, 0, width, 256), Color.White, 0.0f, Vector2.Zero, @@ -54,36 +147,50 @@ namespace Barotrauma } - public void Render(GraphicsDevice graphicsDevice, Camera cam, VertexPositionTexture[] vertices) + public void RenderWalls(GraphicsDevice graphicsDevice, Camera cam) { - if (vertices == null) return; - if (vertices.Length <= 0) return; + if (WallVertices == null || WallVertices.Length <= 0) return; - basicEffect.World = Matrix.CreateTranslation(new Vector3(level.Position, 0.0f)) * cam.ShaderTransform + basicEffect.World = cam.ShaderTransform * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f; - basicEffect.CurrentTechnique.Passes[0].Apply(); - graphicsDevice.SamplerStates[0] = SamplerState.LinearWrap; - graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, (int)Math.Floor(vertices.Length / 3.0f)); + basicEffect.VertexColorEnabled = true; + basicEffect.TextureEnabled = false; + basicEffect.CurrentTechnique = basicEffect.Techniques["BasicEffect_VertexColor"]; + basicEffect.CurrentTechnique.Passes[0].Apply(); + graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, BodyVertices, 0, (int)Math.Floor(BodyVertices.Length / 3.0f)); for (int side = 0; side < 2; side++) { for (int i = 0; i < 2; i++) { - basicEffect.World = Matrix.CreateTranslation( - new Vector3(level.Position + level.WrappingWalls[side, i].Offset, 0.0f)) * - cam.ShaderTransform * - Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f; - - basicEffect.CurrentTechnique.Passes[0].Apply(); - graphicsDevice.DrawUserPrimitives( - PrimitiveType.TriangleList, - level.WrappingWalls[side, i].Vertices, 0, - (int)Math.Floor(level.WrappingWalls[side, i].Vertices.Length / 3.0f)); + PrimitiveType.TriangleList, level.WrappingWalls[side, i].BodyVertices, 0, + (int)Math.Floor(level.WrappingWalls[side, i].BodyVertices.Length / 3.0f)); + + } + } + + basicEffect.VertexColorEnabled = false; + basicEffect.TextureEnabled = true; + basicEffect.CurrentTechnique = basicEffect.Techniques["BasicEffect_Texture"]; + basicEffect.CurrentTechnique.Passes[0].Apply(); + graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, WallVertices, 0, (int)Math.Floor(WallVertices.Length / 3.0f)); + + for (int side = 0; side < 2; side++) + { + for (int i = 0; i < 2; i++) + { + basicEffect.VertexColorEnabled = false; + basicEffect.TextureEnabled = true; + basicEffect.CurrentTechnique = basicEffect.Techniques["BasicEffect_Texture"]; + basicEffect.CurrentTechnique.Passes[0].Apply(); + graphicsDevice.DrawUserPrimitives( + PrimitiveType.TriangleList, level.WrappingWalls[side, i].WallVertices, 0, + (int)Math.Floor(level.WrappingWalls[side, i].WallVertices.Length / 3.0f)); } } diff --git a/Subsurface/Source/Map/Levels/VoronoiElements.cs b/Subsurface/Source/Map/Levels/VoronoiElements.cs index adf3f7832..529e21749 100644 --- a/Subsurface/Source/Map/Levels/VoronoiElements.cs +++ b/Subsurface/Source/Map/Levels/VoronoiElements.cs @@ -180,6 +180,11 @@ namespace Voronoi2 public bool isSolid; + public Vector2 Center + { + get { return (point1 + point2) / 2.0f; } + } + public VoronoiCell AdjacentCell(VoronoiCell cell) { if (cell1==cell) diff --git a/Subsurface/Source/Map/Levels/WrappingWall.cs b/Subsurface/Source/Map/Levels/WrappingWall.cs index 65314d417..5a8db2df9 100644 --- a/Subsurface/Source/Map/Levels/WrappingWall.cs +++ b/Subsurface/Source/Map/Levels/WrappingWall.cs @@ -15,7 +15,9 @@ namespace Barotrauma public const float WallWidth = 20000.0f; - public VertexPositionTexture[] Vertices; + public VertexPositionTexture[] WallVertices; + + public VertexPositionColor[] BodyVertices; private Vector2 midPos; private int slot; @@ -95,8 +97,15 @@ namespace Barotrauma vertices[3] = vertices[0] + Vector2.UnitY * wallSectionSize.Y; VoronoiCell wallCell = new VoronoiCell(vertices); + wallCell.edges[0].cell1 = wallCell; wallCell.edges[1].cell1 = wallCell; + wallCell.edges[2].cell1 = wallCell; wallCell.edges[3].cell1 = wallCell; + + wallCell.edges[0].isSolid = true; + wallCell.edges[2].isSolid = true; + + if (i > 1) { wallCell.edges[1].cell2 = cells[i - 2]; diff --git a/Subsurface/Source/Map/Lights/ConvexHull.cs b/Subsurface/Source/Map/Lights/ConvexHull.cs index b3f6a486f..fe5db85c5 100644 --- a/Subsurface/Source/Map/Lights/ConvexHull.cs +++ b/Subsurface/Source/Map/Lights/ConvexHull.cs @@ -38,6 +38,8 @@ namespace Barotrauma.Lights private VertexPositionColor[] shadowVertices; private VertexPositionTexture[] penumbraVertices; + private Entity parentEntity; + private Rectangle boundingBox; public bool Enabled @@ -51,7 +53,7 @@ namespace Barotrauma.Lights get { return boundingBox; } } - public ConvexHull(Vector2[] points, Color color) + public ConvexHull(Vector2[] points, Color color, Entity parent) { if (shadowEffect == null) { @@ -67,6 +69,8 @@ namespace Barotrauma.Lights penumbraEffect.Texture = TextureLoader.FromFile("Content/Lights/penumbra.png"); } + parentEntity = parent; + cachedShadows = new Dictionary(); vertices = points; @@ -121,6 +125,18 @@ namespace Barotrauma.Lights vertices = points; } + public bool Intersects(Rectangle rect) + { + Rectangle transformedBounds = boundingBox; + if (parentEntity != null && parentEntity.Submarine != null) + { + transformedBounds.X += (int)parentEntity.Submarine.Position.X; + transformedBounds.Y += (int)parentEntity.Submarine.Position.Y; + } + + return transformedBounds.Intersects(rect); + } + private void CalculateShadowVertices(Vector2 lightSourcePos, bool los = true) { //compute facing of each edge, using N*L @@ -245,10 +261,10 @@ namespace Barotrauma.Lights if (!Enabled) return; CachedShadow cachedShadow = null; - if (cachedShadows.TryGetValue(light, out cachedShadow)) + if (cachedShadows.TryGetValue(light, out cachedShadow) && false) { if (light.Position == cachedShadow.LightPos || - Vector2.DistanceSquared(light.Position, cachedShadow.LightPos) < 1.0f) + Vector2.DistanceSquared(light.WorldPosition, cachedShadow.LightPos) < 1.0f) { shadowVertices = cachedShadow.ShadowVertices; penumbraVertices = cachedShadow.PenumbraVertices; @@ -256,8 +272,8 @@ namespace Barotrauma.Lights } else { - CalculateShadowVertices(light.Position, los); - cachedShadow.LightPos = light.Position; + CalculateShadowVertices(light.WorldPosition, los); + cachedShadow.LightPos = light.WorldPosition; cachedShadow.ShadowVertices = shadowVertices; cachedShadow.PenumbraVertices = penumbraVertices; @@ -265,9 +281,15 @@ namespace Barotrauma.Lights } else { - CalculateShadowVertices(light.Position, los); - cachedShadow = new CachedShadow(shadowVertices, penumbraVertices, light.Position); - cachedShadows.Add(light, cachedShadow); + Vector2 lightPos = light.WorldPosition; + if (light.Submarine!=null && parentEntity != null && parentEntity.Submarine == light.Submarine) + { + lightPos = light.Position; + } + + CalculateShadowVertices(lightPos, los); + // cachedShadow = new CachedShadow(shadowVertices, penumbraVertices, light.WorldPosition); + // cachedShadows.Add(light, cachedShadow); } DrawShadows(graphicsDevice, cam, transform, los); @@ -277,6 +299,8 @@ namespace Barotrauma.Lights { if (!Enabled) return; + if (parentEntity != null && parentEntity.Submarine != null) lightSourcePos -= parentEntity.Submarine.Position; + CalculateShadowVertices(lightSourcePos, los); DrawShadows(graphicsDevice, cam, transform, los); @@ -284,7 +308,15 @@ namespace Barotrauma.Lights private void DrawShadows(GraphicsDevice graphicsDevice, Camera cam, Matrix transform, bool los = true) { - shadowEffect.World = transform; + + Vector3 offset = Vector3.Zero; + if (parentEntity != null && parentEntity.Submarine != null) + { + offset = new Vector3(parentEntity.Submarine.DrawPosition.X, parentEntity.Submarine.DrawPosition.Y, 0.0f); + } + + + shadowEffect.World = Matrix.CreateTranslation(offset) * transform; shadowEffect.CurrentTechnique.Passes[0].Apply(); graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, shadowVertices, 0, shadowVertices.Length - 2); diff --git a/Subsurface/Source/Map/Lights/LightManager.cs b/Subsurface/Source/Map/Lights/LightManager.cs index d24be6d67..f8e5d554d 100644 --- a/Subsurface/Source/Map/Lights/LightManager.cs +++ b/Subsurface/Source/Map/Lights/LightManager.cs @@ -69,7 +69,8 @@ namespace Barotrauma.Lights foreach (ConvexHull convexHull in ConvexHull.list) { - if (!camView.Intersects(convexHull.BoundingBox)) continue; + if (!convexHull.Intersects(camView)) continue; + //if (!camView.Intersects(convexHull.BoundingBox)) continue; convexHull.DrawShadows(graphics, cam, pos, shadowTransform); } @@ -109,7 +110,7 @@ namespace Barotrauma.Lights foreach (LightSource light in lights) { if (light.hullsInRange.Count == 0 || light.Color.A < 0.01f || light.Range < 1.0f) continue; - if (!MathUtils.CircleIntersectsRectangle(light.Position, light.Range, viewRect)) continue; + if (!MathUtils.CircleIntersectsRectangle(light.WorldPosition, light.Range, viewRect)) continue; //clear alpha to 1 ClearAlphaToOne(graphics, spriteBatch); @@ -121,7 +122,7 @@ namespace Barotrauma.Lights foreach (ConvexHull ch in light.hullsInRange) { - //if (!MathUtils.CircleIntersectsRectangle(light.Position, light.Range, ch.BoundingBox)) continue; + if (!MathUtils.CircleIntersectsRectangle(light.Position, light.Range, ch.BoundingBox)) continue; //draw shadow ch.DrawShadows(graphics, cam, light, shadowTransform, false); } diff --git a/Subsurface/Source/Map/Lights/LightSource.cs b/Subsurface/Source/Map/Lights/LightSource.cs index 5bb4ced6d..b3818648f 100644 --- a/Subsurface/Source/Map/Lights/LightSource.cs +++ b/Subsurface/Source/Map/Lights/LightSource.cs @@ -19,6 +19,8 @@ namespace Barotrauma.Lights private Texture2D texture; + public Entity Submarine; + private Vector2 position; public Vector2 Position { @@ -32,6 +34,11 @@ namespace Barotrauma.Lights } } + public Vector2 WorldPosition + { + get { return (Submarine == null) ? position : position + Submarine.Position; } + } + public static Texture2D LightTexture { get @@ -64,10 +71,12 @@ namespace Barotrauma.Lights } } - public LightSource(Vector2 position, float range, Color color) + public LightSource(Vector2 position, float range, Color color, Submarine submarine) { hullsInRange = new List(); + this.Submarine = submarine; + this.position = position; this.range = range; this.color = color; @@ -92,7 +101,7 @@ namespace Barotrauma.Lights { Vector2 center = new Vector2(LightTexture.Width / 2, LightTexture.Height / 2); float scale = range / (lightTexture.Width / 2.0f); - spriteBatch.Draw(lightTexture, new Vector2(Position.X, -Position.Y), null, color, 0, center, scale, SpriteEffects.None, 1); + spriteBatch.Draw(lightTexture, new Vector2(WorldPosition.X, -WorldPosition.Y), null, color, 0, center, scale, SpriteEffects.None, 1); } public void Remove() diff --git a/Subsurface/Source/Map/LocationType.cs b/Subsurface/Source/Map/LocationType.cs index a75c36dc0..cbf510651 100644 --- a/Subsurface/Source/Map/LocationType.cs +++ b/Subsurface/Source/Map/LocationType.cs @@ -107,10 +107,15 @@ namespace Barotrauma return null; } - public static LocationType Random() + public static LocationType Random(string seed = "") { Debug.Assert(list.Count > 0, "LocationType.list.Count == 0, you probably need to initialize LocationTypes"); + if (!string.IsNullOrWhiteSpace(seed)) + { + Rand.SetSyncedSeed(ToolBox.StringToInt(seed)); + } + int randInt = Rand.Int(totalWeight, false); foreach (LocationType type in list) diff --git a/Subsurface/Source/Map/MapEntity.cs b/Subsurface/Source/Map/MapEntity.cs index 281d9f506..eada87ff6 100644 --- a/Subsurface/Source/Map/MapEntity.cs +++ b/Subsurface/Source/Map/MapEntity.cs @@ -70,7 +70,12 @@ namespace Barotrauma public virtual Rectangle Rect { get { return rect; } set { rect = value; } - } + } + + public Rectangle WorldRect + { + get { return Submarine == null ? rect : new Rectangle((int)(Submarine.Position.X + rect.X), (int)(Submarine.Position.Y + rect.Y), rect.Width, rect.Height); } + } public virtual Sprite Sprite { @@ -82,7 +87,7 @@ namespace Barotrauma get { return false; } } - public virtual Vector2 Position + public override Vector2 Position { get { @@ -138,7 +143,9 @@ namespace Barotrauma { get { return ""; } } - + + public MapEntity(Submarine submarine) : base(submarine) { } + public virtual void Move(Vector2 amount) { rect.X += (int)amount.X; @@ -147,7 +154,7 @@ namespace Barotrauma public virtual bool Contains(Vector2 position) { - return (Submarine.RectContains(rect, position)); + return (Submarine.RectContains(WorldRect, position)); } protected void InsertToList() @@ -229,8 +236,6 @@ namespace Barotrauma /// public static void UpdateSelecting(Camera cam) { - if (GUIComponent.MouseOn != null) return; - if (DisableSelect) { DisableSelect = false; @@ -243,6 +248,10 @@ namespace Barotrauma e.isSelected = false; } + if (GUIComponent.MouseOn != null) return; + + + if (MapEntityPrefab.Selected != null) { selectionPos = Vector2.Zero; @@ -271,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) { @@ -297,7 +305,6 @@ namespace Barotrauma startMovingPos = Vector2.Zero; } - } //started dragging a "selection rectangle" else if (selectionPos != Vector2.Zero) @@ -390,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); @@ -495,16 +502,21 @@ namespace Barotrauma { MapEntity linked = FindEntityByID(i) as MapEntity; - if (linked != null) - e.linkedTo.Add(linked); + if (linked != null) e.linkedTo.Add(linked); } } - foreach (MapEntity e in mapEntityList) + for (int i = 0; i //{ // return x.Name.CompareTo(y.Name); diff --git a/Subsurface/Source/Map/Structure.cs b/Subsurface/Source/Map/Structure.cs index 718a604e8..903885616 100644 --- a/Subsurface/Source/Map/Structure.cs +++ b/Subsurface/Source/Map/Structure.cs @@ -41,7 +41,7 @@ namespace Barotrauma class Structure : MapEntity, IDamageable { public static int wallSectionSize = 100; - public static List wallList = new List(); + public static List WallList = new List(); ConvexHull convexHull; @@ -138,7 +138,8 @@ namespace Barotrauma //} } - public Structure(Rectangle rectangle, StructurePrefab sp) + public Structure(Rectangle rectangle, StructurePrefab sp, Submarine submarine) + : base(submarine) { if (rectangle.Width == 0 || rectangle.Height == 0) return; @@ -168,7 +169,7 @@ namespace Barotrauma bodies.Add(newBody); - wallList.Add(this); + WallList.Add(this); int xsections = 1; int ysections = 1; @@ -262,7 +263,7 @@ namespace Barotrauma corners[2] = new Vector2(rect.Right, rect.Y); corners[3] = new Vector2(rect.Right, rect.Y - rect.Height); - convexHull = new ConvexHull(corners, Color.Black); + convexHull = new ConvexHull(corners, Color.Black, this); } InsertToList(); @@ -272,7 +273,7 @@ namespace Barotrauma { base.Remove(); - if (wallList.Contains(this)) wallList.Remove(this); + if (WallList.Contains(this)) WallList.Remove(this); if (bodies != null) { @@ -288,27 +289,28 @@ 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; - prefab.sprite.DrawTiled(spriteBatch, new Vector2(rect.X, -rect.Y), new Vector2(rect.Width, rect.Height), Vector2.Zero, color); + Vector2 drawOffset = Submarine == null ? Vector2.Zero : Submarine.DrawPosition; + prefab.sprite.DrawTiled(spriteBatch, new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)), new Vector2(rect.Width, rect.Height), Vector2.Zero, color); foreach (WallSection s in sections) { + if (s.isHighLighted) { GUI.DrawRectangle(spriteBatch, - new Rectangle((int)s.rect.X, (int)-s.rect.Y, (int)s.rect.Width, (int)s.rect.Height), + new Vector2(s.rect.X + drawOffset.X, -(s.rect.Y + drawOffset.Y)), new Vector2(s.rect.Width, s.rect.Height), new Color((s.damage / prefab.MaxHealth), 1.0f - (s.damage / prefab.MaxHealth), 0.0f, 1.0f), true); } - s.isHighLighted = false; if (s.damage < 0.01f) continue; - GUI.DrawRectangle(spriteBatch, - new Rectangle((int)s.rect.X, (int)-s.rect.Y, (int)s.rect.Width, (int)s.rect.Height), + GUI.DrawRectangle(spriteBatch, + new Vector2(s.rect.X + drawOffset.X, -(s.rect.Y + drawOffset.Y)), new Vector2(s.rect.Width, s.rect.Height), Color.Black * (s.damage / prefab.MaxHealth), true); } @@ -411,13 +413,17 @@ namespace Barotrauma return sections[sectionIndex].damage; } - public Vector2 SectionPosition(int sectionIndex) + public Vector2 SectionPosition(int sectionIndex, bool world = false) { if (sectionIndex < 0 || sectionIndex >= sections.Length) return Vector2.Zero; - return new Vector2( + Vector2 sectionPos = new Vector2( sections[sectionIndex].rect.X + sections[sectionIndex].rect.Width / 2.0f, sections[sectionIndex].rect.Y - sections[sectionIndex].rect.Height / 2.0f); + + if (world && Submarine != null) sectionPos += Submarine.Position; + + return sectionPos; } public AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, float deltaTime, bool playSound = false) @@ -425,7 +431,10 @@ namespace Barotrauma if (Submarine.Loaded != null && Submarine.Loaded.GodMode) return new AttackResult(0.0f, 0.0f); if (!prefab.HasBody || prefab.IsPlatform) return new AttackResult(0.0f, 0.0f); - int i = FindSectionIndex(ConvertUnits.ToDisplayUnits(position)); + Vector2 transformedPos = position; + if (Submarine != null) transformedPos -= Submarine.Position; + + int i = FindSectionIndex(transformedPos); if (i == -1) return new AttackResult(0.0f, 0.0f); GameMain.ParticleManager.CreateParticle("dustcloud", SectionPosition(i), 0.0f, 0.0f); @@ -474,7 +483,7 @@ namespace Barotrauma gapRect.Y += 10; gapRect.Width += 20; gapRect.Height += 20; - sections[sectionIndex].gap = new Gap(gapRect, !isHorizontal); + sections[sectionIndex].gap = new Gap(gapRect, !isHorizontal, Submarine); } } @@ -574,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; @@ -590,7 +602,7 @@ namespace Barotrauma return element; } - public static void Load(XElement element) + public static void Load(XElement element, Submarine submarine) { string rectString = ToolBox.GetAttributeString(element, "rect", "0,0,0,0"); string[] rectValues = rectString.Split(','); @@ -609,7 +621,8 @@ namespace Barotrauma { if (ep.Name == name) { - s = new Structure(rect, (StructurePrefab)ep); + s = new Structure(rect, (StructurePrefab)ep, submarine); + s.Submarine = submarine; s.ID = (ushort)int.Parse(element.Attribute("ID").Value); break; } diff --git a/Subsurface/Source/Map/StructurePrefab.cs b/Subsurface/Source/Map/StructurePrefab.cs index fb6cd0848..9938ebfdd 100644 --- a/Subsurface/Source/Map/StructurePrefab.cs +++ b/Subsurface/Source/Map/StructurePrefab.cs @@ -143,7 +143,7 @@ namespace Barotrauma if (PlayerInput.GetMouseState.LeftButton == ButtonState.Released) { - new Structure(newRect, this); + new Structure(newRect, this, Submarine.Loaded); selected = null; return; } diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index 9fd5853ed..13189fd1b 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -23,9 +23,12 @@ namespace Barotrauma class Submarine : Entity { - public static string SavePath = "Data" + System.IO.Path.DirectorySeparatorChar + "SavedSubs"; + //position of the "actual submarine" which is rendered wherever the SubmarineBody is + //should be in an unreachable place + public static readonly Vector2 HiddenSubPosition = new Vector2(0.0f, 50000.0f); + public static List SavedSubmarines = new List(); public static readonly Vector2 GridSize = new Vector2(16.0f, 16.0f); @@ -42,6 +45,7 @@ namespace Barotrauma private string filePath; private string name; + private Vector2 prevPosition; private float lastNetworkUpdate; @@ -94,21 +98,51 @@ namespace Barotrauma return (loaded==null) ? Rectangle.Empty : Loaded.subBody.Borders; } } - - - - public Vector2 Position + + public override Vector2 Position { - get { return (Level.Loaded == null) ? Vector2.Zero : -Level.Loaded.Position; } + get { return subBody==null ? Vector2.Zero : subBody.Position - HiddenSubPosition; } } - public Vector2 Speed + public bool AtEndPosition { - get { return subBody==null ? Vector2.Zero : subBody.Speed; } - set + 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; + private set; + } + + public override Vector2 SimPosition + { + get + { + return ConvertUnits.ToSimUnits(Position); + } + } + + public Vector2 Velocity + { + get { return subBody==null ? Vector2.Zero : subBody.Velocity; } + set { if (subBody == null) return; - subBody.Speed = value; + subBody.Velocity = value; } } @@ -130,7 +164,7 @@ namespace Barotrauma //constructors & generation ---------------------------------------------------- - public Submarine(string filePath, string hash = "") + public Submarine(string filePath, string hash = "") : base(null) { this.filePath = filePath; try @@ -181,6 +215,8 @@ namespace Barotrauma MapEntity.mapEntityList[i].Draw(spriteBatch, editing); } + + if (loaded == null) return; //foreach (HullBody hb in loaded.hullBodies) @@ -204,6 +240,11 @@ namespace Barotrauma } } + public void UpdateTransform() + { + DrawPosition = Physics.Interpolate(prevPosition, Position); + } + //math/physics stuff ---------------------------------------------------- public static Vector2 MouseToWorldGrid(Camera cam) @@ -260,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) => @@ -331,34 +374,7 @@ namespace Barotrauma lastPickedFraction = closestFraction; return closestBody; } - - //public static Body PickBody(Vector2 point) - //{ - // Body foundBody = null; - // AABB aabb = new AABB(point, point); - - // GameMain.World.QueryAABB(p => - // { - // foundBody = p.Body; - - // return true; - - // }, ref aabb); - - // return foundBody; - //} - - //public static bool InsideWall(Vector2 point) - //{ - // Body foundBody = PickBody(point); - // if (foundBody==null) return false; - - // Structure wall = foundBody.UserData as Structure; - // if (wall == null || wall.IsPlatform) return false; - - // return true; - //} - + //movement ---------------------------------------------------- @@ -374,10 +390,17 @@ namespace Barotrauma if (subBody != null) subBody.ApplyForce(force); } + public void SetPrevTransform(Vector2 position) + { + prevPosition = position; + } + public void SetPosition(Vector2 position) { if (!MathUtils.IsValid(position)) return; - Level.Loaded.SetPosition(-position); + + subBody.SetPosition(position); + //Level.Loaded.SetPosition(-position); //prevPosition = position; } @@ -385,18 +408,20 @@ namespace Barotrauma { if (amount == Vector2.Zero || !MathUtils.IsValid(amount)) return; - Level.Loaded.Move(-amount); + subBody.SetPosition(subBody.Position + amount); + + //Level.Loaded.Move(-amount); } public override bool FillNetworkData(Networking.NetworkEventType type, NetBuffer message, object data) { 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(Speed.X); - message.Write(Speed.Y); + message.Write(Velocity.X); + message.Write(Velocity.Y); return true; } @@ -427,7 +452,7 @@ namespace Barotrauma //newTargetPosition = newTargetPosition + newSpeed * (float)(NetTime.Now - sendingTime); subBody.TargetPosition = newTargetPosition; - subBody.Speed = newSpeed; + subBody.Velocity = newSpeed; lastNetworkUpdate = sendingTime; } @@ -592,6 +617,7 @@ namespace Barotrauma XDocument doc = OpenDoc(filePath); if (doc == null) return; + foreach (XElement element in doc.Root.Elements()) { string typeName = element.Name.ToString(); @@ -615,7 +641,7 @@ namespace Barotrauma try { MethodInfo loadMethod = t.GetMethod("Load"); - loadMethod.Invoke(t, new object[] { element }); + loadMethod.Invoke(t, new object[] { element, this }); } catch (Exception e) { @@ -624,25 +650,19 @@ namespace Barotrauma } - subBody = new SubmarineBody(this); + subBody = new SubmarineBody(this); + subBody.SetPosition(HiddenSubPosition); - MapEntity.MapLoaded(); - - foreach (Item item in Item.ItemList) - { - foreach (ItemComponent ic in item.components) - { - ic.OnMapLoaded(); - } - } + loaded = this; + MapEntity.MapLoaded(); + WayPoint.GenerateSubWaypoints(); GameMain.LightManager.OnMapLoaded(); ID = ushort.MaxValue-10; - loaded = this; } public static Submarine Load(string fileName) @@ -682,10 +702,10 @@ namespace Barotrauma { if (GameMain.GameScreen.Cam != null) GameMain.GameScreen.Cam.TargetPos = Vector2.Zero; - subBody = null; - Entity.RemoveAll(); + subBody = null; + PhysicsBody.list.Clear(); Ragdoll.list.Clear(); diff --git a/Subsurface/Source/Map/SubmarineBody.cs b/Subsurface/Source/Map/SubmarineBody.cs index ba08ee4b4..ef7f34881 100644 --- a/Subsurface/Source/Map/SubmarineBody.cs +++ b/Subsurface/Source/Map/SubmarineBody.cs @@ -9,14 +9,13 @@ using Microsoft.Xna.Framework; using System; using System.Collections.Generic; using System.Linq; -using System.Text; using Voronoi2; 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 @@ -32,18 +31,16 @@ namespace Barotrauma private float depthDamageTimer; - private Submarine sub; + private Submarine submarine; private Body body; - private Vector2 speed; - private Vector2 targetPosition; float mass = 10000.0f; - private Vector2? lastContactPoint; - private VoronoiCell lastContactCell; + //private Vector2? lastContactPoint; + //private VoronoiCell lastContactCell; public Rectangle Borders { @@ -51,13 +48,13 @@ namespace Barotrauma private set; } - public Vector2 Speed + public Vector2 Velocity { - get { return speed; } - set + get { return body.LinearVelocity; } + set { if (!MathUtils.IsValid(value)) return; - speed = value; + body.LinearVelocity = value; } } @@ -71,6 +68,10 @@ namespace Barotrauma } } + public Vector2 Position + { + get { return ConvertUnits.ToDisplayUnits(body.Position); } + } public Vector2 Center { @@ -79,12 +80,12 @@ namespace Barotrauma public bool AtDamageDepth { - get { return sub.Position.Y < DamageDepth; } + get { return Position.Y < DamageDepth; } } public SubmarineBody(Submarine sub) { - this.sub = sub; + this.submarine = sub; List convexHull = GenerateConvexHull(); @@ -107,29 +108,54 @@ namespace Barotrauma (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); - var triangulatedVertices = Triangulate.ConvexPartition(shapevertices, TriangulationAlgorithm.Bayazit); + foreach (Hull hull in Hull.hullList) + { + 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 = BodyFactory.CreateCompoundPolygon(GameMain.World, triangulatedVertices, 5.0f); body.BodyType = BodyType.Dynamic; - - body.CollisionCategories = Physics.CollisionMisc; - body.CollidesWith = Physics.CollisionLevel; - body.Restitution = 0.0f; + 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.OnSeparation += OnSeparation; - body.UserData = this; + //body.UserData = this; } private List GenerateConvexHull() { - if (!Structure.wallList.Any()) + 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) }; } @@ -138,7 +164,7 @@ namespace Barotrauma Vector2 leftMost = Vector2.Zero; - foreach (Structure wall in Structure.wallList) + foreach (Structure wall in Structure.WallList) { for (int x = -1; x <= 1; x += 2) { @@ -173,7 +199,7 @@ namespace Barotrauma endPoint = points[i]; } } - + currPoint = endPoint; } @@ -182,31 +208,20 @@ namespace Barotrauma return hullPoints; } - - float collisionRigidness = 1.0f; - public void Update(float deltaTime) - { - if (body.Position!=Vector2.Zero) + { + if (targetPosition != Vector2.Zero && targetPosition != Position) { - UpdateColliding(); - } + float dist = Vector2.Distance(targetPosition, Position); - Vector2 translateAmount = speed * deltaTime; - translateAmount += ConvertUnits.ToDisplayUnits(body.Position) * collisionRigidness; - - if (targetPosition != Vector2.Zero && targetPosition != sub.Position) - { - float dist = Vector2.Distance(targetPosition, sub.Position); - - if (dist>1000.0f) + if (dist > 1000.0f) { - sub.SetPosition(targetPosition); + body.SetTransform(ConvertUnits.ToSimUnits(targetPosition), 0.0f); targetPosition = Vector2.Zero; } - else if (dist>50.0f) + else if (dist > 50.0f) { - translateAmount += (targetPosition - sub.Position) * 0.01f; + body.SetTransform((ConvertUnits.ToSimUnits(targetPosition) - body.Position) * 0.01f, 0.0f); } } else @@ -214,32 +229,25 @@ namespace Barotrauma targetPosition = Vector2.Zero; } - sub.Translate(translateAmount); //------------------------- Vector2 totalForce = CalculateBuoyancy(); - if (speed.LengthSquared() > 0.000001f) + if (body.LinearVelocity.LengthSquared() > 0.000001f) { - float dragCoefficient = 0.00001f; + float dragCoefficient = 0.01f; - float speedLength = (speed == Vector2.Zero) ? 0.0f : speed.Length(); + float speedLength = (body.LinearVelocity == Vector2.Zero) ? 0.0f : body.LinearVelocity.Length(); float drag = speedLength * speedLength * dragCoefficient * mass; - totalForce += -Vector2.Normalize(speed) * drag; + totalForce += -Vector2.Normalize(body.LinearVelocity) * drag; } ApplyForce(totalForce); 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() @@ -257,21 +265,26 @@ namespace Barotrauma float neutralPercentage = 0.07f; float buoyancy = Math.Max(neutralPercentage - waterPercentage, -neutralPercentage*2.0f); - buoyancy *= mass * 30.0f; + buoyancy *= mass; - return new Vector2(0.0f, buoyancy); + return new Vector2(0.0f, buoyancy*10.0f); } public void ApplyForce(Vector2 force) { - Speed += force / mass; + body.ApplyForce(force); + } + + public void SetPosition(Vector2 position) + { + body.SetTransform(ConvertUnits.ToSimUnits(position), 0.0f); } private void UpdateDepthDamage(float deltaTime) { - if (sub.Position.Y > DamageDepth) return; + if (Position.Y > DamageDepth) return; - float depth = DamageDepth - sub.Position.Y; + float depth = DamageDepth - Position.Y; depth = Math.Min(depth, 40000.0f); // float prevTimer = depthDamageTimer; @@ -303,34 +316,65 @@ 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() + public bool OnCollision(Fixture f1, Fixture f2, Contact contact) { - if (body.Position.LengthSquared()<0.00001f) return; - - Vector2 normal = Vector2.Normalize(body.Position); - Vector2 simSpeed = ConvertUnits.ToSimUnits(speed); - - 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); + VoronoiCell cell = f2.Body.UserData as VoronoiCell; - if (lastContactPoint == null || lastContactCell==null || impact < 3.0f) return; - - SoundPlayer.PlayDamageSound(DamageSoundType.StructureBlunt, impact * 10.0f, ConvertUnits.ToDisplayUnits((Vector2)lastContactPoint)); + 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; + Vector2 limbForce = -normal * impact * 0.5f; float length = limbForce.Length(); if (length > 10.0f) limbForce = (limbForce / length) * 10.0f; @@ -339,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) { @@ -348,125 +392,10 @@ namespace Barotrauma } } - 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) - { - lastContactCell = null; - lastContactPoint = null; - return true; - } - - lastContactCell = cell; - - Vector2 normal; - FarseerPhysics.Common.FixedArray2 worldPoints; - contact.GetWorldManifold(out normal, out worldPoints); - - lastContactPoint = worldPoints[0]; + Explosion.RangedStructureDamage(ConvertUnits.ToDisplayUnits(lastContactPoint), impact * 50.0f, impact * DamageMultiplier); return true; - - //Vector2 normal = contact.Manifold.LocalNormal; - //Vector2 simSpeed = ConvertUnits.ToSimUnits(speed); - //float impact = Vector2.Dot(-simSpeed, normal); - - ////Vector2 u = Vector2.Dot(simSpeed, -normal) * -normal; - ////Vector2 w = simSpeed - u; - - //Vector2 limbForce = normal * impact; - - ////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); - //// } - ////} - - //System.Diagnostics.Debug.WriteLine("IMPACT: " + impact + " normal: " + normal + " simspeed: " + simSpeed); - //if (impact > 1.0f) - //{ - - // contact.GetWorldManifold(out normal, out worldPoints); - - // lastContactPoint = worldPoints[0]; - - // AmbientSoundManager.PlayDamageSound(DamageSoundType.StructureBlunt, impact * 10.0f, ConvertUnits.ToDisplayUnits(worldPoints[0])); - - // GameMain.GameScreen.Cam.Shake = impact * 2.0f; - - // //speed = ConvertUnits.ToDisplayUnits(w * 0.9f + u * 0.5f); - - // //FixedArray2 worldPoints; - // //contact.GetWorldManifold(out normal, out worldPoints); - - // //if (contact.Manifold.PointCount >= 1) - // //{ - // // Vector2 contactPoint = worldPoints[0]; - - // // Body wallBody = Submarine.PickBody(contactPoint, contactPoint + normal, new List() { cell.body }); - - // // if (wallBody!=null && wallBody.UserData!=null) - // // { - // // Structure s = wallBody.UserData as Structure; - // // } - // //} - - // //foreach (GraphEdge ge in cell.edges) - // //{ - // // Body wallBody = Submarine.PickBody( - // // ConvertUnits.ToSimUnits(ge.point1 + GameMain.GameSession.Level.Position + normal), - // // ConvertUnits.ToSimUnits(ge.point2 + GameMain.GameSession.Level.Position + normal), new List() { cell.body }); - // // if (wallBody == null || wallBody.UserData == null) continue; - - // // Structure structure = wallBody.UserData as Structure; - // // if (structure == null) continue; - // // structure.AddDamage( - // // structure.FindSectionIndex(ConvertUnits.ToDisplayUnits(Submarine.LastPickedPosition)), impact*50.0f); - // //} - //} - - - //collisionRigidness = 0.8f; - - //return true; } - public void OnSeparation(Fixture f1, Fixture f2) - { - lastContactPoint = null; - } } } diff --git a/Subsurface/Source/Map/WaterRenderer.cs b/Subsurface/Source/Map/WaterRenderer.cs index c774a3ee2..814973ef3 100644 --- a/Subsurface/Source/Map/WaterRenderer.cs +++ b/Subsurface/Source/Map/WaterRenderer.cs @@ -85,7 +85,7 @@ namespace Barotrauma basicEffect.Texture = texture; basicEffect.View = Matrix.Identity; - basicEffect.World = cam.ShaderTransform + basicEffect.World = transform * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f; basicEffect.CurrentTechnique.Passes[0].Apply(); diff --git a/Subsurface/Source/Map/WayPoint.cs b/Subsurface/Source/Map/WayPoint.cs index 1b2df74a1..772f6641b 100644 --- a/Subsurface/Source/Map/WayPoint.cs +++ b/Subsurface/Source/Map/WayPoint.cs @@ -63,7 +63,14 @@ namespace Barotrauma } } - public WayPoint(Rectangle newRect) + public WayPoint(Vector2 position, SpawnType spawnType, Submarine submarine, Gap gap = null) + : this(new Rectangle((int)position.X-3, (int)position.Y+3, 6, 6), submarine) + { + this.spawnType = spawnType; + ConnectedGap = gap; + } + public WayPoint(Rectangle newRect, Submarine submarine) + : base (submarine) { rect = newRect; linkedTo = new ObservableCollection(); @@ -73,30 +80,24 @@ namespace Barotrauma WayPointList.Add(this); } - public WayPoint(Vector2 position, SpawnType spawnType, Gap gap = null) - :this(new Rectangle((int)position.X-3, (int)position.Y+3, 6, 6)) - { - this.spawnType = spawnType; - ConnectedGap = gap; - } - - public override void Draw(SpriteBatch spriteBatch, bool editing, bool back=true) { if (!editing && !GameMain.DebugDraw) return; - Point pos = new Point((int)Position.X, (int)Position.Y); + Rectangle drawRect = + Submarine == null ? rect : new Rectangle((int)(Submarine.DrawPosition.X + rect.X), (int)(Submarine.DrawPosition.Y + rect.Y), rect.Width, rect.Height); + Color clr = (isSelected) ? Color.Red : Color.LightGreen; - GUI.DrawRectangle(spriteBatch, new Rectangle(pos.X - rect.Width / 2, -pos.Y - rect.Height / 2, rect.Width, rect.Height), clr, true); + GUI.DrawRectangle(spriteBatch, new Rectangle(drawRect.X, -drawRect.Y, rect.Width, rect.Height), clr, true); //spriteBatch.DrawString(GUI.SmallFont, Position.ToString(), new Vector2(Position.X, -Position.Y), Color.White); foreach (MapEntity e in linkedTo) { GUI.DrawLine(spriteBatch, - new Vector2(pos.X, -pos.Y), - new Vector2(e.Position.X + e.Rect.Width / 2, -e.Position.Y + e.Rect.Height / 2), + new Vector2(drawRect.X, -drawRect.Y), + new Vector2(e.DrawPosition.X, -e.DrawPosition.Y), Color.Green); } } @@ -218,6 +219,12 @@ namespace Barotrauma public static void GenerateSubWaypoints() { + List existingWaypoints = WayPointList.FindAll(wp => wp.spawnType == SpawnType.Path); + foreach (WayPoint wayPoint in existingWaypoints) + { + wayPoint.Remove(); + } + float minDist = 200.0f; float heightFromFloor = 100.0f; @@ -228,13 +235,13 @@ namespace Barotrauma if (hull.Rect.Width 0) @@ -442,14 +449,14 @@ namespace Barotrauma return element; } - public static void Load(XElement element) + 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)Submarine.GridSize.X, (int)Submarine.GridSize.Y); - WayPoint w = new WayPoint(rect); + WayPoint w = new WayPoint(rect, submarine); w.ID = (ushort)int.Parse(element.Attribute("ID").Value); w.spawnType = (SpawnType)Enum.Parse(typeof(SpawnType), 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 0194b5b11..5300c7070 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -3,6 +3,7 @@ using Lidgren.Network; using Microsoft.Xna.Framework; using System.Collections.Generic; using Barotrauma.Networking.ReliableMessages; +using FarseerPhysics; namespace Barotrauma.Networking { @@ -356,7 +357,7 @@ namespace Barotrauma.Networking if (myCharacter.IsDead) { Character.Controlled = null; - GameMain.GameScreen.Cam.TargetPos = Vector2.Zero; + //GameMain.GameScreen.Cam.TargetPos = Vector2.Zero; } else if (gameStarted) { @@ -610,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"; @@ -742,7 +743,7 @@ namespace Barotrauma.Networking float closestDist = 0.0f; foreach (WayPoint wp in WayPoint.WayPointList) { - float dist = Vector2.Distance(wp.SimPosition, position); + float dist = Vector2.Distance(wp.WorldPosition, position); if (closestWaypoint != null && dist > closestDist) continue; closestWaypoint = wp; @@ -750,9 +751,7 @@ namespace Barotrauma.Networking continue; } - Character character = (closestWaypoint == null) ? - Character.Create(ch, position, !isMyCharacter) : - Character.Create(ch, closestWaypoint, !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 9f130bf95..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], 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]); + 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"; @@ -1223,8 +1229,8 @@ namespace Barotrauma.Networking message.Write((byte)character.Info.HeadSpriteId); - message.Write(character.SimPosition.X); - message.Write(character.SimPosition.Y); + message.Write(character.WorldPosition.X); + message.Write(character.WorldPosition.Y); message.Write(character.Info.Job.Name); } diff --git a/Subsurface/Source/Particles/Particle.cs b/Subsurface/Source/Particles/Particle.cs index 9cacf2284..6481ef1e3 100644 --- a/Subsurface/Source/Particles/Particle.cs +++ b/Subsurface/Source/Particles/Particle.cs @@ -74,7 +74,8 @@ namespace Barotrauma.Particles spriteIndex = Rand.Int(prefab.Sprites.Count); currentHull = Hull.FindHull(position, hullGuess); - if (currentHull == null) position = Submarine.Loaded == null ? position : position + Submarine.Loaded.Position; + if (currentHull != null && currentHull.Submarine != null) speed += ConvertUnits.ToDisplayUnits(currentHull.Submarine.Velocity); + //if (currentHull == null) position = Submarine.Loaded == null ? position : position + Submarine.Loaded.Position; this.position = position; prevPosition = position; @@ -164,8 +165,8 @@ namespace Barotrauma.Particles if ((prefab.DeleteOnCollision || prefab.CollidesWithWalls) && currentHull!=null) { Vector2 edgePos = position + prefab.CollisionRadius * Vector2.Normalize(velocity) * size.X; - - if (!Submarine.RectContains(currentHull.Rect, edgePos)) + + if (!Submarine.RectContains(currentHull.WorldRect, edgePos)) { if (prefab.DeleteOnCollision) return false; @@ -174,13 +175,13 @@ namespace Barotrauma.Particles { if (!gap.isHorizontal) { - if (gap.Rect.X > position.X || gap.Rect.Right < position.X) continue; - if (Math.Sign(velocity.Y) != Math.Sign(gap.Rect.Y - (currentHull.Rect.Y-currentHull.Rect.Height))) continue; + if (gap.WorldRect.X > position.X || gap.WorldRect.Right < position.X) continue; + if (Math.Sign(velocity.Y) != Math.Sign(gap.WorldRect.Y - (currentHull.WorldRect.Y - currentHull.WorldRect.Height))) continue; } else { - if (gap.Rect.Y < position.Y || gap.Rect.Y - gap.Rect.Height > position.Y) continue; - if (Math.Sign(velocity.X) != Math.Sign(gap.Rect.Center.X - currentHull.Rect.Center.X)) continue; + if (gap.WorldRect.Y < position.Y || gap.WorldRect.Y - gap.WorldRect.Height > position.Y) continue; + if (Math.Sign(velocity.X) != Math.Sign(gap.WorldRect.Center.X - currentHull.WorldRect.Center.X)) continue; } //Rectangle enlargedRect = new Rectangle(gap.Rect.X - 10, gap.Rect.Y + 10, gap.Rect.Width + 20, gap.Rect.Height + 20); @@ -224,27 +225,29 @@ namespace Barotrauma.Particles } private void OnWallCollision(Hull prevHull, Vector2 position) - { - if (position.Y < prevHull.Rect.Y - prevHull.Rect.Height) + { + Rectangle prevHullRect = prevHull.WorldRect; + + if (position.Y < prevHullRect.Y - prevHullRect.Height) { - position.Y = prevHull.Rect.Y - prevHull.Rect.Height + 1.0f; + position.Y = prevHullRect.Y - prevHullRect.Height + 1.0f; velocity.Y = -velocity.Y; } - else if (position.Y > prevHull.Rect.Y) + else if (position.Y > prevHullRect.Y) { - position.Y = prevHull.Rect.Y - 1.0f; + position.Y = prevHullRect.Y - 1.0f; velocity.X = Math.Abs(velocity.Y) * Math.Sign(velocity.X); velocity.Y = -velocity.Y*0.1f; } - if (position.X < prevHull.Rect.X) + if (position.X < prevHullRect.X) { - position.X = prevHull.Rect.X + 1.0f; + position.X = prevHullRect.X + 1.0f; velocity.X = -velocity.X; } - else if (position.X > prevHull.Rect.X + prevHull.Rect.Width) + else if (position.X > prevHullRect.X + prevHullRect.Width) { - position.X = prevHull.Rect.X + prevHull.Rect.Width - 1.0f; + position.X = prevHullRect.X + prevHullRect.Width - 1.0f; velocity.X = -velocity.X; } @@ -265,11 +268,8 @@ namespace Barotrauma.Particles drawSize *= ((totalLifeTime - lifeTime) / prefab.GrowTime); } - Vector2 screenSpacePos = currentHull == null && Submarine.Loaded != null ? drawPosition - Submarine.Loaded.Position : drawPosition; - screenSpacePos.Y = -screenSpacePos.Y; - prefab.Sprites[spriteIndex].Draw(spriteBatch, - screenSpacePos, + new Vector2(drawPosition.X, -drawPosition.Y), color * alpha, prefab.Sprites[spriteIndex].origin, drawRotation, drawSize, SpriteEffects.None, prefab.Sprites[spriteIndex].Depth); diff --git a/Subsurface/Source/Physics/PhysicsBody.cs b/Subsurface/Source/Physics/PhysicsBody.cs index cb01c7a18..ccb60628d 100644 --- a/Subsurface/Source/Physics/PhysicsBody.cs +++ b/Subsurface/Source/Physics/PhysicsBody.cs @@ -88,7 +88,7 @@ namespace Barotrauma public Vector2 DrawPosition { - get { return drawPosition; } + get { return Submarine == null ? drawPosition : drawPosition + Submarine.DrawPosition; } } public float DrawRotation @@ -96,6 +96,8 @@ namespace Barotrauma get { return drawRotation; } } + public Submarine Submarine; + public float Dir { get { return dir; } @@ -113,6 +115,11 @@ namespace Barotrauma get { return body.Position; } } + public Vector2 PrevPosition + { + get { return prevPosition; } + } + public float Rotation { get { return body.Rotation; } @@ -313,7 +320,7 @@ namespace Barotrauma color = Color.Blue; } - sprite.Draw(spriteBatch, new Vector2(drawPosition.X, -drawPosition.Y), color, -drawRotation, 1.0f, spriteEffect, depth); + sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y), color, -drawRotation, 1.0f, spriteEffect, depth); } diff --git a/Subsurface/Source/Screens/EditMapScreen.cs b/Subsurface/Source/Screens/EditMapScreen.cs index c55633494..4052cdabf 100644 --- a/Subsurface/Source/Screens/EditMapScreen.cs +++ b/Subsurface/Source/Screens/EditMapScreen.cs @@ -134,6 +134,8 @@ namespace Barotrauma GUIComponent.MouseOn = null; characterMode = false; + + if (Submarine.Loaded != null) cam.Position = Submarine.Loaded.Position + Submarine.HiddenSubPosition; //CreateDummyCharacter(); } diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index 0570daecb..e5e8c87cf 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -15,12 +15,7 @@ namespace Barotrauma readonly RenderTarget2D renderTargetWater; readonly RenderTarget2D renderTargetAir; - readonly Sprite background, backgroundTop; - readonly Texture2D dustParticles; - - Vector2 dustOffset; - - public BackgroundSpriteManager BackgroundSpriteManager; + public BackgroundCreatureManager BackgroundCreatureManager; public Camera Cam { @@ -36,17 +31,16 @@ namespace Barotrauma renderTargetWater = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight); renderTargetAir = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight); - background = new Sprite("Content/Map/background.png", Vector2.Zero); - backgroundTop = new Sprite("Content/Map/background2.png", Vector2.Zero); - dustParticles = Sprite.LoadTexture("Content/Map/dustparticles.png"); - 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; } @@ -58,6 +52,8 @@ namespace Barotrauma Sounds.SoundManager.LowPassHFGain = 1.0f; } + int rendc; + /// /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. @@ -81,30 +77,38 @@ namespace Barotrauma GameMain.GameSession.Submarine.ApplyForce(targetMovement * 1000000.0f); } #endif - dustOffset -= Vector2.UnitY * 10.0f * (float)deltaTime; if (GameMain.GameSession!=null) GameMain.GameSession.Update((float)deltaTime); //EventManager.Update(gameTime); + if (Level.Loaded != null) Level.Loaded.Update((float)deltaTime); + Character.UpdateAll(cam, (float)deltaTime); - BackgroundSpriteManager.Update(cam, (float)deltaTime); + BackgroundCreatureManager.Update(cam, (float)deltaTime); GameMain.ParticleManager.Update((float)deltaTime); StatusEffect.UpdateAll((float)deltaTime); - Physics.accumulator = Math.Min(Physics.accumulator, Physics.step * 4); + Physics.accumulator = Math.Min(Physics.accumulator, Physics.step * 6); //Physics.accumulator = Physics.step; while (Physics.accumulator >= Physics.step) { cam.MoveCamera((float)Physics.step); + if (Character.Controlled != null) + { + cam.TargetPos = Character.Controlled.WorldPosition; + Lights.LightManager.ViewPos = Character.Controlled.WorldPosition; + } + + if (Submarine.Loaded != null) Submarine.Loaded.SetPrevTransform(Submarine.Loaded.Position); foreach (PhysicsBody pb in PhysicsBody.list) { pb.SetPrevTransform(pb.SimPosition, pb.Rotation); } - + MapEntity.UpdateAll(cam, (float)Physics.step); Character.UpdateAnimAll((float)Physics.step); @@ -118,7 +122,7 @@ namespace Barotrauma GameMain.World.Step((float)Physics.step); - Level.AfterWorldStep(); + //Level.AfterWorldStep(); Physics.accumulator -= Physics.step; } @@ -164,11 +168,15 @@ namespace Barotrauma public void DrawMap(GraphicsDevice graphics, SpriteBatch spriteBatch) { + + if (Submarine.Loaded != null) Submarine.Loaded.UpdateTransform(); + GameMain.LightManager.ObstructVision = Character.Controlled != null && Character.Controlled.ObstructVision; GameMain.LightManager.UpdateLightMap(graphics, spriteBatch, cam); GameMain.LightManager.UpdateObstructVision(graphics, spriteBatch, cam, - Character.Controlled==null ? LightManager.ViewPos : Character.Controlled.CursorPosition); + Character.Controlled==null ? LightManager.ViewPos : Character.Controlled.CursorWorldPosition); + //---------------------------------------------------------------------------------------- //1. draw the background, characters and the parts of the submarine that are behind them @@ -177,57 +185,8 @@ namespace Barotrauma graphics.SetRenderTarget(renderTarget); graphics.Clear(new Color(11, 18, 26, 255)); - spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearWrap); + if (Level.Loaded != null) Level.Loaded.DrawBack(spriteBatch, cam, BackgroundCreatureManager); - Vector2 backgroundPos = cam.Position; - if (Level.Loaded != null) backgroundPos -= Level.Loaded.Position; - backgroundPos.Y = -backgroundPos.Y; - backgroundPos /= 20.0f; - - if (backgroundPos.Y < 1024) - { - if (backgroundPos.Y > -1024) - { - background.SourceRect = new Rectangle((int)backgroundPos.X, (int)Math.Max(backgroundPos.Y, 0), 1024, 1024); - background.DrawTiled(spriteBatch, - (backgroundPos.Y < 0) ? new Vector2(0.0f, -backgroundPos.Y) : Vector2.Zero, - new Vector2(GameMain.GraphicsWidth, 1024 - backgroundPos.Y), - Vector2.Zero, Color.White); - } - - if (backgroundPos.Y < 0) - { - backgroundTop.SourceRect = new Rectangle((int)backgroundPos.X, (int)backgroundPos.Y, 1024, (int)Math.Min(-backgroundPos.Y, 1024)); - backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, Math.Min(-backgroundPos.Y, GameMain.GraphicsHeight)), - Vector2.Zero, Color.White); - } - } - - spriteBatch.End(); - - spriteBatch.Begin(SpriteSortMode.BackToFront, - BlendState.AlphaBlend, - SamplerState.LinearWrap, DepthStencilState.Default, null, null, - cam.Transform); - - BackgroundSpriteManager.Draw(spriteBatch); - - backgroundPos = new Vector2(cam.WorldView.X, cam.WorldView.Y) + dustOffset; - if (Level.Loaded != null) backgroundPos -= Level.Loaded.Position; - - Rectangle viewRect = cam.WorldView; - viewRect.Y = -viewRect.Y; - - float multiplier = 0.8f; - for (int i = 1; i < 4; i++) - { - spriteBatch.Draw(dustParticles, viewRect, - new Rectangle((int)((backgroundPos.X * multiplier)), (int)((-backgroundPos.Y * multiplier)), cam.WorldView.Width, cam.WorldView.Height), - Color.White * multiplier, 0.0f, Vector2.Zero, SpriteEffects.None, 1.0f-multiplier); - multiplier -= 0.15f; - } - - spriteBatch.End(); spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, @@ -320,12 +279,6 @@ namespace Barotrauma Hull.renderer.Render(graphics, cam, renderTargetAir, Cam.ShaderTransform); - if (GameMain.GameSession != null && GameMain.GameSession.Level != null) - { - GameMain.GameSession.Level.Render(graphics, cam); - //GameMain.GameSession.Level.SetObserverPosition(cam.WorldViewCenter); - } - //---------------------------------------------------------------------------------------- //3. draw the sections of the map that are on top of the water //---------------------------------------------------------------------------------------- @@ -339,7 +292,7 @@ namespace Barotrauma Submarine.DrawFront(spriteBatch); - if (Level.Loaded!=null) Level.Loaded.Draw(spriteBatch); + if (Level.Loaded!=null) Level.Loaded.DrawFront(spriteBatch); spriteBatch.End(); diff --git a/Subsurface/Source/Screens/LobbyScreen.cs b/Subsurface/Source/Screens/LobbyScreen.cs index 373f0b185..5393f7f3d 100644 --- a/Subsurface/Source/Screens/LobbyScreen.cs +++ b/Subsurface/Source/Screens/LobbyScreen.cs @@ -1,7 +1,4 @@ -using FarseerPhysics; -using FarseerPhysics.Dynamics; -using FarseerPhysics.Factories; -using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; @@ -362,7 +359,7 @@ namespace Barotrauma UpdateCharacterLists(); } - graphics.Clear(Color.CornflowerBlue); + graphics.Clear(Color.Black); //GameMain.GameScreen.DrawMap(graphics, spriteBatch); @@ -370,9 +367,8 @@ namespace Barotrauma Sprite backGround = GameMain.GameSession.Map.CurrentLocation.Type.Background; spriteBatch.Draw(backGround.Texture, Vector2.Zero, null, Color.White, 0.0f, Vector2.Zero, - Math.Max((float)GameMain.GraphicsWidth / backGround.SourceRect.Width, (float)GameMain.GraphicsHeight / backGround.SourceRect.Width), SpriteEffects.None, 0.0f); - - + Math.Max((float)GameMain.GraphicsWidth / backGround.SourceRect.Width, (float)GameMain.GraphicsHeight / backGround.SourceRect.Height), SpriteEffects.None, 0.0f); + topPanel.Draw(spriteBatch); bottomPanel[selectedRightPanel].Draw(spriteBatch); diff --git a/Subsurface/Source/Screens/NetLobbyScreen.cs b/Subsurface/Source/Screens/NetLobbyScreen.cs index 065732e91..0f3b75914 100644 --- a/Subsurface/Source/Screens/NetLobbyScreen.cs +++ b/Subsurface/Source/Screens/NetLobbyScreen.cs @@ -36,6 +36,8 @@ namespace Barotrauma public bool IsServer; public string ServerName, ServerMessage; + private Sprite backgroundSprite; + private GUITextBox serverMessage; public GUIListBox SubList @@ -98,7 +100,10 @@ namespace Barotrauma } private set { + if (levelSeed == value) return; + levelSeed = value; + backgroundSprite = LocationType.Random(levelSeed).Background; seedBox.Text = levelSeed; } } @@ -266,13 +271,12 @@ namespace Barotrauma serverMessage.Wrap = true; serverMessage.TextGetter = GetServerMessage; serverMessage.OnTextChanged = UpdateServerMessage; + } public override void Deselect() { textBox.Deselect(); - - seedBox.Text = ToolBox.RandomSeed(8); } public override void Select() @@ -284,7 +288,7 @@ namespace Barotrauma textBox.Select(); Character.Controlled = null; - GameMain.GameScreen.Cam.TargetPos = Vector2.Zero; + //GameMain.GameScreen.Cam.TargetPos = Vector2.Zero; subList.Enabled = GameMain.Server != null || GameMain.NetworkMember.Voting.AllowSubVoting; playerList.Enabled = GameMain.Server != null; @@ -320,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)); } @@ -358,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"; @@ -597,19 +601,19 @@ namespace Barotrauma { base.Update(deltaTime); - Vector2 pos = new Vector2( - Submarine.Borders.X + Submarine.Borders.Width / 2, - Submarine.Borders.Y - Submarine.Borders.Height / 2); + //Vector2 pos = new Vector2( + // Submarine.Borders.X + Submarine.Borders.Width / 2, + // Submarine.Borders.Y - Submarine.Borders.Height / 2); - camAngle += (float)deltaTime / 10.0f; - Vector2 offset = (new Vector2( - (float)Math.Cos(camAngle) * (Submarine.Borders.Width / 2.0f), - (float)Math.Sin(camAngle) * (Submarine.Borders.Height / 2.0f))); + //camAngle += (float)deltaTime / 10.0f; + //Vector2 offset = (new Vector2( + // (float)Math.Cos(camAngle) * (Submarine.Borders.Width / 2.0f), + // (float)Math.Sin(camAngle) * (Submarine.Borders.Height / 2.0f))); - pos += offset * 0.8f; + //pos += offset * 0.8f; - GameMain.GameScreen.Cam.TargetPos = pos; - GameMain.GameScreen.Cam.MoveCamera((float)deltaTime); + //GameMain.GameScreen.Cam.TargetPos = pos; + //GameMain.GameScreen.Cam.MoveCamera((float)deltaTime); menu.Update((float)deltaTime); @@ -632,12 +636,17 @@ namespace Barotrauma public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch) { - graphics.Clear(Color.CornflowerBlue); - - GameMain.GameScreen.DrawMap(graphics, spriteBatch); - + graphics.Clear(Color.Black); + spriteBatch.Begin(); + if (backgroundSprite!=null) + { + spriteBatch.Draw(backgroundSprite.Texture, Vector2.Zero, null, Color.White, 0.0f, Vector2.Zero, + Math.Max((float)GameMain.GraphicsWidth / backgroundSprite.SourceRect.Width, (float)GameMain.GraphicsHeight / backgroundSprite.SourceRect.Height), + SpriteEffects.None, 0.0f); + } + menu.Draw(spriteBatch); if (jobInfoFrame != null) jobInfoFrame.Draw(spriteBatch); @@ -732,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; } @@ -875,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)); @@ -896,7 +907,7 @@ namespace Barotrauma int modeIndex = 0; //float durationScroll = 0.0f; - string levelSeed = ""; + string newSeed = ""; bool autoRestart = false; @@ -917,7 +928,7 @@ namespace Barotrauma //durationScroll = msg.ReadFloat(); - levelSeed = msg.ReadString(); + newSeed = msg.ReadString(); autoRestart = msg.ReadBoolean(); restartTimer = msg.ReadFloat(); @@ -945,7 +956,7 @@ namespace Barotrauma //durationBar.BarScroll = durationScroll; - LevelSeed = levelSeed; + LevelSeed = newSeed; } } diff --git a/Subsurface/Source/Screens/ServerListScreen.cs b/Subsurface/Source/Screens/ServerListScreen.cs index 16b7b5543..e3acdaddc 100644 --- a/Subsurface/Source/Screens/ServerListScreen.cs +++ b/Subsurface/Source/Screens/ServerListScreen.cs @@ -81,7 +81,6 @@ namespace Barotrauma GUIButton button = new GUIButton(new Rectangle(-20, -20, 100, 30), "Back", Alignment.TopLeft, GUI.Style, menu); button.OnClicked = GameMain.MainMenuScreen.SelectTab; - button.CanBeSelected = false; button.SelectedColor = button.Color; refreshDisableTimer = DateTime.Now; diff --git a/Subsurface/Source/Sounds/Sound.cs b/Subsurface/Source/Sounds/Sound.cs index 4039fad10..694d053c0 100644 --- a/Subsurface/Source/Sounds/Sound.cs +++ b/Subsurface/Source/Sounds/Sound.cs @@ -103,7 +103,7 @@ namespace Barotrauma if (volume <= 0.0f) return -1; - alSourceId = SoundManager.Play(this, relativePos, volume); + alSourceId = SoundManager.Play(this, relativePos/100.0f, volume); return alSourceId; @@ -112,16 +112,16 @@ namespace Barotrauma //return UpdatePosition(newIndex, position, range, volume); } - public int Play(float volume, float range, Body body) - { - //Vector2 bodyPosition = ConvertUnits.ToDisplayUnits(body.Position); - //bodyPosition.Y = -bodyPosition.Y; + //public int Play(float volume, float range, Body body) + //{ + // //Vector2 bodyPosition = ConvertUnits.ToDisplayUnits(body.Position); + // //bodyPosition.Y = -bodyPosition.Y; - alSourceId = Play(volume, range, ConvertUnits.ToDisplayUnits(body.Position)); + // alSourceId = Play(volume, range, ConvertUnits.ToDisplayUnits(body.Position)); - return alSourceId; - } + // return alSourceId; + //} private float GetVolume(Vector2 relativePosition, float range, float baseVolume) { @@ -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); @@ -198,7 +197,7 @@ namespace Barotrauma return sourceIndex; } - return SoundManager.Loop(this, sourceIndex, relativePos, volume); + return SoundManager.Loop(this, sourceIndex, relativePos/100.0f, volume); } @@ -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/Sounds/SoundPlayer.cs b/Subsurface/Source/Sounds/SoundPlayer.cs index 48878cc98..05d088ac5 100644 --- a/Subsurface/Source/Sounds/SoundPlayer.cs +++ b/Subsurface/Source/Sounds/SoundPlayer.cs @@ -76,10 +76,8 @@ namespace Barotrauma startDrone = Sound.Load("Content/Sounds/startDrone.ogg", false); startDrone.Play(); - yield return CoroutineStatus.Running; - waterAmbiences[0] = Sound.Load("Content/Sounds/Water/WaterAmbience1.ogg", false); yield return CoroutineStatus.Running; waterAmbiences[1] = Sound.Load("Content/Sounds/Water/WaterAmbience2.ogg", false); @@ -201,7 +199,7 @@ namespace Barotrauma float movementFactor = 0.0f; if (Submarine.Loaded != null) { - movementFactor = (Submarine.Loaded.Speed == Vector2.Zero) ? 0.0f : Submarine.Loaded.Speed.Length() / 500.0f; + movementFactor = (Submarine.Loaded.Velocity == Vector2.Zero) ? 0.0f : Submarine.Loaded.Velocity.Length() / 5.0f; movementFactor = MathHelper.Clamp(movementFactor, 0.0f, 1.0f); } @@ -276,9 +274,9 @@ namespace Barotrauma } } - public static void PlayDamageSound(DamageSoundType damageType, float damage, Body body) + public static void PlayDamageSound(DamageSoundType damageType, float damage, PhysicsBody body) { - Vector2 bodyPosition = ConvertUnits.ToDisplayUnits(body.Position); + Vector2 bodyPosition = body.DrawPosition; bodyPosition.Y = -bodyPosition.Y; PlayDamageSound(damageType, damage, bodyPosition); diff --git a/Subsurface/Source/Sprite.cs b/Subsurface/Source/Sprite.cs index ab6af11d7..d36dec81d 100644 --- a/Subsurface/Source/Sprite.cs +++ b/Subsurface/Source/Sprite.cs @@ -216,8 +216,8 @@ namespace Barotrauma public void DrawTiled(SpriteBatch spriteBatch, Vector2 pos, Vector2 targetSize, Vector2 startOffset, Color color) { - pos.X = (int)pos.X; - pos.Y = (int)pos.Y; + //pos.X = (int)pos.X; + //pos.Y = (int)pos.Y; //how many times the texture needs to be drawn on the x-axis int xTiles = (int)Math.Ceiling((targetSize.X+startOffset.X) / sourceRect.Width); diff --git a/Subsurface/Source/Utils/MathUtils.cs b/Subsurface/Source/Utils/MathUtils.cs index b46cddf37..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 /// @@ -247,6 +247,11 @@ namespace Barotrauma this.center = center; } public int Compare(Vector2 a, Vector2 b) + { + return Compare(a, b, center); + } + + public static int Compare(Vector2 a, Vector2 b, Vector2 center) { if (a.X - center.X >= 0 && b.X - center.X < 0) return -1; if (a.X - center.X < 0 && b.X - center.X >= 0) return 1; diff --git a/Subsurface/Source/Utils/Rand.cs b/Subsurface/Source/Utils/Rand.cs index e62bcd7cf..20dcaccf5 100644 --- a/Subsurface/Source/Utils/Rand.cs +++ b/Subsurface/Source/Utils/Rand.cs @@ -18,14 +18,12 @@ namespace Barotrauma public static float Range(float minimum, float maximum, bool local = true) { - return (float)(local ? localRandom : syncedRandom).NextDouble() * (maximum - minimum) + minimum; - + return (float)(local ? localRandom : syncedRandom).NextDouble() * (maximum - minimum) + minimum; } public static int Range(int minimum, int maximum, bool local = true) { - return (local ? localRandom : syncedRandom).Next(maximum - minimum) + minimum; - + return (local ? localRandom : syncedRandom).Next(maximum - minimum) + minimum; } public static int Int(int max = int.MaxValue, bool local = true)