From 2f08dcf3f9329e8f2070d76689abd2a1cab4fa54 Mon Sep 17 00:00:00 2001 From: Regalis Date: Fri, 4 Sep 2015 12:57:12 +0300 Subject: [PATCH] Admin can play in multiplayer, backgroundsprites, fixrequirement bugfix, the condition of the reactor won't detoriate when it's running --- .../BackgroundSpritePrefabs.xml | 10 + .../Content/BackgroundSprites/bgFish1.png | Bin 0 -> 26876 bytes Subsurface/Source/Characters/AI/ISteerable.cs | 2 - .../BackgroundSprite/BackgroundSprite.cs | 208 ++++++++++++++++++ .../BackgroundSpriteManager.cs | 74 +++++++ .../BackgroundSpritePrefab.cs | 50 +++++ Subsurface/Source/Characters/Character.cs | 2 +- Subsurface/Source/Characters/Ragdoll.cs | 3 +- Subsurface/Source/GUI/GUIComponent.cs | 4 +- Subsurface/Source/GameSession/GameSession.cs | 2 +- .../Items/Components/Machines/Reactor.cs | 9 +- Subsurface/Source/Items/FixRequirement.cs | 10 +- Subsurface/Source/Map/Levels/Level.cs | 32 ++- Subsurface/Source/Networking/GameClient.cs | 107 ++++----- Subsurface/Source/Networking/GameServer.cs | 88 ++++---- Subsurface/Source/Networking/NetworkEvent.cs | 2 +- Subsurface/Source/Program.cs | 8 +- Subsurface/Source/Screens/GameScreen.cs | 16 +- Subsurface/Source/Screens/NetLobbyScreen.cs | 24 +- Subsurface/Subsurface.csproj | 10 + Subsurface_Solution.v12.suo | Bin 650752 -> 605184 bytes 21 files changed, 547 insertions(+), 114 deletions(-) create mode 100644 Subsurface/Content/BackgroundSprites/BackgroundSpritePrefabs.xml create mode 100644 Subsurface/Content/BackgroundSprites/bgFish1.png create mode 100644 Subsurface/Source/Characters/BackgroundSprite/BackgroundSprite.cs create mode 100644 Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs create mode 100644 Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs diff --git a/Subsurface/Content/BackgroundSprites/BackgroundSpritePrefabs.xml b/Subsurface/Content/BackgroundSprites/BackgroundSpritePrefabs.xml new file mode 100644 index 000000000..ab56223ad --- /dev/null +++ b/Subsurface/Content/BackgroundSprites/BackgroundSpritePrefabs.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Subsurface/Content/BackgroundSprites/bgFish1.png b/Subsurface/Content/BackgroundSprites/bgFish1.png new file mode 100644 index 0000000000000000000000000000000000000000..66e3d62f4f738f0441369efcf7506be716223fa1 GIT binary patch literal 26876 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� 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 + { + + foreach (Voronoi2.VoronoiCell cell in cells) + { + obstacleDiff += cell.Center - position; + } + + obstacleDiff = Vector2.Normalize(obstacleDiff)*prefab.Speed; + } + } + + if (Swarm!=null) + { + Vector2 midPoint = Swarm.MidPoint(); + float midPointDist = Vector2.Distance(position, midPoint); + + + + //steeringManager.SteeringSeek(midPoint + Swarm.AvgVelocity()*1000.0f, prefab.Speed*0.1f); + + //float avgWanderAngle = 0.0f; + //foreach (var other in Swarm.Members) + //{ + // avgWanderAngle += other.steeringManager.WanderAngle; + //} + //avgWanderAngle /= Swarm.Members.Count; + //steeringManager.WanderAngle = MathHelper.Lerp(steeringManager.WanderAngle, avgWanderAngle, 0.1f); + + if (midPointDist > Swarm.MaxDistance) + { + steeringManager.SteeringSeek(midPoint, (midPointDist / Swarm.MaxDistance) * prefab.Speed); + } + } + + if (prefab.WanderAmount > 0.0f) + { + steeringManager.SteeringWander(prefab.Speed); + } + + if (obstacleDiff != Vector2.Zero) + { + steeringManager.SteeringSeek(-obstacleDiff, prefab.Speed); + } + + steeringManager.Update(prefab.Speed); + + if (prefab.WanderZAmount>0.0f) + { + ang += Rand.Range(-prefab.WanderZAmount, prefab.WanderZAmount); + velocity.Z = (float)Math.Sin(ang)*prefab.Speed; + } + + velocity = Vector3.Lerp(velocity, new Vector3(Steering.X, Steering.Y, velocity.Z), deltaTime); + } + + public void Draw(SpriteBatch spriteBatch) + { + float rotation = 0.0f; + if (!prefab.DisableRotation) + { + rotation = MathUtils.VectorToAngle(new Vector2(velocity.X, -velocity.Y)); + if (velocity.X < 0.0f) rotation -= MathHelper.Pi; + } + + Vector2 drawPos = position + Level.Loaded.Position; + + if (depth > 0.0f) + { + Vector2 camOffset = drawPos - Game1.GameScreen.Cam.WorldViewCenter; + + drawPos = drawPos - camOffset * (depth / MaxDepth) * 0.05f; + } + + prefab.Sprite.Draw(spriteBatch, new Vector2(drawPos.X, -drawPos.Y), Color.Lerp(Color.White, Color.DarkBlue, (depth/MaxDepth)*0.3f), + rotation, 1.0f - (depth / MaxDepth) * 0.2f, velocity.X > 0.0f ? SpriteEffects.None : SpriteEffects.FlipHorizontally, (depth / MaxDepth)); + } + } + + class Swarm + { + public List Members; + + public readonly float MaxDistance; + + public Vector2 MidPoint() + { + if (Members.Count == 0) return Vector2.Zero; + + Vector2 midPoint = Vector2.Zero; + + foreach (BackgroundSprite member in Members) + { + midPoint += member.Position; + } + + midPoint /= Members.Count; + + return midPoint; + } + + public Vector2 AvgVelocity() + { + if (Members.Count == 0) return Vector2.Zero; + + Vector2 avgVel = Vector2.Zero; + + foreach (BackgroundSprite member in Members) + { + avgVel += member.Velocity; + } + + avgVel /= Members.Count; + + return avgVel; + } + + public Swarm(List members, float maxDistance) + { + this.Members = members; + + this.MaxDistance = maxDistance; + + foreach (BackgroundSprite bgSprite in members) + { + bgSprite.Swarm = this; + } + } + } +} diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs new file mode 100644 index 000000000..5fa971966 --- /dev/null +++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs @@ -0,0 +1,74 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; + +namespace Subsurface +{ + class BackgroundSpriteManager + { + const int MaxSprites = 100; + + private List prefabs; + private List activeSprites; + + public BackgroundSpriteManager(string configPath) + { + XDocument doc = ToolBox.TryLoadXml(configPath); + if (doc == null) return; + + activeSprites = new List(); + prefabs = new List(); + + foreach (XElement element in doc.Root.Elements()) + { + prefabs.Add(new BackgroundSpritePrefab(element)); + } + } + + public void Update(float deltaTime) + { + if (activeSprites.Count < MaxSprites) + { + WayPoint wp = WayPoint.WayPointList[Rand.Int(WayPoint.WayPointList.Count)]; + + Vector2 pos = new Vector2(wp.Rect.X, wp.Rect.Y); + pos += Rand.Vector(200.0f); + + var prefab = prefabs[Rand.Int(prefabs.Count)]; + + int amount = Rand.Range(prefab.SwarmMin,prefab.SwarmMax); + List swarmMembers = new List(); + + for (int i = 0; i0) + { + Swarm swarm = new Swarm(swarmMembers, prefab.SwarmRadius); + } + + + } + + foreach (BackgroundSprite sprite in activeSprites) + { + sprite.Update(deltaTime); + } + } + + public void Draw(SpriteBatch spriteBatch) + { + foreach (BackgroundSprite sprite in activeSprites) + { + sprite.Draw(spriteBatch); + } + } + } +} diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs new file mode 100644 index 000000000..1326ce05c --- /dev/null +++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml.Linq; + +namespace Subsurface +{ + class BackgroundSpritePrefab + { + public readonly Sprite Sprite; + + public readonly float Speed; + + public readonly float WanderAmount; + + public readonly float WanderZAmount; + + public readonly int SwarmMin, SwarmMax; + + public readonly float SwarmRadius; + + public readonly bool DisableRotation; + + public BackgroundSpritePrefab(XElement element) + { + Speed = ToolBox.GetAttributeFloat(element, "speed", 1.0f); + + WanderAmount = ToolBox.GetAttributeFloat(element, "wanderamount", 0.0f); + + WanderZAmount = ToolBox.GetAttributeFloat(element, "wanderzamount", 0.0f); + + SwarmMin = ToolBox.GetAttributeInt(element, "swarmmin", 1); + SwarmMax = ToolBox.GetAttributeInt(element, "swarmmax", 1); + + SwarmRadius = ToolBox.GetAttributeFloat(element, "swarmradius", 200.0f); + + DisableRotation = ToolBox.GetAttributeBool(element, "disablerotation", false); + + foreach (XElement subElement in element.Elements()) + { + if (subElement.Name.ToString().ToLower() != "sprite") continue; + + Sprite = new Sprite(subElement); + break; + } + } + } + +} diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 714e6260d..7fa3cd14b 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -1123,7 +1123,7 @@ namespace Subsurface else if (type == NetworkEventType.KillCharacter) { Kill(true); - if (Game1.Client != null && controlled == this) + if (Game1.NetworkMember != null && controlled == this) { Game1.Client.AddChatMessage("YOU HAVE DIED. Your chat messages will only be visible to other dead players.", ChatMessageType.Dead); Game1.LightManager.LosEnabled = false; diff --git a/Subsurface/Source/Characters/Ragdoll.cs b/Subsurface/Source/Characters/Ragdoll.cs index f8a22301e..4bf77dd34 100644 --- a/Subsurface/Source/Characters/Ragdoll.cs +++ b/Subsurface/Source/Characters/Ragdoll.cs @@ -607,7 +607,8 @@ namespace Subsurface } else { - correctionMovement = Vector2.Normalize(newMovement) * Math.Min(1.0f + dist, 3.0f); + correctionMovement = Vector2.Normalize(newMovement) * Math.Min(1.0f + dist, 3.0f); + if (Math.Abs(correctionMovement.Y) < 0.1f) correctionMovement.Y = 0.0f; } } diff --git a/Subsurface/Source/GUI/GUIComponent.cs b/Subsurface/Source/GUI/GUIComponent.cs index 9eb4f70fb..98756286a 100644 --- a/Subsurface/Source/GUI/GUIComponent.cs +++ b/Subsurface/Source/GUI/GUIComponent.cs @@ -284,9 +284,9 @@ namespace Subsurface } - foreach (GUIComponent child in children) + for (int i = 0; i < children.Count; i++) { - child.Update(deltaTime); + children[i].Update(deltaTime); } } diff --git a/Subsurface/Source/GameSession/GameSession.cs b/Subsurface/Source/GameSession/GameSession.cs index 692d9f72d..288bc759e 100644 --- a/Subsurface/Source/GameSession/GameSession.cs +++ b/Subsurface/Source/GameSession/GameSession.cs @@ -107,7 +107,7 @@ namespace Subsurface public void StartShift(TimeSpan duration, Level level, bool reloadSub = true) { - Game1.LightManager.LosEnabled = (Game1.Server==null); + Game1.LightManager.LosEnabled = (Game1.Server==null && Character.Controlled==null); this.level = level; diff --git a/Subsurface/Source/Items/Components/Machines/Reactor.cs b/Subsurface/Source/Items/Components/Machines/Reactor.cs index 960667c9c..520f7f074 100644 --- a/Subsurface/Source/Items/Components/Machines/Reactor.cs +++ b/Subsurface/Source/Items/Components/Machines/Reactor.cs @@ -74,7 +74,7 @@ namespace Subsurface.Items.Components fissionRate = MathHelper.Clamp(value, 0.0f, 100.0f); } } - + public float CoolingRate { get { return coolingRate; } @@ -156,7 +156,7 @@ namespace Subsurface.Items.Components } } - item.Condition -= temperature * deltaTime * 0.00005f; + //item.Condition -= temperature * deltaTime * 0.00005f; if (temperature > shutDownTemp) { @@ -204,6 +204,11 @@ namespace Subsurface.Items.Components //the power generated by the reactor is equal to the temperature currPowerConsumption = -temperature*powerPerTemp; + //foreach (Item i in item.ContainedItems) + //{ + // i.Condition = 5.0f; + //} + if (item.CurrentHull != null) { //the sound can be heard from 20 000 display units away when everything running at 100% diff --git a/Subsurface/Source/Items/FixRequirement.cs b/Subsurface/Source/Items/FixRequirement.cs index 6f82159a3..f5cddde2b 100644 --- a/Subsurface/Source/Items/FixRequirement.cs +++ b/Subsurface/Source/Items/FixRequirement.cs @@ -45,7 +45,7 @@ namespace Subsurface } } - public bool Fix(Character character, GUIComponent reqFrame) + public bool CanBeFixed(Character character, GUIComponent reqFrame) { bool success = true; foreach (string itemName in requiredItems) @@ -101,7 +101,8 @@ namespace Subsurface fixButton.OnClicked = FixButtonPressed; fixButton.UserData = requirement; - new GUITickBox(new Rectangle(70, 0, 20,20), requirement.name, Alignment.Left, reqFrame); + var tickBox = new GUITickBox(new Rectangle(70, 0, 20,20), requirement.name, Alignment.Left, reqFrame); + tickBox.Enabled = false; int y2 = 20; foreach (string itemName in requirement.requiredItems) @@ -133,7 +134,10 @@ namespace Subsurface FixRequirement requirement = obj as FixRequirement; if (requirement == null) return false; + if (!requirement.CanBeFixed(Character.Controlled, button.Parent)) return true; + requirement.Fixed = true; + return true; } @@ -152,7 +156,7 @@ namespace Subsurface } else { - bool canBeFixed = requirement.Fix(character, child); + bool canBeFixed = requirement.CanBeFixed(character, child); unfixedFound = true; //child.GetChild().Selected = canBeFixed; GUITickBox tickBox = child.GetChild(); diff --git a/Subsurface/Source/Map/Levels/Level.cs b/Subsurface/Source/Map/Levels/Level.cs index c77d70087..c60253e88 100644 --- a/Subsurface/Source/Map/Levels/Level.cs +++ b/Subsurface/Source/Map/Levels/Level.cs @@ -873,6 +873,37 @@ int currentTargetIndex = 1; //} } + public List GetCells(Vector2 pos, int searchDepth = 2) + { + int gridPosX = (int)Math.Floor(pos.X / GridCellWidth); + int gridPosY = (int)Math.Floor(pos.Y / GridCellWidth); + + int startX = Math.Max(gridPosX - searchDepth, 0); + int endX = Math.Min(gridPosX + searchDepth, cellGrid.GetLength(0) - 1); + + int startY = Math.Max(gridPosY - searchDepth, 0); + int endY = Math.Min(gridPosY + searchDepth, cellGrid.GetLength(1) - 1); + + List cells = new List(); + + for (int x = startX; x < endX; x++) + { + for (int y = startY; y < endY; y++) + { + foreach (VoronoiCell cell in cellGrid[x, y]) + { + for (int i = 0; i < cell.edges.Count; i++) + { + cells.Add(cell); + //GUI.DrawLine(spriteBatch, start, end, (cell.body != null && cell.body.Enabled) ? Color.Green : Color.Red); + } + } + } + } + + return cells; + } + public List GetCellEdges(Vector2 refPos, int searchDepth = 2, bool onlySolid = true) { @@ -885,7 +916,6 @@ int currentTargetIndex = 1; int startY = Math.Max(gridPosY - searchDepth, 0); int endY = Math.Min(gridPosY + searchDepth, cellGrid.GetLength(1) - 1); - List edges = new List(); for (int x = startX; x < endX; x++) diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index c4bb169d5..0cad9f5d1 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -148,62 +148,71 @@ namespace Subsurface.Networking // If new messages arrived if ((inc = client.ReadMessage()) == null) continue; - // Switch based on the message types - switch (inc.MessageType) + try { - // All manually sent messages are type of "Data" - case NetIncomingMessageType.Data: - byte packetType = inc.ReadByte(); - if (packetType == (byte)PacketTypes.LoggedIn) - { - myID = inc.ReadInt32(); - if (inc.ReadBoolean() && Screen.Selected != Game1.GameScreen) + // Switch based on the message types + switch (inc.MessageType) + { + // All manually sent messages are type of "Data" + case NetIncomingMessageType.Data: + byte packetType = inc.ReadByte(); + if (packetType == (byte)PacketTypes.LoggedIn) { - new GUIMessageBox("Please wait", "A round is already running. You will have to wait for a new round to start."); + myID = inc.ReadInt32(); + if (inc.ReadBoolean() && Screen.Selected != Game1.GameScreen) + { + new GUIMessageBox("Please wait", "A round is already running. You will have to wait for a new round to start."); + } + + Game1.NetLobbyScreen.ClearPlayers(); + + //add the names of other connected clients to the lobby screen + int existingClients = inc.ReadInt32(); + for (int i = 1; i <= existingClients; i++) + { + Client otherClient = new Client(inc.ReadString(), inc.ReadInt32()); + + Game1.NetLobbyScreen.AddPlayer(otherClient); + otherClients.Add(otherClient); + } + + //add the name of own client to the lobby screen + Game1.NetLobbyScreen.AddPlayer(new Client(name, myID)); + + CanStart = true; + } + else if (packetType == (byte)PacketTypes.KickedOut) + { + string msg = inc.ReadString(); + DebugConsole.ThrowError(msg); + + Game1.MainMenuScreen.Select(); + } + break; + case NetIncomingMessageType.StatusChanged: + NetConnectionStatus connectionStatus = (NetConnectionStatus)inc.ReadByte(); + Debug.WriteLine(connectionStatus); + + if (connectionStatus != NetConnectionStatus.Connected) + { + string denyMessage = inc.ReadString(); + DebugConsole.ThrowError(denyMessage); } - Game1.NetLobbyScreen.ClearPlayers(); + break; + default: + Console.WriteLine(inc.ReadString() + " Strange message"); + break; + } + } - //add the names of other connected clients to the lobby screen - int existingClients = inc.ReadInt32(); - for (int i = 1; i <= existingClients; i++) - { - Client otherClient = new Client(inc.ReadString(), inc.ReadInt32()); - - Game1.NetLobbyScreen.AddPlayer(otherClient); - otherClients.Add(otherClient); - } - - //add the name of own client to the lobby screen - Game1.NetLobbyScreen.AddPlayer(new Client(name, myID)); - - CanStart = true; - } - else if (packetType == (byte)PacketTypes.KickedOut) - { - string msg = inc.ReadString(); - DebugConsole.ThrowError(msg); - - Game1.MainMenuScreen.Select(); - } - break; - case NetIncomingMessageType.StatusChanged: - NetConnectionStatus connectionStatus = (NetConnectionStatus)inc.ReadByte(); - Debug.WriteLine(connectionStatus); - - if (connectionStatus != NetConnectionStatus.Connected) - { - string denyMessage = inc.ReadString(); - DebugConsole.ThrowError(denyMessage); - } - - break; - default: - Console.WriteLine(inc.ReadString() + " Strange message"); - break; - } + catch + { + break; + } } + if (reconnectBox != null) { reconnectBox.Close(null, null); diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 07c16777c..bba43ce29 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -30,7 +30,9 @@ namespace Subsurface.Networking private string password; - private Client myClient; + // private Client myClient; + + //private CharacterInfo myCharacter; public GameServer(string name, int port, bool isPublic = false, string password = "", bool attemptUPnP = false, int maxPlayers = 10) { @@ -208,7 +210,12 @@ namespace Subsurface.Networking base.Update(deltaTime); - if (gameStarted) inGameHUD.Update((float)Physics.step); + if (gameStarted) + { + if (myCharacter!=null) new NetworkEvent(myCharacter.ID, true); + + inGameHUD.Update((float)Physics.step); + } NetIncomingMessage inc = server.ReadMessage(); if (inc != null) @@ -384,7 +391,7 @@ namespace Subsurface.Networking outmsg.Write(gameStarted); //notify the client about other clients already logged in - outmsg.Write((myClient == null) ? connectedClients.Count - 1 : connectedClients.Count); + outmsg.Write((characterInfo == null) ? connectedClients.Count - 1 : connectedClients.Count); foreach (Client c in connectedClients) { if (c.Connection == inc.SenderConnection) continue; @@ -392,7 +399,11 @@ namespace Subsurface.Networking outmsg.Write(c.ID); } - if (myClient != null) outmsg.Write(myClient.name); + if (characterInfo != null) + { + outmsg.Write(characterInfo.Name); + outmsg.Write(-1); + } server.SendMessage(outmsg, inc.SenderConnection, NetDeliveryMethod.ReliableUnordered, 0); @@ -491,16 +502,17 @@ namespace Subsurface.Networking List recipients = new List(); - Entity e = Entity.FindEntityByID(networkEvent.ID); + Entity e = Entity.FindEntityByID(networkEvent.ID); + if (e == null) continue; - foreach (Client c in connectedClients) - { - if (c.character == null) continue; - //if (networkEvent.Type == NetworkEventType.UpdateEntity && - // Vector2.Distance(e.SimPosition, c.character.SimPosition) > NetConfig.UpdateEntityDistance) continue; + foreach (Client c in connectedClients) + { + if (c.character == null) continue; + //if (networkEvent.Type == NetworkEventType.UpdateEntity && + // Vector2.Distance(e.SimPosition, c.character.SimPosition) > NetConfig.UpdateEntityDistance) continue; - recipients.Add(c.Connection); - } + recipients.Add(c.Connection); + } if (recipients.Count == 0) return; @@ -533,9 +545,7 @@ namespace Subsurface.Networking Game1.NetLobbyScreen.SubList.Flash(); return false; } - - - + AssignJobs(); //selectedMap.Load(); @@ -552,17 +562,20 @@ namespace Subsurface.Networking { client.inGame = true; - WayPoint spawnPoint = WayPoint.GetRandom(SpawnType.Human); - - if (client.characterInfo==null) + if (client.characterInfo == null) { client.characterInfo = new CharacterInfo(Character.HumanConfigFile, client.name); } characterInfos.Add(client.characterInfo); client.characterInfo.Job = new Job(client.assignedJob); + } - //client.character = new Character(client.characterInfo, (spawnPoint == null) ? Vector2.Zero : spawnPoint.SimPosition, true); + //todo: fix + if (characterInfo != null) + { + characterInfo.Job = new Job(Game1.NetLobbyScreen.JobPreferences[0]); + characterInfos.Add(characterInfo); } List crew = new List(); @@ -577,16 +590,16 @@ namespace Subsurface.Networking crew.Add(connectedClients[i].character); } - //todo: fix - if (myClient != null) + if (characterInfo != null) { - WayPoint spawnPoint = WayPoint.GetRandom(SpawnType.Human); - CharacterInfo ch = new CharacterInfo(Character.HumanConfigFile, myClient.name); - myClient.character = new Character(ch, (spawnPoint == null) ? Vector2.Zero : spawnPoint.SimPosition); - } + myCharacter = new Character(characterInfo, assignedWayPoints[assignedWayPoints.Length-1]); + Character.Controlled = myCharacter; - //foreach (Client client in connectedClients) - //{ + myCharacter.GiveJobItems(assignedWayPoints[assignedWayPoints.Length - 1]); + + crew.Add(myCharacter); + } + NetOutgoingMessage msg = server.CreateMessage(); msg.Write((byte)PacketTypes.StartGame); @@ -599,23 +612,20 @@ namespace Subsurface.Networking msg.Write(Game1.NetLobbyScreen.GameDuration.TotalMinutes); - //WriteCharacterData(msg, client.name, client.character); - - msg.Write((myClient == null) ? connectedClients.Count : connectedClients.Count+1); + msg.Write((myCharacter == null) ? connectedClients.Count : connectedClients.Count+1); foreach (Client client in connectedClients) { - //if (otherClient == client) continue; msg.Write(client.ID); WriteCharacterData(msg, client.name, client.character); } - if (myClient!=null) + if (myCharacter != null) { - WriteCharacterData(msg, myClient.name, myClient.character); + msg.Write(-1); + WriteCharacterData(msg, myCharacter.Name, Character.Controlled); } - SendMessage(msg, NetDeliveryMethod.ReliableUnordered, null); - //} + SendMessage(msg, NetDeliveryMethod.ReliableUnordered, null); gameStarted = true; @@ -623,7 +633,6 @@ namespace Subsurface.Networking Game1.GameScreen.Select(); - CreateCrewFrame(crew); return true; @@ -891,6 +900,11 @@ namespace Subsurface.Networking int[] assignedClientCount = new int[JobPrefab.List.Count]; + if (characterInfo!=null) + { + assignedClientCount[JobPrefab.List.FindIndex(jp => jp == Game1.NetLobbyScreen.JobPreferences[0])]=1; + } + //if any of the players has chosen a job that is Always Allowed, give them that job for (int i = unassigned.Count - 1; i >= 0; i--) { @@ -956,7 +970,7 @@ namespace Subsurface.Networking } } - //none of the clients wants the job + //none of the clients wants the job, assign it to random client if (forceAssign && preferredClient == null) { preferredClient = clients[Rand.Int(clients.Count)]; diff --git a/Subsurface/Source/Networking/NetworkEvent.cs b/Subsurface/Source/Networking/NetworkEvent.cs index 59a4b670e..3a4081653 100644 --- a/Subsurface/Source/Networking/NetworkEvent.cs +++ b/Subsurface/Source/Networking/NetworkEvent.cs @@ -59,7 +59,7 @@ namespace Subsurface.Networking { if (isClient) { - if (Game1.Server != null) return; + if (Game1.Server != null && Game1.Server.Character == null) return; } else { diff --git a/Subsurface/Source/Program.cs b/Subsurface/Source/Program.cs index 0c8c357b2..72abd6e6f 100644 --- a/Subsurface/Source/Program.cs +++ b/Subsurface/Source/Program.cs @@ -26,19 +26,19 @@ namespace Subsurface { using (var game = new Game1()) { -#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/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index 96a4d111a..830f896b4 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -16,6 +16,8 @@ namespace Subsurface readonly Sprite background, backgroundTop; + private BackgroundSpriteManager backgroundSpriteManager; + public Camera Cam { get { return cam; } @@ -32,6 +34,8 @@ namespace Subsurface background = new Sprite("Content/Map/background.png", Vector2.Zero); backgroundTop = new Sprite("Content/Map/background2.png", Vector2.Zero); + + backgroundSpriteManager = new BackgroundSpriteManager("Content/BackgroundSprites/BackgroundSpritePrefabs.xml"); } public override void Select() @@ -71,6 +75,8 @@ namespace Subsurface Character.UpdateAll(cam, (float)deltaTime); + backgroundSpriteManager.Update((float)deltaTime); + Game1.ParticleManager.Update((float)deltaTime); StatusEffect.UpdateAll((float)deltaTime); @@ -175,12 +181,20 @@ namespace Subsurface spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.BackToFront, + BlendState.AlphaBlend, + null, null, null, null, + cam.Transform); + + backgroundSpriteManager.Draw(spriteBatch); + + spriteBatch.End(); spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, cam.Transform); - + Submarine.DrawBack(spriteBatch); foreach (Character c in Character.CharacterList) c.Draw(spriteBatch); diff --git a/Subsurface/Source/Screens/NetLobbyScreen.cs b/Subsurface/Source/Screens/NetLobbyScreen.cs index 4a2d9ac97..d76552e98 100644 --- a/Subsurface/Source/Screens/NetLobbyScreen.cs +++ b/Subsurface/Source/Screens/NetLobbyScreen.cs @@ -278,18 +278,20 @@ namespace Subsurface modeList.OnSelected += Game1.Server.UpdateNetLobby; durationBar.OnMoved = Game1.Server.UpdateNetLobby; - if (subList.CountChildren > 0) subList.Select(-1); - if (GameModePreset.list.Count > 0) modeList.Select(0); + if (subList.CountChildren > 0 && subList.Selected == null) subList.Select(-1); + if (GameModePreset.list.Count > 0 && modeList.Selected == null) modeList.Select(-1); - var playYourself = new GUITickBox(new Rectangle(0, -20, 20, 20), "Play yourself", Alignment.TopLeft, playerFrame); - playYourself.OnSelected = TogglePlayYourself; + if (infoFrame.children.Find(c => c.UserData as string == "playyourself") == null) + { + var playYourself = new GUITickBox(new Rectangle(0, -20, 20, 20), "Play yourself", Alignment.TopLeft, playerFrame); + playYourself.OnSelected = TogglePlayYourself; + playYourself.UserData = "playyourself"; + } } else { UpdatePlayerFrame(Game1.Client.CharacterInfo); } - - base.Select(); } @@ -302,8 +304,10 @@ namespace Subsurface if (IsServer && Game1.Server != null) { - var playYourself = new GUITickBox(new Rectangle(0, -20, 200, 30), "Play yourself", Alignment.TopLeft, playerFrame); + var playYourself = new GUITickBox(new Rectangle(0, -20, 20, 20), "Play yourself", Alignment.TopLeft, playerFrame); + playYourself.Selected = Game1.Server.CharacterInfo != null; playYourself.OnSelected = TogglePlayYourself; + playYourself.UserData = "playyourself"; } new GUITextBlock(new Rectangle(60, 0, 200, 30), "Name: ", GUI.style, playerFrame); @@ -368,7 +372,9 @@ namespace Subsurface if (IsServer && Game1.Server != null) { - var playYourself = new GUITickBox(new Rectangle(0, -20, 200, 30), "Play yourself", Alignment.TopLeft, playerFrame); + Game1.Server.CharacterInfo = null; + + var playYourself = new GUITickBox(new Rectangle(0, -20, 20, 20), "Play yourself", Alignment.TopLeft, playerFrame); playYourself.OnSelected = TogglePlayYourself; } } @@ -615,7 +621,7 @@ namespace Subsurface (listBox.children[i] as GUITextBlock).Text = (i+1) + ". " + (listBox.children[i].UserData as JobPrefab).Name; } - Game1.Client.SendCharacterData(); + if (Game1.Client!=null) Game1.Client.SendCharacterData(); } public bool TrySelectMap(string mapName, string md5Hash) diff --git a/Subsurface/Subsurface.csproj b/Subsurface/Subsurface.csproj index 973ad2ef1..65760b52c 100644 --- a/Subsurface/Subsurface.csproj +++ b/Subsurface/Subsurface.csproj @@ -56,6 +56,9 @@ + + + @@ -243,6 +246,13 @@ PreserveNewest + + Designer + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index 9f1e149588e327b8ec41834a1c2ede01a366d9e7..7426e91962b88656c706fd8a324d726420b00bad 100644 GIT binary patch delta 14968 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 HDcS!8>~UxR delta 15672 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