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 000000000..66e3d62f4 Binary files /dev/null and b/Subsurface/Content/BackgroundSprites/bgFish1.png differ diff --git a/Subsurface/Source/Characters/AI/ISteerable.cs b/Subsurface/Source/Characters/AI/ISteerable.cs index 0a814393b..fbea7c827 100644 --- a/Subsurface/Source/Characters/AI/ISteerable.cs +++ b/Subsurface/Source/Characters/AI/ISteerable.cs @@ -15,8 +15,6 @@ namespace Subsurface { get; } - - Vector2 Position { diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSprite.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSprite.cs new file mode 100644 index 000000000..8fe786a65 --- /dev/null +++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSprite.cs @@ -0,0 +1,208 @@ +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 BackgroundSprite : ISteerable + { + const float MaxDepth = 100.0f; + + const float CheckWallsInterval = 5.0f; + + private BackgroundSpritePrefab prefab; + + private Vector2 position; + + private Vector3 velocity; + + private float depth; + + private SteeringManager steeringManager; + + private float checkWallsTimer; + + public Swarm Swarm; + + public Vector2 Position + { + get { return position; } + } + + public Vector2 Velocity + { + get { return new Vector2(velocity.X, velocity.Y); } + } + + public Vector2 Steering + { + get; + set; + } + + public BackgroundSprite(BackgroundSpritePrefab prefab, Vector2 position) + { + this.prefab = prefab; + + this.position = position; + + steeringManager = new SteeringManager(this); + + velocity = new Vector3( + Rand.Range(-prefab.Speed, prefab.Speed), + Rand.Range(-prefab.Speed, prefab.Speed), + Rand.Range(0.0f, prefab.WanderZAmount)); + + } + + float ang; + Vector2 obstacleDiff; + + public void Update(float deltaTime) + { + position += new Vector2(velocity.X, velocity.Y) * deltaTime; + depth = MathHelper.Clamp(depth + velocity.Z * deltaTime, 0.0f, MaxDepth); + + checkWallsTimer -= deltaTime; + if (checkWallsTimer<=0.0f) + { + checkWallsTimer = CheckWallsInterval; + + obstacleDiff = Vector2.Zero; + + var cells = Level.Loaded.GetCells(position, 1); + if (cells.Count>0) + { + + 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 9f1e14958..7426e9196 100644 Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ