diff --git a/Subsurface/Characters/CharacterInfo.cs b/Subsurface/Characters/CharacterInfo.cs index 66efc1ca7..bb894014f 100644 --- a/Subsurface/Characters/CharacterInfo.cs +++ b/Subsurface/Characters/CharacterInfo.cs @@ -13,7 +13,7 @@ namespace Subsurface public int HeadSpriteId; - //public int ID; + public Job Job; public Gender Gender; @@ -24,7 +24,7 @@ namespace Subsurface // return gender.ToString(); //} - public CharacterInfo(string file, string name = "", Gender gender = Gender.None) + public CharacterInfo(string file, string name = "", Gender gender = Gender.None, Job job = null) { this.File = file; @@ -62,6 +62,8 @@ namespace Subsurface HeadSpriteId = Rand.Range((int)headSpriteRange.X, (int)headSpriteRange.Y + 1); } + this.Job = (job == null) ? Job.Random() : job; + if (!string.IsNullOrEmpty(name)) { this.Name = name; diff --git a/Subsurface/Characters/FishAnimController.cs b/Subsurface/Characters/FishAnimController.cs index d01cbc795..b5c56a5a0 100644 --- a/Subsurface/Characters/FishAnimController.cs +++ b/Subsurface/Characters/FishAnimController.cs @@ -106,14 +106,16 @@ namespace Subsurface float movementAngle = MathUtils.VectorToAngle(movement) - MathHelper.PiOver2; Limb tail = GetLimb(LimbType.Tail); - if (tail != null && waveAmplitude>0.0f) + if (tail != null && waveAmplitude > 0.0f) { walkPos -= movement.Length(); - float waveRotation = (float)Math.Sin(walkPos / waveLength)*waveAmplitude; + float waveRotation = (float)Math.Sin(walkPos / waveLength) * waveAmplitude; float angle = MathUtils.GetShortestAngle(tail.body.Rotation, movementAngle + waveRotation); + tail.body.ApplyTorque(angle * tail.Mass); + //limbs[tailIndex].body.ApplyTorque((Math.Sign(angle) + Math.Max(Math.Min(angle * 10.0f, 10.0f), -10.0f)) * limbs[tailIndex].body.Mass); //limbs[tailIndex].body.ApplyTorque(-limbs[tailIndex].body.AngularVelocity * 0.5f * limbs[tailIndex].body.Mass); } diff --git a/Subsurface/Characters/Jobs/Job.cs b/Subsurface/Characters/Jobs/Job.cs index e320341ee..3780b87b6 100644 --- a/Subsurface/Characters/Jobs/Job.cs +++ b/Subsurface/Characters/Jobs/Job.cs @@ -1,56 +1,52 @@ -using System.Collections.Generic; -using System.Xml.Linq; +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; namespace Subsurface { class Job { - public static List jobList; - string name; - string description; - - //names of the items the character spawns with - public List itemNames; + private JobPrefab prefab; + + private Dictionary skills; public string Name { - get { return name; } + get { return prefab.Name; } } - public Job(XElement element) + public string Description { - name = element.Name.ToString(); + get { return prefab.Description; } + } - description = ToolBox.GetAttributeString(element, "description", ""); + public Job(JobPrefab jobPrefab) + { + prefab = jobPrefab; - itemNames = new List(); - - foreach (XElement subElement in element.Elements()) + skills = new Dictionary(); + foreach (KeyValuePair skill in prefab.skills) { - switch (subElement.Name.ToString()) - { - case "item": - string itemName = ToolBox.GetAttributeString(subElement, "name", ""); - if (!string.IsNullOrEmpty(itemName)) itemNames.Add(itemName); - break; - } + skills.Add(skill.Key, Rand.Range(skill.Value.X, skill.Value.Y, false)); } } - - public static void LoadAll(string filePath) + public static Job Random() { - jobList = new List(); + JobPrefab prefab = JobPrefab.List[Rand.Int(JobPrefab.List.Count-1, false)]; - XDocument doc = ToolBox.TryLoadXml(filePath); - if (doc == null) return; + return new Job(prefab); + } - foreach (XElement element in doc.Root.Elements()) - { - Job job = new Job(element); - jobList.Add(job); - } + public float GetSkill(string skillName) + { + float skillLevel = 0.0f; + skills.TryGetValue(skillName.ToLower(), out skillLevel); + + return skillLevel; } } } diff --git a/Subsurface/Characters/Jobs/JobPrefab.cs b/Subsurface/Characters/Jobs/JobPrefab.cs new file mode 100644 index 000000000..830ff1eb9 --- /dev/null +++ b/Subsurface/Characters/Jobs/JobPrefab.cs @@ -0,0 +1,105 @@ +using Microsoft.Xna.Framework; +using System.Collections.Generic; +using System.Globalization; +using System.Xml.Linq; + +namespace Subsurface +{ + class JobPrefab + { + public static List List; + + string name; + string description; + + //names of the items the character spawns with + public List itemNames; + + public Dictionary skills; + + public string Name + { + get { return name; } + } + + public string Description + { + get { return description; } + } + + //public float GetSkill(string skillName) + //{ + // float skillLevel = 0.0f; + // if (skills.TryGetValue(skillName.ToLower(), out skillLevel)) + // { + // return skillLevel; + // } + // else + // { + // DebugConsole.ThrowError("Skill ''"+skillName+" not found!"); + // return skillLevel; + // } + //} + + public JobPrefab(XElement element) + { + name = element.Name.ToString(); + + description = ToolBox.GetAttributeString(element, "description", ""); + + itemNames = new List(); + + skills = new Dictionary(); + + foreach (XElement subElement in element.Elements()) + { + switch (subElement.Name.ToString()) + { + case "item": + string itemName = ToolBox.GetAttributeString(subElement, "name", ""); + if (!string.IsNullOrEmpty(itemName)) itemNames.Add(itemName); + break; + case "skills": + LoadSkills(subElement); + break; + } + } + } + + private void LoadSkills(XElement element) + { + foreach (XElement subElement in element.Elements()) + { + string skillName = subElement.Name.ToString().ToLower(); + if (skills.ContainsKey(skillName)) continue; + + var levelAttribute = subElement.Attribute("level").ToString(); + if (levelAttribute.Contains("'")) + { + skills.Add(skillName, ToolBox.ParseToVector2(levelAttribute, false)); + } + else + { + float skillLevel = float.Parse(levelAttribute, CultureInfo.InvariantCulture); + skills.Add(skillName, new Vector2(skillLevel, skillLevel)); + } + + } + } + + + public static void LoadAll(string filePath) + { + List = new List(); + + XDocument doc = ToolBox.TryLoadXml(filePath); + if (doc == null) return; + + foreach (XElement element in doc.Root.Elements()) + { + JobPrefab job = new JobPrefab(element); + List.Add(job); + } + } + } +} diff --git a/Subsurface/Game1.cs b/Subsurface/Game1.cs index b26253a4c..9db8ebb2c 100644 --- a/Subsurface/Game1.cs +++ b/Subsurface/Game1.cs @@ -145,7 +145,7 @@ namespace Subsurface MapEntityPrefab.Init(); - Job.LoadAll("Content/Characters/Jobs.xml"); + JobPrefab.LoadAll("Content/Characters/Jobs.xml"); StructurePrefab.LoadAll("Content/Map/StructurePrefabs.xml"); ItemPrefab.LoadAll(); diff --git a/Subsurface/Map/Level.cs b/Subsurface/Map/Level.cs index 19d70ac12..a864b8bee 100644 --- a/Subsurface/Map/Level.cs +++ b/Subsurface/Map/Level.cs @@ -2,6 +2,7 @@ using FarseerPhysics.Common; using FarseerPhysics.Dynamics; using FarseerPhysics.Factories; +using Lidgren.Network; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; @@ -24,13 +25,13 @@ namespace Subsurface private int siteInterval; - const int gridCellWidth = 2000; - List[,] cellGrid; + const int GridCellWidth = 2000; + private List[,] cellGrid; //List bodies; - List cells; + private List cells; - BasicEffect basicEffect; + private BasicEffect basicEffect; private VertexPositionColor[] vertices; private VertexBuffer vertexBuffer; @@ -38,7 +39,7 @@ namespace Subsurface private Vector2 startPosition; private Vector2 endPosition; - Rectangle borders; + private Rectangle borders; public Vector2 StartPosition { @@ -65,7 +66,7 @@ namespace Subsurface { seed = Rand.Range(0, int.MaxValue, false).ToString(); } - return new Level((string)seed, 100000, 40000, 2000); + return new Level((string)seed, 100000, 40000, 2000); } public void Generate(float minWidth) @@ -77,7 +78,7 @@ namespace Subsurface if (loaded != null) { - loaded.Unload(); + loaded.Unload(); } loaded = this; @@ -88,7 +89,7 @@ namespace Subsurface Random rand = new Random(ToolBox.SeedToInt(seed)); float siteVariance = siteInterval * 0.8f; - for (int x = siteInterval/2; x < borders.Width; x += siteInterval) + for (int x = siteInterval / 2; x < borders.Width; x += siteInterval) { for (int y = siteInterval / 2; y < borders.Height; y += siteInterval) { @@ -107,10 +108,10 @@ namespace Subsurface Debug.WriteLine("MakeVoronoiGraph: " + sw2.ElapsedMilliseconds + " ms"); sw2.Restart(); - cellGrid = new List[borders.Width / gridCellWidth, borders.Height / gridCellWidth]; - for (int x = 0; x < borders.Width / gridCellWidth; x++) + cellGrid = new List[borders.Width / GridCellWidth, borders.Height / GridCellWidth]; + for (int x = 0; x < borders.Width / GridCellWidth; x++) { - for (int y = 0; y < borders.Height / gridCellWidth; y++) + for (int y = 0; y < borders.Height / GridCellWidth; y++) { cellGrid[x, y] = new List(); } @@ -125,13 +126,13 @@ namespace Subsurface Site site = (i == 0) ? ge.site1 : ge.site2; VoronoiCell cell = cellGrid[ - (int)Math.Floor(site.coord.x / gridCellWidth), - (int)Math.Floor(site.coord.y / gridCellWidth)].Find(c => c.site == site); + (int)Math.Floor(site.coord.x / GridCellWidth), + (int)Math.Floor(site.coord.y / GridCellWidth)].Find(c => c.site == site); if (cell == null) { cell = new VoronoiCell(site); - cellGrid[(int)Math.Floor(cell.Center.X / gridCellWidth), (int)Math.Floor(cell.Center.Y / gridCellWidth)].Add(cell); + cellGrid[(int)Math.Floor(cell.Center.X / GridCellWidth), (int)Math.Floor(cell.Center.Y / GridCellWidth)].Add(cell); cells.Add(cell); } @@ -146,7 +147,7 @@ namespace Subsurface cell.edges.Add(ge); } } - + Debug.WriteLine("find cells: " + sw2.ElapsedMilliseconds + " ms"); sw2.Restart(); @@ -162,21 +163,21 @@ namespace Subsurface //generate a couple of random paths - for (int i = 0; i < rand.Next() % 3; i++ ) + for (int i = 0; i < rand.Next() % 3; i++) { pathBorders = new Rectangle( borders.X + siteInterval * 2, borders.Y - siteInterval * 2, borders.Right - siteInterval * 2, borders.Y + borders.Height - siteInterval * 2); - Vector2 start = pathCells[rand.Next(1,pathCells.Count-2)].Center; + Vector2 start = pathCells[rand.Next(1, pathCells.Count - 2)].Center; float x = pathBorders.X + (float)rand.NextDouble() * (pathBorders.Right - pathBorders.X); float y = pathBorders.Y + (float)rand.NextDouble() * (pathBorders.Bottom - pathBorders.Y); - Vector2 end = new Vector2(x,y); - + Vector2 end = new Vector2(x, y); + pathCells.AddRange ( - GeneratePath(rand, start,end, cells, pathBorders, 0.0f, 0.8f) + GeneratePath(rand, start, end, cells, pathBorders, 0.0f, 0.8f) ); } @@ -187,15 +188,15 @@ namespace Subsurface endPosition = pathCells[pathCells.Count - 1].Center; cells = CleanCells(pathCells); - + foreach (VoronoiCell cell in pathCells) { cells.Remove(cell); } - for (int x = 0; x < cellGrid.GetLength(0); x++ ) + for (int x = 0; x < cellGrid.GetLength(0); x++) { - for (int y = 0; y < cellGrid.GetLength(1); y++ ) + for (int y = 0; y < cellGrid.GetLength(1); y++) { cellGrid[x, y].Clear(); } @@ -203,7 +204,7 @@ namespace Subsurface foreach (VoronoiCell cell in cells) { - cellGrid[(int)Math.Floor(cell.Center.X / gridCellWidth), (int)Math.Floor(cell.Center.Y / gridCellWidth)].Add(cell); + cellGrid[(int)Math.Floor(cell.Center.X / GridCellWidth), (int)Math.Floor(cell.Center.Y / GridCellWidth)].Add(cell); } GeneratePolygons(cells, pathCells); @@ -230,7 +231,7 @@ namespace Subsurface basicEffect = new BasicEffect(Game1.CurrGraphicsDevice); basicEffect.VertexColorEnabled = true; - Debug.WriteLine("Generated a map with "+sites.Count+" sites in "+sw.ElapsedMilliseconds+" ms"); + Debug.WriteLine("Generated a map with " + sites.Count + " sites in " + sw.ElapsedMilliseconds + " ms"); } private List GeneratePath(Random rand, Vector2 start, Vector2 end, List cells, Microsoft.Xna.Framework.Rectangle limits, float minWidth, float wanderAmount = 0.3f) @@ -238,7 +239,7 @@ namespace Subsurface Stopwatch sw2 = new Stopwatch(); sw2.Start(); - + //how heavily the path "steers" towards the endpoint //lower values will cause the path to "wander" more, higher will make it head straight to the end wanderAmount = MathHelper.Clamp(wanderAmount, 0.0f, 1.0f); @@ -255,7 +256,7 @@ namespace Subsurface int edgeIndex = 0; //steer towards target - if (rand.NextDouble()>wanderAmount) + if (rand.NextDouble() > wanderAmount) { for (int i = 0; i < currentCell.edges.Count; i++) { @@ -268,14 +269,14 @@ namespace Subsurface else { List allowedEdges = new List(); - - foreach(GraphEdge edge in currentCell.edges) + + foreach (GraphEdge edge in currentCell.edges) { if (!limits.Contains(edge.AdjacentCell(currentCell).Center)) continue; - + allowedEdges.Add(edge); } - edgeIndex = (allowedEdges.Count==0) ? + edgeIndex = (allowedEdges.Count == 0) ? 0 : currentCell.edges.IndexOf(allowedEdges[rand.Next() % allowedEdges.Count]); } @@ -284,7 +285,7 @@ namespace Subsurface pathCells.Add(currentCell); - } while (currentCell!=endCell); + } while (currentCell != endCell); Debug.WriteLine("genpath: " + sw2.ElapsedMilliseconds + " ms"); sw2.Restart(); @@ -305,7 +306,7 @@ namespace Subsurface private List GetTooCloseCells(List emptyCells, float minDistance) { List tooCloseCells = new List(); - + Vector2 position = emptyCells[0].Center; if (minDistance == 0.0f) return tooCloseCells; @@ -317,18 +318,18 @@ namespace Subsurface minDistance *= 0.5f; do { - for (int x = -1; x<=1; x++) + for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { if (x == 0 && y == 0) continue; - Vector2 cornerPos = position + new Vector2(x*minDistance, y*minDistance); - + Vector2 cornerPos = position + new Vector2(x * minDistance, y * minDistance); + int cellIndex = FindCellIndex(cornerPos); if (cellIndex == -1) continue; - if (!tooCloseCells.Contains(cells[cellIndex])) + if (!tooCloseCells.Contains(cells[cellIndex])) { - tooCloseCells.Add(cells[cellIndex]); + tooCloseCells.Add(cells[cellIndex]); } } } @@ -337,9 +338,9 @@ namespace Subsurface if (Vector2.Distance(emptyCells[targetCellIndex].Center, position) < step * 2.0f) targetCellIndex++; - } while (Vector2.Distance(position, emptyCells[emptyCells.Count - 1].Center) > step*2.0f); + } while (Vector2.Distance(position, emptyCells[emptyCells.Count - 1].Center) > step * 2.0f); - return tooCloseCells; + return tooCloseCells; } /// @@ -389,7 +390,7 @@ namespace Subsurface // return point; //} - + /// /// find the index of the cell which the point is inside /// (actually finds the cell whose center is closest, but it's always the correct cell assuming the point is inside the borders of the diagram) @@ -399,16 +400,16 @@ namespace Subsurface float closestDist = 0.0f; VoronoiCell closestCell = null; - int gridPosX = (int)Math.Floor(position.X / gridCellWidth); - int gridPosY = (int)Math.Floor(position.Y / gridCellWidth); + int gridPosX = (int)Math.Floor(position.X / GridCellWidth); + int gridPosY = (int)Math.Floor(position.Y / GridCellWidth); int searchOffset = 1; - for (int x = Math.Max(gridPosX-searchOffset,0); x<=Math.Min(gridPosX+searchOffset, cellGrid.GetLength(0)-1); x++) + for (int x = Math.Max(gridPosX - searchOffset, 0); x <= Math.Min(gridPosX + searchOffset, cellGrid.GetLength(0) - 1); x++) { - for (int y = Math.Max(gridPosY-searchOffset,0); y<=Math.Min(gridPosY+searchOffset, cellGrid.GetLength(1)-1); y++) + for (int y = Math.Max(gridPosY - searchOffset, 0); y <= Math.Min(gridPosY + searchOffset, cellGrid.GetLength(1) - 1); y++) { - for (int i = 0; i < cellGrid[x,y].Count; i++) + for (int i = 0; i < cellGrid[x, y].Count; i++) { float dist = Vector2.Distance(cellGrid[x, y][i].Center, position); if (closestDist != 0.0f && dist > closestDist) continue; @@ -421,7 +422,7 @@ namespace Subsurface - return cells.IndexOf(closestCell); + return cells.IndexOf(closestCell); } private void GeneratePolygons(List cells, List emptyCells) @@ -455,26 +456,26 @@ namespace Subsurface } if (tempVertices.Count < 3) continue; - + int triangleCount = tempVertices.Count - 2; tempVertices.Sort(new CompareCCW(cell.Center)); int lastIndex = 1; - for (int i = 0; i < triangleCount; i++ ) + for (int i = 0; i < triangleCount; i++) { //simple triangulation - List triangleVertices = new List(); + List triangleVertices = new List(); triangleVertices.Add(tempVertices[0]); - for (int j = lastIndex; j<=lastIndex+1; j++) + for (int j = lastIndex; j <= lastIndex + 1; j++) { triangleVertices.Add(tempVertices[j]); } lastIndex += 1; - + foreach (Vector2 vertex in triangleVertices) { - verticeList.Add(new VertexPositionColor(new Vector3(vertex, 0.0f), Color.LightGray*0.8f));//new Color(n,(n*2)%255,(n*3)%255)*0.5f)); + verticeList.Add(new VertexPositionColor(new Vector3(vertex, 0.0f), Color.LightGray * 0.8f));//new Color(n,(n*2)%255,(n*3)%255)*0.5f)); } //bool isSame = false; @@ -492,17 +493,16 @@ namespace Subsurface //todo: make sure the first point is the one where the edge should start from bodyPoints.Sort(new CompareCCW(cell.Center)); - if (bodyPoints.Count == tempVertices.Count) - { - - } + //if (bodyPoints.Count == tempVertices.Count) + //{ + //} for (int i = 0; i < bodyPoints.Count; i++) { cell.bodyVertices.Add(bodyPoints[i]); bodyPoints[i] = ConvertUnits.ToSimUnits(bodyPoints[i]); } - + Vertices bodyVertices = new Vertices(bodyPoints); Body edgeBody = BodyFactory.CreateLoopShape(Game1.World, bodyVertices); @@ -510,7 +510,7 @@ namespace Subsurface //Body edgeBody = (bodyVertices.Count == tempVertices.Count) ? // BodyFactory.CreateLoopShape(Game1.world, bodyVertices) : // BodyFactory.CreateChainShape(Game1.world, bodyVertices); - + edgeBody.UserData = cell; edgeBody.BodyType = BodyType.Kinematic; @@ -543,7 +543,7 @@ namespace Subsurface //position += amount; Vector2 velocity = amount; - Vector2 simVelocity = ConvertUnits.ToSimUnits(amount / (float)Physics.step); + Vector2 simVelocity = ConvertUnits.ToSimUnits(amount / (float)Physics.step); //DebugCheckPos(); @@ -567,7 +567,7 @@ namespace Subsurface if (limb.type == LimbType.LeftFoot || limb.type == LimbType.RightFoot) continue; limb.body.ApplyForce((simVelocity - prevVelocity) * 10.0f * limb.Mass); } - } + } } foreach (Item item in Item.itemList) @@ -598,11 +598,11 @@ namespace Subsurface foreach (Character character in Character.CharacterList) { if (character.AnimController.CurrentHull != null) continue; - + foreach (Limb limb in character.AnimController.limbs) { limb.body.LinearVelocity -= prevVelocity; - } + } } foreach (Item item in Item.itemList) @@ -627,7 +627,7 @@ namespace Subsurface avgPos += cell.body.Position; } - System.Diagnostics.Debug.WriteLine("avgpos: "+avgPos / cells.Count); + System.Diagnostics.Debug.WriteLine("avgpos: " + avgPos / cells.Count); System.Diagnostics.Debug.WriteLine("pos: " + Position); } @@ -636,8 +636,8 @@ namespace Subsurface public void SetObserverPosition(Vector2 position) { observerPosition = position - this.Position; - int gridPosX = (int)Math.Floor(observerPosition.X / gridCellWidth); - int gridPosY = (int)Math.Floor(observerPosition.Y / gridCellWidth); + int gridPosX = (int)Math.Floor(observerPosition.X / GridCellWidth); + int gridPosY = (int)Math.Floor(observerPosition.Y / GridCellWidth); int searchOffset = 2; int startX = Math.Max(gridPosX - searchOffset, 0); @@ -706,14 +706,14 @@ namespace Subsurface foreach (VoronoiCell cell in cells) { - for (int i = 0; i < cell.bodyVertices.Count-1; i++) + for (int i = 0; i < cell.bodyVertices.Count - 1; i++) { Vector2 start = cell.bodyVertices[i]; start.X += Position.X; start.Y = -start.Y - Position.Y; start.X += Rand.Range(-10.0f, 10.0f); - Vector2 end = cell.bodyVertices[i+1]; + Vector2 end = cell.bodyVertices[i + 1]; end.X += Position.X; end.Y = -end.Y - Position.Y; end.X += Rand.Range(-10.0f, 10.0f); @@ -726,8 +726,8 @@ namespace Subsurface public List GetCellEdges(Vector2 refPos, int searchDepth = 2, bool onlySolid = true) { - int gridPosX = (int)Math.Floor(refPos.X / gridCellWidth); - int gridPosY = (int)Math.Floor(refPos.Y / gridCellWidth); + int gridPosX = (int)Math.Floor(refPos.X / GridCellWidth); + int gridPosY = (int)Math.Floor(refPos.Y / GridCellWidth); int startX = Math.Max(gridPosX - searchDepth, 0); int endX = Math.Min(gridPosX + searchDepth, cellGrid.GetLength(0) - 1); @@ -742,7 +742,7 @@ namespace Subsurface { for (int y = startY; y < endY; y++) { - foreach (VoronoiCell cell in cellGrid[x,y]) + foreach (VoronoiCell cell in cellGrid[x, y]) { for (int i = 0; i < cell.edges.Count; i++) { @@ -759,7 +759,7 @@ namespace Subsurface } } } - + return edges; } @@ -768,12 +768,12 @@ namespace Subsurface if (vertices == null) return; if (vertices.Length <= 0) return; - basicEffect.World = Matrix.CreateTranslation(new Vector3(Position, 0.0f))*cam.ShaderTransform + basicEffect.World = Matrix.CreateTranslation(new Vector3(Position, 0.0f)) * cam.ShaderTransform * Matrix.CreateOrthographic(Game1.GraphicsWidth, Game1.GraphicsHeight, -1, 1) * 0.5f; - basicEffect.CurrentTechnique.Passes[0].Apply(); - + basicEffect.CurrentTechnique.Passes[0].Apply(); + graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, (int)Math.Floor(vertices.Length / 3.0f)); } @@ -800,6 +800,7 @@ namespace Subsurface vertexBuffer.Dispose(); vertexBuffer = null; } + } } diff --git a/Subsurface/Map/Submarine.cs b/Subsurface/Map/Submarine.cs index 4bcc5209b..e7ea328aa 100644 --- a/Subsurface/Map/Submarine.cs +++ b/Subsurface/Map/Submarine.cs @@ -5,6 +5,7 @@ using FarseerPhysics.Common.Decomposition; using FarseerPhysics.Dynamics; using FarseerPhysics.Dynamics.Contacts; using FarseerPhysics.Factories; +using Lidgren.Network; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; @@ -22,14 +23,14 @@ namespace Subsurface None = 0, Left = 1, Right = 2 } - class Submarine + class Submarine : Entity { public static List SavedSubmarines = new List(); - private static Submarine loaded; - public static readonly Vector2 GridSize = new Vector2(16.0f, 16.0f); + private static Submarine loaded; + private static Vector2 lastPickedPosition; private static float lastPickedFraction; @@ -38,6 +39,9 @@ namespace Subsurface Vector2 speed; + Vector2 targetPosition; + Vector2 targetSpeed; + private Rectangle borders; private Body hullBody; @@ -45,6 +49,10 @@ namespace Subsurface private string filePath; private string name; + + private double lastNetworkUpdate; + + //properties ---------------------------------------------------- public string Name @@ -99,6 +107,11 @@ namespace Subsurface get { return new Vector2(borders.X+borders.Width/2, borders.Y - borders.Height/2); } } + public Vector2 Position + { + get { return (Level.Loaded==null) ? Vector2.Zero : -Level.Loaded.Position; } + } + public string FilePath { get { return filePath; } @@ -392,19 +405,30 @@ namespace Subsurface public void Update(float deltaTime) { - Translate(ConvertUnits.ToDisplayUnits(hullBody.Position) * collisionRigidness + speed * deltaTime); + Vector2 translateAmount = speed * deltaTime; + translateAmount += ConvertUnits.ToDisplayUnits(hullBody.Position) * collisionRigidness; + if (targetPosition != Vector2.Zero && Vector2.Distance(targetPosition, Position) > 5.0f) + { + translateAmount += (targetPosition - Position)*0.1f; + } + else + { + targetPosition = Vector2.Zero; + } - CalculateBuoyancy(); + Translate(translateAmount); + + ApplyForce(CalculateBuoyancy()); float dragCoefficient = 0.00001f; float speedLength = speed.Length(); float drag = speedLength * speedLength * dragCoefficient * mass; - System.Diagnostics.Debug.WriteLine("speed: "+speed); - if (speed!=Vector2.Zero) + + if (speed != Vector2.Zero) { - ApplyForce(-Vector2.Normalize(speed)*drag); + ApplyForce(-Vector2.Normalize(speed) * drag); } //hullBodies[0].body.LinearVelocity = -hullBodies[0].body.Position; @@ -439,7 +463,7 @@ namespace Subsurface } - private void CalculateBuoyancy() + private Vector2 CalculateBuoyancy() { float waterVolume = 0.0f; float volume = 0.0f; @@ -456,7 +480,7 @@ namespace Subsurface float buoyancy = neutralPercentage-waterPercentage; buoyancy *= mass * 10.0f; - ApplyForce(new Vector2(0.0f, buoyancy)); + return new Vector2(0.0f, buoyancy); } public void SetPosition(Vector2 position) @@ -509,6 +533,34 @@ namespace Subsurface { collidingCell = null; } + + public override void FillNetworkData(Networking.NetworkEventType type, NetOutgoingMessage message, object data) + { + message.Write(NetTime.Now); + message.Write(Position.X); + message.Write(Position.Y); + + } + + public override void ReadNetworkData(Networking.NetworkEventType type, NetIncomingMessage message) + { + double sendingTime = message.ReadDouble(); + + if (sendingTime <= lastNetworkUpdate) return; + + Vector2 newPosition = new Vector2(message.ReadFloat(), message.ReadFloat()); + if (newPosition == Position) return; + if ((newPosition - Position).Length() > 500.0f) + { + System.Diagnostics.Debug.WriteLine("Submarine has moved over 500 pixels since last update"); + return; + } + + targetPosition = Position; + + lastNetworkUpdate = sendingTime; + } + //saving/loading ---------------------------------------------------- @@ -553,7 +605,7 @@ namespace Subsurface if (loaded==null) { loaded = new Submarine(savePath); - return; + // return; } loaded.SaveAs(savePath); @@ -767,8 +819,7 @@ namespace Subsurface Submarine sub = new Submarine(file); sub.Load(); - return sub; - + return sub; } public static void Unload() @@ -793,9 +844,4 @@ namespace Subsurface } - //class HullBody - //{ - // public Body body; - // //public Texture2D shapeTexture; - //} } diff --git a/Subsurface/Screens/LobbyScreen.cs b/Subsurface/Screens/LobbyScreen.cs index b56601b23..49dde1e29 100644 --- a/Subsurface/Screens/LobbyScreen.cs +++ b/Subsurface/Screens/LobbyScreen.cs @@ -187,7 +187,7 @@ namespace Subsurface { GUITextBlock textBlock = new GUITextBlock( new Rectangle(0, 0, 0, 25), - c.Name, GUI.style, + c.Name + " ("+c.Job.Name+")", GUI.style, Alignment.Left, Alignment.Left, characterList); @@ -205,7 +205,7 @@ namespace Subsurface GUITextBlock textBlock = new GUITextBlock( new Rectangle(0, 0, 0, 25), - c.Name, + c.Name + " (" + c.Job.Name + ")", Color.Transparent, Color.Black, Alignment.Left, null, frame); diff --git a/Subsurface/Screens/MainMenu.cs b/Subsurface/Screens/MainMenu.cs index 8d0a2d9b4..325362492 100644 --- a/Subsurface/Screens/MainMenu.cs +++ b/Subsurface/Screens/MainMenu.cs @@ -10,15 +10,15 @@ namespace Subsurface { enum Tabs { Main = 0, NewGame = 1, LoadGame = 2, JoinServer = 3 } - GUIFrame[] menuTabs; - GUIListBox mapList; + private GUIFrame[] menuTabs; + private GUIListBox mapList; - GUIListBox saveList; + private GUIListBox saveList; - GUITextBox nameBox; - GUITextBox ipBox; + private GUITextBox nameBox; + private GUITextBox ipBox; - Game1 game; + private Game1 game; int selectedTab; @@ -87,6 +87,18 @@ namespace Subsurface new GUITextBlock(new Rectangle(0, 0, 0, 30), "Load Game", Color.Transparent, Color.Black, Alignment.CenterX, null, menuTabs[(int)Tabs.LoadGame]); + if (!Directory.Exists(SaveUtil.SaveFolder)) + { + DebugConsole.ThrowError("Save folder ''"+SaveUtil.SaveFolder+" not found! Attempting to create a new folder"); + try + { + Directory.CreateDirectory(SaveUtil.SaveFolder); + } + catch (Exception e) + { + DebugConsole.ThrowError("Failed to create the folder ''"+SaveUtil.SaveFolder+"''!", e); + } + } string[] saveFiles = Directory.GetFiles(SaveUtil.SaveFolder, "*.save"); diff --git a/Subsurface/Screens/NetLobbyScreen.cs b/Subsurface/Screens/NetLobbyScreen.cs index 85fe13758..4a8c6f4c4 100644 --- a/Subsurface/Screens/NetLobbyScreen.cs +++ b/Subsurface/Screens/NetLobbyScreen.cs @@ -227,7 +227,7 @@ namespace Subsurface GUIListBox jobList = new GUIListBox(new Rectangle(0,180,200,0), GUI.style, playerFrame); - foreach (Job job in Job.jobList) + foreach (JobPrefab job in JobPrefab.List) { GUITextBlock jobText = new GUITextBlock(new Rectangle(0,0,0,20), job.Name, GUI.style, jobList); GUIButton upButton = new GUIButton(new Rectangle(jobText.Rect.Width - 40, 0, 20, 20), "u", GUI.style, jobText); diff --git a/Subsurface/Subsurface.csproj b/Subsurface/Subsurface.csproj index f5e950ae0..25d44f6a8 100644 --- a/Subsurface/Subsurface.csproj +++ b/Subsurface/Subsurface.csproj @@ -61,6 +61,7 @@ + @@ -197,6 +198,10 @@ + + False + bin\Windows\Debug\FarseerPhysics MonoGame.dll + False .\Lidgren.Network.dll @@ -715,10 +720,6 @@ - - {0aad36e3-51a5-4a07-ab60-5c8a66bd38b7} - Farseer Physics MonoGame - {1e6bf44d-6e31-40cc-8321-3d5958c983e7} Subsurface_content diff --git a/Subsurface/Subsurface.csproj.user b/Subsurface/Subsurface.csproj.user index 505c3a0bf..693505ea4 100644 --- a/Subsurface/Subsurface.csproj.user +++ b/Subsurface/Subsurface.csproj.user @@ -9,6 +9,6 @@ en-US false - ProjectFiles + ShowAllFiles \ No newline at end of file diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index 87ea3e923..b47011268 100644 Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ