This commit is contained in:
Regalis
2015-07-31 21:05:55 +03:00
parent 23d847a4ac
commit 85b0cda4ca
181 changed files with 4455 additions and 4073 deletions
+237
View File
@@ -0,0 +1,237 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Subsurface
{
static class MathUtils
{
public static Vector2 SmoothStep(Vector2 v1, Vector2 v2, float amount)
{
return new Vector2(
MathHelper.SmoothStep(v1.X, v2.X, amount),
MathHelper.SmoothStep(v1.Y, v2.Y, amount));
}
public static float Round(float value, float div)
{
return (float)Math.Floor(value / div) * div;
}
public static float VectorToAngle(Vector2 vector)
{
return (float)Math.Atan2(vector.Y, vector.X);
}
public static float CurveAngle(float from, float to, float step)
{
from = WrapAngleTwoPi(from);
to = WrapAngleTwoPi(to);
if (Math.Abs(from - to) < MathHelper.Pi)
{
// The simple case - a straight lerp will do.
return MathHelper.Lerp(from, to, step);
}
// If we get here we have the more complex case.
// First, increment the lesser value to be greater.
if (from < to)
from += MathHelper.TwoPi;
else
to += MathHelper.TwoPi;
float retVal = MathHelper.Lerp(from, to, step);
// Now ensure the return value is between 0 and 2pi
if (retVal >= MathHelper.TwoPi)
retVal -= MathHelper.TwoPi;
return retVal;
}
/// <summary>
/// wrap the angle between 0.0f and 2pi
/// </summary>
public static float WrapAngleTwoPi(float angle)
{
if (float.IsInfinity(angle) || float.IsNegativeInfinity(angle) || float.IsNaN(angle))
{
return 0.0f;
}
while (angle < 0)
angle += MathHelper.TwoPi;
while (angle >= MathHelper.TwoPi)
angle -= MathHelper.TwoPi;
return angle;
}
/// <summary>
/// wrap the angle between -pi and pi
/// </summary>
public static float WrapAnglePi(float angle)
{
if (float.IsInfinity(angle) || float.IsNegativeInfinity(angle) || float.IsNaN(angle))
{
return 0.0f;
}
// Ensure that -pi <= angle < pi for both "from" and "to"
while (angle < -MathHelper.Pi)
angle += MathHelper.TwoPi;
while (angle >= MathHelper.Pi)
angle -= MathHelper.TwoPi;
return angle;
}
public static float GetShortestAngle(float from, float to)
{
// Ensure that 0 <= angle < 2pi for both "from" and "to"
from = WrapAngleTwoPi(from);
to = WrapAngleTwoPi(to);
if (Math.Abs(from - to) < MathHelper.Pi)
{
return to - from;
}
// If we get here we have the more complex case.
// First, increment the lesser value to be greater.
if (from < to)
from += MathHelper.TwoPi;
else
to += MathHelper.TwoPi;
return to - from;
}
/// <summary>
/// solves the angle opposite to side a (parameters: lengths of each side)
/// </summary>
public static float SolveTriangleSSS(float a, float b, float c)
{
float A = (float)Math.Acos((b * b + c * c - a * a) / (2 * b * c));
if (float.IsNaN(A)) A = 1.0f;
return A;
}
public static byte AngleToByte(float angle)
{
angle = WrapAngleTwoPi(angle);
angle = angle * (255.0f / MathHelper.TwoPi);
return Convert.ToByte(angle);
}
public static float ByteToAngle(byte b)
{
float angle = (float)b;
angle = angle * (MathHelper.TwoPi / 255.0f);
return angle;
}
/// <summary>
/// check whether line from a to b is intersecting with line from c to b
/// </summary>
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);
}
public static bool CircleIntersectsRectangle(Vector2 circlePos, float radius, Rectangle rect)
{
Vector2 circleDistance = new Vector2(Math.Abs(circlePos.X - rect.Center.X), Math.Abs(circlePos.Y -rect.Center.Y));
if (circleDistance.X > (rect.Width / 2 + radius)) { return false; }
if (circleDistance.Y > (rect.Height / 2 + radius)) { return false; }
if (circleDistance.X <= (rect.Width / 2)) { return true; }
if (circleDistance.Y <= (rect.Height / 2)) { return true; }
float distSqX = circleDistance.X - rect.Width / 2;
float distSqY = circleDistance.Y - rect.Height / 2;
float cornerDistanceSq = distSqX * distSqX + distSqY * distSqY;
return (cornerDistanceSq <= (radius * radius));
}
/// <summary>
/// divide a convex hull into triangles
/// </summary>
/// <returns>List of triangle vertices (sorted counter-clockwise)</returns>
public static List<Vector2[]> TriangulateConvexHull(List<Vector2> vertices, Vector2 center)
{
List<Vector2[]> triangles = new List<Vector2[]>();
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<Vector2>
{
private Vector2 center;
public CompareCCW(Vector2 center)
{
this.center = center;
}
public int Compare(Vector2 a, Vector2 b)
{
if (a.X - center.X >= 0 && b.X - center.X < 0) return -1;
if (a.X - center.X < 0 && b.X - center.X >= 0) return 1;
if (a.X - center.X == 0 && b.X - center.X == 0)
{
if (a.Y - center.Y >= 0 || b.Y - center.Y >= 0) return Math.Sign(b.Y - a.Y);
return Math.Sign(a.Y - b.Y);
}
// compute the cross product of vectors (center -> a) x (center -> b)
float det = (a.X - center.X) * (b.Y - center.Y) - (b.X - center.X) * (a.Y - center.Y);
if (det < 0) return -1;
if (det > 0) return 1;
// points a and b are on the same line from the center
// check which point is closer to the center
float d1 = (a.X - center.X) * (a.X - center.X) + (a.Y - center.Y) * (a.Y - center.Y);
float d2 = (b.X - center.X) * (b.X - center.X) + (b.Y - center.Y) * (b.Y - center.Y);
return Math.Sign(d2 - d1);
}
}
}
+46
View File
@@ -0,0 +1,46 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Subsurface
{
static class Rand
{
private static Random localRandom = new Random();
private static Random syncedRandom = new Random();
public static void SetSyncedSeed(int seed)
{
syncedRandom = new Random(seed);
}
public static float Range(float minimum, float maximum, bool local = true)
{
return (float)(local ? localRandom : syncedRandom).NextDouble() * (maximum - minimum) + minimum;
}
public static int Range(int minimum, int maximum, bool local = true)
{
return (local ? localRandom : syncedRandom).Next(maximum - minimum) + minimum;
}
public static int Int(int max = int.MaxValue, bool local = true)
{
return (local ? localRandom : syncedRandom).Next(max);
}
public static Vector2 Vector(float length = 1.0f, bool local = true)
{
Vector2 randomVector = new Vector2(Range(-1.0f, 1.0f, local), Range(-1.0f, 1.0f, local));
if (randomVector == Vector2.Zero) return new Vector2(0.0f, length);
return Vector2.Normalize(randomVector) * length;
}
}
}
+272
View File
@@ -0,0 +1,272 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Subsurface
{
class SaveUtil
{
private const string SaveFolder = "Content/Data/Saves/";
public delegate void ProgressDelegate(string sMessage);
public static void SaveGame(string fileName)
{
fileName = SaveFolder + fileName;
string tempPath = SaveFolder + "\\temp";
if (Directory.Exists(tempPath))
{
Directory.Delete(tempPath, true);
}
Directory.CreateDirectory(tempPath);
//Directory.CreateDirectory(Path.GetDirectoryName(filePath) + "\\temp");
try
{
if (Submarine.Loaded!=null)
{
Submarine.Loaded.SaveAs(tempPath + "\\map.gz");
}
else
{
File.Copy(Game1.GameSession.Submarine.FilePath, tempPath + "\\map.gz");
}
}
catch (Exception e)
{
DebugConsole.ThrowError("Error saving submarine", e);
}
try
{
Game1.GameSession.Save(tempPath + "\\gamesession.xml");
}
catch (Exception e)
{
DebugConsole.ThrowError("Error saving gamesession", e);
}
//Game1.GameSession.crewManager.Save(directory+"\\crew.xml");
CompressDirectory(tempPath, fileName+".save", null);
//Directory.Delete(tempPath, true);
}
public static void LoadGame(string fileName)
{
string filePath = SaveFolder + fileName+".save";
string tempPath = SaveFolder + "\\temp";
DecompressToDirectory(filePath, tempPath, null);
Submarine selectedMap = Submarine.Load(tempPath +"\\map.gz");
Game1.GameSession = new GameSession(selectedMap, fileName, tempPath + "\\gamesession.xml");
//Directory.Delete(tempPath, true);
}
public static XDocument LoadGameSessionDoc(string fileName)
{
string filePath = SaveFolder + fileName + ".save";
string tempPath = SaveFolder + "\\temp";
DecompressToDirectory(filePath, tempPath, null);
return ToolBox.TryLoadXml(tempPath + "\\gamesession.xml");
}
public static void DeleteSave(string fileName)
{
fileName = SaveFolder + fileName + ".save";
try
{
File.Delete(fileName);
}
catch (Exception e)
{
DebugConsole.ThrowError("ERROR: deleting save file ''"+fileName+" failed.", e);
}
}
public static string[] GetSaveFiles()
{
if (!Directory.Exists(SaveFolder))
{
DebugConsole.ThrowError("Save folder ''" + SaveFolder + " not found! Attempting to create a new folder");
try
{
Directory.CreateDirectory(SaveFolder);
}
catch (Exception e)
{
DebugConsole.ThrowError("Failed to create the folder ''" + SaveFolder + "''!", e);
}
}
string[] files = Directory.GetFiles(SaveFolder, "*.save");
for (int i = 0; i < files.Length; i++)
{
files[i] = Path.GetFileNameWithoutExtension(files[i]);
}
return files;
}
public static string CreateSavePath(string fileName="save")
{
if (!Directory.Exists(SaveFolder))
{
DebugConsole.ThrowError("Save folder ''"+SaveFolder+"'' not found. Created new folder");
Directory.CreateDirectory(SaveFolder);
}
string extension = ".save";
int i = 0;
while (File.Exists(SaveFolder + fileName + i + extension))
{
i++;
}
return fileName + i;
}
public static void CompressStringToFile(string fileName, string value)
{
// A.
// Write string to temporary file.
string temp = Path.GetTempFileName();
File.WriteAllText(temp, value);
// B.
// Read file into byte array buffer.
byte[] b;
using (FileStream f = new FileStream(temp, FileMode.Open))
{
b = new byte[f.Length];
f.Read(b, 0, (int)f.Length);
}
// C.
// Use GZipStream to write compressed bytes to target file.
using (FileStream f2 = new FileStream(fileName, FileMode.Create))
using (GZipStream gz = new GZipStream(f2, CompressionMode.Compress, false))
{
gz.Write(b, 0, b.Length);
}
}
public static Stream DecompressFiletoStream(string fileName)
{
if (!File.Exists(fileName))
{
DebugConsole.ThrowError("File ''"+fileName+" doesn't exist!");
return null;
}
using (FileStream originalFileStream = new FileStream(fileName, FileMode.Open))
{
MemoryStream decompressedFileStream = new MemoryStream();
using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
{
decompressionStream.CopyTo(decompressedFileStream);
return decompressedFileStream;
}
}
}
public static void CompressFile(string sDir, string sRelativePath, GZipStream zipStream)
{
//Compress file name
char[] chars = sRelativePath.ToCharArray();
zipStream.Write(BitConverter.GetBytes(chars.Length), 0, sizeof(int));
foreach (char c in chars)
zipStream.Write(BitConverter.GetBytes(c), 0, sizeof(char));
//Compress file content
byte[] bytes = File.ReadAllBytes(Path.Combine(sDir, sRelativePath));
zipStream.Write(BitConverter.GetBytes(bytes.Length), 0, sizeof(int));
zipStream.Write(bytes, 0, bytes.Length);
}
public static bool DecompressFile(string sDir, GZipStream zipStream, ProgressDelegate progress)
{
//Decompress file name
byte[] bytes = new byte[sizeof(int)];
int Readed = zipStream.Read(bytes, 0, sizeof(int));
if (Readed < sizeof(int))
return false;
int iNameLen = BitConverter.ToInt32(bytes, 0);
bytes = new byte[sizeof(char)];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < iNameLen; i++)
{
zipStream.Read(bytes, 0, sizeof(char));
char c = BitConverter.ToChar(bytes, 0);
sb.Append(c);
}
string sFileName = sb.ToString();
if (progress != null)
progress(sFileName);
//Decompress file content
bytes = new byte[sizeof(int)];
zipStream.Read(bytes, 0, sizeof(int));
int iFileLen = BitConverter.ToInt32(bytes, 0);
bytes = new byte[iFileLen];
zipStream.Read(bytes, 0, bytes.Length);
string sFilePath = Path.Combine(sDir, sFileName);
string sFinalDir = Path.GetDirectoryName(sFilePath);
if (!Directory.Exists(sFinalDir))
Directory.CreateDirectory(sFinalDir);
using (FileStream outFile = new FileStream(sFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
outFile.Write(bytes, 0, iFileLen);
return true;
}
public static void CompressDirectory(string sInDir, string sOutFile, ProgressDelegate progress)
{
string[] sFiles = Directory.GetFiles(sInDir, "*.*", SearchOption.AllDirectories);
int iDirLen = sInDir[sInDir.Length - 1] == Path.DirectorySeparatorChar ? sInDir.Length : sInDir.Length + 1;
using (FileStream outFile = new FileStream(sOutFile, FileMode.Create, FileAccess.Write, FileShare.None))
using (GZipStream str = new GZipStream(outFile, CompressionMode.Compress))
foreach (string sFilePath in sFiles)
{
string sRelativePath = sFilePath.Substring(iDirLen);
if (progress != null)
progress(sRelativePath);
CompressFile(sInDir, sRelativePath, str);
}
}
public static void DecompressToDirectory(string sCompressedFile, string sDir, ProgressDelegate progress)
{
using (FileStream inFile = new FileStream(sCompressedFile, FileMode.Open, FileAccess.Read, FileShare.None))
using (GZipStream zipStream = new GZipStream(inFile, CompressionMode.Decompress, true))
while (DecompressFile(sDir, zipStream, progress)) ;
}
}
}
+125
View File
@@ -0,0 +1,125 @@
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using Microsoft.Xna.Framework.Graphics;
using Color = Microsoft.Xna.Framework.Color;
using System;
namespace Subsurface
{
/// <summary>
/// Based on http://jakepoz.com/jake_poznanski__background_load_xna.html
/// </summary>
public class TextureLoader
{
static TextureLoader()
{
BlendColorBlendState = new BlendState
{
ColorDestinationBlend = Blend.Zero,
ColorWriteChannels = ColorWriteChannels.Red | ColorWriteChannels.Green | ColorWriteChannels.Blue,
AlphaDestinationBlend = Blend.Zero,
AlphaSourceBlend = Blend.SourceAlpha,
ColorSourceBlend = Blend.SourceAlpha
};
BlendAlphaBlendState = new BlendState
{
ColorWriteChannels = ColorWriteChannels.Alpha,
AlphaDestinationBlend = Blend.Zero,
ColorDestinationBlend = Blend.Zero,
AlphaSourceBlend = Blend.One,
ColorSourceBlend = Blend.One
};
}
public TextureLoader(GraphicsDevice graphicsDevice, bool needsBmp = false)
{
_graphicsDevice = graphicsDevice;
_needsBmp = needsBmp;
_spriteBatch = new SpriteBatch(_graphicsDevice);
}
public Texture2D FromFile(string path, bool preMultiplyAlpha = true)
{
try
{
using (Stream fileStream = File.OpenRead(path))
return FromStream(fileStream, preMultiplyAlpha);
}
catch (Exception e)
{
DebugConsole.ThrowError("Loading texture ''"+path+"'' failed!", e);
return null;
}
}
public Texture2D FromStream(Stream stream, bool preMultiplyAlpha = true)
{
Texture2D texture;
if (_needsBmp)
{
// Load image using GDI because Texture2D.FromStream doesn't support BMP
using (Image image = Image.FromStream(stream))
{
// Now create a MemoryStream which will be passed to Texture2D after converting to PNG internally
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png);
ms.Seek(0, SeekOrigin.Begin);
texture = Texture2D.FromStream(_graphicsDevice, ms);
}
}
}
else
{
texture = Texture2D.FromStream(_graphicsDevice, stream);
}
if (preMultiplyAlpha)
{
// Setup a render target to hold our final texture which will have premulitplied alpha values
using (RenderTarget2D renderTarget = new RenderTarget2D(_graphicsDevice, texture.Width, texture.Height))
{
Viewport viewportBackup = _graphicsDevice.Viewport;
_graphicsDevice.SetRenderTarget(renderTarget);
_graphicsDevice.Clear(Color.Black);
// Multiply each color by the source alpha, and write in just the color values into the final texture
_spriteBatch.Begin(SpriteSortMode.Immediate, BlendColorBlendState);
_spriteBatch.Draw(texture, texture.Bounds, Color.White);
_spriteBatch.End();
// Now copy over the alpha values from the source texture to the final one, without multiplying them
_spriteBatch.Begin(SpriteSortMode.Immediate, BlendAlphaBlendState);
_spriteBatch.Draw(texture, texture.Bounds, Color.White);
_spriteBatch.End();
// Release the GPU back to drawing to the screen
_graphicsDevice.SetRenderTarget(null);
_graphicsDevice.Viewport = viewportBackup;
// Store data from render target because the RenderTarget2D is volatile
Color[] data = new Color[texture.Width * texture.Height];
renderTarget.GetData(data);
// Unset texture from graphic device and set modified data back to it
_graphicsDevice.Textures[0] = null;
texture.SetData(data);
}
}
return texture;
}
private static readonly BlendState BlendColorBlendState;
private static readonly BlendState BlendAlphaBlendState;
private readonly GraphicsDevice _graphicsDevice;
private readonly SpriteBatch _spriteBatch;
private readonly bool _needsBmp;
}
}
+373
View File
@@ -0,0 +1,373 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Subsurface
{
static class ToolBox
{
public static XDocument TryLoadXml(string filePath)
{
XDocument doc;
try
{
doc = XDocument.Load(filePath);
}
catch (Exception e)
{
DebugConsole.ThrowError("Couldn't load xml document ''"+filePath+"''!", e);
return null;
}
if (doc.Root == null) return null;
return doc;
}
public static SpriteFont TryLoadFont(string file, Microsoft.Xna.Framework.Content.ContentManager contentManager)
{
SpriteFont font = null;
try
{
font = contentManager.Load<SpriteFont>(file);
}
catch
{
DebugConsole.ThrowError("Loading font ''"+file+"'' failed");
}
return font;
}
public static object GetAttributeObject(XElement element, string name)
{
if (element.Attribute(name) == null) return null;
return GetAttributeObject(element.Attribute(name));
}
public static object GetAttributeObject(XAttribute attribute)
{
if (attribute == null) return null;
return ParseToObject(attribute.Value.ToString());
}
public static object ParseToObject(string value)
{
float floatVal;
int intVal;
if (value.ToString().Contains(".") && float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out floatVal))
{
return floatVal;
}
else if (int.TryParse(value, out intVal))
{
return intVal;
}
else
{
string lowerTrimmedVal = value.ToLower().Trim();
if (lowerTrimmedVal == "true")
{
return true;
}
else if (lowerTrimmedVal == "false")
{
return false;
}
else
{
return value;
}
}
}
public static string GetAttributeString(XElement element, string name, string defaultValue)
{
if (element.Attribute(name) == null) return defaultValue;
return GetAttributeString(element.Attribute(name), defaultValue);
}
public static string GetAttributeString(XAttribute attribute, string defaultValue)
{
string value = attribute.Value;
if (String.IsNullOrEmpty(value)) return defaultValue;
return value;
}
public static float GetAttributeFloat(XElement element, string name, float defaultValue)
{
if (element.Attribute(name) == null) return defaultValue;
float val = defaultValue;
try
{
if (!float.TryParse(element.Attribute(name).Value, NumberStyles.Float, CultureInfo.InvariantCulture, out val))
{
return defaultValue;
}
}
catch (Exception e)
{
DebugConsole.ThrowError("Error in "+element+"!", e);
}
return val;
}
public static float GetAttributeFloat(XAttribute attribute, float defaultValue)
{
if (attribute == null) return defaultValue;
float val = defaultValue;
try
{
val = float.Parse(attribute.Value, CultureInfo.InvariantCulture);
}
catch (Exception e)
{
DebugConsole.ThrowError("Error in " + attribute + "! ", e);
}
return val;
}
public static int GetAttributeInt(XElement element, string name, int defaultValue)
{
if (element.Attribute(name) == null) return defaultValue;
int val = defaultValue;
try
{
val = int.Parse(element.Attribute(name).Value);
}
catch (Exception e)
{
DebugConsole.ThrowError("Error in " + element + "! ", e);
}
return val;
}
public static bool GetAttributeBool(XElement element, string name, bool defaultValue)
{
if (element.Attribute(name) == null) return defaultValue;
string val = element.Attribute(name).Value.ToLower().Trim();
if (val == "true")
{
return true;
}
else if (val == "false")
{
return false;
}
else
{
DebugConsole.ThrowError("Error in " + element + "! ''" + val + "'' is not a valid boolean value");
return false;
}
}
public static Vector2 GetAttributeVector2(XElement element, string name, Vector2 defaultValue)
{
if (element.Attribute(name) == null) return defaultValue;
string val = element.Attribute(name).Value;
return ParseToVector2(val);
}
public static Vector4 GetAttributeVector4(XElement element, string name, Vector4 defaultValue)
{
if (element.Attribute(name) == null) return defaultValue;
string val = element.Attribute(name).Value;
return ParseToVector4(val);
}
public static Vector2 ParseToVector2(string stringVector2, bool errorMessages = true)
{
string[] components = stringVector2.Split(',');
Vector2 vector = Vector2.Zero;
if (components.Length!=2)
{
if (!errorMessages) return vector;
DebugConsole.ThrowError("Failed to parse the string ''"+stringVector2+"'' to Vector2");
return vector;
}
float.TryParse(components[0], NumberStyles.Any, CultureInfo.InvariantCulture, out vector.X);
float.TryParse(components[1], NumberStyles.Any, CultureInfo.InvariantCulture, out vector.Y);
return vector;
}
public static string Vector2ToString(Vector2 vector)
{
return vector.X.ToString("G", CultureInfo.InvariantCulture) + "," + vector.Y.ToString("G", CultureInfo.InvariantCulture);
}
public static Vector4 ParseToVector4(string stringVector4)
{
string[] components = stringVector4.Split(',');
Vector4 vector = Vector4.Zero;
if (components.Length < 3)
{
DebugConsole.ThrowError("Failed to parse the string ''" + stringVector4 + "'' to Vector4");
return vector;
}
float.TryParse(components[0], NumberStyles.Float, CultureInfo.InvariantCulture, out vector.X);
float.TryParse(components[1], NumberStyles.Float, CultureInfo.InvariantCulture, out vector.Y);
float.TryParse(components[2], NumberStyles.Float, CultureInfo.InvariantCulture, out vector.Z);
if (components.Length>3)
float.TryParse(components[3], NumberStyles.Float, CultureInfo.InvariantCulture, out vector.W);
return vector;
}
public static string Vector4ToString(Vector4 vector)
{
return vector.X.ToString("G", CultureInfo.InvariantCulture) + "," +
vector.Y.ToString("G", CultureInfo.InvariantCulture) + "," +
vector.Z.ToString("G", CultureInfo.InvariantCulture) + "," +
vector.W.ToString("G", CultureInfo.InvariantCulture);
}
public static float[] ParseArrayToFloat(string[] stringArray)
{
if (stringArray == null || stringArray.Length == 0) return null;
float[] floatArray = new float[stringArray.Length];
for (int i = 0; i<floatArray.Length; i++)
{
floatArray[i]=0.0f;
float.TryParse(stringArray[i], NumberStyles.Float, CultureInfo.InvariantCulture, out floatArray[i]);
}
return floatArray;
}
public static string RandomSeed(int length)
{
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
return new string(
Enumerable.Repeat(chars, length)
.Select(s => s[Rand.Int(s.Length)])
.ToArray());
}
public static string WrapText(string text, float lineLength, SpriteFont font)
{
if (font.MeasureString(text).X < lineLength) return text;
string[] words = text.Split(' ', '\n');
StringBuilder wrappedText = new StringBuilder();
float linePos = 0f;
float spaceWidth = font.MeasureString(" ").X;
for (int i = 0; i < words.Length; ++i)
{
if (string.IsNullOrWhiteSpace(words[i])) continue;
Vector2 size;
string tempWord = words[i];
string prevWord = words[i];
while ((size = font.MeasureString(tempWord)).X > lineLength)
{
tempWord = tempWord.Remove(tempWord.Length - 1, 1);
}
words[i] = tempWord;
if (prevWord.Length> tempWord.Length)
{
wrappedText.Append(words[i]);
wrappedText.Append(" \n");
wrappedText.Append(prevWord.Remove(0, tempWord.Length));
linePos = lineLength*2.0f;
continue;
}
if (linePos + size.X < lineLength)
{
wrappedText.Append(words[i]);
linePos += size.X + spaceWidth;
}
else
{
//if (i>0)wrappedText.Remove(wrappedText.Length - 1, 1);
wrappedText.Append("\n");
wrappedText.Append(words[i]);
linePos = size.X + spaceWidth;
}
if (i<words.Length-1) wrappedText.Append(" ");
}
return wrappedText.ToString();
}
public static string GetRandomLine(string filePath)
{
try
{
string randomLine = "";
StreamReader file = new StreamReader(filePath);
var lines = File.ReadLines(filePath).ToList();
int lineCount = lines.Count();
if (lineCount == 0)
{
DebugConsole.ThrowError("File ''" + filePath + "'' is empty!");
file.Close();
return "";
}
int lineNumber = Rand.Int(lineCount, false);
int i = 0;
foreach (string line in lines)
{
if (i == lineNumber)
{
randomLine = line;
break;
}
i++;
}
file.Close();
return randomLine;
}
catch (Exception e)
{
DebugConsole.ThrowError("Couldn't open file ''" + filePath + "''!", e);
return "";
}
}
}
}