diff --git a/Subsurface/Characters/Character.cs b/Subsurface/Characters/Character.cs index dc24e7d04..65938ee66 100644 --- a/Subsurface/Characters/Character.cs +++ b/Subsurface/Characters/Character.cs @@ -82,6 +82,7 @@ namespace Subsurface //private float blood; private Sound[] sounds; + private float[] soundRange; //which AIstate each sound is for private AIController.AiState[] soundStates; @@ -340,10 +341,12 @@ namespace Subsurface { sounds = new Sound[soundElements.Count()]; soundStates = new AIController.AiState[soundElements.Count()]; + soundRange = new float[soundElements.Count()]; int i = 0; foreach (XElement soundElement in soundElements) { sounds[i] = Sound.Load(soundElement.Attribute("file").Value); + soundRange[i] = ToolBox.GetAttributeFloat(soundElement, "range", 1000.0f); if (soundElement.Attribute("state") == null) { soundStates[i] = AIController.AiState.None; diff --git a/Subsurface/Characters/FishAnimController.cs b/Subsurface/Characters/FishAnimController.cs index b5c56a5a0..be14ee66e 100644 --- a/Subsurface/Characters/FishAnimController.cs +++ b/Subsurface/Characters/FishAnimController.cs @@ -14,8 +14,12 @@ namespace Subsurface private float waveAmplitude; private float waveLength; + private bool rotateTowardsMovement; + private bool flip; + private float flipTimer; + public FishAnimController(Character character, XElement element) : base(character, element) { @@ -26,6 +30,8 @@ namespace Subsurface walkSpeed = ToolBox.GetAttributeFloat(element, "walkspeed", 1.0f); swimSpeed = ToolBox.GetAttributeFloat(element, "swimspeed", 1.0f); + + rotateTowardsMovement = ToolBox.GetAttributeBool(element, "rotatetowardsmovement", true); } public override void UpdateAnim(float deltaTime) @@ -60,11 +66,11 @@ namespace Subsurface if (flip) { //targetDir = (movement.X > 0.0f) ? Direction.Right : Direction.Left; - if (movement.X > 0.1f && movement.X > Math.Abs(movement.Y)) + if (movement.X > 0.1f && movement.X > Math.Abs(movement.Y)*0.5f) { TargetDir = Direction.Right; } - else if (movement.X < -0.1f && movement.X < -Math.Abs(movement.Y)) + else if (movement.X < -0.1f && movement.X < -Math.Abs(movement.Y)*0.5f) { TargetDir = Direction.Left; } @@ -88,11 +94,16 @@ namespace Subsurface } //if (stunTimer > gameTime.TotalGameTime.TotalMilliseconds) return; - + flipTimer += deltaTime; + if (TargetDir != dir) - { - Flip(); - if (flip) Mirror(); + { + if (flipTimer>1.0f) + { + Flip(); + if (flip) Mirror(); + flipTimer = 0.0f; + } } } @@ -125,11 +136,12 @@ namespace Subsurface Limb head = GetLimb(LimbType.Head); if (head != null) { - float angle = MathUtils.GetShortestAngle(head.body.Rotation, movementAngle); + float angle = (rotateTowardsMovement) ? + head.body.Rotation+ MathUtils.GetShortestAngle(head.body.Rotation, movementAngle) : + HeadAngle*Dir; - head.body.SmoothRotate(head.body.Rotation+angle, 25.0f); - + head.body.SmoothRotate(angle, 25.0f); //rotate head towards the angle of movement //float torque = (Math.Sign(angle)*10.0f + MathHelper.Clamp(angle * 10.0f, -10.0f, 10.0f)); //angular drag diff --git a/Subsurface/Content/Characters/Crawler/attack.ogg b/Subsurface/Content/Characters/Crawler/attack.ogg new file mode 100644 index 000000000..a4f41d094 Binary files /dev/null and b/Subsurface/Content/Characters/Crawler/attack.ogg differ diff --git a/Subsurface/Content/Characters/Crawler/crawler.xml b/Subsurface/Content/Characters/Crawler/crawler.xml index dd5fce2a4..aa2176b27 100644 --- a/Subsurface/Content/Characters/Crawler/crawler.xml +++ b/Subsurface/Content/Characters/Crawler/crawler.xml @@ -1,6 +1,8 @@  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Subsurface/Content/SavedMaps/d.gz b/Subsurface/Content/SavedMaps/d.gz new file mode 100644 index 000000000..23ea15f1a Binary files /dev/null and b/Subsurface/Content/SavedMaps/d.gz differ diff --git a/Subsurface/Content/Sounds/sounds.xml b/Subsurface/Content/Sounds/sounds.xml index e5f706f98..7d65e512a 100644 --- a/Subsurface/Content/Sounds/sounds.xml +++ b/Subsurface/Content/Sounds/sounds.xml @@ -10,14 +10,14 @@ - - + + - - + + diff --git a/Subsurface/GameSession/SinglePlayerMode.cs b/Subsurface/GameSession/SinglePlayerMode.cs index 5b06a622b..3655d1e0d 100644 --- a/Subsurface/GameSession/SinglePlayerMode.cs +++ b/Subsurface/GameSession/SinglePlayerMode.cs @@ -31,7 +31,7 @@ namespace Subsurface crewManager = new CrewManager(); hireManager = new HireManager(); - endShiftButton = new GUIButton(new Rectangle(Game1.GraphicsWidth - 240, 20, 100, 25), "End shift", Alignment.Left | Alignment.Top, GUI.style); + endShiftButton = new GUIButton(new Rectangle(Game1.GraphicsWidth - 220, 20, 200, 25), "End shift", Alignment.TopLeft, GUI.style); endShiftButton.OnClicked = EndShift; hireManager.GenerateCharacters("Content/Characters/Human/human.xml", 10); @@ -83,7 +83,17 @@ namespace Subsurface crewManager.Draw(spriteBatch); - endShiftButton.Draw(spriteBatch); + if (Level.Loaded.AtEndPosition) + { + endShiftButton.Text = "Enter " + Game1.GameSession.map.SelectedLocation.Name; + endShiftButton.Draw(spriteBatch); + } + else if (Level.Loaded.AtStartPosition) + { + endShiftButton.Text = "Enter " + Game1.GameSession.map.CurrentLocation.Name; + endShiftButton.Draw(spriteBatch); + } + //chatBox.Draw(spriteBatch); //textBox.Draw(spriteBatch); @@ -145,11 +155,11 @@ namespace Subsurface sb.Append("No casualties!"); } - Game1.GameSession.map.MoveToNextLocation(); + if (Level.Loaded.AtEndPosition) + { + Game1.GameSession.map.MoveToNextLocation(); + } - //new GUIMessageBox("Day #" + day + " is over!\n", sb.ToString()); - - //day++; } crewManager.EndShift(); diff --git a/Subsurface/Map/Level.cs b/Subsurface/Map/Level.cs index 843ea220a..05991cdba 100644 --- a/Subsurface/Map/Level.cs +++ b/Subsurface/Map/Level.cs @@ -23,6 +23,9 @@ namespace Subsurface private static Texture2D shaftTexture; + //how close the sub has to be to start/endposition to exit + const float ExitDistance = 3000.0f; + private string seed; private int siteInterval; @@ -50,6 +53,18 @@ namespace Subsurface get { return startPosition; } } + public bool AtStartPosition + { + get; + private set; + } + + public bool AtEndPosition + { + get; + private set; + } + public Vector2 Position { get { return ConvertUnits.ToDisplayUnits(cells[0].body.Position); } @@ -80,8 +95,9 @@ namespace Subsurface return new Level(seed, 100000, 40000, 2000); } - public void Generate(float minWidth) + public void Generate(float minWidth, bool mirror=false) { + mirror = true; Stopwatch sw = new Stopwatch(); sw.Start(); @@ -96,16 +112,20 @@ namespace Subsurface List sites = new List(); - Random rand = new Random(seed.GetHashCode()); + Random rand = new Random(100); float siteVariance = siteInterval * 0.8f; for (int x = siteInterval / 2; x < borders.Width; x += siteInterval) { for (int y = siteInterval / 2; y < borders.Height; y += siteInterval) { - sites.Add(new Vector2( + Vector2 site = new Vector2( x + (float)(rand.NextDouble() - 0.5) * siteVariance, - y + (float)(rand.NextDouble() - 0.5) * siteVariance)); + y + (float)(rand.NextDouble() - 0.5) * siteVariance); + + if (mirror) site.X = borders.Width - site.X; + + sites.Add(site); } } @@ -166,14 +186,22 @@ namespace Subsurface borders.X + (int)minWidth * 2, borders.Y + (int)minWidth * 2, borders.Right - (int)minWidth * 4, borders.Y + borders.Height - (int)minWidth * 4); - List pathCells = GeneratePath(rand, - new Vector2((int)minWidth * 2, rand.Next((int)minWidth * 2, borders.Height - (int)minWidth * 2)), - new Vector2(borders.Width - (int)minWidth * 2, rand.Next((int)minWidth * 2, borders.Height - (int)minWidth * 2)), - cells, pathBorders, minWidth); + Vector2 startPath = new Vector2((int)minWidth * 2, rand.Next((int)minWidth * 2, borders.Height - (int)minWidth * 2)); + Vector2 endPath = new Vector2(borders.Width - (int)minWidth * 2, rand.Next((int)minWidth * 2, borders.Height - (int)minWidth * 2)); + if (mirror) + { + startPath.X = borders.Width - startPath.X; + endPath.X = borders.Width - endPath.X; + } + + List pathCells = GeneratePath(rand, + startPath, endPath, cells, pathBorders, minWidth); + + //place some enemy spawnpoints at random points in the path for (int i = 0; i <3 ; i++ ) { - Vector2 position = pathCells[rand.Next((int)(pathCells.Count*0.5f), pathCells.Count - 2)].Center; + Vector2 position = pathCells[rand.Next((int)(pathCells.Count * 0.5f), pathCells.Count - 2)].Center; WayPoint wayPoint = new WayPoint(new Rectangle((int)position.X, (int)position.Y, 10, 10)); wayPoint.MoveWithLevel = true; wayPoint.SpawnType = SpawnType.Enemy; @@ -193,6 +221,9 @@ namespace Subsurface float x = pathBorders.X + (float)rand.NextDouble() * (pathBorders.Right - pathBorders.X); float y = pathBorders.Y + (float)rand.NextDouble() * (pathBorders.Bottom - pathBorders.Y); + + if (mirror) x = borders.Width - x; + Vector2 end = new Vector2(x, y); pathCells.AddRange @@ -203,14 +234,11 @@ namespace Subsurface Debug.WriteLine("path: " + sw2.ElapsedMilliseconds + " ms"); sw2.Restart(); - - - + for (int i = 0; i < 2; i++ ) { Vector2 tunnelStart = (i == 0) ? startPosition : endPosition; - pathCells.AddRange ( GeneratePath(rand, tunnelStart, new Vector2(tunnelStart.X, borders.Height), cells, pathBorders, minWidth, 0.1f) @@ -288,7 +316,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); @@ -309,7 +337,7 @@ namespace Subsurface { for (int i = 0; i < currentCell.edges.Count; i++) { - if (!IsIntersecting(currentCell.Center, end, currentCell.edges[i].point1, currentCell.edges[i].point2)) continue; + if (!MathUtils.LinesIntersect(currentCell.Center, end, currentCell.edges[i].point1, currentCell.edges[i].point2)) continue; edgeIndex = i; break; } @@ -411,23 +439,6 @@ namespace Subsurface return newCells; } - /// - /// check whether line from a to b is intersecting with line from c to b - /// - bool IsIntersecting(Vector2 a, Vector2 b, Vector2 c, Vector2 d) - { - float denominator = ((b.X - a.X) * (d.Y - c.Y)) - ((b.Y - a.Y) * (d.X - c.X)); - float numerator1 = ((a.Y - c.Y) * (d.X - c.X)) - ((a.X - c.X) * (d.Y - c.Y)); - float numerator2 = ((a.Y - c.Y) * (b.X - a.X)) - ((a.X - c.X) * (b.Y - a.Y)); - - if (denominator == 0) return numerator1 == 0 && numerator2 == 0; - - float r = numerator1 / denominator; - float s = numerator2 / denominator; - - return (r >= 0 && r <= 1) && (s >= 0 && s <= 1); - } - /// /// 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) @@ -492,7 +503,7 @@ namespace Subsurface if (tempVertices.Count < 3) continue; - var triangles = TriangulateConvex(tempVertices, cell.Center); + var triangles = MathUtils.TriangulateConvexHull(tempVertices, cell.Center); for (int i = 0; i < triangles.Count; i++ ) { foreach (Vector2 vertex in triangles[i]) @@ -520,7 +531,7 @@ namespace Subsurface bodyPoints[i] = ConvertUnits.ToSimUnits(bodyPoints[i]); } - triangles = TriangulateConvex(bodyPoints, cell.Center); + triangles = MathUtils.TriangulateConvexHull(bodyPoints, cell.Center); Body edgeBody = new Body(Game1.World); @@ -553,33 +564,6 @@ namespace Subsurface vertices = verticeList.ToArray(); } - private List TriangulateConvex(List vertices, Vector2 center) - { - List triangles = new List(); - - int triangleCount = vertices.Count - 2; - - vertices.Sort(new CompareCCW(center)); - - int lastIndex = 1; - for (int i = 0; i < triangleCount; i++) - { - Vector2[] triangleVertices = new Vector2[3]; - triangleVertices[0] = vertices[0]; - int k = 1; - for (int j = lastIndex; j <= lastIndex + 1; j++) - { - triangleVertices[k]=vertices[j]; - k++; - } - lastIndex += 1; - - triangles.Add(triangleVertices); - } - - return triangles; - } - public void SetPosition(Vector2 pos) { Vector2 amount = pos - Position; @@ -616,19 +600,9 @@ namespace Subsurface Vector2 prevVelocity; public void Move(Vector2 amount) { - //position += amount; - Vector2 velocity = amount; Vector2 simVelocity = ConvertUnits.ToSimUnits(amount / (float)Physics.step); - //DebugCheckPos(); - - //foreach (VoronoiCell cell in cells) - //{ - // if (cell.body == null) continue; - // cell.body.LinearVelocity = simVelocity; - //} - foreach (Body body in bodies) { body.LinearVelocity = simVelocity; @@ -638,16 +612,9 @@ namespace Subsurface { foreach (Limb limb in character.AnimController.limbs) { - //limb.body.SetTransform(limb.body.Position + amount * (float)Physics.step, limb.body.Rotation); - if (character.AnimController.CurrentHull == null) - { - limb.body.LinearVelocity += simVelocity; - } - else - { - //if (limb.type == LimbType.LeftFoot || limb.type == LimbType.RightFoot) continue; - //limb.body.ApplyForce((simVelocity - prevVelocity) * 10.0f * limb.Mass); - } + if (character.AnimController.CurrentHull != null) continue; + + limb.body.LinearVelocity += simVelocity; } } @@ -665,6 +632,9 @@ namespace Subsurface item.body.LinearVelocity += simVelocity; } } + + AtStartPosition = Vector2.Distance(startPosition, -Position) < ExitDistance; + AtEndPosition = Vector2.Distance(endPosition, -Position) < ExitDistance; prevVelocity = simVelocity; } diff --git a/Subsurface/Map/Map.cs b/Subsurface/Map/Map.cs index fbad41b5d..4ea6fa1c0 100644 --- a/Subsurface/Map/Map.cs +++ b/Subsurface/Map/Map.cs @@ -26,6 +26,17 @@ namespace Subsurface private Location currentLocation; private Location selectedLocation; + public Location CurrentLocation + { + get { return currentLocation; } + } + + public Location SelectedLocation + { + get { return selectedLocation; } + } + + public Map(int seed, int size) { this.seed = seed; diff --git a/Subsurface/MathUtils.cs b/Subsurface/MathUtils.cs index c56ec2445..696d424df 100644 --- a/Subsurface/MathUtils.cs +++ b/Subsurface/MathUtils.cs @@ -127,6 +127,54 @@ namespace Subsurface angle = angle * (MathHelper.TwoPi / 255.0f); return angle; } + + /// + /// check whether line from a to b is intersecting with line from c to b + /// + public static bool LinesIntersect(Vector2 a, Vector2 b, Vector2 c, Vector2 d) + { + float denominator = ((b.X - a.X) * (d.Y - c.Y)) - ((b.Y - a.Y) * (d.X - c.X)); + float numerator1 = ((a.Y - c.Y) * (d.X - c.X)) - ((a.X - c.X) * (d.Y - c.Y)); + float numerator2 = ((a.Y - c.Y) * (b.X - a.X)) - ((a.X - c.X) * (b.Y - a.Y)); + + if (denominator == 0) return numerator1 == 0 && numerator2 == 0; + + float r = numerator1 / denominator; + float s = numerator2 / denominator; + + return (r >= 0 && r <= 1) && (s >= 0 && s <= 1); + } + + /// + /// divide a convex hull into triangles + /// + /// List of triangle vertices (sorted counter-clockwise) + public static List TriangulateConvexHull(List vertices, Vector2 center) + { + List triangles = new List(); + + int triangleCount = vertices.Count - 2; + + vertices.Sort(new CompareCCW(center)); + + int lastIndex = 1; + for (int i = 0; i < triangleCount; i++) + { + Vector2[] triangleVertices = new Vector2[3]; + triangleVertices[0] = vertices[0]; + int k = 1; + for (int j = lastIndex; j <= lastIndex + 1; j++) + { + triangleVertices[k] = vertices[j]; + k++; + } + lastIndex += 1; + + triangles.Add(triangleVertices); + } + + return triangles; + } } class CompareCCW : IComparer diff --git a/Subsurface/Sounds/Sound.cs b/Subsurface/Sounds/Sound.cs index 0901783e2..03d9341a5 100644 --- a/Subsurface/Sounds/Sound.cs +++ b/Subsurface/Sounds/Sound.cs @@ -10,6 +10,7 @@ namespace Subsurface { public class Sound { + public static Vector3 CameraPos; private static List loadedSounds = new List(); @@ -19,7 +20,6 @@ namespace Subsurface string filePath; - public static Vector3 CameraPos; //public float Volume //{ diff --git a/Subsurface/Subsurface.csproj b/Subsurface/Subsurface.csproj index 249543efd..8f447551c 100644 --- a/Subsurface/Subsurface.csproj +++ b/Subsurface/Subsurface.csproj @@ -269,6 +269,13 @@ PreserveNewest Designer + + PreserveNewest + + + Designer + PreserveNewest + Designer PreserveNewest @@ -604,6 +611,21 @@ + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index 3bc148c02..323685529 100644 Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ