diff --git a/Launcher/Form1.cs b/Launcher/Form1.cs index ed2448611..01d7e274a 100644 --- a/Launcher/Form1.cs +++ b/Launcher/Form1.cs @@ -285,7 +285,7 @@ namespace Launcher } filesToDownload = UpdaterUtil.GetRequiredFiles(doc); - + string dir = Directory.GetCurrentDirectory(); filesToDownloadCount = filesToDownload.Count; diff --git a/Launcher2/LauncherMain.cs b/Launcher2/LauncherMain.cs index d24cee5a8..0825c8119 100644 --- a/Launcher2/LauncherMain.cs +++ b/Launcher2/LauncherMain.cs @@ -98,7 +98,7 @@ namespace Launcher2 // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); - GUI.LoadContent(GraphicsDevice); + GUI.LoadContent(GraphicsDevice, false); backgroundTexture = TextureLoader.FromFile("Content/UI/titleBackground.png"); titleTexture = TextureLoader.FromFile("Content/UI/titleText.png"); @@ -550,6 +550,17 @@ namespace Launcher2 textBlock.TextColor = Color.Red; //textBlock.CanBeFocused = false; + GUIFrame dummyFrame = new GUIFrame(new Rectangle(0, 0, graphicsWidth, graphicsHeight)); + GUIMessageBox errorBox = new GUIMessageBox("Error while updating", "Downloading the update failed.", + new string[] { "Retry", "Cancel" }, 400, 250, Alignment.TopLeft, dummyFrame); + + errorBox.Buttons[0].OnClicked += DownloadButtonClicked; + errorBox.Buttons[0].OnClicked += errorBox.Close; + + errorBox.Buttons[1].OnClicked = CancelUpdate; + errorBox.Buttons[1].OnClicked += errorBox.Close; + + return; } filesDownloaded++; @@ -557,6 +568,14 @@ namespace Launcher2 DownloadNextFile(); } + + private bool CancelUpdate(GUIButton button, object obj) + { + downloadButton.Enabled = false; + launchButton.Enabled = true; + + return true; + } } } diff --git a/Subsurface/Content/Characters/Moloch/moloch.xml b/Subsurface/Content/Characters/Moloch/moloch.xml index d9168a7ab..3f9a40f45 100644 --- a/Subsurface/Content/Characters/Moloch/moloch.xml +++ b/Subsurface/Content/Characters/Moloch/moloch.xml @@ -46,15 +46,15 @@ - + - + - + diff --git a/Subsurface/Content/Sounds/Damage/StructureBlunt6.ogg b/Subsurface/Content/Sounds/Damage/StructureBlunt6.ogg index 3593d8bc8..b4390c6dc 100644 Binary files a/Subsurface/Content/Sounds/Damage/StructureBlunt6.ogg and b/Subsurface/Content/Sounds/Damage/StructureBlunt6.ogg differ diff --git a/Subsurface/Data/SavedSubs/Aegir Mark II.gz b/Subsurface/Data/SavedSubs/Aegir Mark II.gz index 21d1c980f..615518a1c 100644 Binary files a/Subsurface/Data/SavedSubs/Aegir Mark II.gz and b/Subsurface/Data/SavedSubs/Aegir Mark II.gz differ diff --git a/Subsurface/Data/SavedSubs/Vellamo.gz b/Subsurface/Data/SavedSubs/Vellamo.gz index aacaeab7f..64666757d 100644 Binary files a/Subsurface/Data/SavedSubs/Vellamo.gz and b/Subsurface/Data/SavedSubs/Vellamo.gz differ diff --git a/Subsurface/Source/Characters/AICharacter.cs b/Subsurface/Source/Characters/AICharacter.cs index 90b78a7c7..874120463 100644 --- a/Subsurface/Source/Characters/AICharacter.cs +++ b/Subsurface/Source/Characters/AICharacter.cs @@ -107,7 +107,7 @@ namespace Subsurface aiController.FillNetworkData(message); - LargeUpdateTimer = 10; + LargeUpdateTimer = 50; } else { @@ -123,7 +123,7 @@ namespace Subsurface public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message) { - if (type == NetworkEventType.KillCharacter) + if (type == NetworkEventType.KillCharacter) { Kill(true); return; diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 332f0ce47..20c15154b 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -741,7 +741,7 @@ namespace Subsurface public virtual void Update(Camera cam, float deltaTime) { - AnimController.SimplePhysicsEnabled = (Character.controlled!=this && Vector2.Distance(cam.WorldViewCenter, Position)>5000.0f); + //AnimController.SimplePhysicsEnabled = (Character.controlled!=this && Vector2.Distance(cam.WorldViewCenter, Position)>5000.0f); if (isDead) return; @@ -839,6 +839,11 @@ namespace Subsurface } } + if (GameMain.DebugDraw) + { + AnimController.DebugDraw(spriteBatch); + } + Vector2 healthBarPos = new Vector2(Position.X - 50, -Position.Y - 50.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); @@ -1100,7 +1105,7 @@ namespace Subsurface message.WriteRangedSingle(MathHelper.Clamp(AnimController.StunTimer,0.0f,60.0f), 0.0f, 60.0f, 8); message.Write((byte)((health/maxHealth)*255.0f)); - LargeUpdateTimer = 10; + LargeUpdateTimer = 50; } else { @@ -1115,6 +1120,8 @@ namespace Subsurface { if (type == NetworkEventType.PickItem) { + System.Diagnostics.Debug.WriteLine("**************** PickItem networkevent received"); + int itemId = -1; try @@ -1126,6 +1133,8 @@ namespace Subsurface return; } + System.Diagnostics.Debug.WriteLine("item id: "+itemId); + Item item = FindEntityByID(itemId) as Item; if (item != null) { diff --git a/Subsurface/Source/Characters/HumanoidAnimController.cs b/Subsurface/Source/Characters/HumanoidAnimController.cs index fcb959d86..240b00281 100644 --- a/Subsurface/Source/Characters/HumanoidAnimController.cs +++ b/Subsurface/Source/Characters/HumanoidAnimController.cs @@ -214,7 +214,7 @@ namespace Subsurface float walkPosX = (float)Math.Cos(walkPos); float walkPosY = (float)Math.Sin(walkPos); - float runningModifier = (float)Math.Max(Math.Abs(TargetMovement.X) / 1.5f, 1.0); + float runningModifier = (float)Math.Max(Math.Min(Math.Abs(TargetMovement.X),3.0f) / 1.5f, 1.0); Vector2 stepSize = new Vector2( this.stepSize.X * walkPosX * runningModifier, @@ -229,7 +229,7 @@ namespace Subsurface } TargetMovement *= (1.0f - 0.5f * ((float)limbsInWater / (float)Limbs.Count())); - + movement = MathUtils.SmoothStep(movement, TargetMovement, movementLerp); movement.Y = 0.0f; diff --git a/Subsurface/Source/Characters/Ragdoll.cs b/Subsurface/Source/Characters/Ragdoll.cs index d40e3ae07..58bf9a95f 100644 --- a/Subsurface/Source/Characters/Ragdoll.cs +++ b/Subsurface/Source/Characters/Ragdoll.cs @@ -384,8 +384,11 @@ namespace Subsurface foreach (Limb limb in Limbs) { limb.Draw(spriteBatch); - } - + } + } + + public void DebugDraw(SpriteBatch spriteBatch) + { if (!GameMain.DebugDraw) return; foreach (Limb limb in Limbs) @@ -416,16 +419,19 @@ namespace Subsurface GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), Color.White, true); } - if (refLimb.body.TargetPosition != Vector2.Zero) + foreach (Limb limb in Limbs) { - Vector2 pos = ConvertUnits.ToDisplayUnits(refLimb.body.TargetPosition); - pos.Y = -pos.Y; - GUI.DrawLine(spriteBatch, pos+new Vector2(-30.0f,0.0f), pos+new Vector2(30.0f,0.0f), Color.LightBlue); - GUI.DrawLine(spriteBatch, pos + new Vector2(0.0f,-30.0f), pos + new Vector2(0.0f,30.0f), Color.LightBlue); - + if (limb.body.TargetPosition != Vector2.Zero) + { + Vector2 pos = ConvertUnits.ToDisplayUnits(limb.body.TargetPosition); + pos.Y = -pos.Y; + GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X - 10, (int)pos.Y - 10, 20, 20), Color.Cyan, false, 0.01f); + GUI.DrawLine(spriteBatch, pos, new Vector2(limb.Position.X, -limb.Position.Y), limb==RefLimb ? Color.Orange : Color.Cyan); + } } + } public virtual void Flip() @@ -635,7 +641,7 @@ namespace Subsurface float resetDistance = NetConfig.ResetRagdollDistance; //if the limb is closer than alloweddistance, just ignore the difference - float allowedDistance = NetConfig.AllowedRagdollDistance; + float allowedDistance = NetConfig.AllowedRagdollDistance * ((inWater) ? 2.0f : 1.0f); float dist = Vector2.Distance(refLimb.body.SimPosition, refLimb.body.TargetPosition); bool resetAll = (dist > resetDistance && character.LargeUpdateTimer == 1); @@ -645,6 +651,11 @@ namespace Subsurface if (newMovement == Vector2.Zero || newMovement.Length() < allowedDistance) { refLimb.body.TargetPosition = Vector2.Zero; + foreach (Limb limb in Limbs) + { + limb.body.TargetPosition = Vector2.Zero; + } + correctionMovement = Vector2.Zero; return; } @@ -656,14 +667,14 @@ namespace Subsurface { //if (limb.body.TargetPosition == Vector2.Zero) continue; - limb.body.SetTransform(limb.SimPosition + newMovement * 0.1f, limb.Rotation); + //limb.body.SetTransform(limb.SimPosition + newMovement * 0.1f, limb.Rotation); } - correctionMovement = Vector2.Normalize(newMovement) * Math.Min(0.1f + dist, 3.0f); + correctionMovement = Vector2.Normalize(newMovement) * MathHelper.Clamp(dist*5.0f, 0.1f, 5.0f); } else { - correctionMovement = Vector2.Normalize(newMovement) * Math.Min(0.1f + dist, 3.0f); + correctionMovement = Vector2.Normalize(newMovement) * MathHelper.Clamp(dist * 5.0f, 0.1f, 5.0f); if (Math.Abs(correctionMovement.Y) < 0.1f) correctionMovement.Y = 0.0f; } } diff --git a/Subsurface/Source/Events/MonsterEvent.cs b/Subsurface/Source/Events/MonsterEvent.cs index cc0aeadfd..feb097ed9 100644 --- a/Subsurface/Source/Events/MonsterEvent.cs +++ b/Subsurface/Source/Events/MonsterEvent.cs @@ -31,7 +31,7 @@ namespace Subsurface for (int i = 0; i < amount; i++) { - Vector2 position = (randomWayPoint == null) ? Vector2.Zero : randomWayPoint.SimPosition; + Vector2 position = (randomWayPoint == null) ? Vector2.Zero : FarseerPhysics.ConvertUnits.ToSimUnits(randomWayPoint.Position + Level.Loaded.Position); position.X += Rand.Range(-0.5f, 0.5f); position.Y += Rand.Range(-0.5f, 0.5f); monsters[i] = new AICharacter(characterFile, position); diff --git a/Subsurface/Source/GUI/GUI.cs b/Subsurface/Source/GUI/GUI.cs index 369ac7475..9df743cb7 100644 --- a/Subsurface/Source/GUI/GUI.cs +++ b/Subsurface/Source/GUI/GUI.cs @@ -48,12 +48,15 @@ namespace Subsurface get { return pauseMenuOpen; } } - public static void LoadContent(GraphicsDevice graphics) + public static void LoadContent(GraphicsDevice graphics, bool loadSounds = true) { graphicsDevice = graphics; - sounds = new Sound[2]; - sounds[0] = Sound.Load("Content/Sounds/UI/UImsg.ogg", false); + if (loadSounds) + { + sounds = new Sound[2]; + sounds[0] = Sound.Load("Content/Sounds/UI/UImsg.ogg", false); + } // create 1x1 texture for line drawing t = new Texture2D(graphicsDevice, 1, 1); diff --git a/Subsurface/Source/GameSession/GameModes/TutorialMode.cs b/Subsurface/Source/GameSession/GameModes/TutorialMode.cs index 32ad2fe35..c2a61cfef 100644 --- a/Subsurface/Source/GameSession/GameModes/TutorialMode.cs +++ b/Subsurface/Source/GameSession/GameModes/TutorialMode.cs @@ -543,11 +543,10 @@ namespace Subsurface messageBox.Buttons[0].OnClicked += Restart; messageBox.Buttons[0].OnClicked += messageBox.Close; - //messageBox.Buttons[1].UserData = MainMenuScreen.Tabs.Main; + messageBox.Buttons[1].OnClicked = GameMain.MainMenuScreen.SelectTab; messageBox.Buttons[1].OnClicked += messageBox.Close; - yield return CoroutineStatus.Success; } diff --git a/Subsurface/Source/Items/Components/Machines/Radar.cs b/Subsurface/Source/Items/Components/Machines/Radar.cs index 25cecb794..4c40a4ce7 100644 --- a/Subsurface/Source/Items/Components/Machines/Radar.cs +++ b/Subsurface/Source/Items/Components/Machines/Radar.cs @@ -77,7 +77,11 @@ namespace Subsurface.Items.Components if (voltage < minVoltage) return; - if (GUI.DrawButton(spriteBatch, new Rectangle(x+20, y+20, 200, 30), "Activate Radar")) IsActive = !IsActive; + if (GUI.DrawButton(spriteBatch, new Rectangle(x + 20, y + 20, 200, 30), "Activate Radar")) + { + IsActive = !IsActive; + item.NewComponentEvent(this, true); + } int radius = GuiFrame.Rect.Height / 2 - 10; DrawRadar(spriteBatch, new Rectangle((int)GuiFrame.Center.X - radius, (int)GuiFrame.Center.Y - radius, radius * 2, radius * 2)); @@ -217,5 +221,22 @@ namespace Subsurface.Items.Components spriteBatch.DrawString(GUI.SmallFont, (int)(dist / 80.0f) + " m", new Vector2(markerPos.X + 10, markerPos.Y + 15), Color.LightGreen); } + public override void FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetOutgoingMessage message) + { + message.Write(IsActive); + } + + public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message) + { + try + { + IsActive = message.ReadBoolean(); + } + catch + { + return; + } + } + } } diff --git a/Subsurface/Source/Items/Components/Machines/Steering.cs b/Subsurface/Source/Items/Components/Machines/Steering.cs index c73ad1387..80b870d68 100644 --- a/Subsurface/Source/Items/Components/Machines/Steering.cs +++ b/Subsurface/Source/Items/Components/Machines/Steering.cs @@ -163,7 +163,7 @@ namespace Subsurface.Items.Components if (autopilotRayCastTimer<=0.0f && steeringPath.NextNode != null) { - Vector2 diff = steeringPath.NextNode.Position - Submarine.Loaded.Position; + Vector2 diff = ConvertUnits.ToSimUnits(steeringPath.NextNode.Position - Submarine.Loaded.Position); bool nextVisible = true; for (int x = -1; x < 2; x += 2) diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index 367a376a9..f8a2fc131 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -517,24 +517,36 @@ namespace Subsurface body.SetToTargetPosition(); + bool inWater = true; + if (CurrentHull != null) { float surfaceY = ConvertUnits.ToSimUnits(CurrentHull.Surface); - if (surfaceY > body.SimPosition.Y) return; - //the item has gone through the surface of the water -> apply an impulse which serves as surface tension - if ((body.SimPosition.Y - (body.LinearVelocity.Y / 60.0f)) < surfaceY) + if (body.SimPosition.Y < surfaceY ) { - Vector2 impulse = -body.LinearVelocity * (body.Mass / body.Density); - body.ApplyLinearImpulse(impulse); - int n = (int)((ConvertUnits.ToDisplayUnits(body.SimPosition.X) - CurrentHull.Rect.X) / Hull.WaveWidth); - CurrentHull.WaveVel[n] = impulse.Y * 10.0f; + inWater = true; + + //the item has gone through the surface of the water -> apply an impulse which serves as surface tension + //if (body.SimPosition.Y - (body.LinearVelocity.Y / 60.0f) < surfaceY) + //{ + // Vector2 impulse = -body.LinearVelocity * (body.Mass / body.Density); + // body.ApplyLinearImpulse(impulse); + // int n = (int)((ConvertUnits.ToDisplayUnits(body.SimPosition.X) - CurrentHull.Rect.X) / Hull.WaveWidth); + // CurrentHull.WaveVel[n] = impulse.Y * 10.0f; + //} + } + else + { + inWater = false; } } + if (!inWater) return; + //calculate (a rough approximation of) buoyancy float volume = body.Mass / body.Density; - Vector2 buoyancy = new Vector2(0, volume * 20.0f); + Vector2 buoyancy = new Vector2(0, volume * 10.0f); //apply buoyancy and drag @@ -808,7 +820,7 @@ namespace Subsurface public bool Pick(Character picker, bool forcePick=false) { - + System.Diagnostics.Debug.WriteLine("Item.Pick("+picker+", "+forcePick+")"); bool hasRequiredSkills = true; bool picked = false, selected = false; diff --git a/Subsurface/Source/Map/Levels/Level.cs b/Subsurface/Source/Map/Levels/Level.cs index e175708ca..e05b90325 100644 --- a/Subsurface/Source/Map/Levels/Level.cs +++ b/Subsurface/Source/Map/Levels/Level.cs @@ -447,6 +447,16 @@ int currentTargetIndex = 1; for (int i = 0; i < pathCells.Count; i++) { + //clean "loops" from the path + for (int n = 0; n < i; n++) + { + if (pathCells[n] != pathCells[i]) continue; + + pathCells.RemoveRange(n+1, i-n); + break; + } + if (i >= pathCells.Count) break; + newWaypoint = new WayPoint(new Rectangle((int)pathCells[i].Center.X, (int)pathCells[i].Center.Y, 10, 10)); newWaypoint.MoveWithLevel = true; if (prevWaypoint != null) @@ -460,11 +470,9 @@ int currentTargetIndex = 1; newWaypoint = new WayPoint(new Rectangle((int)pathCells[pathCells.Count - 1].Center.X, (int)(borders.Height + shaftHeight), 10, 10)); newWaypoint.MoveWithLevel = true; - if (prevWaypoint != null) - { - prevWaypoint.linkedTo.Add(newWaypoint); - newWaypoint.linkedTo.Add(prevWaypoint); - } + prevWaypoint.linkedTo.Add(newWaypoint); + newWaypoint.linkedTo.Add(prevWaypoint); + } Debug.WriteLine("genpath: " + sw2.ElapsedMilliseconds + " ms"); @@ -748,6 +756,13 @@ int currentTargetIndex = 1; 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; diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index 54ee2a618..6c4616040 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -380,7 +380,6 @@ namespace Subsurface message.Write(Speed.X); message.Write(Speed.Y); - } public override void ReadNetworkData(Networking.NetworkEventType type, NetIncomingMessage message) diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index dd3ecae38..63af4fe4d 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -61,7 +61,7 @@ namespace Subsurface.Networking NetPeerConfiguration config = new NetPeerConfiguration("subsurface"); #if DEBUG - config.SimulatedLoss = 0.2f; + config.SimulatedLoss = 0.1f; config.SimulatedMinimumLatency = 0.3f; #endif @@ -90,11 +90,14 @@ namespace Subsurface.Networking catch (ArgumentNullException e) { DebugConsole.ThrowError("Couldn't connect to "+hostIP+". Error message: "+e.Message); + Disconnect(); + + GameMain.NetLobbyScreen.Select(); return; } - // Create timespan of 30ms - updateInterval = new TimeSpan(0, 0, 0, 0, 200); + + updateInterval = new TimeSpan(0, 0, 0, 0, 100); // Set timer to tick every 50ms //update = new System.Timers.Timer(50); @@ -127,6 +130,9 @@ namespace Subsurface.Networking Disconnect(); GameMain.NetworkMember = null; GameMain.MainMenuScreen.Select(); + + GameMain.MainMenuScreen.SelectTab(MainMenuScreen.Tab.LoadGame); + return true; } @@ -160,11 +166,21 @@ namespace Subsurface.Networking if (packetType == (byte)PacketTypes.LoggedIn) { myID = inc.ReadInt32(); - if (inc.ReadBoolean() && Screen.Selected != GameMain.GameScreen) + bool gameStarted= inc.ReadBoolean(); + if (gameStarted && Screen.Selected != GameMain.GameScreen) { new GUIMessageBox("Please wait", "A round is already running. You will have to wait for a new round to start."); } + bool hasCharacter = inc.ReadBoolean(); + + if (gameStarted && !hasCharacter && myCharacter!=null) + { + GameMain.NetLobbyScreen.Select(); + + new GUIMessageBox("Connection timed out", "You were disconnected for too long and your character was deleted. Please wait for another round to start."); + } + GameMain.NetLobbyScreen.ClearPlayers(); //add the names of other connected clients to the lobby screen @@ -173,12 +189,12 @@ namespace Subsurface.Networking { Client otherClient = new Client(inc.ReadString(), inc.ReadInt32()); - GameMain.NetLobbyScreen.AddPlayer(otherClient); + GameMain.NetLobbyScreen.AddPlayer(otherClient.name); otherClients.Add(otherClient); } //add the name of own client to the lobby screen - GameMain.NetLobbyScreen.AddPlayer(new Client(name, myID)); + GameMain.NetLobbyScreen.AddPlayer(name); CanStart = true; } @@ -245,7 +261,7 @@ namespace Subsurface.Networking if (client.ConnectionStatus == NetConnectionStatus.Disconnected) { - GameMain.NetLobbyScreen.RemovePlayer(myID); + //GameMain.NetLobbyScreen.RemovePlayer(myID); if (reconnectBox==null) { reconnectBox = new GUIMessageBox("CONNECTION LOST", "You have been disconnected from the server. Reconnecting...", new string[0]); @@ -330,7 +346,7 @@ namespace Subsurface.Networking Client otherClient = new Client(inc.ReadString(), inc.ReadInt32()); - GameMain.NetLobbyScreen.AddPlayer(otherClient); + GameMain.NetLobbyScreen.AddPlayer(otherClient.name); otherClients.Add(otherClient); AddChatMessage(otherClient.name + " has joined the server", ChatMessageType.Server); @@ -340,13 +356,15 @@ namespace Subsurface.Networking int leavingID = inc.ReadInt32(); AddChatMessage(inc.ReadString(), ChatMessageType.Server); - GameMain.NetLobbyScreen.RemovePlayer(otherClients.Find(c => c.ID==leavingID)); + Client disconnectedClient = otherClients.Find(c => c.ID == leavingID); + if (disconnectedClient != null) GameMain.NetLobbyScreen.RemovePlayer(disconnectedClient.name); + break; case (byte)PacketTypes.KickedOut: string msg = inc.ReadString(); - new GUIMessageBox("KICKED", msg); + new GUIMessageBox("You have been kicked out from the server", msg); GameMain.MainMenuScreen.Select(); @@ -370,9 +388,7 @@ namespace Subsurface.Networking new GUIMessageBox("You are the Traitor!", "Your secret task is to assassinate " + targetName + "!"); break; - } - - + } } } @@ -388,6 +404,16 @@ namespace Subsurface.Networking string mapName = inc.ReadString(); string mapHash = inc.ReadString(); + string modeName = inc.ReadString(); + + GameModePreset gameMode = GameModePreset.list.Find(gm => gm.Name == modeName); + + if (gameMode == null) + { + DebugConsole.ThrowError("Game mode ''"+gameMode+"'' not found!"); + yield return CoroutineStatus.Success; + } + if (!GameMain.NetLobbyScreen.TrySelectMap(mapName, mapHash)) { yield return CoroutineStatus.Success; @@ -401,7 +427,7 @@ namespace Subsurface.Networking Rand.SetSyncedSeed(seed); //int gameModeIndex = inc.ReadInt32(); - GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedMap, "", GameMain.NetLobbyScreen.SelectedMode); + GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedMap, "", gameMode); yield return CoroutineStatus.Running; @@ -508,6 +534,7 @@ namespace Subsurface.Networking client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered); client.Shutdown(""); + GameMain.NetworkMember = null; } public void SendCharacterData() diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index fa95c2e06..c23846ece 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -22,12 +22,12 @@ namespace Subsurface.Networking private NetServer server; private NetPeerConfiguration config; - private TimeSpan SparseUpdateInterval = new TimeSpan(0, 0, 0, 3); + private TimeSpan sparseUpdateInterval = new TimeSpan(0, 0, 0, 3); private DateTime sparseUpdateTimer; private TimeSpan refreshMasterInterval = new TimeSpan(0, 0, 40); private DateTime refreshMasterTimer; - + private bool masterServerResponded; private bool registeredToMaster; @@ -110,9 +110,8 @@ namespace Subsurface.Networking { RegisterToMasterServer(); } - - - updateInterval = new TimeSpan(0, 0, 0, 0, 30); + + updateInterval = new TimeSpan(0, 0, 0, 0, 60); DebugConsole.NewMessage("Server started", Color.Green); @@ -203,17 +202,15 @@ namespace Subsurface.Networking return; } } - + public override void Update(float deltaTime) { if (!started) return; base.Update(deltaTime); - + if (gameStarted) { - if (myCharacter!=null) new NetworkEvent(myCharacter.ID, true); - inGameHUD.Update((float)Physics.step); } @@ -221,6 +218,13 @@ namespace Subsurface.Networking { disconnectedClients[i].deleteDisconnectedTimer -= deltaTime; if (disconnectedClients[i].deleteDisconnectedTimer > 0.0f) continue; + + if (gameStarted && disconnectedClients[i].character!=null) + { + disconnectedClients[i].character.Remove(); + disconnectedClients[i].character = null; + } + disconnectedClients.RemoveAt(i); } @@ -240,6 +244,21 @@ namespace Subsurface.Networking // if 30ms has passed if (updateTimer < DateTime.Now) { + if (gameStarted) + { + if (myCharacter != null) new NetworkEvent(myCharacter.ID, true); + + foreach (Character c in Character.CharacterList) + { + if (c as AICharacter == null) continue; + + if (c.SimPosition == Vector2.Zero || c.SimPosition.Length() < 100.0f) + { + new NetworkEvent(c.ID, false); + } + } + } + if (server.ConnectionsCount > 0) { if (sparseUpdateTimer < DateTime.Now) SparseUpdate(); @@ -260,26 +279,9 @@ namespace Subsurface.Networking private void SparseUpdate() { - foreach (Character c in Character.CharacterList) - { - bool isClient = false; - foreach (Client client in connectedClients) - { - if (client.character != c) continue; - isClient = true; - break; - } - - if (!isClient && (c.SimPosition==Vector2.Zero || c.SimPosition.Length() < 300.0f)) - { - c.LargeUpdateTimer -= 2; - new NetworkEvent(c.ID, false); - } - } - if (gameStarted) new NetworkEvent(Submarine.Loaded.ID, false); - sparseUpdateTimer = DateTime.Now + SparseUpdateInterval; + sparseUpdateTimer = DateTime.Now + sparseUpdateInterval; } private void ReadMessage(NetIncomingMessage inc) @@ -313,7 +315,7 @@ namespace Subsurface.Networking { //AssignJobs(); - GameMain.NetLobbyScreen.AddPlayer(sender); + GameMain.NetLobbyScreen.AddPlayer(sender.name); // Notify the client that they have logged in outmsg = server.CreateMessage(); @@ -324,6 +326,8 @@ namespace Subsurface.Networking outmsg.Write(gameStarted); + outmsg.Write(gameStarted && sender.character!=null); + //notify the client about other clients already logged in outmsg.Write((characterInfo == null) ? connectedClients.Count - 1 : connectedClients.Count); foreach (Client c in connectedClients) @@ -365,7 +369,8 @@ namespace Subsurface.Networking disconnectedClients.Add(connectedClient); } - DisconnectClient(inc.SenderConnection); + DisconnectClient(inc.SenderConnection, + connectedClient != null ? connectedClient.name+" has disconnected" : ""); } break; @@ -392,9 +397,7 @@ namespace Subsurface.Networking if (recipients.Count == 0) break; server.SendMessage(outmsg, recipients, inc.DeliveryMethod, 0); - - System.Diagnostics.Debug.WriteLine("Sending networkevent (" + outmsg.LengthBytes+" bytes)"); - + break; case (byte)PacketTypes.Chatmessage: ChatMessageType messageType = (ChatMessageType)inc.ReadByte(); @@ -537,10 +540,9 @@ namespace Subsurface.Networking private void SendNetworkEvents() { if (NetworkEvent.events.Count == 0) return; - + foreach (NetworkEvent networkEvent in NetworkEvent.events) { - //System.Diagnostics.Debug.WriteLine("networkevent "+networkEvent.ID); List recipients = new List(); @@ -565,16 +567,13 @@ namespace Subsurface.Networking networkEvent.FillData(message); - System.Diagnostics.Debug.WriteLine("Sending networkevent " + Entity.FindEntityByID(networkEvent.ID).ToString() + " (" + message.LengthBytes + " bytes)"); - if (server.ConnectionsCount>0) { server.SendMessage(message, recipients, (networkEvent.IsImportant) ? NetDeliveryMethod.Unreliable : NetDeliveryMethod.ReliableUnordered, 0); - } - + } } - NetworkEvent.events.Clear(); + NetworkEvent.events.Clear(); } @@ -661,6 +660,8 @@ namespace Subsurface.Networking msg.Write(GameMain.NetLobbyScreen.SelectedMap.Name); msg.Write(GameMain.NetLobbyScreen.SelectedMap.MD5Hash.Hash); + msg.Write(GameMain.NetLobbyScreen.SelectedMode.Name); + msg.Write(GameMain.NetLobbyScreen.GameDuration.TotalMinutes); msg.Write((myCharacter == null) ? connectedClients.Count : connectedClients.Count + 1); @@ -677,8 +678,11 @@ namespace Subsurface.Networking } SendMessage(msg, NetDeliveryMethod.ReliableUnordered, null); + + CreateCrewFrame(crew); - yield return CoroutineStatus.Running; + //give some time for the clients to load the map + yield return new WaitForSeconds(2.0f); gameStarted = true; @@ -686,8 +690,6 @@ namespace Subsurface.Networking GameMain.GameScreen.Select(); - CreateCrewFrame(crew); - yield return CoroutineStatus.Success; } @@ -758,10 +760,10 @@ namespace Subsurface.Networking } - private void DisconnectClient(NetConnection senderConnection) + private void DisconnectClient(NetConnection senderConnection, string msg = "", string targetmsg = "") { Client client = connectedClients.Find(x => x.Connection == senderConnection); - if (client != null) DisconnectClient(client); + if (client != null) DisconnectClient(client, msg, targetmsg); } private void DisconnectClient(Client client, string msg = "", string targetmsg = "") @@ -770,8 +772,8 @@ namespace Subsurface.Networking if (gameStarted && client.character != null) client.character.ClearInputs(); - if (msg == "") msg = client.name + " has left the server"; - if (targetmsg == "") targetmsg = "You have left the server"; + if (string.IsNullOrWhiteSpace(msg)) msg = client.name + " has left the server"; + if (string.IsNullOrWhiteSpace(targetmsg)) targetmsg = "You have left the server"; NetOutgoingMessage outmsg = server.CreateMessage(); outmsg.Write((byte)PacketTypes.KickedOut); @@ -785,7 +787,7 @@ namespace Subsurface.Networking outmsg.Write(client.ID); outmsg.Write(msg); - GameMain.NetLobbyScreen.RemovePlayer(client); + GameMain.NetLobbyScreen.RemovePlayer(client.name); if (server.Connections.Count > 0) { @@ -1092,7 +1094,7 @@ namespace Subsurface.Networking public override void Disconnect() { - server.Shutdown(""); + server.Shutdown("The server has shut down"); } } diff --git a/Subsurface/Source/Networking/NetworkEvent.cs b/Subsurface/Source/Networking/NetworkEvent.cs index 047357f60..6cc1420f5 100644 --- a/Subsurface/Source/Networking/NetworkEvent.cs +++ b/Subsurface/Source/Networking/NetworkEvent.cs @@ -18,7 +18,7 @@ namespace Subsurface.Networking { public static List events = new List(); - private static bool[] isImportant = { false, true, false, true, true, true, true, false }; + private static bool[] isImportant = { false, true, false, true, true, true, true }; private int id; diff --git a/Subsurface/Source/Particles/Particle.cs b/Subsurface/Source/Particles/Particle.cs index 73da4aaf8..643fefdbf 100644 --- a/Subsurface/Source/Particles/Particle.cs +++ b/Subsurface/Source/Particles/Particle.cs @@ -113,36 +113,40 @@ namespace Subsurface.Particles private List FindAdjacentHulls(List adjacentHulls, Hull currentHull, bool isHorizontal) { - foreach (Gap gap in Gap.GapList) + foreach (Gap gap in Gap.GapList) + { + if (gap.isHorizontal != isHorizontal) continue; + if (gap.Open < 0.01f) continue; + if (gap.linkedTo.Count==0) { - if (gap.isHorizontal != isHorizontal) continue; - if (gap.Open < 0.01f) continue; - if (gap.linkedTo.Count==1) + continue; + } + else if (gap.linkedTo.Count==1) + { + if (!adjacentHulls.Contains(gap.linkedTo[0] as Hull)) { - if (!adjacentHulls.Contains(gap.linkedTo[0] as Hull)) - { - adjacentHulls.Add(gap.linkedTo[0] as Hull); - } - } - else if (gap.linkedTo[0] == currentHull && gap.linkedTo[1] != null) - { - if (!adjacentHulls.Contains(gap.linkedTo[1] as Hull)) - { - adjacentHulls.Add(gap.linkedTo[1] as Hull); - FindAdjacentHulls(adjacentHulls, gap.linkedTo[1] as Hull, isHorizontal); - } - } - else if (gap.linkedTo[1] == currentHull && gap.linkedTo[0] != null) - { - if (!adjacentHulls.Contains(gap.linkedTo[0] as Hull)) - { - adjacentHulls.Add(gap.linkedTo[0] as Hull); - FindAdjacentHulls(adjacentHulls, gap.linkedTo[0] as Hull, isHorizontal); - } + adjacentHulls.Add(gap.linkedTo[0] as Hull); } } + else if (gap.linkedTo[0] == currentHull && gap.linkedTo[1] != null) + { + if (!adjacentHulls.Contains(gap.linkedTo[1] as Hull)) + { + adjacentHulls.Add(gap.linkedTo[1] as Hull); + FindAdjacentHulls(adjacentHulls, gap.linkedTo[1] as Hull, isHorizontal); + } + } + else if (gap.linkedTo[1] == currentHull && gap.linkedTo[0] != null) + { + if (!adjacentHulls.Contains(gap.linkedTo[0] as Hull)) + { + adjacentHulls.Add(gap.linkedTo[0] as Hull); + FindAdjacentHulls(adjacentHulls, gap.linkedTo[0] as Hull, isHorizontal); + } + } + } - return adjacentHulls; + return adjacentHulls; } public bool Update(float deltaTime) diff --git a/Subsurface/Source/Program.cs b/Subsurface/Source/Program.cs index c0c6c7dec..0b6a9b028 100644 --- a/Subsurface/Source/Program.cs +++ b/Subsurface/Source/Program.cs @@ -28,19 +28,19 @@ namespace Subsurface { using (var game = new GameMain()) { -#if !DEBUG +//#if !DEBUG try { -#endif +//#endif game.Run(); -#if !DEBUG +//#if !DEBUG } catch (Exception e) { CrashDump(game, "crashreport.txt", e); } -#endif +//#endif } } diff --git a/Subsurface/Source/Screens/MainMenuScreen.cs b/Subsurface/Source/Screens/MainMenuScreen.cs index 6529e55db..a9f02b5a2 100644 --- a/Subsurface/Source/Screens/MainMenuScreen.cs +++ b/Subsurface/Source/Screens/MainMenuScreen.cs @@ -10,7 +10,7 @@ namespace Subsurface { class MainMenuScreen : Screen { - public enum Tabs { NewGame = 1, LoadGame = 2, HostServer = 3 } + public enum Tab { NewGame = 1, LoadGame = 2, HostServer = 3 } GUIFrame buttonsTab; @@ -30,7 +30,7 @@ namespace Subsurface public MainMenuScreen(GameMain game) { - menuTabs = new GUIFrame[Enum.GetValues(typeof(Tabs)).Length+1]; + menuTabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length+1]; @@ -45,11 +45,11 @@ namespace Subsurface button.OnClicked = TutorialButtonClicked; button = new GUIButton(new Rectangle(0, 70, 0, 30), "New Game", Alignment.CenterX, GUI.Style, buttonsTab); - button.UserData = (int)Tabs.NewGame; + button.UserData = Tab.NewGame; button.OnClicked = SelectTab; button = new GUIButton(new Rectangle(0, 130, 0, 30), "Load Game", Alignment.CenterX, GUI.Style, buttonsTab); - button.UserData = (int)Tabs.LoadGame; + button.UserData = Tab.LoadGame; button.OnClicked = SelectTab; button = new GUIButton(new Rectangle(0, 200, 0, 30), "Join Server", Alignment.CenterX, GUI.Style, buttonsTab); @@ -57,7 +57,7 @@ namespace Subsurface button.OnClicked = JoinServerClicked; button = new GUIButton(new Rectangle(0, 260, 0, 30), "Host Server", Alignment.CenterX, GUI.Style, buttonsTab); - button.UserData = (int)Tabs.HostServer; + button.UserData = Tab.HostServer; button.OnClicked = SelectTab; button = new GUIButton(new Rectangle(0, 330, 0, 30), "Quit", Alignment.CenterX, GUI.Style, buttonsTab); @@ -65,13 +65,13 @@ namespace Subsurface //---------------------------------------------------------------------- - menuTabs[(int)Tabs.NewGame] = new GUIFrame(panelRect, GUI.Style); + menuTabs[(int)Tab.NewGame] = new GUIFrame(panelRect, GUI.Style); //menuTabs[(int)Tabs.NewGame].Padding = GUI.style.smallPadding; //new GUITextBlock(new Rectangle(0, -20, 0, 30), "New Game", null, null, Alignment.CenterX, GUI.style, menuTabs[(int)Tabs.NewGame]); - new GUITextBlock(new Rectangle(0, 0, 0, 30), "Selected submarine:", null, null, Alignment.Left, GUI.Style, menuTabs[(int)Tabs.NewGame]); - mapList = new GUIListBox(new Rectangle(0, 30, 200, panelRect.Height-100), GUI.Style, menuTabs[(int)Tabs.NewGame]); + new GUITextBlock(new Rectangle(0, 0, 0, 30), "Selected submarine:", null, null, Alignment.Left, GUI.Style, menuTabs[(int)Tab.NewGame]); + mapList = new GUIListBox(new Rectangle(0, 30, 200, panelRect.Height-100), GUI.Style, menuTabs[(int)Tab.NewGame]); foreach (Submarine sub in Submarine.SavedSubmarines) { @@ -86,68 +86,68 @@ namespace Subsurface if (Submarine.SavedSubmarines.Count > 0) mapList.Select(Submarine.SavedSubmarines[0]); new GUITextBlock(new Rectangle((int)(mapList.Rect.Width + 20), 0, 100, 20), - "Save name: ", GUI.Style, Alignment.Left, Alignment.Left, menuTabs[(int)Tabs.NewGame]); + "Save name: ", GUI.Style, Alignment.Left, Alignment.Left, menuTabs[(int)Tab.NewGame]); saveNameBox = new GUITextBox(new Rectangle((int)(mapList.Rect.Width + 20), 30, 180, 20), - Alignment.TopLeft, GUI.Style, menuTabs[(int)Tabs.NewGame]); + Alignment.TopLeft, GUI.Style, menuTabs[(int)Tab.NewGame]); saveNameBox.Text = SaveUtil.CreateSavePath(); new GUITextBlock(new Rectangle((int)(mapList.Rect.Width + 20), 60, 100, 20), - "Map Seed: ", GUI.Style, Alignment.Left, Alignment.Left, menuTabs[(int)Tabs.NewGame]); + "Map Seed: ", GUI.Style, Alignment.Left, Alignment.Left, menuTabs[(int)Tab.NewGame]); seedBox = new GUITextBox(new Rectangle((int)(mapList.Rect.Width + 20), 90, 180, 20), - Alignment.TopLeft, GUI.Style, menuTabs[(int)Tabs.NewGame]); + Alignment.TopLeft, GUI.Style, menuTabs[(int)Tab.NewGame]); seedBox.Text = ToolBox.RandomSeed(8); - button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.BottomRight, GUI.Style, menuTabs[(int)Tabs.NewGame]); + button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.BottomRight, GUI.Style, menuTabs[(int)Tab.NewGame]); button.OnClicked = StartGame; //---------------------------------------------------------------------- - menuTabs[(int)Tabs.LoadGame] = new GUIFrame(panelRect, GUI.Style); + menuTabs[(int)Tab.LoadGame] = new GUIFrame(panelRect, GUI.Style); //menuTabs[(int)Tabs.LoadGame].Padding = GUI.style.smallPadding; - menuTabs[(int)Tabs.HostServer] = new GUIFrame(panelRect, GUI.Style); + menuTabs[(int)Tab.HostServer] = new GUIFrame(panelRect, GUI.Style); //menuTabs[(int)Tabs.JoinServer].Padding = GUI.style.smallPadding; //new GUITextBlock(new Rectangle(0, -25, 0, 30), "Host Server", GUI.style, Alignment.CenterX, Alignment.CenterX, menuTabs[(int)Tabs.HostServer], false, GUI.LargeFont); - new GUITextBlock(new Rectangle(0, 0, 0, 30), "Server Name:", GUI.Style, Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tabs.HostServer]); - serverNameBox = new GUITextBox(new Rectangle(160, 0, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, GUI.Style, menuTabs[(int)Tabs.HostServer]); + new GUITextBlock(new Rectangle(0, 0, 0, 30), "Server Name:", GUI.Style, Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]); + serverNameBox = new GUITextBox(new Rectangle(160, 0, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, GUI.Style, menuTabs[(int)Tab.HostServer]); - new GUITextBlock(new Rectangle(0, 50, 0, 30), "Server port:", GUI.Style, Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tabs.HostServer]); - portBox = new GUITextBox(new Rectangle(160, 50, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, GUI.Style, menuTabs[(int)Tabs.HostServer]); + new GUITextBlock(new Rectangle(0, 50, 0, 30), "Server port:", GUI.Style, Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]); + portBox = new GUITextBox(new Rectangle(160, 50, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, GUI.Style, menuTabs[(int)Tab.HostServer]); portBox.Text = NetConfig.DefaultPort.ToString(); portBox.ToolTip = "Server port"; - new GUITextBlock(new Rectangle(0, 100, 100, 30), "Max players:", GUI.Style, Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tabs.HostServer]); - maxPlayersBox = new GUITextBox(new Rectangle(195, 100, 30, 30), null, null, Alignment.TopLeft, Alignment.Center, GUI.Style, menuTabs[(int)Tabs.HostServer]); + new GUITextBlock(new Rectangle(0, 100, 100, 30), "Max players:", GUI.Style, Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]); + maxPlayersBox = new GUITextBox(new Rectangle(195, 100, 30, 30), null, null, Alignment.TopLeft, Alignment.Center, GUI.Style, menuTabs[(int)Tab.HostServer]); maxPlayersBox.Text = "8"; maxPlayersBox.Enabled = false; - var plusPlayersBox = new GUIButton(new Rectangle(230, 100, 30, 30), "+", GUI.Style, menuTabs[(int)Tabs.HostServer]); + var plusPlayersBox = new GUIButton(new Rectangle(230, 100, 30, 30), "+", GUI.Style, menuTabs[(int)Tab.HostServer]); plusPlayersBox.UserData = 1; plusPlayersBox.OnClicked = ChangeMaxPlayers; - var minusPlayersBox = new GUIButton(new Rectangle(160, 100, 30, 30), "-", GUI.Style, menuTabs[(int)Tabs.HostServer]); + var minusPlayersBox = new GUIButton(new Rectangle(160, 100, 30, 30), "-", GUI.Style, menuTabs[(int)Tab.HostServer]); minusPlayersBox.UserData = -1; minusPlayersBox.OnClicked = ChangeMaxPlayers; - new GUITextBlock(new Rectangle(0, 150, 0, 30), "Password (optional):", GUI.Style, Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tabs.HostServer]); - passwordBox = new GUITextBox(new Rectangle(160, 150, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, GUI.Style, menuTabs[(int)Tabs.HostServer]); + new GUITextBlock(new Rectangle(0, 150, 0, 30), "Password (optional):", GUI.Style, Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]); + passwordBox = new GUITextBox(new Rectangle(160, 150, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, GUI.Style, menuTabs[(int)Tab.HostServer]); - isPublicBox = new GUITickBox(new Rectangle(10, 200, 20, 20), "Public server", Alignment.TopLeft, menuTabs[(int)Tabs.HostServer]); + isPublicBox = new GUITickBox(new Rectangle(10, 200, 20, 20), "Public server", Alignment.TopLeft, menuTabs[(int)Tab.HostServer]); isPublicBox.ToolTip = "Public servers are shown in the list of available servers in the ''Join Server'' -tab"; - useUpnpBox = new GUITickBox(new Rectangle(10, 250, 20, 20), "Attempt UPnP port forwarding", Alignment.TopLeft, menuTabs[(int)Tabs.HostServer]); + useUpnpBox = new GUITickBox(new Rectangle(10, 250, 20, 20), "Attempt UPnP port forwarding", Alignment.TopLeft, menuTabs[(int)Tab.HostServer]); useUpnpBox.ToolTip = "UPnP can be used for forwarding ports on your router to allow players join the server." + " However, UPnP isn't supported by all routers, so you may need to setup port forwards manually" +" if players are unable to join the server (see the readme for instructions)."; - GUIButton hostButton = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.BottomRight, GUI.Style, menuTabs[(int)Tabs.HostServer]); + GUIButton hostButton = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.BottomRight, GUI.Style, menuTabs[(int)Tab.HostServer]); hostButton.OnClicked = HostServerClicked; this.game = game; @@ -165,7 +165,14 @@ namespace Subsurface public bool SelectTab(GUIButton button, object obj) { - selectedTab = (int)obj; + try + { + SelectTab((Tab)obj); + } + catch + { + selectedTab = 0; + } if (button != null) button.Selected = true; @@ -177,12 +184,16 @@ namespace Subsurface otherButton.Selected = false; } - if (selectedTab == (int)Tabs.LoadGame) UpdateLoadScreen(); - - if (Selected != this) this.Select(); return true; } + public void SelectTab(Tab tab) + { + selectedTab = (int)tab; + + if (selectedTab == (int)Tab.LoadGame) UpdateLoadScreen(); + } + private bool TutorialButtonClicked(GUIButton button, object obj) { TutorialMode.Start(); @@ -242,11 +253,11 @@ namespace Subsurface private void UpdateLoadScreen() { - menuTabs[(int)Tabs.LoadGame].ClearChildren(); + menuTabs[(int)Tab.LoadGame].ClearChildren(); string[] saveFiles = SaveUtil.GetSaveFiles(); - saveList = new GUIListBox(new Rectangle(0, 0, 200, menuTabs[(int)Tabs.LoadGame].Rect.Height - 80), Color.White, GUI.Style, menuTabs[(int)Tabs.LoadGame]); + saveList = new GUIListBox(new Rectangle(0, 0, 200, menuTabs[(int)Tab.LoadGame].Rect.Height - 80), Color.White, GUI.Style, menuTabs[(int)Tab.LoadGame]); saveList.OnSelected = SelectSaveFile; foreach (string saveFile in saveFiles) @@ -262,7 +273,7 @@ namespace Subsurface textBlock.UserData = saveFile; } - var button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.Right | Alignment.Bottom, GUI.Style, menuTabs[(int)Tabs.LoadGame]); + var button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.Right | Alignment.Bottom, GUI.Style, menuTabs[(int)Tab.LoadGame]); button.OnClicked = LoadGame; } @@ -295,7 +306,7 @@ namespace Subsurface string mapseed = ToolBox.GetAttributeString(modeElement, "mapseed", "unknown"); - GUIFrame saveFileFrame = new GUIFrame(new Rectangle((int)(saveList.Rect.Width + 20), 0, 200, 230), Color.Black*0.4f, GUI.Style, menuTabs[(int)Tabs.LoadGame]); + GUIFrame saveFileFrame = new GUIFrame(new Rectangle((int)(saveList.Rect.Width + 20), 0, 200, 230), Color.Black*0.4f, GUI.Style, menuTabs[(int)Tab.LoadGame]); saveFileFrame.UserData = "savefileframe"; saveFileFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f); @@ -333,14 +344,14 @@ namespace Subsurface private void RemoveSaveFrame() { GUIComponent prevFrame = null; - foreach (GUIComponent child in menuTabs[(int)Tabs.LoadGame].children) + foreach (GUIComponent child in menuTabs[(int)Tab.LoadGame].children) { if (child.UserData as string != "savefileframe") continue; prevFrame = child; break; } - menuTabs[(int)Tabs.LoadGame].RemoveChild(prevFrame); + menuTabs[(int)Tab.LoadGame].RemoveChild(prevFrame); } public override void Update(double deltaTime) diff --git a/Subsurface/Source/Screens/NetLobbyScreen.cs b/Subsurface/Source/Screens/NetLobbyScreen.cs index dbec38b8d..625464bf3 100644 --- a/Subsurface/Source/Screens/NetLobbyScreen.cs +++ b/Subsurface/Source/Screens/NetLobbyScreen.cs @@ -102,7 +102,7 @@ namespace Subsurface public string DurationText() { - return "Duration: " + GameDuration.Minutes + " min"; + return "Duration: " + GameDuration.TotalMinutes + " min"; } public NetLobbyScreen() @@ -423,33 +423,29 @@ namespace Subsurface return true; } - public void AddPlayer(Client client) + public void AddPlayer(string name) { GUITextBlock textBlock = new GUITextBlock( - new Rectangle(0, 0, 0, 25), - client.name + ((client.assignedJob==null) ? "" : " (" + client.assignedJob.Name + ")"), + new Rectangle(0, 0, 0, 25), name, GUI.Style, Alignment.Left, Alignment.Left, playerList); + textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f); - textBlock.UserData = client; + textBlock.UserData = name; } - public void RemovePlayer(int clientID) + public void RemovePlayer(string name) { - GUIComponent child = playerList.children.Find(c => - { - Client client = c.UserData as Client; - return (client.ID == clientID); - }); + GUIComponent child = playerList.children.Find(c => c.UserData as string == name); if (child != null) playerList.RemoveChild(child); } - public void RemovePlayer(Client client) - { - if (client == null) return; - playerList.RemoveChild(playerList.GetChild(client)); - } + //public void RemovePlayer(Client client) + //{ + // if (client == null) return; + // playerList.RemoveChild(playerList.GetChild(client)); + //} public void ClearPlayers() { @@ -709,13 +705,12 @@ namespace Subsurface msg.Write(durationBar.BarScroll); msg.Write(LevelSeed); - //msg.Write(playerList.CountChildren - 1); - //for (int i = 1; i < playerList.CountChildren; i++) - //{ - // Client client = playerList.children[i].UserData as Client; - // msg.Write(client.ID); - // msg.Write(client.assignedJob==null ? "" : client.assignedJob.Name); - //} + msg.Write((byte)(playerList.CountChildren - 1)); + for (int i = 0; i < playerList.CountChildren; i++) + { + string clientName = playerList.children[i].UserData as string; + msg.Write(clientName==null ? "" : clientName); + } } @@ -742,6 +737,14 @@ namespace Subsurface durationScroll = msg.ReadFloat(); levelSeed = msg.ReadString(); + + int playerCount = msg.ReadByte(); + + playerList.ClearChildren(); + for (int i = 0; i0 && SoundManager.IsPlaying(alSourceId)) { - ALHelper.Check(); SoundManager.Stop(alSourceId); ALHelper.Check(); } diff --git a/Subsurface/Source/Sounds/SoundManager.cs b/Subsurface/Source/Sounds/SoundManager.cs index 62c89c6ae..8fcd7c96e 100644 --- a/Subsurface/Source/Sounds/SoundManager.cs +++ b/Subsurface/Source/Sounds/SoundManager.cs @@ -37,7 +37,7 @@ namespace Subsurface.Sounds { alSources.Add(OpenTK.Audio.OpenAL.AL.GenSource()); } - + ALHelper.Check(); if (ALHelper.Efx.IsInitialized) { lowpassFilterId = ALHelper.Efx.GenFilter(); @@ -162,6 +162,7 @@ namespace Subsurface.Sounds { return Loop(sound,sourceIndex, Vector2.Zero, volume); } + public static int Loop(Sound sound, int sourceIndex, Vector2 position, float volume = 1.0f) { if (!MathUtils.IsValid(volume)) @@ -177,8 +178,6 @@ namespace Subsurface.Sounds // AL.Source(alSources[sourceIndex], ALSourceb.Looping, true); // AL.Source(alSources[sourceIndex], ALSourcef.Gain, volume); //} - ALHelper.Check(); - return sourceIndex; } else { @@ -189,9 +188,11 @@ namespace Subsurface.Sounds //OpenTK.Audio.OpenAL.AL.Source(alSources[sourceIndex], OpenTK.Audio.OpenAL.ALSource3f.Position, position.X, position.Y, 0.0f); AL.Source(alSources[sourceIndex], ALSourceb.Looping, true); //AL.Source(alSources[sourceIndex], ALSourcef.Gain, volume); - ALHelper.Check(); - return sourceIndex; + } + + ALHelper.Check(); + return sourceIndex; } //public static int Loop(int sourceIndex, float volume = 1.0f) @@ -320,12 +321,13 @@ namespace Subsurface.Sounds if (oggStreamer == null) oggStreamer = new OggStreamer(); - oggStream = new OggStream(file); - - oggStreamer.AddStream(oggStream); + oggStream = new OggStream(file); + oggStreamer.AddStream(oggStream); oggStream.Play(volume); + ALHelper.Check(); + return oggStream; } @@ -337,15 +339,12 @@ namespace Subsurface.Sounds public static void ClearAlSource(int bufferId) { for (int i = 1; i < DefaultSourceCount; i++) - { - if (alBuffers[i] == bufferId) - { - OpenTK.Audio.OpenAL.AL.Source(alSources[i], OpenTK.Audio.OpenAL.ALSourcei.Buffer, 0); - } - } - - - + { + if (alBuffers[i] != bufferId) continue; + + OpenTK.Audio.OpenAL.AL.Source(alSources[i], OpenTK.Audio.OpenAL.ALSourceb.Looping, false); + OpenTK.Audio.OpenAL.AL.Source(alSources[i], OpenTK.Audio.OpenAL.ALSourcei.Buffer, 0); + } } public static void Dispose() diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index 3097c7716..b8a3af50c 100644 Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ