From 242af12f141c0eb3235e71b126621fc7bcea088e Mon Sep 17 00:00:00 2001 From: Regalis Date: Fri, 4 Dec 2015 01:37:30 +0200 Subject: [PATCH] Progress --- Subsurface/Source/Camera.cs | 12 ++++--- .../AI/Objectives/AIObjectiveIdle.cs | 16 +++++---- Subsurface/Source/Characters/AICharacter.cs | 1 - .../Source/Characters/Animation/Ragdoll.cs | 15 +++++++-- Subsurface/Source/Characters/Character.cs | 30 ++++++++++------- .../Source/Events/Quests/SalvageQuest.cs | 2 +- Subsurface/Source/GameSession/CargoManager.cs | 2 +- Subsurface/Source/Items/Components/Door.cs | 2 +- Subsurface/Source/Items/Item.cs | 31 +++++++++++++----- Subsurface/Source/Items/ItemPrefab.cs | 4 +-- Subsurface/Source/Items/ItemSpawner.cs | 3 +- Subsurface/Source/Map/Entity.cs | 25 +++++++++++++- Subsurface/Source/Map/Gap.cs | 14 ++++---- Subsurface/Source/Map/Hull.cs | 31 ++++++++++-------- Subsurface/Source/Map/Levels/Level.cs | 8 ++--- Subsurface/Source/Map/MapEntity.cs | 6 ++-- Subsurface/Source/Map/Structure.cs | 21 +++++++----- Subsurface/Source/Map/StructurePrefab.cs | 2 +- Subsurface/Source/Map/Submarine.cs | 29 ++++++++++++---- Subsurface/Source/Map/WaterRenderer.cs | 2 +- Subsurface/Source/Map/WayPoint.cs | 31 +++++++++--------- Subsurface/Source/Physics/PhysicsBody.cs | 6 ++-- Subsurface/Source/Screens/GameScreen.cs | 12 ++++--- Subsurface/Source/Sprite.cs | 4 +-- Subsurface_Solution.v12.suo | Bin 800256 -> 805376 bytes 25 files changed, 200 insertions(+), 109 deletions(-) diff --git a/Subsurface/Source/Camera.cs b/Subsurface/Source/Camera.cs index d483da785..2aac86935 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; @@ -210,6 +211,7 @@ namespace Barotrauma public Vector2 Position { get { return position; } + set { position = value; } } public Vector2 ScreenToWorld(Vector2 coords) diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs index 1c2b2c4cb..0e9d9ea34 100644 --- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs +++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveIdle.cs @@ -54,15 +54,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); + } + else if (character.Position.X > character.AnimController.CurrentHull.Rect.Right - WallAvoidDistance) + { + pathSteering.SteeringManual(deltaTime, -Vector2.UnitX); + } } + character.AIController.SteeringManager.SteeringWander(1.0f); return; } diff --git a/Subsurface/Source/Characters/AICharacter.cs b/Subsurface/Source/Characters/AICharacter.cs index ba52cab67..e1247ffdb 100644 --- a/Subsurface/Source/Characters/AICharacter.cs +++ b/Subsurface/Source/Characters/AICharacter.cs @@ -94,7 +94,6 @@ namespace Barotrauma case NetworkEventType.KillCharacter: return true; case NetworkEventType.ImportantEntityUpdate: - int i = 0; //foreach (Limb limb in AnimController.Limbs) //{ //if (RefLimb.ignoreCollisions) continue; diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index 8d3ab1458..2bcb357c5 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 @@ -534,8 +544,9 @@ namespace Barotrauma if (newHull == currentHull) return; - currentHull = newHull; + CurrentHull = newHull; + UpdateCollisionCategories(); } diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 53a9f3573..2126dbb26 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -273,19 +273,19 @@ 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) @@ -334,6 +334,7 @@ namespace Barotrauma } protected Character(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false) + : base(null) { keys = new Key[Enum.GetNames(typeof(InputType)).Length]; @@ -522,7 +523,7 @@ namespace Barotrauma continue; } - Item item = new Item(itemPrefab, Position); + Item item = new Item(itemPrefab, Position, null); if (info.Job.EquipSpawnItem[i]) { @@ -754,12 +755,15 @@ namespace Barotrauma if (moveCam) { - cam.TargetPos = ConvertUnits.ToDisplayUnits(AnimController.Limbs[0].SimPosition); + cam.TargetPos = WorldPosition; 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); @@ -877,9 +881,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; diff --git a/Subsurface/Source/Events/Quests/SalvageQuest.cs b/Subsurface/Source/Events/Quests/SalvageQuest.cs index b46c52dd7..7f911a0ba 100644 --- a/Subsurface/Source/Events/Quests/SalvageQuest.cs +++ b/Subsurface/Source/Events/Quests/SalvageQuest.cs @@ -65,7 +65,7 @@ namespace Barotrauma } while (tries < 10); - item = new Item(itemPrefab, position); + item = new Item(itemPrefab, position, null); item.MoveWithLevel = true; item.body.FarseerBody.GravityScale = 0.5f; //item.MoveWithLevel = true; diff --git a/Subsurface/Source/GameSession/CargoManager.cs b/Subsurface/Source/GameSession/CargoManager.cs index 3e106d654..8d0226448 100644 --- a/Subsurface/Source/GameSession/CargoManager.cs +++ b/Subsurface/Source/GameSession/CargoManager.cs @@ -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/Items/Components/Door.cs b/Subsurface/Source/Items/Components/Door.cs index 210d4cc9c..a5fb7cc62 100644 --- a/Subsurface/Source/Items/Components/Door.cs +++ b/Subsurface/Source/Items/Components/Door.cs @@ -45,7 +45,7 @@ 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.Open = openState; item.linkedTo.Add(linkedGap); return linkedGap; diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index 8f4177483..0d923aaf3 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -255,13 +255,14 @@ namespace Barotrauma //} - public Item(ItemPrefab itemPrefab, Vector2 position) - : this(new Rectangle((int)position.X, (int)position.Y, (int)itemPrefab.sprite.size.X, (int)itemPrefab.sprite.size.Y), itemPrefab) + public Item(ItemPrefab itemPrefab, Vector2 position, Submarine submarine) + : this(new Rectangle((int)position.X, (int)position.Y, (int)itemPrefab.sprite.size.X, (int)itemPrefab.sprite.size.Y), itemPrefab, submarine) { } - public Item(Rectangle newRect, ItemPrefab itemPrefab) + public Item(Rectangle newRect, ItemPrefab itemPrefab, Submarine submarine) + : base(submarine) { prefab = itemPrefab; @@ -409,6 +410,10 @@ namespace Barotrauma public virtual Hull FindHull() { CurrentHull = Hull.FindHull((body == null) ? Position : ConvertUnits.ToDisplayUnits(body.SimPosition), CurrentHull); + if (body!=null) + { + body.Submarine = CurrentHull == null ? null : Submarine.Loaded; + } return CurrentHull; } @@ -598,7 +603,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 +629,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 { @@ -1159,8 +1173,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; @@ -1195,7 +1209,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(); 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..a1f3c6b12 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; + protected 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/Gap.cs b/Subsurface/Source/Map/Gap.cs index 3a62159f0..5fe9e32ba 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(); @@ -564,7 +564,7 @@ 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), @@ -572,7 +572,7 @@ namespace Barotrauma int.Parse(element.Attribute("width").Value), int.Parse(element.Attribute("height").Value)); - Gap g = new Gap(rect); + 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..22f0f9f69 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; @@ -376,12 +377,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.Position.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.Position.Y) - surface) / 10.0f; + float drawSurface = surface + Submarine.Position.Y; Matrix transform = cam.Transform * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f; @@ -393,15 +395,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.Loaded.Position, 0.0f); uvCoords[i] = Vector2.Transform(new Vector2(corners[i].X, -corners[i].Y), transform); } @@ -418,8 +421,8 @@ namespace Barotrauma return; } - int x = rect.X; - int start = (int)Math.Floor((float)(cam.WorldView.X - x) / WaveWidth); + float x = rect.X+Submarine.Position.X; + int start = (int)Math.Floor((cam.WorldView.X - x) / WaveWidth); start = Math.Max(start, 0); int end = (waveY.Length - 1) @@ -435,7 +438,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 +449,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++) @@ -527,7 +530,7 @@ 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), @@ -535,7 +538,7 @@ namespace Barotrauma int.Parse(element.Attribute("width").Value), int.Parse(element.Attribute("height").Value)); - Hull h = new Hull(rect); + Hull h = new Hull(rect, submarine); h.volume = ToolBox.GetAttributeFloat(element, "pressure", 0.0f); diff --git a/Subsurface/Source/Map/Levels/Level.cs b/Subsurface/Source/Map/Levels/Level.cs index dc2f70655..53361633b 100644 --- a/Subsurface/Source/Map/Levels/Level.cs +++ b/Subsurface/Source/Map/Levels/Level.cs @@ -239,7 +239,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; } @@ -454,7 +454,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; @@ -471,7 +471,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) { @@ -481,7 +481,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); diff --git a/Subsurface/Source/Map/MapEntity.cs b/Subsurface/Source/Map/MapEntity.cs index 281d9f506..05e282a27 100644 --- a/Subsurface/Source/Map/MapEntity.cs +++ b/Subsurface/Source/Map/MapEntity.cs @@ -82,7 +82,7 @@ namespace Barotrauma get { return false; } } - public virtual Vector2 Position + public override Vector2 Position { get { @@ -138,7 +138,9 @@ namespace Barotrauma { get { return ""; } } - + + public MapEntity(Submarine submarine) : base(submarine) { } + public virtual void Move(Vector2 amount) { rect.X += (int)amount.X; diff --git a/Subsurface/Source/Map/Structure.cs b/Subsurface/Source/Map/Structure.cs index 718a604e8..b76cb1149 100644 --- a/Subsurface/Source/Map/Structure.cs +++ b/Subsurface/Source/Map/Structure.cs @@ -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; @@ -291,24 +292,25 @@ namespace Barotrauma Color color = (isHighlighted) ? Color.Green : 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 drawPos = Submarine == null ? new Vector2(rect.X, -rect.Y) : new Vector2(rect.X + Submarine.DrawPosition.X, -(rect.Y + Submarine.DrawPosition.Y)); + + prefab.sprite.DrawTiled(spriteBatch, drawPos, 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), + drawPos, new Vector2(rect.Width, 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, + drawPos, new Vector2(rect.Width, rect.Height), Color.Black * (s.damage / prefab.MaxHealth), true); } @@ -474,7 +476,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); } } @@ -590,7 +592,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 +611,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 5de6fd1db..fe80f64d8 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -41,6 +41,7 @@ namespace Barotrauma private string filePath; private string name; + private Vector2 prevPosition; private float lastNetworkUpdate; @@ -93,14 +94,18 @@ namespace Barotrauma return (loaded==null) ? Rectangle.Empty : Loaded.subBody.Borders; } } - - - - public Vector2 Position + + public override Vector2 Position { get { return subBody.Position; } } + public new Vector2 DrawPosition + { + get; + private set; + } + public Vector2 Speed { get { return subBody==null ? Vector2.Zero : subBody.Speed; } @@ -129,7 +134,7 @@ namespace Barotrauma //constructors & generation ---------------------------------------------------- - public Submarine(string filePath, string hash = "") + public Submarine(string filePath, string hash = "") : base(null) { this.filePath = filePath; try @@ -180,6 +185,12 @@ namespace Barotrauma MapEntity.mapEntityList[i].Draw(spriteBatch, editing); } + if (Submarine.Loaded!=null) + { + Submarine.Loaded.DrawPosition = Physics.Interpolate(Submarine.Loaded.prevPosition, Submarine.Loaded.Position); + } + + if (loaded == null) return; //foreach (HullBody hb in loaded.hullBodies) @@ -373,6 +384,12 @@ namespace Barotrauma if (subBody != null) subBody.ApplyForce(force); } + public void SetPrevTransform(Vector2 position, Camera cam = null) + { + if (cam != null) cam.Position += prevPosition - position; + prevPosition = position; + } + public void SetPosition(Vector2 position) { if (!MathUtils.IsValid(position)) return; @@ -618,7 +635,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) { 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..7ed2808f5 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,14 +80,6 @@ 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; @@ -228,13 +227,13 @@ namespace Barotrauma if (hull.Rect.Width /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. @@ -94,12 +96,14 @@ namespace Barotrauma 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 (Submarine.Loaded != null) Submarine.Loaded.SetPrevTransform(Submarine.Loaded.Position, cam); + foreach (PhysicsBody pb in PhysicsBody.list) { pb.SetPrevTransform(pb.SimPosition, pb.Rotation); @@ -229,7 +233,7 @@ namespace Barotrauma spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, - Matrix.CreateTranslation(new Vector3(Submarine.Loaded.Position.X, -Submarine.Loaded.Position.Y, 0.0f))*cam.Transform); + cam.Transform); Submarine.DrawBack(spriteBatch); @@ -315,7 +319,7 @@ namespace Barotrauma hull.Render(graphics, cam); } - Hull.renderer.Render(graphics, cam, renderTargetAir,Cam.ShaderTransform); + Hull.renderer.Render(graphics, cam, renderTargetAir, Cam.ShaderTransform); if (GameMain.GameSession != null && GameMain.GameSession.Level != null) { @@ -330,7 +334,7 @@ namespace Barotrauma spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, SamplerState.LinearWrap, null, null, null, - Matrix.CreateTranslation(new Vector3(Submarine.Loaded.Position.X, -Submarine.Loaded.Position.Y, 0.0f))*cam.Transform); + cam.Transform); foreach (Character c in Character.CharacterList) c.DrawFront(spriteBatch); 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_Solution.v12.suo b/Subsurface_Solution.v12.suo index e9dcb3c81d10607f0941619ce2db1f004a1fb279..ffd5b832a25c2379f3b2b82eb4781af785a93154 100644 GIT binary patch delta 13667 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 Py+1;4X^kJQuV?=Sg_V-s delta 12926 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