diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj index 47a1f3b6b..95e215df9 100644 --- a/Subsurface/Barotrauma.csproj +++ b/Subsurface/Barotrauma.csproj @@ -95,6 +95,7 @@ + diff --git a/Subsurface/Content/Map/StructurePrefabs.xml b/Subsurface/Content/Map/StructurePrefabs.xml index 3e7b7f062..c0c311d07 100644 --- a/Subsurface/Content/Map/StructurePrefabs.xml +++ b/Subsurface/Content/Map/StructurePrefabs.xml @@ -48,6 +48,18 @@ + + + + + + + + @@ -73,11 +85,14 @@ width="64" height="64" resizehorizontal="true" resizevertical="true"/> + width="64" height="64" resizehorizontal="true" resizevertical="true"/> + + diff --git a/Subsurface/Content/Map/testroom.png b/Subsurface/Content/Map/testroom.png index 01924bcc7..2690c5653 100644 Binary files a/Subsurface/Content/Map/testroom.png and b/Subsurface/Content/Map/testroom.png differ diff --git a/Subsurface/Source/Characters/AICharacter.cs b/Subsurface/Source/Characters/AICharacter.cs index 367740635..8d7694cb6 100644 --- a/Subsurface/Source/Characters/AICharacter.cs +++ b/Subsurface/Source/Characters/AICharacter.cs @@ -91,19 +91,19 @@ namespace Barotrauma return true; case NetworkEventType.ImportantEntityUpdate: int i = 0; - foreach (Limb limb in AnimController.Limbs) - { - if (limb.ignoreCollisions) continue; + //foreach (Limb limb in AnimController.Limbs) + //{ + //if (RefLimb.ignoreCollisions) continue; - if (limb.SimPosition.Length() > NetConfig.CharacterIgnoreDistance) return false; + if (AnimController.RefLimb.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.WriteRangedSingle(AnimController.RefLimb.SimPosition.X, -NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16); + message.WriteRangedSingle(AnimController.RefLimb.SimPosition.Y, -NetConfig.CharacterIgnoreDistance, NetConfig.CharacterIgnoreDistance, 16); - message.Write(limb.body.Rotation); - i++; - } + message.Write(AnimController.RefLimb.Rotation); + // i++; + //} message.WriteRangedSingle(MathHelper.Clamp(AnimController.StunTimer, 0.0f, 60.0f), 0.0f, 60.0f, 8); message.Write((byte)((health / maxHealth) * 255.0f)); @@ -126,8 +126,9 @@ namespace Barotrauma return true; } - public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message) + public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message, out object data) { + data = null; Enabled = true; switch (type) @@ -136,12 +137,12 @@ namespace Barotrauma Kill(CauseOfDeath.Damage, true); return; case NetworkEventType.ImportantEntityUpdate: - foreach (Limb limb in AnimController.Limbs) - { - if (limb.ignoreCollisions) continue; + //foreach (Limb limb in AnimController.Limbs) + //{ + // if (limb.ignoreCollisions) continue; - Vector2 limbPos = limb.SimPosition; - float rotation = limb.Rotation; + Vector2 limbPos = AnimController.RefLimb.SimPosition; + float rotation = AnimController.RefLimb.Rotation; try { @@ -155,14 +156,14 @@ namespace Barotrauma return; } - if (limb.body != null) + if (AnimController.RefLimb.body != null) { - limb.body.TargetVelocity = limb.body.LinearVelocity; - limb.body.TargetPosition = limbPos;// +vel * (float)(deltaTime / 60.0); - limb.body.TargetRotation = rotation;// +angularVel * (float)(deltaTime / 60.0); - limb.body.TargetAngularVelocity = limb.body.AngularVelocity; + //AnimController.RefLimb.body.TargetVelocity = limb.body.LinearVelocity; + AnimController.RefLimb.body.TargetPosition = limbPos;// +vel * (float)(deltaTime / 60.0); + AnimController.RefLimb.body.TargetRotation = rotation;// +angularVel * (float)(deltaTime / 60.0); + //limb.body.TargetAngularVelocity = limb.body.AngularVelocity; } - } + //} float newStunTimer = 0.0f, newHealth = 0.0f; diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 142a33cdd..c3a62accf 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -443,6 +443,12 @@ namespace Barotrauma return keys[(int)inputType].Held; } + public void ClearInput(InputType inputType) + { + keys[(int)inputType].Hit = false; + keys[(int)inputType].Held = false; + } + public void ClearInputs() { foreach (Key key in keys) @@ -577,10 +583,13 @@ namespace Barotrauma public void CreateUpdateNetworkEvent(bool isClient) { - new NetworkEvent(importantUpdateTimer <= 0 ? NetworkEventType.ImportantEntityUpdate : NetworkEventType.EntityUpdate, ID, isClient); + //new NetworkEvent(importantUpdateTimer <= 0 ? NetworkEventType.ImportantEntityUpdate : NetworkEventType.EntityUpdate, ID, isClient); - importantUpdateTimer -= 1; - if (importantUpdateTimer < 0) importantUpdateTimer = (this is AICharacter) ? 40 : 25; + new NetworkEvent(NetworkEventType.EntityUpdate, ID, isClient); + + + //importantUpdateTimer -= 1; + //if (importantUpdateTimer < 0) importantUpdateTimer = (this is AICharacter) ? 30 : 10; } @@ -1301,9 +1310,10 @@ namespace Barotrauma } } - public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message) + public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message, out object data) { Enabled = true; + data = null; switch (type) { @@ -1315,6 +1325,8 @@ namespace Barotrauma bool pickHit = message.ReadBoolean(); bool actionHit = message.ReadBoolean(); + data = new int[] { (int)itemId, pickHit ? 1 : 0, actionHit ? 1: 0 }; + System.Diagnostics.Debug.WriteLine("item id: "+itemId); Item item = FindEntityByID(itemId) as Item; @@ -1323,6 +1335,8 @@ namespace Barotrauma return; case NetworkEventType.SelectCharacter: ushort characterId = message.ReadUInt16(); + data = characterId; + if (characterId==0) { DeselectCharacter(false); @@ -1352,6 +1366,8 @@ namespace Barotrauma causeOfDeath = CauseOfDeath.Damage; } + data = causeOfDeath; + if (causeOfDeath==CauseOfDeath.Pressure) { Implode(true); diff --git a/Subsurface/Source/Characters/Ragdoll.cs b/Subsurface/Source/Characters/Ragdoll.cs index 604f64724..7e17cf90b 100644 --- a/Subsurface/Source/Characters/Ragdoll.cs +++ b/Subsurface/Source/Characters/Ragdoll.cs @@ -649,9 +649,63 @@ namespace Barotrauma } limb.Update(deltaTime); + } + } + public void SetPosition(Vector2 simPosition) + { + Vector2 moveAmount = simPosition - refLimb.SimPosition; + + foreach (Limb limb in Limbs) + { + if (limb==refLimb) + { + limb.body.SetTransform(simPosition, limb.Rotation); + continue; + } + + //check visibility from the new position of RefLimb to the new position of this limb + Vector2 movePos = limb.SimPosition + moveAmount; + + TrySetLimbPosition(limb, simPosition, movePos); + } + } + + private void TrySetLimbPosition(Limb limb, Vector2 original, Vector2 simPosition) + { + if (original == simPosition) return; + + Body body = Submarine.CheckVisibility(original, simPosition); + Vector2 movePos = simPosition; + + //if there's something in between the limbs + if (body != null) + { + //move the limb close to the position where the raycast hit something + movePos = original + ((simPosition - original) * Submarine.LastPickedFraction * 0.9f); + } + + limb.body.SetTransform(movePos, limb.Rotation); + } + + public void SetRotation(float rotation) + { + float rotateAmount = rotation - refLimb.Rotation; + + Matrix rotationMatrix = Matrix.CreateRotationZ(rotateAmount); + + refLimb.body.SetTransform(refLimb.SimPosition, rotation); + + foreach (Limb limb in Limbs) + { + if (limb == refLimb) continue; + + Vector2 newPos = limb.SimPosition - refLimb.SimPosition; + newPos = Vector2.Transform(newPos, rotationMatrix); + + TrySetLimbPosition(limb, refLimb.SimPosition, refLimb.SimPosition + newPos); + limb.body.SetTransform(limb.SimPosition, limb.Rotation + rotateAmount); } - } private void UpdateNetPlayerPosition() @@ -708,22 +762,26 @@ namespace Barotrauma if (resetAll) { - System.Diagnostics.Debug.WriteLine("reset ragdoll limb positions"); + System.Diagnostics.Debug.WriteLine("reset ragdoll limb positions"); - foreach (Limb limb in Limbs) - { - //if (limb.body.TargetPosition == Vector2.Zero) - //{ - limb.body.SetTransform(limb.body.SimPosition + diff, limb.body.Rotation); - //continue; - //} + SetPosition(refLimb.body.TargetPosition); - //limb.body.LinearVelocity = limb.body.TargetVelocity; - //limb.body.AngularVelocity = limb.body.TargetAngularVelocity; + if (character is AICharacter) SetRotation(refLimb.body.TargetRotation); - //limb.body.SetTransform(limb.body.TargetPosition, limb.body.TargetRotation); - limb.body.TargetPosition = Vector2.Zero; - } + //foreach (Limb limb in Limbs) + //{ + // if (limb.body.TargetPosition == Vector2.Zero) + // { + // limb.body.SetTransform(limb.body.SimPosition + diff, limb.body.Rotation); + // continue; + // } + + // limb.body.LinearVelocity = limb.body.TargetVelocity; + // limb.body.AngularVelocity = limb.body.TargetAngularVelocity; + + // limb.body.SetTransform(limb.body.TargetPosition, limb.body.TargetRotation); + // limb.body.TargetPosition = Vector2.Zero; + //} } } diff --git a/Subsurface/Source/DebugConsole.cs b/Subsurface/Source/DebugConsole.cs index d5d27bb5f..7502c5707 100644 --- a/Subsurface/Source/DebugConsole.cs +++ b/Subsurface/Source/DebugConsole.cs @@ -239,10 +239,10 @@ namespace Barotrauma break; case "generatelevel": GameMain.Level = new Level("asdf", 50.0f, 500,500, 50); - GameMain.Level.Generate(100.0f); + GameMain.Level.Generate(); break; case "fixitems": - foreach (Item it in Item.itemList) + foreach (Item it in Item.ItemList) { it.Condition = 100.0f; } diff --git a/Subsurface/Source/GameMain.cs b/Subsurface/Source/GameMain.cs index 40aa5f961..3046fe462 100644 --- a/Subsurface/Source/GameMain.cs +++ b/Subsurface/Source/GameMain.cs @@ -287,7 +287,7 @@ namespace Barotrauma } else { - NetworkEvent.events.Clear(); + NetworkEvent.Events.Clear(); } } diff --git a/Subsurface/Source/GameSession/GameModes/TutorialMode.cs b/Subsurface/Source/GameSession/GameModes/TutorialMode.cs index 45618a090..80994a91a 100644 --- a/Subsurface/Source/GameSession/GameModes/TutorialMode.cs +++ b/Subsurface/Source/GameSession/GameModes/TutorialMode.cs @@ -102,7 +102,7 @@ namespace Barotrauma infoBox = CreateInfoFrame("Open the door at your right side by highlighting the button next to it with your cursor and pressing E"); - Door tutorialDoor = Item.itemList.Find(i => i.HasTag("tutorialdoor")).GetComponent(); + Door tutorialDoor = Item.ItemList.Find(i => i.HasTag("tutorialdoor")).GetComponent(); while (!tutorialDoor.IsOpen) { @@ -124,7 +124,7 @@ namespace Barotrauma infoBox = CreateInfoFrame("At the moment the submarine has no power, which means that crucial systems such as the oxygen generator or the engine aren't running. Let's fix this: go to the upper left corner of the submarine, where you'll find a nuclear reactor."); - Reactor reactor = Item.itemList.Find(i => i.HasTag("tutorialreactor")).GetComponent(); + Reactor reactor = Item.ItemList.Find(i => i.HasTag("tutorialreactor")).GetComponent(); reactor.MeltDownTemp = 20000.0f; while (Vector2.Distance(Character.Controlled.Position, reactor.Item.Position)>200.0f) @@ -183,7 +183,7 @@ namespace Barotrauma infoBox = CreateInfoFrame("That's the basics of operating the reactor! Now that there's power available for the engines, it's time to get the submarine moving. " +"Deselect the reactor by pressing E and head to the command room at the right edge of the vessel."); - Steering steering = Item.itemList.Find(i => i.HasTag("tutorialsteering")).GetComponent(); + Steering steering = Item.ItemList.Find(i => i.HasTag("tutorialsteering")).GetComponent(); Radar radar = steering.Item.GetComponent(); while (Vector2.Distance(Character.Controlled.Position, steering.Item.Position) > 150.0f) @@ -233,7 +233,7 @@ namespace Barotrauma infoBox = CreateInfoFrame("Head back to the navigation terminal to fix the wiring."); - PowerTransfer junctionBox = Item.itemList.Find(i => i!=null && i.HasTag("tutorialjunctionbox")).GetComponent(); + PowerTransfer junctionBox = Item.ItemList.Find(i => i!=null && i.HasTag("tutorialjunctionbox")).GetComponent(); while ((Character.Controlled.SelectedConstruction != junctionBox.Item && Character.Controlled.SelectedConstruction != steering.Item) || @@ -380,15 +380,15 @@ namespace Barotrauma Submarine.Loaded.GodMode = true; - var capacitor1 = Item.itemList.Find(i => i.HasTag("capacitor1")).GetComponent(); - var capacitor2 = Item.itemList.Find(i => i.HasTag("capacitor1")).GetComponent(); + var capacitor1 = Item.ItemList.Find(i => i.HasTag("capacitor1")).GetComponent(); + var capacitor2 = Item.ItemList.Find(i => i.HasTag("capacitor1")).GetComponent(); CoroutineManager.StartCoroutine(KeepEnemyAway(moloch, new PowerContainer[] { capacitor1, capacitor2 })); infoBox = CreateInfoFrame("The hull has been breached! Close all the doors to the command room to stop the water from flooding the entire sub!"); - Door commandDoor1 = Item.itemList.Find(i => i.HasTag("commanddoor1")).GetComponent(); - Door commandDoor2 = Item.itemList.Find(i => i.HasTag("commanddoor2")).GetComponent(); - Door commandDoor3 = Item.itemList.Find(i => i.HasTag("commanddoor3")).GetComponent(); + Door commandDoor1 = Item.ItemList.Find(i => i.HasTag("commanddoor1")).GetComponent(); + Door commandDoor2 = Item.ItemList.Find(i => i.HasTag("commanddoor2")).GetComponent(); + Door commandDoor3 = Item.ItemList.Find(i => i.HasTag("commanddoor3")).GetComponent(); while (commandDoor1.IsOpen || (commandDoor2.IsOpen || commandDoor3.IsOpen)) { @@ -425,7 +425,7 @@ namespace Barotrauma infoBox = CreateInfoFrame("Now you should stop the creature attacking the submarine before it does any more damage. Head to the railgun room at the upper right corner of the sub."); - var railGun = Item.itemList.Find(i => i.GetComponent()!=null); + var railGun = Item.ItemList.Find(i => i.GetComponent()!=null); while (Vector2.Distance(Character.Controlled.Position, railGun.Position)>500) { @@ -445,7 +445,7 @@ namespace Barotrauma "time to head to the room below and load some shells for the railgun."); - var loader = Item.itemList.Find(i => i.Name == "Railgun Loader").GetComponent(); + var loader = Item.ItemList.Find(i => i.Name == "Railgun Loader").GetComponent(); while (Math.Abs(Character.Controlled.Position.Y - loader.Item.Position.Y)>80) { @@ -525,7 +525,7 @@ namespace Barotrauma infoBox = CreateInfoFrame("Great! However, there's still quite a bit of water inside the sub. It should be pumped out " +"using the pump in the room at the bottom of the submarine."); - Pump pump = Item.itemList.Find(i => i.HasTag("tutorialpump")).GetComponent(); + Pump pump = Item.ItemList.Find(i => i.HasTag("tutorialpump")).GetComponent(); while (Vector2.Distance(Character.Controlled.Position, pump.Item.Position) > 100.0f) { @@ -640,7 +640,7 @@ namespace Barotrauma reactor.ShutDownTemp = 5000.0f; yield return CoroutineStatus.Running; - } while (Item.itemList.Contains(reactor.Item)); + } while (Item.ItemList.Contains(reactor.Item)); yield return CoroutineStatus.Success; } diff --git a/Subsurface/Source/GameSession/GameSession.cs b/Subsurface/Source/GameSession/GameSession.cs index a2ce69108..30d7433aa 100644 --- a/Subsurface/Source/GameSession/GameSession.cs +++ b/Subsurface/Source/GameSession/GameSession.cs @@ -121,7 +121,7 @@ namespace Barotrauma if (level != null) { - level.Generate(submarine == null ? 100.0f : Math.Max(Submarine.Borders.Width, Submarine.Borders.Height)); + level.Generate(); submarine.SetPosition(level.StartPosition - new Vector2(0.0f, 2000.0f)); GameMain.GameScreen.BackgroundSpriteManager.SpawnSprites(80); diff --git a/Subsurface/Source/Items/CharacterInventory.cs b/Subsurface/Source/Items/CharacterInventory.cs index e7a2e91d7..3ba043613 100644 --- a/Subsurface/Source/Items/CharacterInventory.cs +++ b/Subsurface/Source/Items/CharacterInventory.cs @@ -373,6 +373,8 @@ namespace Barotrauma public override void ReadNetworkData(NetworkEventType type, NetBuffer message) { + character.ClearInput(InputType.Use); + for (int i = 0; i<5; i++) { ushort itemId = message.ReadUInt16(); @@ -391,17 +393,11 @@ namespace Barotrauma List newItemIDs = new List(); - try + for (int i = 5; i < capacity; i++) { - while (message.Position <= message.LengthBits - (sizeof(ushort) * 8)) - { - newItemIDs.Add(message.ReadUInt16()); - } - } - catch - { - return; + newItemIDs.Add(message.ReadUInt16()); } + for (int i = 5; i < capacity; i++) { diff --git a/Subsurface/Source/Items/Components/Machines/Fabricator.cs b/Subsurface/Source/Items/Components/Machines/Fabricator.cs index 5918a41a9..ffde50cc3 100644 --- a/Subsurface/Source/Items/Components/Machines/Fabricator.cs +++ b/Subsurface/Source/Items/Components/Machines/Fabricator.cs @@ -73,34 +73,23 @@ namespace Barotrauma.Items.Components } - int width = 400, height = 300; - itemList = new GUIListBox(new Rectangle(GameMain.GraphicsWidth / 2 - width / 2, GameMain.GraphicsHeight / 2 - height / 2, width, height), Color.White * 0.7f); + int width = 500, height = 300; + itemList = new GUIListBox(new Rectangle(GameMain.GraphicsWidth / 2 - width / 2, GameMain.GraphicsHeight / 2 - height / 2, width, height), GUI.Style); itemList.OnSelected = SelectItem; //structureList.CheckSelected = MapEntityPrefab.GetSelected; foreach (FabricableItem fi in fabricableItems) { - Color color = ((itemList.CountChildren % 2) == 0) ? Color.White : Color.LightGray; - - //GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 50), Color.Transparent, itemList); - //frame.UserData = fi; - //frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f); - //frame.Color = color; - //frame.HoverColor = Color.Gold * 0.2f; - //frame.SelectedColor = Color.Gold * 0.5f; - + Color color = ((itemList.CountChildren % 2) == 0) ? Color.Transparent : Color.Black*0.3f; + GUITextBlock textBlock = new GUITextBlock( new Rectangle(0, 0, 0, 25), fi.TargetItem.Name, - color, Color.Black, + color, Color.White, Alignment.Left, Alignment.Left, null, itemList); textBlock.UserData = fi; textBlock.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f); - - //if (fi.TargetItem.sprite != null) - //{ - // GUIImage img = new GUIImage(new Rectangle(0, 0, 40, 40), fi.TargetItem.sprite, Alignment.Left, frame); - // img.Scale = Math.Min(Math.Min(40.0f / img.SourceRect.Width, 40.0f / img.SourceRect.Height), 1.0f); - //} + textBlock.HoverColor = Color.Gold * 0.2f; + textBlock.SelectedColor = Color.Gold * 0.5f; } } @@ -110,7 +99,7 @@ namespace Barotrauma.Items.Components if (targetItem == null) return false; int width = 200, height = 150; - selectedItemFrame = new GUIFrame(new Rectangle(GameMain.GraphicsWidth / 2 - width / 2, itemList.Rect.Bottom+20, width, height), Color.Black*0.8f); + selectedItemFrame = new GUIFrame(new Rectangle(itemList.Rect.Right - width - 20, GameMain.GraphicsHeight/2-height/2, width, height), Color.Black*0.8f); //selectedItemFrame.Padding = GUI.style.smallPadding; if (targetItem.TargetItem.sprite != null) @@ -177,7 +166,7 @@ namespace Barotrauma.Items.Components container.inventory.RemoveItem(requiredItem); } - new Item(fabricatedItem.TargetItem, item.Position); + Item.Spawner.QueueItem(fabricatedItem.TargetItem, item.Position); IsActive = false; fabricatedItem = null; @@ -199,7 +188,6 @@ namespace Barotrauma.Items.Components } } - itemList.Update(0.016f); itemList.Draw(spriteBatch); diff --git a/Subsurface/Source/Items/Components/Machines/Radar.cs b/Subsurface/Source/Items/Components/Machines/Radar.cs index a0ac2f6cf..e494a8a19 100644 --- a/Subsurface/Source/Items/Components/Machines/Radar.cs +++ b/Subsurface/Source/Items/Components/Machines/Radar.cs @@ -131,10 +131,14 @@ namespace Barotrauma.Items.Components float cellDot = Vector2.Dot(cell.Center + Level.Loaded.Position, (edge.point1 + edge.point2) / 2.0f - 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); + Vector2 point1 = (edge.point1 + Level.Loaded.Position); Vector2 point2 = (edge.point2 + Level.Loaded.Position); - for (float x=0; x<(point1-point2).Length(); x+=Rand.Range(600.0f, 800.0f)) + float length = (point1 - point2).Length(); + for (float x=0; x pingRadius) continue; - float step = 4.0f; + float step = 5.0f * (Math.Abs(facingDot)+1.0f); + float alpha = Rand.Range(1.5f, 2.0f); for (float z = 0; z radius) + { + blip.FadeTimer = 0.0f; + return; + } pos.X = MathUtils.Round(pos.X, 4); - pos.Y = MathUtils.Round(pos.Y, 2); GUI.DrawRectangle(spriteBatch, center + pos, new Vector2(4, 2), color, true); diff --git a/Subsurface/Source/Items/Inventory.cs b/Subsurface/Source/Items/Inventory.cs index 5e26e60f9..5568c70fc 100644 --- a/Subsurface/Source/Items/Inventory.cs +++ b/Subsurface/Source/Items/Inventory.cs @@ -297,10 +297,11 @@ namespace Barotrauma public virtual bool FillNetworkData(NetworkEventType type, NetBuffer message, object data) { - for (int i = 0; i i != null); + message.Write((byte)foundItems.Count()); + foreach (Item item in foundItems) { - if (items[i] == null) continue; - message.Write((ushort)items[i].ID); + message.Write((ushort)item.ID); } return true; @@ -309,20 +310,13 @@ namespace Barotrauma public virtual void ReadNetworkData(NetworkEventType type, NetBuffer message) { List newItemIDs = new List(); - - try - { - - while (message.Position <= message.LengthBits - (sizeof(ushort) * 8)) - { - newItemIDs.Add(message.ReadUInt16()); - } - } - catch - { - return; - } + byte count = message.ReadByte(); + for (int i = 0; i itemList = new List(); + public static List ItemList = new List(); protected ItemPrefab prefab; + public static ItemSpawner Spawner = new ItemSpawner(); + private List tags; public Hull CurrentHull; @@ -308,7 +310,7 @@ namespace Barotrauma } InsertToList(); - itemList.Add(this); + ItemList.Add(this); } public T GetComponent() @@ -359,7 +361,7 @@ namespace Barotrauma { base.Move(amount); - if (itemList != null && body != null) + if (ItemList != null && body != null) { amount = ConvertUnits.ToSimUnits(amount); //Vector2 pos = new Vector2(rect.X + rect.Width / 2.0f, rect.Y - rect.Height / 2.0f); @@ -387,7 +389,7 @@ namespace Barotrauma /// public static void UpdateHulls() { - foreach (Item item in itemList) item.FindHull(); + foreach (Item item in ItemList) item.FindHull(); } public virtual Hull FindHull() @@ -812,7 +814,7 @@ namespace Barotrauma Vector2 displayPos = ConvertUnits.ToDisplayUnits(position); Vector2 displayPickPos = ConvertUnits.ToDisplayUnits(pickPosition); - foreach (Item item in itemList) + foreach (Item item in ItemList) { if (ignoredItems!=null && ignoredItems.Contains(item)) continue; //if (hull != item.CurrentHull && (hull==null || (item.Rect.Height=FixRequirements.Count) return; FixRequirements[requirementIndex].Fixed = true; break; case NetworkEventType.InventoryUpdate: + var itemContainer = GetComponent(); if (itemContainer == null || itemContainer.inventory == null) return; itemContainer.inventory.ReadNetworkData(NetworkEventType.DropItem, message); @@ -1322,6 +1329,9 @@ namespace Barotrauma case NetworkEventType.ComponentUpdate: case NetworkEventType.ImportantComponentUpdate: int componentIndex = message.ReadByte(); + + data = componentIndex; + if (componentIndex < 0 || componentIndex > components.Count - 1) return; components[componentIndex].ReadNetworkData(type, message); break; @@ -1331,6 +1341,7 @@ namespace Barotrauma try { propertyName = message.ReadString(); + data = propertyName; } catch { @@ -1380,9 +1391,9 @@ namespace Barotrauma { ic.Remove(); } - itemList.Remove(this); + ItemList.Remove(this); - foreach (Item it in itemList) + foreach (Item it in ItemList) { if (it.linkedTo.Contains(this)) { diff --git a/Subsurface/Source/Items/ItemPrefab.cs b/Subsurface/Source/Items/ItemPrefab.cs index c83ded41c..e914559a5 100644 --- a/Subsurface/Source/Items/ItemPrefab.cs +++ b/Subsurface/Source/Items/ItemPrefab.cs @@ -111,7 +111,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); - + placePosition = Vector2.Zero; //selected = null; return; } diff --git a/Subsurface/Source/Items/ItemSpawner.cs b/Subsurface/Source/Items/ItemSpawner.cs new file mode 100644 index 000000000..7c73b7407 --- /dev/null +++ b/Subsurface/Source/Items/ItemSpawner.cs @@ -0,0 +1,37 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Barotrauma +{ + class ItemSpawner + { + private Queue> spawnQueue; + + public ItemSpawner() + { + spawnQueue = new Queue>(); + } + + public void QueueItem(ItemPrefab itemPrefab, Vector2 position) + { + var itemInfo = new Pair(); + itemInfo.First = itemPrefab; + itemInfo.Second = position; + + spawnQueue.Enqueue(itemInfo); + } + + public void Update() + { + while (spawnQueue.Count>0) + { + var itemInfo = spawnQueue.Dequeue(); + + new Item(itemInfo.First, itemInfo.Second); + } + } + } +} diff --git a/Subsurface/Source/Map/Entity.cs b/Subsurface/Source/Map/Entity.cs index 4377ef8a9..bbda52b13 100644 --- a/Subsurface/Source/Map/Entity.cs +++ b/Subsurface/Source/Map/Entity.cs @@ -69,7 +69,10 @@ namespace Barotrauma { return false; } - public virtual void ReadNetworkData(NetworkEventType type, NetIncomingMessage message) { } + public virtual void ReadNetworkData(NetworkEventType type, NetIncomingMessage message, out object data) + { + data = null; + } /// /// Find an entity based on the ID diff --git a/Subsurface/Source/Map/Hull.cs b/Subsurface/Source/Map/Hull.cs index 0f509df31..17447f643 100644 --- a/Subsurface/Source/Map/Hull.cs +++ b/Subsurface/Source/Map/Hull.cs @@ -479,8 +479,10 @@ namespace Barotrauma return true; } - public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message) + public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message, out object data) { + data = null; + float newVolume = this.volume; try diff --git a/Subsurface/Source/Map/Levels/Level.cs b/Subsurface/Source/Map/Levels/Level.cs index a923c2ae2..e274d1197 100644 --- a/Subsurface/Source/Map/Levels/Level.cs +++ b/Subsurface/Source/Map/Levels/Level.cs @@ -145,7 +145,7 @@ namespace Barotrauma return new Level(seed, Rand.Range(30.0f,80.0f,false), 100000, 40000, 2000); } - public void Generate(float minWidth, bool mirror=false) + public void Generate(bool mirror=false) { Stopwatch sw = new Stopwatch(); sw.Start(); @@ -230,6 +230,8 @@ namespace Barotrauma Debug.WriteLine("find cells: " + sw2.ElapsedMilliseconds + " ms"); sw2.Restart(); + float minWidth = Submarine.Loaded == null ? 3000.0f : Math.Max(Submarine.Borders.Width, Submarine.Borders.Height); + //generate a path from the left edge of the map to right edge Rectangle pathBorders = new Rectangle( borders.X + (int)minWidth * 2, borders.Y + (int)minWidth * 2, @@ -775,7 +777,7 @@ namespace Barotrauma } } - foreach (Item item in Item.itemList) + foreach (Item item in Item.ItemList) { if (item.body==null || item.CurrentHull != null) continue; item.body.LinearVelocity += simVelocity; @@ -815,7 +817,7 @@ namespace Barotrauma } } - foreach (Item item in Item.itemList) + foreach (Item item in Item.ItemList) { if (item.body == null || item.CurrentHull != null) continue; item.body.LinearVelocity -= prevVelocity; diff --git a/Subsurface/Source/Map/MapEntity.cs b/Subsurface/Source/Map/MapEntity.cs index 9660beee3..e3d109813 100644 --- a/Subsurface/Source/Map/MapEntity.cs +++ b/Subsurface/Source/Map/MapEntity.cs @@ -199,7 +199,7 @@ namespace Barotrauma /// public static void UpdateAll(Camera cam, float deltaTime) { - foreach (Item item in Item.itemList) + foreach (Item item in Item.ItemList) { item.Updated = false; } @@ -214,36 +214,12 @@ namespace Barotrauma gap.Update(cam, deltaTime); } - foreach (Item item in Item.itemList) + foreach (Item item in Item.ItemList) { item.Update(cam, deltaTime); } - //Stopwatch sw = new Stopwatch(); - - //for (int i = 0; i < mapEntityList.Count; i++) - //{ - // sw.Restart(); - // mapEntityList[i].Update(cam, deltaTime); - // sw.Stop(); - - // if (timeElapsed.ContainsKey(mapEntityList[i].Name)) - // { - // float asd = 0.0f; - // timeElapsed.TryGetValue(mapEntityList[i].Name, out asd); - // asd += sw.ElapsedTicks; - - // timeElapsed.Remove(mapEntityList[i].Name); - // timeElapsed.Add(mapEntityList[i].Name, asd); - // } - // else - // { - // timeElapsed.Add(mapEntityList[i].Name, sw.ElapsedTicks); - // } - //} - - - + Item.Spawner.Update(); } public virtual void Update(Camera cam, float deltaTime) { } diff --git a/Subsurface/Source/Map/Structure.cs b/Subsurface/Source/Map/Structure.cs index 0584d5541..8f0d6cc9a 100644 --- a/Subsurface/Source/Map/Structure.cs +++ b/Subsurface/Source/Map/Structure.cs @@ -449,6 +449,8 @@ namespace Barotrauma if (Submarine.Loaded != null && Submarine.Loaded.GodMode) return; if (!prefab.HasBody) return; + if (!MathUtils.IsValid(damage)) return; + if (damage != sections[sectionIndex].damage && Math.Abs(sections[sectionIndex].lastSentDamage - damage)>5.0f) { new NetworkEvent(NetworkEventType.WallDamage, ID, false); @@ -640,9 +642,16 @@ namespace Barotrauma { message.Write((float)NetTime.Now); - for (int i = 0; i < sections.Length; i++) + var updateSections = Array.FindAll(sections, s => s != null && Math.Abs(s.damage - s.lastSentDamage)/Health > 0.01f); + + if (updateSections.Length == 0) return false; + + Debug.Assert(updateSections.Length<255); + + message.Write((byte)updateSections.Length); + + for (int i = 0; i < updateSections.Length; i++) { - if (Math.Abs(sections[i].damage - sections[i].lastSentDamage) < 0.1f) continue; message.Write((byte)i); message.WriteRangedSingle(sections[i].damage / Health, 0.0f, 1.0f, 8); @@ -652,16 +661,22 @@ namespace Barotrauma return true; } - public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message) + public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message, out object data) { + data = null; + float updateTime = message.ReadFloat(); if (updateTime < lastUpdate) return; - while (message.Position <= message.LengthBits-8) + int sectionCount = message.ReadByte(); + + for (int i = 0; i= sections.Length) continue; + SetDamage(sectionIndex, damage); } } diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index 094a301b6..baf5dcc31 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -254,8 +254,6 @@ namespace Barotrauma public static Body PickBody(Vector2 rayStart, Vector2 rayEnd, List ignoredBodies = null, Category? collisionCategory = null) { - - float closestFraction = 1.0f; Body closestBody = null; GameMain.World.RayCast((fixture, point, normal, fraction) => @@ -302,7 +300,8 @@ namespace Barotrauma GameMain.World.RayCast((fixture, point, normal, fraction) => { - if (fixture == null || fixture.CollisionCategories != Physics.CollisionWall) return -1; + if (fixture == null || + (fixture.CollisionCategories != Physics.CollisionWall && fixture.CollisionCategories != Physics.CollisionLevel)) return -1; Structure structure = fixture.Body.UserData as Structure; if (structure != null) @@ -397,8 +396,10 @@ namespace Barotrauma return true; } - public override void ReadNetworkData(Networking.NetworkEventType type, NetIncomingMessage message) + public override void ReadNetworkData(Networking.NetworkEventType type, NetIncomingMessage message, out object data) { + data = null; + float sendingTime; Vector2 newTargetPosition, newSpeed; try @@ -630,7 +631,7 @@ namespace Barotrauma MapEntity.MapLoaded(); - foreach (Item item in Item.itemList) + foreach (Item item in Item.ItemList) { foreach (ItemComponent ic in item.components) { diff --git a/Subsurface/Source/Map/WaterRenderer.cs b/Subsurface/Source/Map/WaterRenderer.cs index 4a7227776..7f05f52bb 100644 --- a/Subsurface/Source/Map/WaterRenderer.cs +++ b/Subsurface/Source/Map/WaterRenderer.cs @@ -23,10 +23,10 @@ namespace Barotrauma public WaterRenderer(GraphicsDevice graphicsDevice) { #if WINDOWS - byte[] bytecode = File.ReadAllBytes("Content/watershader.mgfx"); + byte[] bytecode = File.ReadAllBytes("Content/watershader.mgfx"); #endif #if LINUX - byte[] bytecode = File.ReadAllBytes("Content/effects_linux.mgfx"); + byte[] bytecode = File.ReadAllBytes("Content/watershader_opengl.mgfx"); #endif waterEffect = new Effect(graphicsDevice, bytecode); @@ -34,10 +34,15 @@ namespace Barotrauma waterTexture = TextureLoader.FromFile("Content/waterbump.png"); waterEffect.Parameters["xWaveWidth"].SetValue(0.05f); waterEffect.Parameters["xWaveHeight"].SetValue(0.05f); - +#if WINDOWS + waterEffect.Parameters["xTexture"].SetValue(waterTexture); +#endif +#if LINUX + waterEffect.Parameters["xWaterBumpMap"].SetValue(waterTexture); +#endif - if (basicEffect==null) - { + if (basicEffect == null) + { basicEffect = new BasicEffect(GameMain.CurrGraphicsDevice); basicEffect.VertexColorEnabled = false; @@ -45,12 +50,11 @@ namespace Barotrauma } } - public void RenderBack (SpriteBatch spriteBatch, RenderTarget2D texture, float blurAmount = 0.0f) - { + public void RenderBack(SpriteBatch spriteBatch, RenderTarget2D texture, float blurAmount = 0.0f) + { spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearWrap); waterEffect.CurrentTechnique = waterEffect.Techniques["WaterShader"]; - waterEffect.Parameters["xTexture"].SetValue(texture); waterEffect.Parameters["xWavePos"].SetValue(wavePos); waterEffect.Parameters["xBlurDistance"].SetValue(blurAmount); waterEffect.CurrentTechnique.Passes[0].Apply(); @@ -58,7 +62,13 @@ namespace Barotrauma wavePos.X += 0.0001f; wavePos.Y += 0.0001f; - spriteBatch.Draw(waterTexture, new Rectangle(0,0,GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White); +#if WINDOWS + waterEffect.Parameters["xTexture"].SetValue(texture); + spriteBatch.Draw(waterTexture, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White); +#elif LINUX + + spriteBatch.Draw(texture, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White); +#endif spriteBatch.End(); } @@ -73,7 +83,7 @@ namespace Barotrauma basicEffect.View = Matrix.Identity; basicEffect.World = cam.ShaderTransform * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f; - + basicEffect.CurrentTechnique.Passes[0].Apply(); graphicsDevice.SamplerStates[0] = SamplerState.LinearWrap; @@ -89,7 +99,7 @@ namespace Barotrauma protected virtual void Dispose(bool disposing) { if (!disposing) return; - + if (waterEffect != null) { waterEffect.Dispose(); @@ -100,7 +110,7 @@ namespace Barotrauma { basicEffect.Dispose(); basicEffect = null; - } + } } } diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 502b082dd..76cc24db5 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -75,6 +75,7 @@ namespace Barotrauma.Networking // Create new client, with previously created configs client = new NetClient(config); + netPeer = client; reliableChannel = new ReliableChannel(client); NetOutgoingMessage outmsg = client.CreateMessage(); @@ -358,33 +359,46 @@ namespace Barotrauma.Networking myCharacter.CreateUpdateNetworkEvent(true); } } - - foreach (NetworkEvent networkEvent in NetworkEvent.events) + + var message = ComposeNetworkEventMessage(true); + if (message != null) { - if (networkEvent.IsImportant) - { - ReliableMessage reliableMessage = reliableChannel.CreateMessage(); - reliableMessage.InnerMessage.Write((byte)PacketTypes.NetworkEvent); + ReliableMessage reliableMessage = reliableChannel.CreateMessage(); + message.Position = 0; + reliableMessage.InnerMessage.Write(message.ReadBytes(message.LengthBytes)); - if (networkEvent.FillData(reliableMessage.InnerMessage)) - { - reliableChannel.SendMessage(reliableMessage, client.ServerConnection); - } - } - else - { - NetOutgoingMessage message = client.CreateMessage(); - message.Write((byte)PacketTypes.NetworkEvent); - - - if (networkEvent.FillData(message)) - { - client.SendMessage(message, NetDeliveryMethod.Unreliable); - } - } + reliableChannel.SendMessage(reliableMessage, client.ServerConnection); } + + message = ComposeNetworkEventMessage(false); + if (message != null) client.SendMessage(message, NetDeliveryMethod.Unreliable); + + //foreach (NetworkEvent networkEvent in NetworkEvent.Events) + //{ + // if (networkEvent.IsImportant) + // { + // ReliableMessage reliableMessage = reliableChannel.CreateMessage(); + // reliableMessage.InnerMessage.Write((byte)PacketTypes.NetworkEvent); + + // if (networkEvent.FillData(reliableMessage.InnerMessage)) + // { + // reliableChannel.SendMessage(reliableMessage, client.ServerConnection); + // } + // } + // else + // { + // NetOutgoingMessage message = client.CreateMessage(); + // message.Write((byte)PacketTypes.NetworkEvent); + + + // if (networkEvent.FillData(message)) + // { + // client.SendMessage(message, NetDeliveryMethod.Unreliable); + // } + // } + //} - NetworkEvent.events.Clear(); + NetworkEvent.Events.Clear(); // Update current time updateTimer = DateTime.Now + updateInterval; @@ -475,33 +489,8 @@ namespace Barotrauma.Networking //read the data from the message and update client state accordingly if (!gameStarted) break; - byte msgCount = inc.ReadByte(); - - long currPos = inc.PositionInBytes; - - System.Diagnostics.Debug.WriteLine("msgcount: " + msgCount + " startpos: " + inc.PositionInBytes); - for (int i = 0; i < msgCount; i++ ) - { - - byte msgLength = inc.ReadByte(); - - System.Diagnostics.Debug.WriteLine("msglength: "+msgLength); - try - { - NetworkEvent.ReadData(inc); - } - catch - { - int afghj = 1; - } - //+1 because msgLength is one additional byte - currPos += msgLength+1; - inc.Position = currPos*8; - - System.Diagnostics.Debug.WriteLine("currpos: " + currPos); - } - - + NetworkEvent.ReadMessage(inc); + break; case (byte)PacketTypes.UpdateNetLobby: if (gameStarted) continue; @@ -800,7 +789,7 @@ namespace Barotrauma.Networking case 2: msg.Write((byte)PacketTypes.NetworkEvent); msg.Write((byte)NetworkEventType.ComponentUpdate); - msg.Write((int)Item.itemList[Rand.Int(Item.itemList.Count)].ID); + msg.Write((int)Item.ItemList[Rand.Int(Item.ItemList.Count)].ID); msg.Write(Rand.Int(8)); break; case 3: diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 771cbc109..925463667 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -74,6 +74,7 @@ namespace Barotrauma.Networking try { server = new NetServer(config); + netPeer = server; server.Start(); } catch (Exception e) @@ -282,7 +283,7 @@ namespace Barotrauma.Networking foreach (Character c in Character.CharacterList) { - if (c as AICharacter == null) continue; + if (c as AICharacter == null || c.IsDead) continue; if (c.SimPosition.Length() > NetConfig.CharacterIgnoreDistance) continue; @@ -312,6 +313,13 @@ namespace Barotrauma.Networking { if (gameStarted) new NetworkEvent(Submarine.Loaded.ID, false); + foreach (Character c in Character.CharacterList) + { + if (c as AICharacter != null || c.IsDead) continue; + + new NetworkEvent(NetworkEventType.ImportantEntityUpdate, c.ID, false); + } + sparseUpdateTimer = DateTime.Now + sparseUpdateInterval; } @@ -433,34 +441,34 @@ namespace Barotrauma.Networking { case (byte)PacketTypes.NetworkEvent: if (!gameStarted) break; - if (!NetworkEvent.ReadData(inc)) break; + NetworkEvent.ReadMessage(inc, true); - List recipients = connectedClients.FindAll(c => c.Connection != inc.SenderConnection && c.inGame); - if (recipients.Count == 0) break; + //List recipients = connectedClients.FindAll(c => c.Connection != inc.SenderConnection && c.inGame); + //if (recipients.Count == 0) break; - if (isReliable) - { - Debug.WriteLine("receiver reliable networkevent"); - foreach (Client c in recipients) - { - var reliableMessage = c.ReliableChannel.CreateMessage(); - inc.Position = 8+16; - byte[] messageBytes = inc.ReadBytes(inc.LengthBytes-3); - reliableMessage.InnerMessage.Write(messageBytes); + //if (isReliable) + //{ + // Debug.WriteLine("receiver reliable networkevent"); + // foreach (Client c in recipients) + // { + // var reliableMessage = c.ReliableChannel.CreateMessage(); + // inc.Position = 8+16; + // byte[] messageBytes = inc.ReadBytes(inc.LengthBytes-3); + // reliableMessage.InnerMessage.Write(messageBytes); - c.ReliableChannel.SendMessage(reliableMessage, c.Connection); - } - } - else - { - outmsg = server.CreateMessage(); - outmsg.Write(inc); + // c.ReliableChannel.SendMessage(reliableMessage, c.Connection); + // } + //} + //else + //{ + // outmsg = server.CreateMessage(); + // outmsg.Write(inc); - List recipientConnections = new List(); - foreach (Client c in recipients) recipientConnections.Add(c.Connection); + // List recipientConnections = new List(); + // foreach (Client c in recipients) recipientConnections.Add(c.Connection); - server.SendMessage(outmsg, recipientConnections, inc.DeliveryMethod, 0); - } + // server.SendMessage(outmsg, recipientConnections, inc.DeliveryMethod, 0); + //} break; case (byte)PacketTypes.Chatmessage: @@ -624,7 +632,7 @@ namespace Barotrauma.Networking private void SendNetworkEvents() { - if (NetworkEvent.events.Count == 0) return; + if (NetworkEvent.Events.Count == 0) return; List recipients = connectedClients.FindAll(c => c.character != null); @@ -636,55 +644,85 @@ namespace Barotrauma.Networking if (recipients.Count == 0) return; - for (int i = 0; i<2; i++) + //foreach (Client c in recipients) + //{ + + // for (int i = 0; i < 2; i++) + // { + // bool important = i == 0; + + // var events = NetworkEvent.Events.FindAll(e => e.IsImportant == important && e.SenderConnection != c.Connection); + // if (events.Count == 0) continue; + + // List msgBytes = new List(); + + // int totalLength = 1; + + // foreach (NetworkEvent unreliableEvent in events) + // { + // NetBuffer tempMessage = new NetBuffer();// server.CreateMessage(); + // if (!unreliableEvent.FillData(tempMessage)) continue; + // tempMessage.WritePadBits(); + + // tempMessage.Position = 0; + // msgBytes.Add(tempMessage.ReadBytes(tempMessage.LengthBytes)); + + // //one extra byte for writing the length + // totalLength += 1 + tempMessage.LengthBytes; + // } + + // //NetOutgoingMessage combinedMessage = null; + // //reliableMessage = null; + // if (important) + // { + // ReliableMessage reliableMessage = c.ReliableChannel.CreateMessage(); + + // reliableMessage.InnerMessage.Write((byte)msgBytes.Count); + // foreach (byte[] msgData in msgBytes) + // { + // if (msgData.Length > 255) DebugConsole.ThrowError("too large networkevent (" + msgData.Length + " bytes)"); + + // reliableMessage.InnerMessage.Write((byte)msgData.Length); + // reliableMessage.InnerMessage.Write(msgData); + // } + + // c.ReliableChannel.SendMessage(reliableMessage, c.Connection); + // } + // else + // { + // var combinedMessage = server.CreateMessage(totalLength); + + // combinedMessage.Write((byte)msgBytes.Count); + // foreach (byte[] msgData in msgBytes) + // { + // if (msgData.Length > 255) DebugConsole.ThrowError("too large networkevent (" + msgData.Length + " bytes)"); + + // combinedMessage.Write((byte)msgData.Length); + // combinedMessage.Write(msgData); + // } + + // server.SendMessage(combinedMessage, c.Connection, NetDeliveryMethod.Unreliable, 0); + // } + + // } + //} + foreach (Client c in recipients) { - bool important = i==0; - - var unreliableEvents = NetworkEvent.events.FindAll(e => e.IsImportant == important); - if (unreliableEvents.Count == 0) continue; - - NetOutgoingMessage message = server.CreateMessage(); - message.Write((byte)PacketTypes.NetworkEvent); - - List msgBytes = new List(); - - foreach (NetworkEvent unreliableEvent in unreliableEvents) + var message = ComposeNetworkEventMessage(true, c.Connection); + if (message != null) { - NetBuffer tempMessage = new NetBuffer();// server.CreateMessage(); - if (!unreliableEvent.FillData(tempMessage)) continue; - tempMessage.WritePadBits(); + ReliableMessage reliableMessage = c.ReliableChannel.CreateMessage(); + message.Position = 0; + reliableMessage.InnerMessage.Write(message.ReadBytes(message.LengthBytes)); - tempMessage.Position = 0; - msgBytes.Add(tempMessage.ReadBytes(tempMessage.LengthBytes)); + c.ReliableChannel.SendMessage(reliableMessage, c.Connection); } - message.Write((byte)msgBytes.Count); - foreach (byte[] msgData in msgBytes) + message = ComposeNetworkEventMessage(false, c.Connection); + if (message != null) { - if (msgData.Length > 255) DebugConsole.ThrowError("too large networkevent ("+msgData.Length+" bytes)"); - - message.Write((byte)msgData.Length); - message.Write(msgData); - } - - if (important) - { - foreach (Client c in recipients) - { - ReliableMessage reliableMessage = c.ReliableChannel.CreateMessage(); - message.Position = 0; - reliableMessage.InnerMessage.Write(message.ReadBytes(message.LengthBytes)); - - c.ReliableChannel.SendMessage(reliableMessage, c.Connection); - } - } - else - { - if (server.ConnectionsCount>0) - { - server.SendMessage(message, recipientConnections, NetDeliveryMethod.Unreliable, 0); - } - } + server.SendMessage(message, c.Connection, NetDeliveryMethod.Unreliable, 0); + } } @@ -720,7 +758,7 @@ namespace Barotrauma.Networking // } // } //} - NetworkEvent.events.Clear(); + NetworkEvent.Events.Clear(); } @@ -1372,7 +1410,7 @@ namespace Barotrauma.Networking case 1: msg.Write((byte)PacketTypes.NetworkEvent); msg.Write((byte)NetworkEventType.ComponentUpdate); - msg.Write((int)Item.itemList[Rand.Int(Item.itemList.Count)].ID); + msg.Write((int)Item.ItemList[Rand.Int(Item.ItemList.Count)].ID); msg.Write(Rand.Int(8)); break; case 2: diff --git a/Subsurface/Source/Networking/NetStats.cs b/Subsurface/Source/Networking/NetStats.cs index 9d8025344..650012ae5 100644 --- a/Subsurface/Source/Networking/NetStats.cs +++ b/Subsurface/Source/Networking/NetStats.cs @@ -109,7 +109,7 @@ namespace Barotrauma.Networking public float Average() { - return values.Average(); + return values.Length == 0 ? 0.0f : values.Average(); } public void Update(float newValue) @@ -133,11 +133,13 @@ namespace Barotrauma.Networking graphMaxVal = (float)maxVal; } + GUI.DrawRectangle(spriteBatch, rect, Color.White); + + if (values.Length == 0) return; + float lineWidth = (float)rect.Width / (float)(values.Length - 2); float yScale = (float)rect.Height / graphMaxVal; - GUI.DrawRectangle(spriteBatch, rect, Color.White); - Vector2 prevPoint = new Vector2(rect.Right, rect.Bottom - (values[1] + (values[0] - values[1]) * xOffset) * yScale); float currX = rect.Right - ((xOffset - 1.0f) * lineWidth); diff --git a/Subsurface/Source/Networking/NetworkEvent.cs b/Subsurface/Source/Networking/NetworkEvent.cs index 26350fa8a..14a930ea9 100644 --- a/Subsurface/Source/Networking/NetworkEvent.cs +++ b/Subsurface/Source/Networking/NetworkEvent.cs @@ -26,7 +26,7 @@ namespace Barotrauma.Networking class NetworkEvent { - public static List events = new List(); + public static List Events = new List(); private static bool[] isImportant; private static bool[] overridePrevious; @@ -68,6 +68,8 @@ namespace Barotrauma.Networking private object data; + public NetConnection SenderConnection; + //private NetOutgoingMessage message; public ushort ID @@ -110,7 +112,7 @@ namespace Barotrauma.Networking if (overridePrevious[(int)type]) { - if (events.Find(e => e.id == id && e.eventType == type) != null) return; + if (Events.Find(e => e.id == id && e.eventType == type) != null) return; } this.id = id; @@ -118,7 +120,7 @@ namespace Barotrauma.Networking this.data = data; - events.Add(this); + Events.Add(this); } public bool FillData(NetBuffer message) @@ -147,7 +149,31 @@ namespace Barotrauma.Networking return true; } - public static bool ReadData(NetIncomingMessage message) + public static void ReadMessage(NetIncomingMessage message, bool resend=false) + { + byte msgCount = message.ReadByte(); + long currPos = message.PositionInBytes; + + for (int i = 0; i < msgCount; i++) + { + + byte msgLength = message.ReadByte(); + + try + { + NetworkEvent.ReadData(message, resend); + } + catch + { + int afghj = 1; + } + //+1 because msgLength is one additional byte + currPos += msgLength + 1; + message.Position = currPos * 8; + } + } + + public static bool ReadData(NetIncomingMessage message, bool resend=false) { NetworkEventType eventType; ushort id; @@ -175,9 +201,11 @@ namespace Barotrauma.Networking return false; } + object data; + try { - e.ReadNetworkData(eventType, message); + e.ReadNetworkData(eventType, message, out data); } catch (Exception exception) { @@ -187,6 +215,12 @@ namespace Barotrauma.Networking return false; } + if (resend) + { + var resendEvent = new NetworkEvent(eventType, id, false, data); + resendEvent.SenderConnection = message.SenderConnection; + } + return true; } } diff --git a/Subsurface/Source/Networking/NetworkMember.cs b/Subsurface/Source/Networking/NetworkMember.cs index fd52419a9..e49ae368b 100644 --- a/Subsurface/Source/Networking/NetworkMember.cs +++ b/Subsurface/Source/Networking/NetworkMember.cs @@ -3,6 +3,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using System.Collections.Generic; +using Lidgren.Network; namespace Barotrauma.Networking { @@ -41,7 +42,9 @@ namespace Barotrauma.Networking { protected static Color[] messageColor = { Color.White, Color.Red, Color.LightBlue, Color.LightGreen }; - + + protected NetPeer netPeer; + protected string name; protected TimeSpan updateInterval; @@ -120,6 +123,44 @@ namespace Barotrauma.Networking Voting = new Voting(); } + protected NetOutgoingMessage ComposeNetworkEventMessage(bool isImportant, NetConnection excludedConnection = null) + { + if (netPeer == null) return null; + + var events = NetworkEvent.Events.FindAll(e => e.IsImportant == isImportant); + if (events.Count == 0) return null; + + List msgBytes = new List(); + + foreach (NetworkEvent networkEvent in events) + { + if (excludedConnection != null && networkEvent.SenderConnection == excludedConnection) continue; + + NetBuffer tempMessage = new NetBuffer();// server.CreateMessage(); + if (!networkEvent.FillData(tempMessage)) continue; + tempMessage.WritePadBits(); + + tempMessage.Position = 0; + msgBytes.Add(tempMessage.ReadBytes(tempMessage.LengthBytes)); + } + + if (msgBytes.Count == 0) return null; + + NetOutgoingMessage message = netPeer.CreateMessage(); + message.Write((byte)PacketTypes.NetworkEvent); + + message.Write((byte)msgBytes.Count); + foreach (byte[] msgData in msgBytes) + { + if (msgData.Length > 255) DebugConsole.ThrowError("too large networkevent (" + msgData.Length + " bytes)"); + + message.Write((byte)msgData.Length); + message.Write(msgData); + } + + return message; + } + protected void CreateCrewFrame(List crew) { int width = 600, height = 400; diff --git a/Subsurface/Source/Screens/EditMapScreen.cs b/Subsurface/Source/Screens/EditMapScreen.cs index 335fed863..9214a425c 100644 --- a/Subsurface/Source/Screens/EditMapScreen.cs +++ b/Subsurface/Source/Screens/EditMapScreen.cs @@ -7,17 +7,17 @@ namespace Barotrauma { class EditMapScreen : Screen { - Camera cam; + private Camera cam; - GUIComponent GUIpanel; + private GUIComponent GUIpanel; - GUIComponent[] GUItabs; - int selectedTab; + private GUIComponent[] GUItabs; + private int selectedTab; //a character used for picking up and manipulating items - Character dummyCharacter; + private Character dummyCharacter; - bool characterMode; + private bool characterMode; public Camera Cam { @@ -31,12 +31,12 @@ namespace Barotrauma private string GetItemCount() { - return "Items: " +Item.itemList.Count; + return "Items: " +Item.ItemList.Count; } private string GetStructureCount() { - return "Structures: " + (MapEntity.mapEntityList.Count - Item.itemList.Count); + return "Structures: " + (MapEntity.mapEntityList.Count - Item.ItemList.Count); } private string GetPhysicsBodyCount() diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index 728c5959b..37f70570d 100644 Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ