Functional level generation + moving the submarine
This commit is contained in:
@@ -162,6 +162,8 @@ namespace Subsurface
|
|||||||
if (Keyboard.GetState().IsKeyDown(Keys.Right)) moveCam.X += moveSpeed;
|
if (Keyboard.GetState().IsKeyDown(Keys.Right)) moveCam.X += moveSpeed;
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.Down)) moveCam.Y -= moveSpeed;
|
if (Keyboard.GetState().IsKeyDown(Keys.Down)) moveCam.Y -= moveSpeed;
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.Up)) moveCam.Y += moveSpeed;
|
if (Keyboard.GetState().IsKeyDown(Keys.Up)) moveCam.Y += moveSpeed;
|
||||||
|
|
||||||
|
Zoom = MathHelper.Clamp(Zoom + PlayerInput.ScrollWheelSpeed / 1000.0f, 0.1f, 2.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -219,9 +219,9 @@ namespace Subsurface
|
|||||||
//check if there's a wall between the target and the character
|
//check if there's a wall between the target and the character
|
||||||
Vector2 rayStart = character.animController.limbs[0].SimPosition;
|
Vector2 rayStart = character.animController.limbs[0].SimPosition;
|
||||||
Vector2 rayEnd = selectedTarget.Position;
|
Vector2 rayEnd = selectedTarget.Position;
|
||||||
Body closestBody = Map.CheckVisibility(rayStart, rayEnd);
|
Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd);
|
||||||
|
|
||||||
if (Map.LastPickedFraction == 1.0f || closestBody == null)
|
if (Submarine.LastPickedFraction == 1.0f || closestBody == null)
|
||||||
{
|
{
|
||||||
wallAttackPos = Vector2.Zero;
|
wallAttackPos = Vector2.Zero;
|
||||||
return;
|
return;
|
||||||
@@ -230,11 +230,11 @@ namespace Subsurface
|
|||||||
Structure wall = closestBody.UserData as Structure;
|
Structure wall = closestBody.UserData as Structure;
|
||||||
if (wall == null)
|
if (wall == null)
|
||||||
{
|
{
|
||||||
wallAttackPos = Map.LastPickedPosition;
|
wallAttackPos = Submarine.LastPickedPosition;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int sectionIndex = wall.FindSectionIndex(ConvertUnits.ToDisplayUnits(Map.LastPickedPosition));
|
int sectionIndex = wall.FindSectionIndex(ConvertUnits.ToDisplayUnits(Submarine.LastPickedPosition));
|
||||||
|
|
||||||
float sectionDamage = wall.SectionDamage(sectionIndex);
|
float sectionDamage = wall.SectionDamage(sectionIndex);
|
||||||
for (int i = sectionIndex - 2; i <= sectionIndex + 2; i++)
|
for (int i = sectionIndex - 2; i <= sectionIndex + 2; i++)
|
||||||
@@ -377,7 +377,7 @@ namespace Subsurface
|
|||||||
Vector2 rayStart = character.animController.limbs[0].SimPosition;
|
Vector2 rayStart = character.animController.limbs[0].SimPosition;
|
||||||
Vector2 rayEnd = target.Position;
|
Vector2 rayEnd = target.Position;
|
||||||
|
|
||||||
Body closestBody = Map.CheckVisibility(rayStart, rayEnd);
|
Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd);
|
||||||
Structure closestStructure = (closestBody == null) ? null : closestBody.UserData as Structure;
|
Structure closestStructure = (closestBody == null) ? null : closestBody.UserData as Structure;
|
||||||
|
|
||||||
//if (targetCharacter != null)
|
//if (targetCharacter != null)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
this.host = host;
|
this.host = host;
|
||||||
|
|
||||||
wanderAngle = ToolBox.RandomFloat(0.0f, MathHelper.TwoPi);
|
wanderAngle = ToolBox.RandomFloatLocal(0.0f, MathHelper.TwoPi);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SteeringSeek(Vector2 target, float speed = 1.0f)
|
public void SteeringSeek(Vector2 target, float speed = 1.0f)
|
||||||
@@ -90,7 +90,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
float angleChange = 1.5f;
|
float angleChange = 1.5f;
|
||||||
|
|
||||||
wanderAngle += ToolBox.RandomFloat(0.0f, 1.0f) * angleChange - angleChange * 0.5f;
|
wanderAngle += ToolBox.RandomFloatLocal(0.0f, 1.0f) * angleChange - angleChange * 0.5f;
|
||||||
|
|
||||||
Vector2 newSteering = circleCenter + displacement;
|
Vector2 newSteering = circleCenter + displacement;
|
||||||
float steeringSpeed = (newSteering + host.Steering).Length();
|
float steeringSpeed = (newSteering + host.Steering).Length();
|
||||||
@@ -113,7 +113,7 @@ namespace Subsurface
|
|||||||
if (rayCastTimer <= 0.0f)
|
if (rayCastTimer <= 0.0f)
|
||||||
{
|
{
|
||||||
rayCastTimer = RayCastInterval;
|
rayCastTimer = RayCastInterval;
|
||||||
Body closestBody = Map.CheckVisibility(host.Position, ahead);
|
Body closestBody = Submarine.CheckVisibility(host.Position, ahead);
|
||||||
if (closestBody == null)
|
if (closestBody == null)
|
||||||
{
|
{
|
||||||
avoidSteering = Vector2.Zero;
|
avoidSteering = Vector2.Zero;
|
||||||
@@ -124,7 +124,7 @@ namespace Subsurface
|
|||||||
Structure closestStructure = closestBody.UserData as Structure;
|
Structure closestStructure = closestBody.UserData as Structure;
|
||||||
if (closestStructure!=null)
|
if (closestStructure!=null)
|
||||||
{
|
{
|
||||||
Vector2 obstaclePosition = Map.LastPickedPosition;
|
Vector2 obstaclePosition = Submarine.LastPickedPosition;
|
||||||
if (closestStructure.IsHorizontal)
|
if (closestStructure.IsHorizontal)
|
||||||
{
|
{
|
||||||
obstaclePosition.Y = closestStructure.SimPosition.Y;
|
obstaclePosition.Y = closestStructure.SimPosition.Y;
|
||||||
@@ -134,7 +134,7 @@ namespace Subsurface
|
|||||||
obstaclePosition.X = closestStructure.SimPosition.X;
|
obstaclePosition.X = closestStructure.SimPosition.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
avoidSteering = Vector2.Normalize(Map.LastPickedPosition - obstaclePosition);
|
avoidSteering = Vector2.Normalize(Submarine.LastPickedPosition - obstaclePosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -769,13 +769,13 @@ namespace Subsurface
|
|||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
Particle p = Game1.particleManager.CreateParticle("waterblood",
|
Particle p = Game1.particleManager.CreateParticle("waterblood",
|
||||||
torso.SimPosition + new Vector2(ToolBox.RandomFloat(-0.5f, 0.5f), ToolBox.RandomFloat(-0.5f, 0.5f)),
|
torso.SimPosition + new Vector2(ToolBox.RandomFloatLocal(-0.5f, 0.5f), ToolBox.RandomFloatLocal(-0.5f, 0.5f)),
|
||||||
Vector2.Zero);
|
Vector2.Zero);
|
||||||
if (p!=null) p.Size *= 2.0f;
|
if (p!=null) p.Size *= 2.0f;
|
||||||
|
|
||||||
Game1.particleManager.CreateParticle("bubbles",
|
Game1.particleManager.CreateParticle("bubbles",
|
||||||
torso.SimPosition,
|
torso.SimPosition,
|
||||||
new Vector2(ToolBox.RandomFloat(-0.5f, 0.5f), ToolBox.RandomFloat(-1.0f,0.5f)));
|
new Vector2(ToolBox.RandomFloatLocal(-0.5f, 0.5f), ToolBox.RandomFloatLocal(-1.0f,0.5f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var joint in animController.limbJoints)
|
foreach (var joint in animController.limbJoints)
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
Game1.particleManager.CreateParticle("blood",
|
Game1.particleManager.CreateParticle("blood",
|
||||||
SimPosition,
|
SimPosition,
|
||||||
particleVel * ToolBox.RandomFloat(1.0f, 3.0f));
|
particleVel * ToolBox.RandomFloatLocal(1.0f, 3.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < bloodAmount / 2; i++)
|
for (int i = 0; i < bloodAmount / 2; i++)
|
||||||
|
|||||||
@@ -462,7 +462,7 @@ namespace Subsurface
|
|||||||
//limb isn't in any room -> it's in the water
|
//limb isn't in any room -> it's in the water
|
||||||
limb.inWater = true;
|
limb.inWater = true;
|
||||||
}
|
}
|
||||||
else if (limbHull.Volume>0.0f && Map.RectContains(limbHull.Rect, limbPosition))
|
else if (limbHull.Volume>0.0f && Submarine.RectContains(limbHull.Rect, limbPosition))
|
||||||
{
|
{
|
||||||
|
|
||||||
if (limbPosition.Y < limbHull.Surface)
|
if (limbPosition.Y < limbHull.Surface)
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
<sprite texture="DivingSuit.png" limb="RightArm" sourcerect="0,0,18,40" origin="0.5,0.4" depth="0.005"/>
|
<sprite texture="DivingSuit.png" limb="RightArm" sourcerect="0,0,18,40" origin="0.5,0.4" depth="0.005"/>
|
||||||
<sprite texture="DivingSuit.png" limb="LeftArm" sourcerect="0,0,18,40" origin="0.5,0.4" depth="0.005"/>
|
<sprite texture="DivingSuit.png" limb="LeftArm" sourcerect="0,0,18,40" origin="0.5,0.4" depth="0.005"/>
|
||||||
|
|
||||||
<StatusEffect type="OnWearing" target="Contained,Character" targetnames="Oxygen Tank" Condition="-0.7" Oxygen="20.0"/>
|
<StatusEffect type="OnWearing" target="Contained,Character" targetnames="Oxygen Tank,human" Condition="-0.7" Oxygen="20.0"/>
|
||||||
<StatusEffect type="OnWearing" target="Character" PressureProtection="100.0"/>
|
<StatusEffect type="OnWearing" target="Character" PressureProtection="100.0"/>
|
||||||
</Wearable>
|
</Wearable>
|
||||||
|
|
||||||
|
|||||||
@@ -197,6 +197,10 @@ namespace Subsurface
|
|||||||
case "editchar":
|
case "editchar":
|
||||||
Game1.EditCharacterScreen.Select();
|
Game1.EditCharacterScreen.Select();
|
||||||
break;
|
break;
|
||||||
|
case "freecamera":
|
||||||
|
Character.Controlled = null;
|
||||||
|
Game1.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||||
|
break;
|
||||||
case "editwater":
|
case "editwater":
|
||||||
case "water":
|
case "water":
|
||||||
if (Game1.Client== null)
|
if (Game1.Client== null)
|
||||||
@@ -205,7 +209,8 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "generatelevel":
|
case "generatelevel":
|
||||||
Game1.Level = new Level(Game1.localRandom.Next(), 20, 500, 500);
|
Game1.Level = new Level(100, 500,500, 50);
|
||||||
|
Game1.Level.Generate(100.0f);
|
||||||
break;
|
break;
|
||||||
case "fowenabled":
|
case "fowenabled":
|
||||||
case "fow":
|
case "fow":
|
||||||
@@ -218,12 +223,12 @@ namespace Subsurface
|
|||||||
break;
|
break;
|
||||||
case "savemap":
|
case "savemap":
|
||||||
if (commands.Length < 2) break;
|
if (commands.Length < 2) break;
|
||||||
Map.SaveCurrent("Content/SavedMaps/" + commands[1]);
|
Submarine.SaveCurrent("Content/SavedMaps/" + commands[1]);
|
||||||
NewMessage("map saved", Color.Green);
|
NewMessage("map saved", Color.Green);
|
||||||
break;
|
break;
|
||||||
case "loadmap":
|
case "loadmap":
|
||||||
if (commands.Length < 2) break;
|
if (commands.Length < 2) break;
|
||||||
Map.Load("Content/SavedMaps/" + commands[1]);
|
Submarine.Load("Content/SavedMaps/" + commands[1]);
|
||||||
break;
|
break;
|
||||||
case "savegame":
|
case "savegame":
|
||||||
SaveUtil.SaveGame(SaveUtil.SaveFolder+"save");
|
SaveUtil.SaveGame(SaveUtil.SaveFolder+"save");
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ namespace Subsurface
|
|||||||
for (int i = 0; i < amount; i++)
|
for (int i = 0; i < amount; i++)
|
||||||
{
|
{
|
||||||
Vector2 position = (randomWayPoint == null) ? Vector2.Zero : randomWayPoint.SimPosition;
|
Vector2 position = (randomWayPoint == null) ? Vector2.Zero : randomWayPoint.SimPosition;
|
||||||
position.X += ToolBox.RandomFloat(-0.5f,0.5f);
|
position.X += ToolBox.RandomFloatLocal(-0.5f,0.5f);
|
||||||
position.Y += ToolBox.RandomFloat(-0.5f,0.5f);
|
position.Y += ToolBox.RandomFloatLocal(-0.5f,0.5f);
|
||||||
monsters[i] = new Character(characterFile, position);
|
monsters[i] = new Character(characterFile, position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-9
@@ -7,7 +7,13 @@ using Microsoft.Xna.Framework.Input;
|
|||||||
namespace Subsurface
|
namespace Subsurface
|
||||||
{
|
{
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum Alignment { CenterX = 1, Left = 2, Right = 4, CenterY = 8, Top = 16, Bottom = 32 }
|
public enum Alignment
|
||||||
|
{
|
||||||
|
CenterX = 1, Left = 2, Right = 4, CenterY = 8, Top = 16, Bottom = 32 ,
|
||||||
|
TopRight = (Top | Right), TopLeft = (Top | Left), TopCenter = (CenterX | Top),
|
||||||
|
Center = (CenterX | CenterY),
|
||||||
|
BottomRight = (Bottom | Right), BottomLeft = (Bottom | Left), BottomCenter = (CenterX | Bottom)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class GUIMessage
|
class GUIMessage
|
||||||
@@ -258,15 +264,15 @@ namespace Subsurface
|
|||||||
|
|
||||||
public static void Draw(float deltaTime, SpriteBatch spriteBatch, Camera cam)
|
public static void Draw(float deltaTime, SpriteBatch spriteBatch, Camera cam)
|
||||||
{
|
{
|
||||||
//spriteBatch.DrawString(font,
|
spriteBatch.DrawString(font,
|
||||||
// "FPS: " + (int)Game1.frameCounter.AverageFramesPerSecond
|
"FPS: " + (int)Game1.frameCounter.AverageFramesPerSecond
|
||||||
// + " - render: "+Game1.renderTimeElapsed,
|
+ " - render: " + Game1.renderTimeElapsed,
|
||||||
// new Vector2(10, 10), Color.White);
|
new Vector2(10, 10), Color.White);
|
||||||
|
|
||||||
//spriteBatch.DrawString(font,
|
spriteBatch.DrawString(font,
|
||||||
// "Physics: " + Game1.world.UpdateTime
|
"Physics: " + Game1.world.UpdateTime
|
||||||
// + " - bodies: " + Game1.world.BodyList.Count,
|
+ " - bodies: " + Game1.world.BodyList.Count,
|
||||||
// new Vector2(10, 30), Color.White);
|
new Vector2(10, 30), Color.White);
|
||||||
|
|
||||||
|
|
||||||
if (Character.Controlled != null && cam!=null) Character.Controlled.DrawHud(spriteBatch, cam);
|
if (Character.Controlled != null && cam!=null) Character.Controlled.DrawHud(spriteBatch, cam);
|
||||||
|
|||||||
+12
-7
@@ -15,10 +15,12 @@ namespace Subsurface
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
class Game1 : Game
|
class Game1 : Game
|
||||||
{
|
{
|
||||||
GraphicsDeviceManager graphics;
|
public static GraphicsDeviceManager graphics;
|
||||||
static int graphicsWidth, graphicsHeight;
|
static int graphicsWidth, graphicsHeight;
|
||||||
static SpriteBatch spriteBatch;
|
static SpriteBatch spriteBatch;
|
||||||
|
|
||||||
|
public static GraphicsDevice CurrGraphicsDevice;
|
||||||
|
|
||||||
public static FrameCounter frameCounter;
|
public static FrameCounter frameCounter;
|
||||||
|
|
||||||
public static readonly Version version = Assembly.GetEntryAssembly().GetName().Version;
|
public static readonly Version version = Assembly.GetEntryAssembly().GetName().Version;
|
||||||
@@ -46,7 +48,7 @@ namespace Subsurface
|
|||||||
public static Random localRandom;
|
public static Random localRandom;
|
||||||
public static Random random;
|
public static Random random;
|
||||||
|
|
||||||
private Stopwatch renderTimer;
|
//private Stopwatch renderTimer;
|
||||||
public static int renderTimeElapsed;
|
public static int renderTimeElapsed;
|
||||||
|
|
||||||
|
|
||||||
@@ -55,6 +57,7 @@ namespace Subsurface
|
|||||||
get { return GameScreen.Cam; }
|
get { return GameScreen.Cam; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static int GraphicsWidth
|
public static int GraphicsWidth
|
||||||
{
|
{
|
||||||
get { return graphicsWidth; }
|
get { return graphicsWidth; }
|
||||||
@@ -82,7 +85,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
frameCounter = new FrameCounter();
|
frameCounter = new FrameCounter();
|
||||||
|
|
||||||
renderTimer = new Stopwatch();
|
//renderTimer = new Stopwatch();
|
||||||
|
|
||||||
IsMouseVisible = true;
|
IsMouseVisible = true;
|
||||||
|
|
||||||
@@ -107,6 +110,8 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
|
CurrGraphicsDevice = GraphicsDevice;
|
||||||
|
|
||||||
particleManager = new ParticleManager("Content/Particles/prefabs.xml", Cam);
|
particleManager = new ParticleManager("Content/Particles/prefabs.xml", Cam);
|
||||||
|
|
||||||
GameMode.Init();
|
GameMode.Init();
|
||||||
@@ -145,7 +150,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
AmbientSoundManager.Init("Content/Sounds/Sounds.xml");
|
AmbientSoundManager.Init("Content/Sounds/Sounds.xml");
|
||||||
|
|
||||||
Map.PreloadMaps("Content/SavedMaps");
|
Submarine.Preload("Content/SavedMaps");
|
||||||
GameScreen = new GameScreen(graphics.GraphicsDevice);
|
GameScreen = new GameScreen(graphics.GraphicsDevice);
|
||||||
MainMenuScreen = new MainMenuScreen(this);
|
MainMenuScreen = new MainMenuScreen(this);
|
||||||
LobbyScreen = new LobbyScreen();
|
LobbyScreen = new LobbyScreen();
|
||||||
@@ -209,7 +214,7 @@ namespace Subsurface
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected override void Draw(GameTime gameTime)
|
protected override void Draw(GameTime gameTime)
|
||||||
{
|
{
|
||||||
renderTimer.Restart();
|
//renderTimer.Restart();
|
||||||
|
|
||||||
double deltaTime = gameTime.ElapsedGameTime.TotalSeconds;
|
double deltaTime = gameTime.ElapsedGameTime.TotalSeconds;
|
||||||
|
|
||||||
@@ -217,8 +222,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
Screen.Selected.Draw(deltaTime, GraphicsDevice, spriteBatch);
|
Screen.Selected.Draw(deltaTime, GraphicsDevice, spriteBatch);
|
||||||
|
|
||||||
renderTimeElapsed = (int)renderTimer.Elapsed.Ticks;
|
//renderTimeElapsed = (int)renderTimer.Elapsed.Ticks;
|
||||||
renderTimer.Stop();
|
//renderTimer.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnExiting(object sender, EventArgs args)
|
protected override void OnExiting(object sender, EventArgs args)
|
||||||
|
|||||||
@@ -27,15 +27,29 @@ namespace Subsurface
|
|||||||
|
|
||||||
private string savePath;
|
private string savePath;
|
||||||
|
|
||||||
private Map selectedMap;
|
private Submarine submarine;
|
||||||
|
|
||||||
public GameSession(Map selectedMap, GameModePreset gameModePreset)
|
private Level level;
|
||||||
:this(selectedMap, gameModePreset.Instantiate())
|
|
||||||
|
public Map map;
|
||||||
|
|
||||||
|
public Level Level
|
||||||
|
{
|
||||||
|
get { return level; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Submarine Submarine
|
||||||
|
{
|
||||||
|
get { return submarine; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameSession(Submarine submarine, GameModePreset gameModePreset)
|
||||||
|
:this(submarine, gameModePreset.Instantiate())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameSession(Map selectedMap, GameMode gameMode = null)
|
public GameSession(Submarine selectedMap, GameMode gameMode = null)
|
||||||
{
|
{
|
||||||
taskManager = new TaskManager(this);
|
taskManager = new TaskManager(this);
|
||||||
|
|
||||||
@@ -43,6 +57,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
guiRoot = new GUIFrame(new Rectangle(0,0,Game1.GraphicsWidth,Game1.GraphicsWidth), Color.Transparent);
|
guiRoot = new GUIFrame(new Rectangle(0,0,Game1.GraphicsWidth,Game1.GraphicsWidth), Color.Transparent);
|
||||||
|
|
||||||
|
map = new Map(Game1.random.Next(), 500);
|
||||||
|
|
||||||
int width = 350, height = 100;
|
int width = 350, height = 100;
|
||||||
if (Game1.Client!=null || Game1.Server!=null)
|
if (Game1.Client!=null || Game1.Server!=null)
|
||||||
{
|
{
|
||||||
@@ -67,7 +83,7 @@ namespace Subsurface
|
|||||||
//startTime = DateTime.Now;
|
//startTime = DateTime.Now;
|
||||||
//endTime = startTime + gameDuration;
|
//endTime = startTime + gameDuration;
|
||||||
|
|
||||||
this.selectedMap = selectedMap;
|
this.submarine = selectedMap;
|
||||||
|
|
||||||
//if (!save) return;
|
//if (!save) return;
|
||||||
|
|
||||||
@@ -75,7 +91,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameSession(Map selectedMap, string savePath, string filePath)
|
public GameSession(Submarine selectedMap, string savePath, string filePath)
|
||||||
: this(selectedMap)
|
: this(selectedMap)
|
||||||
{
|
{
|
||||||
XDocument doc = ToolBox.TryLoadXml(filePath);
|
XDocument doc = ToolBox.TryLoadXml(filePath);
|
||||||
@@ -95,14 +111,31 @@ namespace Subsurface
|
|||||||
this.savePath = savePath;
|
this.savePath = savePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void StartShift(TimeSpan duration, Level level)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (Submarine.Loaded != submarine) submarine.Load();
|
||||||
|
|
||||||
|
level.Generate(submarine==null ? 100.0f : Math.Max(Submarine.Borders.Width, Submarine.Borders.Height));
|
||||||
|
|
||||||
|
this.level = level;
|
||||||
|
|
||||||
|
StartShift(duration, 1);
|
||||||
|
}
|
||||||
|
|
||||||
public void StartShift(TimeSpan duration, int scriptedEventCount = 1)
|
public void StartShift(TimeSpan duration, int scriptedEventCount = 1)
|
||||||
{
|
{
|
||||||
//if (crewManager.characterInfos.Count == 0) return;
|
//if (crewManager.characterInfos.Count == 0) return;
|
||||||
|
|
||||||
if (Map.Loaded!=selectedMap) selectedMap.Load();
|
if (Submarine.Loaded!=submarine) submarine.Load();
|
||||||
|
|
||||||
if (gameMode!=null) gameMode.Start(duration);
|
if (gameMode!=null) gameMode.Start(duration);
|
||||||
|
|
||||||
|
if (level!=null)
|
||||||
|
{
|
||||||
|
submarine.Move(level.StartPosition - submarine.Center, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
//crewManager.StartShift();
|
//crewManager.StartShift();
|
||||||
taskManager.StartShift(scriptedEventCount);
|
taskManager.StartShift(scriptedEventCount);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ namespace Subsurface.Items.Components
|
|||||||
{
|
{
|
||||||
base.Move(amount);
|
base.Move(amount);
|
||||||
|
|
||||||
LinkedGap.Move(amount);
|
//LinkedGap.Move(amount);
|
||||||
|
|
||||||
body.SetTransform(body.Position + ConvertUnits.ToSimUnits(amount), 0.0f);
|
body.SetTransform(body.Position + ConvertUnits.ToSimUnits(amount), 0.0f);
|
||||||
|
|
||||||
|
|||||||
@@ -41,12 +41,12 @@ namespace Subsurface.Items.Components
|
|||||||
|
|
||||||
Rectangle miniMap = new Rectangle(x + 20, y + 40, width - 40, height - 60);
|
Rectangle miniMap = new Rectangle(x + 20, y + 40, width - 40, height - 60);
|
||||||
|
|
||||||
float size = Math.Min((float)miniMap.Width / (float)Map.Borders.Width, (float)miniMap.Height / (float)Map.Borders.Height);
|
float size = Math.Min((float)miniMap.Width / (float)Submarine.Borders.Width, (float)miniMap.Height / (float)Submarine.Borders.Height);
|
||||||
foreach (Hull hull in Hull.hullList)
|
foreach (Hull hull in Hull.hullList)
|
||||||
{
|
{
|
||||||
Rectangle hullRect = new Rectangle(
|
Rectangle hullRect = new Rectangle(
|
||||||
miniMap.X + (int)((hull.Rect.X - Map.Borders.X) * size),
|
miniMap.X + (int)((hull.Rect.X - Submarine.Borders.X) * size),
|
||||||
miniMap.Y - (int)((hull.Rect.Y - Map.Borders.Y) * size),
|
miniMap.Y - (int)((hull.Rect.Y - Submarine.Borders.Y) * size),
|
||||||
(int)(hull.Rect.Width * size),
|
(int)(hull.Rect.Width * size),
|
||||||
(int)(hull.Rect.Height * size));
|
(int)(hull.Rect.Height * size));
|
||||||
|
|
||||||
@@ -71,8 +71,8 @@ namespace Subsurface.Items.Components
|
|||||||
if (c.animController.CurrentHull!=null) continue;
|
if (c.animController.CurrentHull!=null) continue;
|
||||||
|
|
||||||
Rectangle characterRect = new Rectangle(
|
Rectangle characterRect = new Rectangle(
|
||||||
miniMap.X + (int)((c.Position.X - Map.Borders.X) * size),
|
miniMap.X + (int)((c.Position.X - Submarine.Borders.X) * size),
|
||||||
miniMap.Y - (int)((c.Position.Y - Map.Borders.Y) * size),
|
miniMap.Y - (int)((c.Position.Y - Submarine.Borders.Y) * size),
|
||||||
5, 5);
|
5, 5);
|
||||||
|
|
||||||
GUI.DrawRectangle(spriteBatch, characterRect, Color.White, true);
|
GUI.DrawRectangle(spriteBatch, characterRect, Color.White, true);
|
||||||
|
|||||||
@@ -109,8 +109,8 @@ namespace Subsurface.Items.Components
|
|||||||
ignoredBodies.Add(limb.body.FarseerBody);
|
ignoredBodies.Add(limb.body.FarseerBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
Body targetBody = Map.PickBody(TransformedBarrelPos, targetPosition, ignoredBodies);
|
Body targetBody = Submarine.PickBody(TransformedBarrelPos, targetPosition, ignoredBodies);
|
||||||
pickedPosition = Map.LastPickedPosition;
|
pickedPosition = Submarine.LastPickedPosition;
|
||||||
|
|
||||||
if (targetBody==null || targetBody.UserData==null) return true;
|
if (targetBody==null || targetBody.UserData==null) return true;
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ namespace Subsurface.Items.Components
|
|||||||
{
|
{
|
||||||
class ConnectionPanel : ItemComponent
|
class ConnectionPanel : ItemComponent
|
||||||
{
|
{
|
||||||
|
|
||||||
public List<Connection> connections;
|
public List<Connection> connections;
|
||||||
|
|
||||||
Character user;
|
Character user;
|
||||||
@@ -31,10 +30,20 @@ namespace Subsurface.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Move(Vector2 amount)
|
//public override void Move(Vector2 amount)
|
||||||
{
|
//{
|
||||||
base.Move(amount);
|
// base.Move(amount);
|
||||||
}
|
|
||||||
|
// foreach (Connection c in connections)
|
||||||
|
// {
|
||||||
|
// foreach (Wire w in c.wires)
|
||||||
|
// {
|
||||||
|
// if (w == null) continue;
|
||||||
|
|
||||||
|
// w.Move
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,6 +35,15 @@ namespace Subsurface.Items.Components
|
|||||||
connections = new Connection[2];
|
connections = new Connection[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Move(Vector2 amount)
|
||||||
|
{
|
||||||
|
amount = FarseerPhysics.ConvertUnits.ToDisplayUnits(amount);
|
||||||
|
for (int i = 0; i<nodes.Count; i++)
|
||||||
|
{
|
||||||
|
nodes[i] += amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Connection OtherConnection(Connection connection)
|
public Connection OtherConnection(Connection connection)
|
||||||
{
|
{
|
||||||
if (connection == null) return null;
|
if (connection == null) return null;
|
||||||
|
|||||||
@@ -287,8 +287,9 @@ namespace Subsurface
|
|||||||
|
|
||||||
if (itemList != null && body!=null)
|
if (itemList != null && body!=null)
|
||||||
{
|
{
|
||||||
Vector2 pos = new Vector2(rect.X + rect.Width / 2.0f, rect.Y - rect.Height / 2.0f);
|
amount = ConvertUnits.ToSimUnits(amount);
|
||||||
body.SetTransform(ConvertUnits.ToSimUnits(pos), 0.0f);
|
//Vector2 pos = new Vector2(rect.X + rect.Width / 2.0f, rect.Y - rect.Height / 2.0f);
|
||||||
|
body.SetTransform(body.Position+amount, body.Rotation);
|
||||||
}
|
}
|
||||||
foreach (ItemComponent ic in components)
|
foreach (ItemComponent ic in components)
|
||||||
{
|
{
|
||||||
@@ -679,7 +680,7 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
Rectangle transformedTrigger = item.TransformTrigger(trigger);
|
Rectangle transformedTrigger = item.TransformTrigger(trigger);
|
||||||
|
|
||||||
if (!Map.RectContains(transformedTrigger, displayPos))continue;
|
if (!Submarine.RectContains(transformedTrigger, displayPos))continue;
|
||||||
|
|
||||||
|
|
||||||
Vector2 triggerCenter =
|
Vector2 triggerCenter =
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
public override void UpdatePlacing(SpriteBatch spriteBatch, Camera cam)
|
public override void UpdatePlacing(SpriteBatch spriteBatch, Camera cam)
|
||||||
{
|
{
|
||||||
Vector2 position = Map.MouseToWorldGrid(cam);
|
Vector2 position = Submarine.MouseToWorldGrid(cam);
|
||||||
|
|
||||||
if (!resizeHorizontal && !resizeVertical)
|
if (!resizeHorizontal && !resizeVertical)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace Subsurface
|
|||||||
for (int i = 0; i<range*10; i++)
|
for (int i = 0; i<range*10; i++)
|
||||||
{
|
{
|
||||||
Game1.particleManager.CreateParticle("explosionfire", position,
|
Game1.particleManager.CreateParticle("explosionfire", position,
|
||||||
Vector2.Normalize(new Vector2(ToolBox.RandomFloat(-1.0f, 1.0f), ToolBox.RandomFloat(-1.0f, 1.0f))) * ToolBox.RandomFloat(3.0f, 4.0f),
|
Vector2.Normalize(new Vector2(ToolBox.RandomFloatLocal(-1.0f, 1.0f), ToolBox.RandomFloatLocal(-1.0f, 1.0f))) * ToolBox.RandomFloatLocal(3.0f, 4.0f),
|
||||||
0.0f);
|
0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,8 +90,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
public override bool Contains(Vector2 position)
|
public override bool Contains(Vector2 position)
|
||||||
{
|
{
|
||||||
return (Map.RectContains(rect, position) &&
|
return (Submarine.RectContains(rect, position) &&
|
||||||
!Map.RectContains(new Rectangle(rect.X + 4, rect.Y - 4, rect.Width - 8, rect.Height - 8), position));
|
!Submarine.RectContains(new Rectangle(rect.X + 4, rect.Y - 4, rect.Width - 8, rect.Height - 8), position));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FindHulls()
|
private void FindHulls()
|
||||||
@@ -102,7 +102,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
foreach (Hull h in Hull.hullList)
|
foreach (Hull h in Hull.hullList)
|
||||||
{
|
{
|
||||||
if (!Map.RectsOverlap(h.Rect, rect, false)) continue;
|
if (!Submarine.RectsOverlap(h.Rect, rect, false)) continue;
|
||||||
|
|
||||||
//if the gap is inside the hull completely, ignore it
|
//if the gap is inside the hull completely, ignore it
|
||||||
if (rect.X > h.Rect.X && rect.X + rect.Width < h.Rect.X+h.Rect.Width &&
|
if (rect.X > h.Rect.X && rect.X + rect.Width < h.Rect.X+h.Rect.Width &&
|
||||||
@@ -250,20 +250,20 @@ namespace Subsurface
|
|||||||
pos.Y = ConvertUnits.ToSimUnits(MathHelper.Clamp(lowerSurface, rect.Y-rect.Height, rect.Y));
|
pos.Y = ConvertUnits.ToSimUnits(MathHelper.Clamp(lowerSurface, rect.Y-rect.Height, rect.Y));
|
||||||
|
|
||||||
Game1.particleManager.CreateParticle("watersplash",
|
Game1.particleManager.CreateParticle("watersplash",
|
||||||
new Vector2(pos.X, pos.Y - ToolBox.RandomFloat(0.0f, 0.1f)),
|
new Vector2(pos.X, pos.Y - ToolBox.RandomFloatLocal(0.0f, 0.1f)),
|
||||||
new Vector2(flowForce.X * ToolBox.RandomFloat(0.005f, 0.007f), flowForce.Y * ToolBox.RandomFloat(0.005f, 0.007f)));
|
new Vector2(flowForce.X * ToolBox.RandomFloatLocal(0.005f, 0.007f), flowForce.Y * ToolBox.RandomFloatLocal(0.005f, 0.007f)));
|
||||||
|
|
||||||
pos.Y = ConvertUnits.ToSimUnits(ToolBox.RandomFloat(lowerSurface, rect.Y - rect.Height));
|
pos.Y = ConvertUnits.ToSimUnits(ToolBox.RandomFloatLocal(lowerSurface, rect.Y - rect.Height));
|
||||||
Game1.particleManager.CreateParticle("bubbles", pos, flowForce / 200.0f);
|
Game1.particleManager.CreateParticle("bubbles", pos, flowForce / 200.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pos.Y += Math.Sign(flowForce.Y) * ConvertUnits.ToSimUnits(rect.Height / 2.0f);
|
pos.Y += Math.Sign(flowForce.Y) * ConvertUnits.ToSimUnits(rect.Height / 2.0f);
|
||||||
for (int i = 0; i < rect.Width; i += (int)ToolBox.RandomFloat(80, 100))
|
for (int i = 0; i < rect.Width; i += (int)ToolBox.RandomFloatLocal(80, 100))
|
||||||
{
|
{
|
||||||
pos.X = ConvertUnits.ToSimUnits(ToolBox.RandomFloat(rect.X, rect.X+rect.Width));
|
pos.X = ConvertUnits.ToSimUnits(ToolBox.RandomFloatLocal(rect.X, rect.X+rect.Width));
|
||||||
Subsurface.Particles.Particle splash = Game1.particleManager.CreateParticle("watersplash", pos,
|
Subsurface.Particles.Particle splash = Game1.particleManager.CreateParticle("watersplash", pos,
|
||||||
new Vector2(flowForce.X * ToolBox.RandomFloat(0.005f, 0.008f), flowForce.Y * ToolBox.RandomFloat(0.005f, 0.008f)));
|
new Vector2(flowForce.X * ToolBox.RandomFloatLocal(0.005f, 0.008f), flowForce.Y * ToolBox.RandomFloatLocal(0.005f, 0.008f)));
|
||||||
|
|
||||||
if (splash!=null) splash.Size = splash.Size * MathHelper.Clamp(rect.Width / 50.0f, 0.8f, 4.0f);
|
if (splash!=null) splash.Size = splash.Size * MathHelper.Clamp(rect.Width / 50.0f, 0.8f, 4.0f);
|
||||||
|
|
||||||
|
|||||||
@@ -150,8 +150,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
public override bool Contains(Vector2 position)
|
public override bool Contains(Vector2 position)
|
||||||
{
|
{
|
||||||
return (Map.RectContains(rect, position) &&
|
return (Submarine.RectContains(rect, position) &&
|
||||||
!Map.RectContains(new Rectangle(rect.X + 8, rect.Y - 8, rect.Width - 16, rect.Height - 16), position));
|
!Submarine.RectContains(new Rectangle(rect.X + 8, rect.Y - 8, rect.Width - 16, rect.Height - 16), position));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetWaveIndex(Vector2 position)
|
public int GetWaveIndex(Vector2 position)
|
||||||
@@ -189,7 +189,7 @@ namespace Subsurface
|
|||||||
if (EditWater)
|
if (EditWater)
|
||||||
{
|
{
|
||||||
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||||
if (Map.RectContains(rect, position))
|
if (Submarine.RectContains(rect, position))
|
||||||
{
|
{
|
||||||
if (PlayerInput.LeftButtonDown())
|
if (PlayerInput.LeftButtonDown())
|
||||||
{
|
{
|
||||||
@@ -210,7 +210,7 @@ namespace Subsurface
|
|||||||
for (int i = 0; i < waveY.Length; i++)
|
for (int i = 0; i < waveY.Length; i++)
|
||||||
{
|
{
|
||||||
float maxDelta = Math.Max(Math.Abs(rightDelta[i]), Math.Abs(leftDelta[i]));
|
float maxDelta = Math.Max(Math.Abs(rightDelta[i]), Math.Abs(leftDelta[i]));
|
||||||
if (maxDelta > ToolBox.RandomFloat(0.2f,10.0f))
|
if (maxDelta > ToolBox.RandomFloatLocal(0.2f,10.0f))
|
||||||
{
|
{
|
||||||
Game1.particleManager.CreateParticle("mist",
|
Game1.particleManager.CreateParticle("mist",
|
||||||
ConvertUnits.ToSimUnits(new Vector2(rect.X + WaveWidth * i,surface + waveY[i])),
|
ConvertUnits.ToSimUnits(new Vector2(rect.X + WaveWidth * i,surface + waveY[i])),
|
||||||
@@ -390,12 +390,12 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
if (guess != null && hullList.Contains(guess))
|
if (guess != null && hullList.Contains(guess))
|
||||||
{
|
{
|
||||||
if (Map.RectContains(guess.rect, position)) return guess;
|
if (Submarine.RectContains(guess.rect, position)) return guess;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Hull w in hullList)
|
foreach (Hull w in hullList)
|
||||||
{
|
{
|
||||||
if (Map.RectContains(w.rect, position)) return w;
|
if (Submarine.RectContains(w.rect, position)) return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
+488
-49
@@ -6,107 +6,546 @@ using Microsoft.Xna.Framework;
|
|||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Voronoi2;
|
using Voronoi2;
|
||||||
|
|
||||||
namespace Subsurface
|
namespace Subsurface
|
||||||
{
|
{
|
||||||
class Level
|
class Level
|
||||||
{
|
{
|
||||||
|
public static Level Loaded
|
||||||
|
{
|
||||||
|
get { return loaded; }
|
||||||
|
}
|
||||||
|
|
||||||
|
static Level loaded;
|
||||||
|
|
||||||
private int seed;
|
private int seed;
|
||||||
|
|
||||||
List<Body> bodies;
|
private int siteInterval;
|
||||||
|
|
||||||
|
const int gridCellWidth = 1000;
|
||||||
|
List<VoronoiCell>[,] cellGrid;
|
||||||
|
|
||||||
|
//List<Body> bodies;
|
||||||
List<VoronoiCell> cells;
|
List<VoronoiCell> cells;
|
||||||
|
|
||||||
public Level(int seed, int siteCount, int width, int height)
|
BasicEffect basicEffect;
|
||||||
|
|
||||||
|
private VertexPositionColor[] vertices;
|
||||||
|
private VertexBuffer vertexBuffer;
|
||||||
|
|
||||||
|
private Vector2 startPosition;
|
||||||
|
private Vector2 endPosition;
|
||||||
|
|
||||||
|
Rectangle borders;
|
||||||
|
|
||||||
|
public Vector2 StartPosition
|
||||||
|
{
|
||||||
|
get { return startPosition; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Level(int seed, int width, int height, int siteInterval)
|
||||||
{
|
{
|
||||||
this.seed = seed;
|
this.seed = seed;
|
||||||
|
|
||||||
Voronoi voronoi = new Voronoi(1.0);
|
this.siteInterval = siteInterval;
|
||||||
|
|
||||||
List<PointF> sites = new List<PointF>();
|
borders = new Rectangle(0, 0, width, height);
|
||||||
Random rand = new Random(seed);
|
}
|
||||||
|
|
||||||
for (int i = 0; i < siteCount; i++)
|
public static Level CreateRandom()
|
||||||
|
{
|
||||||
|
return new Level(100, 100000, 40000, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Generate(float minWidth)
|
||||||
|
{
|
||||||
|
Stopwatch sw = new Stopwatch();
|
||||||
|
sw.Start();
|
||||||
|
|
||||||
|
Game1.random = new Random(seed);
|
||||||
|
|
||||||
|
if (loaded != this && loaded != null)
|
||||||
{
|
{
|
||||||
sites.Add(new PointF((float)(rand.NextDouble() * width), (float)(rand.NextDouble() * width)));
|
loaded.Unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<GraphEdge> graphEdges = MakeVoronoiGraph(sites, voronoi, width, height);
|
loaded = this;
|
||||||
|
|
||||||
|
Voronoi voronoi = new Voronoi(1.0);
|
||||||
|
|
||||||
|
List<Vector2> sites = new List<Vector2>();
|
||||||
|
Random rand = new Random(seed);
|
||||||
|
|
||||||
|
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(
|
||||||
|
x + (float)(Game1.random.NextDouble() - 0.5) * siteVariance,
|
||||||
|
y + (float)(Game1.random.NextDouble() - 0.5) * siteVariance));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Stopwatch sw2 = new Stopwatch();
|
||||||
|
sw2.Start();
|
||||||
|
|
||||||
|
List<GraphEdge> graphEdges = voronoi.MakeVoronoiGraph(sites, borders.Width, borders.Height);
|
||||||
|
|
||||||
|
|
||||||
|
Debug.WriteLine("MakeVoronoiGraph: " + sw2.ElapsedMilliseconds + " ms");
|
||||||
|
sw2.Restart();
|
||||||
|
|
||||||
|
cellGrid = new List<VoronoiCell>[borders.Width / gridCellWidth, borders.Height / gridCellWidth];
|
||||||
|
for (int x = 0; x < borders.Width / gridCellWidth; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < borders.Height / gridCellWidth; y++)
|
||||||
|
{
|
||||||
|
cellGrid[x, y] = new List<VoronoiCell>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//construct voronoi cells based on the graph edges
|
||||||
cells = new List<VoronoiCell>();
|
cells = new List<VoronoiCell>();
|
||||||
foreach (GraphEdge ge in graphEdges)
|
foreach (GraphEdge ge in graphEdges)
|
||||||
{
|
{
|
||||||
for (int i = 0; i<2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
Site site = (i==0) ? ge.site1 : ge.site2;
|
Site site = (i == 0) ? ge.site1 : ge.site2;
|
||||||
VoronoiCell cell = cells.Find(c => c.site == site);
|
|
||||||
|
VoronoiCell cell = cellGrid[
|
||||||
|
(int)Math.Floor(site.coord.x / gridCellWidth),
|
||||||
|
(int)Math.Floor(site.coord.y / gridCellWidth)].Find(c => c.site == site);
|
||||||
|
|
||||||
if (cell == null)
|
if (cell == null)
|
||||||
{
|
{
|
||||||
cell = new VoronoiCell(site);
|
cell = new VoronoiCell(site);
|
||||||
|
cellGrid[(int)Math.Floor(cell.Center.X / gridCellWidth), (int)Math.Floor(cell.Center.Y / gridCellWidth)].Add(cell);
|
||||||
cells.Add(cell);
|
cells.Add(cell);
|
||||||
}
|
}
|
||||||
if (!cell.edges.Contains(ge)) cell.edges.Add(ge);
|
|
||||||
|
if (ge.cell1 == null)
|
||||||
|
{
|
||||||
|
ge.cell1 = cell;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ge.cell2 = cell;
|
||||||
|
}
|
||||||
|
cell.edges.Add(ge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.WriteLine("find cells: " + sw2.ElapsedMilliseconds + " ms");
|
||||||
|
sw2.Restart();
|
||||||
|
|
||||||
|
//generate a path from the left edge of the map to right edge
|
||||||
|
Rectangle pathBorders = new Rectangle(
|
||||||
|
borders.X + (int)minWidth, borders.Y + (int)minWidth,
|
||||||
|
borders.Right - (int)minWidth, borders.Y + borders.Height - (int)minWidth);
|
||||||
|
|
||||||
|
List<VoronoiCell> pathCells = GeneratePath(
|
||||||
|
new Vector2((int)minWidth, Game1.random.Next((int)minWidth, borders.Height - (int)minWidth)),
|
||||||
|
new Vector2(borders.Width - (int)minWidth, Game1.random.Next((int)minWidth, borders.Height - (int)minWidth)),
|
||||||
|
cells, pathBorders, minWidth);
|
||||||
|
|
||||||
|
|
||||||
|
//generate a couple of random paths
|
||||||
|
for (int i = 0; i < Game1.random.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[Game1.random.Next(1,pathCells.Count-2)].Center;
|
||||||
|
Vector2 end = new Vector2(ToolBox.RandomFloat(pathBorders.X, pathBorders.Right), ToolBox.RandomFloat(pathBorders.Y, pathBorders.Bottom));
|
||||||
|
|
||||||
|
pathCells.AddRange
|
||||||
|
(
|
||||||
|
GeneratePath( start,end, cells, pathBorders, 0.0f)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.WriteLine("path: " + sw2.ElapsedMilliseconds + " ms");
|
||||||
|
sw2.Restart();
|
||||||
|
|
||||||
|
startPosition = pathCells[0].Center;
|
||||||
|
endPosition = pathCells[pathCells.Count - 1].Center;
|
||||||
|
|
||||||
|
foreach (VoronoiCell cell in pathCells)
|
||||||
|
{
|
||||||
|
cells.Remove(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
GenerateLevel(cells);
|
||||||
|
|
||||||
|
Debug.WriteLine("Generatelevel: " + sw2.ElapsedMilliseconds + " ms");
|
||||||
|
sw2.Restart();
|
||||||
|
|
||||||
|
vertexBuffer = new VertexBuffer(Game1.CurrGraphicsDevice, VertexPositionColor.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly);
|
||||||
|
|
||||||
|
vertexBuffer.SetData(vertices);
|
||||||
|
|
||||||
|
basicEffect = new BasicEffect(Game1.CurrGraphicsDevice);
|
||||||
|
basicEffect.VertexColorEnabled = true;
|
||||||
|
|
||||||
|
Debug.WriteLine("Generated a map with "+sites.Count+" sites in "+sw.ElapsedMilliseconds+" ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<VoronoiCell> GeneratePath(Vector2 start, Vector2 end, List<VoronoiCell> cells, Microsoft.Xna.Framework.Rectangle limits, float minWidth, float wanderAmount = 0.3f)
|
||||||
|
{
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
List<VoronoiCell> pathCells = new List<VoronoiCell>();
|
||||||
|
|
||||||
|
VoronoiCell currentCell = cells[FindCellIndex(start)];
|
||||||
|
pathCells.Add(currentCell);
|
||||||
|
|
||||||
|
VoronoiCell endCell = cells[FindCellIndex(end)];
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int edgeIndex = 0;
|
||||||
|
|
||||||
|
//steer towards target
|
||||||
|
if (Game1.random.NextDouble()>wanderAmount)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < currentCell.edges.Count; i++)
|
||||||
|
{
|
||||||
|
if (!IsIntersecting(currentCell.Center, end, currentCell.edges[i].point1, currentCell.edges[i].point2)) continue;
|
||||||
|
edgeIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//choose random edge (ignoring ones where the adjacent cell is outside limits)
|
||||||
|
else
|
||||||
|
{
|
||||||
|
List<GraphEdge> allowedEdges = new List<GraphEdge>();
|
||||||
|
|
||||||
|
foreach(GraphEdge edge in currentCell.edges)
|
||||||
|
{
|
||||||
|
if (!limits.Contains(edge.AdjacentCell(currentCell).Center)) continue;
|
||||||
|
|
||||||
|
allowedEdges.Add(edge);
|
||||||
|
}
|
||||||
|
edgeIndex = (allowedEdges.Count==0) ?
|
||||||
|
0 : currentCell.edges.IndexOf(allowedEdges[Game1.random.Next() % allowedEdges.Count]);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentCell = currentCell.edges[edgeIndex].AdjacentCell(currentCell);
|
||||||
|
|
||||||
|
|
||||||
|
pathCells.Add(currentCell);
|
||||||
|
|
||||||
|
} while (currentCell!=endCell);
|
||||||
|
|
||||||
|
Debug.WriteLine("genpath: " + sw2.ElapsedMilliseconds + " ms");
|
||||||
|
sw2.Restart();
|
||||||
|
|
||||||
|
List<VoronoiCell> removedCells = GetTooCloseCells(pathCells, minWidth);
|
||||||
|
foreach (VoronoiCell removedCell in removedCells)
|
||||||
|
{
|
||||||
|
if (pathCells.Contains(removedCell)) continue;
|
||||||
|
pathCells.Add(removedCell);
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.WriteLine("gettooclose: " + sw2.ElapsedMilliseconds + " ms");
|
||||||
|
sw2.Restart();
|
||||||
|
|
||||||
|
return pathCells;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<VoronoiCell> GetTooCloseCells(List<VoronoiCell> emptyCells, float minDistance)
|
||||||
|
{
|
||||||
|
List<VoronoiCell> tooCloseCells = new List<VoronoiCell>();
|
||||||
|
|
||||||
|
Vector2 position = emptyCells[0].Center;
|
||||||
|
|
||||||
|
if (minDistance == 0.0f) return tooCloseCells;
|
||||||
|
|
||||||
|
float step = 100.0f;
|
||||||
|
|
||||||
|
int targetCellIndex = 1;
|
||||||
|
|
||||||
|
minDistance *= 0.5f;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
int cellIndex = FindCellIndex(cornerPos);
|
||||||
|
if (cellIndex == -1) continue;
|
||||||
|
if (!tooCloseCells.Contains(cells[cellIndex]))
|
||||||
|
{
|
||||||
|
tooCloseCells.Add(cells[cellIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
position += Vector2.Normalize(emptyCells[targetCellIndex].Center - position) * step;
|
||||||
|
|
||||||
|
if (Vector2.Distance(emptyCells[targetCellIndex].Center, position) < step * 2.0f) targetCellIndex++;
|
||||||
|
|
||||||
|
} while (Vector2.Distance(position, emptyCells[emptyCells.Count - 1].Center) > step*2.0f);
|
||||||
|
|
||||||
|
return tooCloseCells;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// check whether line from a to b is intersecting with line from c to b
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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)
|
||||||
|
/// </summary>
|
||||||
|
private int FindCellIndex(Vector2 position)
|
||||||
|
{
|
||||||
|
float closestDist = 0.0f;
|
||||||
|
VoronoiCell closestCell = null;
|
||||||
|
|
||||||
|
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 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++)
|
||||||
|
{
|
||||||
|
float dist = Vector2.Distance(cellGrid[x, y][i].Center, position);
|
||||||
|
if (closestDist != 0.0f && dist > closestDist) continue;
|
||||||
|
|
||||||
|
closestDist = dist;
|
||||||
|
closestCell = cellGrid[x, y][i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bodies = new List<Body>();
|
|
||||||
|
return cells.IndexOf(closestCell);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateLevel(List<VoronoiCell> cells)
|
||||||
|
{
|
||||||
|
List<VertexPositionColor> verticeList = new List<VertexPositionColor>();
|
||||||
|
//bodies = new List<Body>();
|
||||||
|
|
||||||
|
|
||||||
|
List<Vector2> tempVertices = new List<Vector2>();
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
foreach (VoronoiCell cell in cells)
|
foreach (VoronoiCell cell in cells)
|
||||||
{
|
{
|
||||||
//List of vectors defining my custom poly
|
n = (n + 30) % 255;
|
||||||
List<Vector2> vlist = new List<Vector2>();
|
|
||||||
|
tempVertices.Clear();
|
||||||
foreach (GraphEdge ge in cell.edges)
|
foreach (GraphEdge ge in cell.edges)
|
||||||
{
|
{
|
||||||
if (!vlist.Contains(ge.point1)) vlist.Add(ge.point1);
|
if (ge.point1 == ge.point2) continue;
|
||||||
if (!vlist.Contains(ge.point2)) vlist.Add(ge.point2);
|
if (!tempVertices.Contains(ge.point1)) tempVertices.Add(ge.point1);
|
||||||
|
if (!tempVertices.Contains(ge.point2)) tempVertices.Add(ge.point2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vlist.Count < 3) continue;
|
if (tempVertices.Count < 3) continue;
|
||||||
|
|
||||||
for (int i = 0; i < vlist.Count; i++ )
|
int triangleCount = tempVertices.Count - 2;
|
||||||
|
|
||||||
|
tempVertices.Sort(new CompareCCW(cell.Center));
|
||||||
|
|
||||||
|
int lastIndex = 1;
|
||||||
|
for (int i = 0; i < triangleCount; i++ )
|
||||||
{
|
{
|
||||||
vlist[i] = ConvertUnits.ToSimUnits(vlist[i]);
|
List<Vector2> triangleVertices = new List<Vector2>();
|
||||||
|
|
||||||
|
triangleVertices.Add(tempVertices[0]);
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSame = false;
|
||||||
|
if (triangleVertices[0].Y == triangleVertices[1].Y && triangleVertices[1].Y == triangleVertices[2].Y) isSame = true;
|
||||||
|
if (triangleVertices[0].X == triangleVertices[1].X && triangleVertices[1].X == triangleVertices[2].X) isSame = true;
|
||||||
|
|
||||||
|
if (isSame) continue;
|
||||||
|
|
||||||
|
CreateBody(cell, triangleVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//get farseer 'vertices' from vectors
|
|
||||||
Vertices _shapevertices = new Vertices(vlist);
|
|
||||||
_shapevertices.Sort(new CompareCCW(cell.Center));
|
|
||||||
|
|
||||||
//feed vertices array to BodyFactory.CreatePolygon to get a new farseer polygonal body
|
|
||||||
Body _newBody = BodyFactory.CreatePolygon(Game1.world, _shapevertices, 15);
|
|
||||||
_newBody.BodyType = BodyType.Static;
|
|
||||||
_newBody.CollisionCategories = Physics.CollisionWall;
|
|
||||||
|
|
||||||
bodies.Add(_newBody);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vertices = verticeList.ToArray();
|
||||||
|
|
||||||
|
//return bodies;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<GraphEdge> MakeVoronoiGraph(List<PointF> sites, Voronoi voronoi, int width, int height)
|
private void CreateBody(VoronoiCell cell, List<Vector2> bodyVertices)
|
||||||
{
|
{
|
||||||
double[] xVal = new double[sites.Count];
|
for (int i = 0; i < bodyVertices.Count; i++)
|
||||||
double[] yVal = new double[sites.Count];
|
|
||||||
for (int i = 0; i < sites.Count; i++)
|
|
||||||
{
|
{
|
||||||
xVal[i] = sites[i].X;
|
bodyVertices[i] = ConvertUnits.ToSimUnits(bodyVertices[i]);
|
||||||
yVal[i] = sites[i].Y;
|
|
||||||
}
|
}
|
||||||
return voronoi.generateVoronoi(xVal, yVal, 0, width, 0, height);
|
//get farseer 'vertices' from vectors
|
||||||
|
Vertices _shapevertices = new Vertices(bodyVertices);
|
||||||
|
//_shapevertices.Sort(new CompareCCW(cell.Center));
|
||||||
|
|
||||||
|
//feed vertices array to BodyFactory.CreatePolygon to get a new farseer polygonal body
|
||||||
|
Body _newBody = BodyFactory.CreatePolygon(Game1.world, _shapevertices, 15);
|
||||||
|
_newBody.BodyType = BodyType.Static;
|
||||||
|
_newBody.CollisionCategories = Physics.CollisionWall;
|
||||||
|
|
||||||
|
cell.bodies.Add(_newBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Render(SpriteBatch spriteBatch)
|
|
||||||
|
Vector2 position;
|
||||||
|
public void Move(Vector2 amount, float deltaTime)
|
||||||
{
|
{
|
||||||
|
amount = amount * deltaTime;
|
||||||
|
position += amount;
|
||||||
|
|
||||||
|
amount = ConvertUnits.ToSimUnits(amount);
|
||||||
|
foreach (VoronoiCell cell in cells)
|
||||||
|
{
|
||||||
|
foreach (Body b in cell.bodies)
|
||||||
|
{
|
||||||
|
b.SetTransform(b.Position+amount, b.Rotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void SetObserverPosition(Vector2 position)
|
||||||
|
{
|
||||||
|
position = position - this.position;
|
||||||
|
int gridPosX = (int)Math.Floor(position.X / gridCellWidth);
|
||||||
|
int gridPosY = (int)Math.Floor(position.Y / gridCellWidth);
|
||||||
|
int searchOffset = 1;
|
||||||
|
|
||||||
|
for (int x = 0; x < cellGrid.GetLength(0); x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y <cellGrid.GetLength(1); y++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < cellGrid[x, y].Count; i++)
|
||||||
|
{
|
||||||
|
foreach (Body b in cellGrid[x, y][i].bodies)
|
||||||
|
{
|
||||||
|
b.Enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 i = 0; i < cellGrid[x, y].Count; i++)
|
||||||
|
{
|
||||||
|
foreach (Body b in cellGrid[x, y][i].bodies)
|
||||||
|
{
|
||||||
|
b.Enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void RenderLines(SpriteBatch spriteBatch)
|
||||||
|
{
|
||||||
|
GUI.DrawRectangle(spriteBatch, new Rectangle(borders.X, borders.Y-borders.Height, borders.Width, borders.Height), Color.Cyan);
|
||||||
|
|
||||||
foreach (VoronoiCell cell in cells)
|
foreach (VoronoiCell cell in cells)
|
||||||
{
|
{
|
||||||
for (int i = 0; i<cell.edges.Count; i++)
|
for (int i = 0; i<cell.edges.Count; i++)
|
||||||
{
|
{
|
||||||
GUI.DrawLine(spriteBatch, cell.edges[i].point1, cell.edges[i].point2, Microsoft.Xna.Framework.Color.Red);
|
Vector2 start = cell.edges[i].point1+position;
|
||||||
|
start.Y = -start.Y;
|
||||||
|
|
||||||
|
Vector2 end = cell.edges[i].point2+position;
|
||||||
|
end.Y = -end.Y;
|
||||||
|
|
||||||
|
GUI.DrawLine(spriteBatch, start, end, Color.Red);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Render(GraphicsDevice graphicsDevice, Camera cam)
|
||||||
|
{
|
||||||
|
if (vertices == null) return;
|
||||||
|
if (vertices.Length <= 0) return;
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
|
||||||
|
graphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleList, vertices, 0, (int)Math.Floor(vertices.Length / 3.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Unload()
|
||||||
|
{
|
||||||
|
foreach (VoronoiCell cell in cells)
|
||||||
|
{
|
||||||
|
foreach (Body b in cell.bodies)
|
||||||
|
{
|
||||||
|
Game1.world.RemoveBody(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//bodies = null;
|
||||||
|
|
||||||
|
vertices = null;
|
||||||
|
|
||||||
|
cells = null;
|
||||||
|
|
||||||
|
vertexBuffer.Dispose();
|
||||||
|
vertexBuffer = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CompareCCW : IComparer<Vector2>
|
class CompareCCW : IComparer<Vector2>
|
||||||
@@ -119,24 +558,24 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
public int Compare(Vector2 a, Vector2 b)
|
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) 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.X - center.X == 0 && b.X - center.X == 0)
|
||||||
{
|
{
|
||||||
if (a.Y - center.Y >= 0 || b.Y - center.Y >= 0) return Math.Sign(a.Y - b.Y);
|
if (a.Y - center.Y >= 0 || b.Y - center.Y >= 0) return Math.Sign(b.Y-a.Y);
|
||||||
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)
|
// 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);
|
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;
|
||||||
if (det > 0) return -1;
|
if (det > 0) return 1;
|
||||||
|
|
||||||
// points a and b are on the same line from the center
|
// points a and b are on the same line from the center
|
||||||
// check which point is closer to 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 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);
|
float d2 = (b.X - center.X) * (b.X - center.X) + (b.Y - center.Y) * (b.Y - center.Y);
|
||||||
return Math.Sign(d1 - d2);
|
return Math.Sign(d2-d1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Subsurface
|
||||||
|
{
|
||||||
|
class Location
|
||||||
|
{
|
||||||
|
string name;
|
||||||
|
|
||||||
|
Vector2 mapPosition;
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return name; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 MapPosition
|
||||||
|
{
|
||||||
|
get { return mapPosition; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location(string name, Vector2 mapPosition)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
|
||||||
|
this.mapPosition = mapPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Location CreateRandom(Vector2 position)
|
||||||
|
{
|
||||||
|
return new Location("Location " + (Game1.random.Next() % 10000), position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+159
-459
@@ -1,539 +1,239 @@
|
|||||||
using FarseerPhysics;
|
using Microsoft.Xna.Framework;
|
||||||
using FarseerPhysics.Collision;
|
|
||||||
using FarseerPhysics.Dynamics;
|
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Text;
|
||||||
using System.Xml.Linq;
|
using Voronoi2;
|
||||||
|
|
||||||
namespace Subsurface
|
namespace Subsurface
|
||||||
{
|
{
|
||||||
public enum Direction : byte
|
|
||||||
{
|
|
||||||
None = 0, Left = 1, Right = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
class Map
|
class Map
|
||||||
{
|
{
|
||||||
static string MapFolder;
|
private List<Level> levels;
|
||||||
MapHash mapHash;
|
|
||||||
|
|
||||||
public static List<Map> SavedMaps = new List<Map>();
|
private List<Location> locations;
|
||||||
|
|
||||||
private static Map loaded;
|
private List<LocationConnection> connections;
|
||||||
|
|
||||||
//public static Map Loaded
|
private int seed;
|
||||||
//{
|
private int size;
|
||||||
// get { return loaded; }
|
|
||||||
// set { loaded = value; }
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
private Location currentLocation;
|
||||||
|
private Location selectedLocation;
|
||||||
|
|
||||||
public static readonly Vector2 gridSize = new Vector2(16.0f, 16.0f);
|
public Map(int seed, int size)
|
||||||
|
|
||||||
private static Vector2 lastPickedPosition;
|
|
||||||
private static float lastPickedFraction;
|
|
||||||
|
|
||||||
private Rectangle borders;
|
|
||||||
|
|
||||||
private string filePath;
|
|
||||||
private string name;
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
{
|
||||||
get { return name; }
|
this.seed = seed;
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector2 LastPickedPosition
|
this.size = size;
|
||||||
{
|
|
||||||
get { return lastPickedPosition; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float LastPickedFraction
|
levels = new List<Level>();
|
||||||
{
|
|
||||||
get { return lastPickedFraction; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public MapHash MapHash
|
locations = new List<Location>();
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (mapHash != null) return mapHash;
|
|
||||||
|
|
||||||
XDocument doc = OpenDoc(filePath);
|
connections = new List<LocationConnection>();
|
||||||
mapHash = new MapHash(doc);
|
|
||||||
|
|
||||||
return mapHash;
|
GenerateLocations();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map Loaded
|
//for (int i = 0; i<10; i++)
|
||||||
{
|
|
||||||
get { return loaded; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Rectangle Borders
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return (loaded==null) ? Rectangle.Empty : loaded.borders;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string FilePath
|
|
||||||
{
|
|
||||||
get { return filePath; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Draw(SpriteBatch spriteBatch, bool editing = false)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < MapEntity.mapEntityList.Count(); i++ )
|
|
||||||
{
|
|
||||||
MapEntity.mapEntityList[i].Draw(spriteBatch, editing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DrawFront(SpriteBatch spriteBatch, bool editing = false)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < MapEntity.mapEntityList.Count(); i++)
|
|
||||||
{
|
|
||||||
if (MapEntity.mapEntityList[i].sprite == null || MapEntity.mapEntityList[i].sprite.Depth < 0.5f)
|
|
||||||
MapEntity.mapEntityList[i].Draw(spriteBatch, editing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DrawBack(SpriteBatch spriteBatch, bool editing = false)
|
|
||||||
{
|
|
||||||
|
|
||||||
for (int i = 0; i < MapEntity.mapEntityList.Count(); i++)
|
|
||||||
{
|
|
||||||
if (MapEntity.mapEntityList[i].sprite == null || MapEntity.mapEntityList[i].sprite.Depth >= 0.5f)
|
|
||||||
MapEntity.mapEntityList[i].Draw(spriteBatch, editing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector2 MouseToWorldGrid(Camera cam)
|
|
||||||
{
|
|
||||||
Vector2 position = new Vector2(PlayerInput.GetMouseState.X, PlayerInput.GetMouseState.Y);
|
|
||||||
position = cam.ScreenToWorld(position);
|
|
||||||
|
|
||||||
return VectorToWorldGrid(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector2 VectorToWorldGrid(Vector2 position)
|
|
||||||
{
|
|
||||||
position.X = (float)Math.Floor(Convert.ToDouble(position.X / gridSize.X)) * gridSize.X;
|
|
||||||
position.Y = (float)Math.Ceiling(Convert.ToDouble(position.Y / gridSize.Y)) * gridSize.Y;
|
|
||||||
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static Rectangle AbsRect(Vector2 pos, Vector2 size)
|
|
||||||
{
|
|
||||||
if (size.X < 0.0f)
|
|
||||||
{
|
|
||||||
pos.X += size.X;
|
|
||||||
size.X = -size.X;
|
|
||||||
}
|
|
||||||
if (size.Y < 0.0f)
|
|
||||||
{
|
|
||||||
pos.Y -= size.Y;
|
|
||||||
size.Y = -size.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Rectangle((int)pos.X, (int)pos.Y, (int)size.X, (int)size.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool RectContains(Rectangle rect, Vector2 pos)
|
|
||||||
{
|
|
||||||
return (pos.X > rect.X && pos.X < rect.X + rect.Width
|
|
||||||
&& pos.Y < rect.Y && pos.Y > rect.Y - rect.Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool RectsOverlap(Rectangle rect1, Rectangle rect2, bool inclusive=true)
|
|
||||||
{
|
|
||||||
if (inclusive)
|
|
||||||
{
|
|
||||||
return !(rect1.X > rect2.X + rect2.Width || rect1.X + rect1.Width < rect2.X ||
|
|
||||||
rect1.Y < rect2.Y - rect2.Height || rect1.Y - rect1.Height > rect2.Y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return !(rect1.X >= rect2.X + rect2.Width || rect1.X + rect1.Width <= rect2.X ||
|
|
||||||
rect1.Y <= rect2.Y - rect2.Height || rect1.Y - rect1.Height >= rect2.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Body PickBody(Vector2 rayStart, Vector2 rayEnd, List<Body> ignoredBodies = null)
|
|
||||||
{
|
|
||||||
float closestFraction = 1.0f;
|
|
||||||
Body closestBody = null;
|
|
||||||
Game1.world.RayCast((fixture, point, normal, fraction) =>
|
|
||||||
{
|
|
||||||
if (fixture == null || fixture.CollisionCategories == Category.None) return -1;
|
|
||||||
if (ignoredBodies != null && ignoredBodies.Contains(fixture.Body)) return -1;
|
|
||||||
|
|
||||||
Structure structure = fixture.Body.UserData as Structure;
|
|
||||||
if (structure != null && (structure.IsPlatform || !structure.HasBody)) return -1;
|
|
||||||
|
|
||||||
if (fraction < closestFraction)
|
|
||||||
{
|
|
||||||
closestFraction = fraction;
|
|
||||||
if (fixture.Body!=null) closestBody = fixture.Body;
|
|
||||||
}
|
|
||||||
return fraction;
|
|
||||||
}
|
|
||||||
, rayStart, rayEnd);
|
|
||||||
|
|
||||||
lastPickedPosition = rayStart + (rayEnd - rayStart) * closestFraction;
|
|
||||||
lastPickedFraction = closestFraction;
|
|
||||||
return closestBody;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static Body CheckVisibility(Vector2 rayStart, Vector2 rayEnd)
|
|
||||||
{
|
|
||||||
Body closestBody = null;
|
|
||||||
float closestFraction = 1.0f;
|
|
||||||
|
|
||||||
if (Vector2.Distance(rayStart,rayEnd)<0.01f)
|
|
||||||
{
|
|
||||||
closestFraction = 0.01f;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Game1.world.RayCast((fixture, point, normal, fraction) =>
|
|
||||||
{
|
|
||||||
if (fixture == null || fixture.CollisionCategories != Physics.CollisionWall) return -1;
|
|
||||||
|
|
||||||
Structure structure = fixture.Body.UserData as Structure;
|
|
||||||
if (structure != null)
|
|
||||||
{
|
|
||||||
if (structure.IsPlatform || structure.StairDirection != Direction.None) return -1;
|
|
||||||
int sectionIndex = structure.FindSectionIndex(ConvertUnits.ToDisplayUnits(point));
|
|
||||||
if (sectionIndex > -1 && structure.SectionHasHole(sectionIndex)) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fraction < closestFraction)
|
|
||||||
{
|
|
||||||
closestBody = fixture.Body;
|
|
||||||
closestFraction = fraction;
|
|
||||||
}
|
|
||||||
return closestFraction;
|
|
||||||
}
|
|
||||||
, rayStart, rayEnd);
|
|
||||||
|
|
||||||
|
|
||||||
lastPickedPosition = rayStart + (rayEnd - rayStart) * closestFraction;
|
|
||||||
lastPickedFraction = closestFraction;
|
|
||||||
return closestBody;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Body PickBody(Vector2 point)
|
|
||||||
{
|
|
||||||
Body foundBody = null;
|
|
||||||
AABB aabb = new AABB(point, point);
|
|
||||||
|
|
||||||
Game1.world.QueryAABB(p =>
|
|
||||||
{
|
|
||||||
foundBody = p.Body;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}, ref aabb);
|
|
||||||
|
|
||||||
return foundBody;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool InsideWall(Vector2 point)
|
|
||||||
{
|
|
||||||
Body foundBody = PickBody(point);
|
|
||||||
if (foundBody==null) return false;
|
|
||||||
|
|
||||||
Structure wall = foundBody.UserData as Structure;
|
|
||||||
if (wall == null || wall.IsPlatform) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void Save()
|
|
||||||
{
|
|
||||||
SaveAs(filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveAs(string filePath)
|
|
||||||
{
|
|
||||||
//if (filePath=="")
|
|
||||||
//{
|
//{
|
||||||
// DebugConsole.ThrowError("No save file selected");
|
// Vector2 pos = new Vector2((float)Game1.random.NextDouble() * size, (float)Game1.random.NextDouble() * size);
|
||||||
// return;
|
|
||||||
|
// Location location =
|
||||||
|
// locations.Add(location);
|
||||||
//}
|
//}
|
||||||
XDocument doc = new XDocument(new XElement((XName)name));
|
|
||||||
|
|
||||||
foreach (MapEntity e in MapEntity.mapEntityList)
|
//for (int i = 0; i < 10; i++)
|
||||||
{
|
//{
|
||||||
e.Save(doc);
|
|
||||||
}
|
|
||||||
|
|
||||||
mapHash = new MapHash(doc);
|
// int closestIndex = 0;
|
||||||
doc.Root.Add(new XAttribute("md5hash", mapHash.MD5Hash));
|
// float closestDistance = 0.0f;
|
||||||
|
// for (int j = 0; j<10; j++)
|
||||||
|
// {
|
||||||
|
// if (j == i) continue;
|
||||||
|
|
||||||
try
|
// //ignore if already connected
|
||||||
{
|
// bool alreadyConnected = false;
|
||||||
SaveUtil.CompressStringToFile(filePath, doc.ToString());
|
// foreach (LocationConnection connection in connections)
|
||||||
}
|
// {
|
||||||
catch (Exception e)
|
// if (connection.Locations.Contains(locations[i]) && connection.Locations.Contains(locations[j]))
|
||||||
{
|
// {
|
||||||
DebugConsole.ThrowError("Saving map ''" + filePath + "'' failed!", e);
|
// alreadyConnected = true;
|
||||||
}
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (alreadyConnected) continue;
|
||||||
|
|
||||||
|
// float dist = Vector2.Distance(locations[i].MapPosition, locations[j].MapPosition);
|
||||||
|
// if (closestDistance > 0.0f && dist > closestDistance) continue;
|
||||||
|
|
||||||
|
// closestDistance = dist;
|
||||||
|
// closestIndex = j;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
//doc.Save(filePath);
|
// connections.Add(new LocationConnection(locations[i], locations[closestIndex], level));
|
||||||
|
//}
|
||||||
|
|
||||||
|
currentLocation = locations[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SaveCurrent(string savePath)
|
private void GenerateLocations()
|
||||||
{
|
{
|
||||||
if (loaded==null)
|
Voronoi voronoi = new Voronoi(0.5f);
|
||||||
|
|
||||||
|
List<Vector2> sites = new List<Vector2>();
|
||||||
|
for (int i = 0; i < 50; i++)
|
||||||
{
|
{
|
||||||
loaded = new Map(savePath);
|
sites.Add(new Vector2((float)Game1.random.NextDouble() * size, (float)Game1.random.NextDouble() * size));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
List<GraphEdge> edges = voronoi.MakeVoronoiGraph(sites, size, size);
|
||||||
|
|
||||||
loaded.SaveAs(savePath);
|
sites.Clear();
|
||||||
}
|
foreach (GraphEdge edge in edges)
|
||||||
|
|
||||||
public static void PreloadMaps(string mapFolder)
|
|
||||||
{
|
|
||||||
MapFolder = mapFolder;
|
|
||||||
|
|
||||||
//string[] mapFilePaths;
|
|
||||||
Unload();
|
|
||||||
SavedMaps.Clear();
|
|
||||||
|
|
||||||
if (!Directory.Exists(MapFolder))
|
|
||||||
{
|
{
|
||||||
try
|
if (edge.point1 == edge.point2) continue;
|
||||||
|
|
||||||
|
Location[] newLocations = new Location[2];
|
||||||
|
newLocations[0] = locations.Find(l => l.MapPosition == edge.point1 || l.MapPosition == edge.point2);
|
||||||
|
newLocations[1] = locations.Find(l => l != newLocations[0] && (l.MapPosition == edge.point1 || l.MapPosition == edge.point2));
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(MapFolder);
|
if (newLocations[i] != null) continue;
|
||||||
|
|
||||||
|
Vector2[] points = new Vector2[] { edge.point1, edge.point2 };
|
||||||
|
|
||||||
|
int positionIndex = Game1.random.Next(0, 1);
|
||||||
|
|
||||||
|
Vector2 position = points[positionIndex];
|
||||||
|
if (newLocations[1 - i] != null && newLocations[1 - i].MapPosition == position) position = points[1 - positionIndex];
|
||||||
|
|
||||||
|
newLocations[i] = Location.CreateRandom(position);
|
||||||
|
locations.Add(newLocations[i]);
|
||||||
}
|
}
|
||||||
catch
|
|
||||||
|
connections.Add(new LocationConnection(newLocations[0], newLocations[1], Level.CreateRandom()));
|
||||||
|
}
|
||||||
|
|
||||||
|
float minDistance = 50.0f;
|
||||||
|
for (int i = connections.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
LocationConnection connection = connections[i];
|
||||||
|
|
||||||
|
if (Vector2.Distance(connection.Locations[0].MapPosition, connection.Locations[1].MapPosition) > minDistance) continue;
|
||||||
|
|
||||||
|
locations.Remove(connection.Locations[0]);
|
||||||
|
connections.Remove(connection);
|
||||||
|
|
||||||
|
foreach (LocationConnection connection2 in connections)
|
||||||
{
|
{
|
||||||
|
if (connection2.Locations[0] == connection.Locations[0]) connection2.Locations[0] = connection.Locations[1];
|
||||||
DebugConsole.ThrowError("Directory ''Content/SavedMaps'' not found and creating the directory failed.");
|
if (connection2.Locations[1] == connection.Locations[0]) connection2.Locations[1] = connection.Locations[1];
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string[] mapFilePaths;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mapFilePaths = Directory.GetFiles(MapFolder);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Couldn't open directory ''Content/SavedMaps''!", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (string mapPath in mapFilePaths)
|
|
||||||
{
|
|
||||||
//Map savedMap = new Map(mapPath);
|
|
||||||
SavedMaps.Add(new Map(mapPath));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map(string filePath, string mapHash="")
|
|
||||||
{
|
|
||||||
this.filePath = filePath;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
name = Path.GetFileNameWithoutExtension(filePath);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Error loading map " + filePath + "!", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (mapHash != "")
|
|
||||||
{
|
|
||||||
this.mapHash = new MapHash(mapHash);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//XDocument doc = OpenDoc(filePath);
|
|
||||||
|
|
||||||
//string md5Hash = ToolBox.GetAttributeString(doc.Root, "md5hash", "");
|
|
||||||
//if (md5Hash == "" || md5Hash.Length < 16)
|
|
||||||
//{
|
|
||||||
// DebugConsole.ThrowError("Couldn't find a valid MD5 hash in the map file");
|
|
||||||
//}
|
|
||||||
|
|
||||||
//this.mapHash = new MapHash(md5Hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private XDocument OpenDoc(string file)
|
public void Draw(SpriteBatch spriteBatch, Rectangle rect)
|
||||||
{
|
{
|
||||||
XDocument doc = null;
|
GUI.DrawRectangle(spriteBatch, rect, Color.DarkBlue, true);
|
||||||
string extension = "";
|
|
||||||
|
|
||||||
try
|
Vector2 scale = new Vector2((float)rect.Width/ size, (float)rect.Height/size);
|
||||||
{
|
|
||||||
extension = Path.GetExtension(file);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Couldn't load map ''" + file + "! (Unrecognized file extension)");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extension == ".gz")
|
float maxDist = 20.0f;
|
||||||
|
float closestDist = 0.0f;
|
||||||
|
Location highlightedLocation = null;
|
||||||
|
foreach (Location location in locations)
|
||||||
{
|
{
|
||||||
Stream stream = SaveUtil.DecompressFiletoStream(file);
|
Vector2 pos = location.MapPosition * scale;
|
||||||
if (stream == null)
|
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X + (int)pos.X, rect.Y + (int)pos.Y, 5, 5), Color.White, true);
|
||||||
|
|
||||||
|
if (currentLocation == location)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Loading map ''" + file + "'' failed!");
|
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X + (int)pos.X - 4, rect.Y + (int)pos.Y - 4, 5+8, 5+8), Color.Red, false);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
float dist = Vector2.Distance(PlayerInput.MousePosition, new Vector2(rect.X + pos.X, rect.Y + pos.Y));
|
||||||
|
if (dist < maxDist && (highlightedLocation == null || dist < closestDist))
|
||||||
{
|
{
|
||||||
stream.Position = 0;
|
closestDist = dist;
|
||||||
doc = XDocument.Load(stream); //ToolBox.TryLoadXml(file);
|
highlightedLocation = location;
|
||||||
stream.Close();
|
|
||||||
stream.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Loading map ''" + file + "'' failed!");
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (extension == ".xml")
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
doc = XDocument.Load(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
catch
|
if (highlightedLocation!=null)
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Loading map ''" + file + "'' failed!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Couldn't load map ''" + file + "! (Unrecognized file extension)");
|
Vector2 pos = highlightedLocation.MapPosition * scale;
|
||||||
return null;
|
spriteBatch.DrawString(GUI.font, highlightedLocation.Name, pos + new Vector2(rect.X - 50, rect.Y), Color.White);
|
||||||
|
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X + (int)pos.X - 4, rect.Y + (int)pos.Y - 4, 5 + 8, 5 + 8), Color.White, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return doc;
|
if (selectedLocation != null)
|
||||||
}
|
|
||||||
|
|
||||||
public void Load()
|
|
||||||
{
|
|
||||||
//string file = filePath;
|
|
||||||
|
|
||||||
XDocument doc = OpenDoc(filePath);
|
|
||||||
if (doc == null) return;
|
|
||||||
|
|
||||||
foreach (XElement element in doc.Root.Elements())
|
|
||||||
{
|
{
|
||||||
string typeName = element.Name.ToString();
|
Vector2 pos = selectedLocation.MapPosition * scale;
|
||||||
|
spriteBatch.DrawString(GUI.font, selectedLocation.Name, pos + new Vector2(rect.X - 50, rect.Y), Color.White);
|
||||||
|
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X + (int)pos.X - 4, rect.Y + (int)pos.Y - 4, 5 + 8, 5 + 8), Color.White, false);
|
||||||
|
}
|
||||||
|
|
||||||
Type t;
|
Vector2 rectCorner = new Vector2(rect.X, rect.Y);
|
||||||
try
|
foreach (LocationConnection connection in connections)
|
||||||
|
{
|
||||||
|
GUI.DrawLine(spriteBatch,
|
||||||
|
connection.Locations[0].MapPosition * scale + rectCorner,
|
||||||
|
connection.Locations[1].MapPosition * scale + rectCorner, Color.LightGray);
|
||||||
|
|
||||||
|
if (highlightedLocation!=currentLocation &&
|
||||||
|
connection.Locations.Contains(highlightedLocation) && connection.Locations.Contains(currentLocation))
|
||||||
{
|
{
|
||||||
// Get the type of a specified class.
|
GUI.DrawLine(spriteBatch,
|
||||||
t = Type.GetType("Subsurface." + typeName + ", Subsurface", true, true);
|
connection.Locations[0].MapPosition * scale + rectCorner +Vector2.One,
|
||||||
if (t == null)
|
connection.Locations[1].MapPosition * scale + rectCorner + Vector2.One, Color.White);
|
||||||
|
|
||||||
|
if (PlayerInput.LeftButtonClicked())
|
||||||
|
if(selectedLocation!=highlightedLocation && highlightedLocation!=null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Error in " + filePath + "! Could not find a entity of the type ''" + typeName + "''.");
|
//currentLocation = highlightedLocation;
|
||||||
continue;
|
Game1.LobbyScreen.SelectLocation(highlightedLocation, connection);
|
||||||
|
selectedLocation = highlightedLocation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
|
if (selectedLocation != currentLocation &&
|
||||||
|
(connection.Locations.Contains(selectedLocation) && connection.Locations.Contains(currentLocation)))
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Error in " + filePath + "! Could not find a entity of the type ''" + typeName + "''.", e);
|
GUI.DrawLine(spriteBatch,
|
||||||
continue;
|
connection.Locations[0].MapPosition * scale + rectCorner + Vector2.One,
|
||||||
}
|
connection.Locations[1].MapPosition * scale + rectCorner + Vector2.One, Color.White);
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
MethodInfo loadMethod = t.GetMethod("Load");
|
|
||||||
loadMethod.Invoke(t, new object[] { element });
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Could not find the method ''Load'' in " + t + ".", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
borders = new Rectangle(0, 0, 1, 1);
|
|
||||||
foreach (Hull hull in Hull.hullList)
|
|
||||||
{
|
|
||||||
if (hull.Rect.X < borders.X || borders.X == 0) borders.X = hull.Rect.X;
|
|
||||||
if (hull.Rect.Y > borders.Y || borders.Y == 0) borders.Y = hull.Rect.Y;
|
|
||||||
|
|
||||||
if (hull.Rect.X + hull.Rect.Width > borders.X + borders.Width) borders.Width = hull.Rect.X + hull.Rect.Width - borders.X;
|
|
||||||
if (hull.Rect.Y - hull.Rect.Height < borders.Y - borders.Height) borders.Height = borders.Y - (hull.Rect.Y - hull.Rect.Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
MapEntity.LinkAll();
|
|
||||||
foreach (Item item in Item.itemList)
|
|
||||||
{
|
|
||||||
foreach (ItemComponent ic in item.components)
|
|
||||||
{
|
|
||||||
ic.OnMapLoaded();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loaded = this;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Map Load(string file)
|
|
||||||
|
class LocationConnection
|
||||||
|
{
|
||||||
|
Location[] locations;
|
||||||
|
Level level;
|
||||||
|
|
||||||
|
public Location[] Locations
|
||||||
{
|
{
|
||||||
Unload();
|
get { return locations; }
|
||||||
|
|
||||||
Map map = new Map(file);
|
|
||||||
map.Load();
|
|
||||||
|
|
||||||
return map;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Unload()
|
public Level Level
|
||||||
{
|
{
|
||||||
if (loaded == null) return;
|
get { return level; }
|
||||||
loaded.Clear();
|
|
||||||
loaded = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Clear()
|
public LocationConnection(Location location1, Location location2, Level level)
|
||||||
{
|
{
|
||||||
if (Game1.GameScreen.Cam != null) Game1.GameScreen.Cam.TargetPos = Vector2.Zero;
|
locations = new Location[] { location1, location2 };
|
||||||
|
this.level = level;
|
||||||
Entity.RemoveAll();
|
|
||||||
|
|
||||||
PhysicsBody.list.Clear();
|
|
||||||
|
|
||||||
Ragdoll.list.Clear();
|
|
||||||
|
|
||||||
Game1.world.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
public virtual bool Contains(Vector2 position)
|
public virtual bool Contains(Vector2 position)
|
||||||
{
|
{
|
||||||
return (Map.RectContains(rect, position));
|
return (Submarine.RectContains(rect, position));
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Draw(SpriteBatch spriteBatch, bool editing) {}
|
public virtual void Draw(SpriteBatch spriteBatch, bool editing) {}
|
||||||
@@ -216,7 +216,7 @@ namespace Subsurface
|
|||||||
//mouse released -> move the entities to the new position of the mouse
|
//mouse released -> move the entities to the new position of the mouse
|
||||||
|
|
||||||
Vector2 moveAmount = position - startMovingPos;
|
Vector2 moveAmount = position - startMovingPos;
|
||||||
moveAmount = Map.VectorToWorldGrid(moveAmount);
|
moveAmount = Submarine.VectorToWorldGrid(moveAmount);
|
||||||
|
|
||||||
if (moveAmount != Vector2.Zero)
|
if (moveAmount != Vector2.Zero)
|
||||||
{
|
{
|
||||||
@@ -235,7 +235,7 @@ namespace Subsurface
|
|||||||
selectionSize.Y = selectionPos.Y - position.Y;
|
selectionSize.Y = selectionPos.Y - position.Y;
|
||||||
|
|
||||||
List<MapEntity> newSelection = new List<MapEntity>();// FindSelectedEntities(selectionPos, selectionSize);
|
List<MapEntity> newSelection = new List<MapEntity>();// FindSelectedEntities(selectionPos, selectionSize);
|
||||||
if (Math.Abs(selectionSize.X) > Map.gridSize.X || Math.Abs(selectionSize.Y) > Map.gridSize.Y)
|
if (Math.Abs(selectionSize.X) > Submarine.gridSize.X || Math.Abs(selectionSize.Y) > Submarine.gridSize.Y)
|
||||||
{
|
{
|
||||||
newSelection = FindSelectedEntities(selectionPos, selectionSize);
|
newSelection = FindSelectedEntities(selectionPos, selectionSize);
|
||||||
}
|
}
|
||||||
@@ -315,7 +315,7 @@ namespace Subsurface
|
|||||||
if (startMovingPos != Vector2.Zero)
|
if (startMovingPos != Vector2.Zero)
|
||||||
{
|
{
|
||||||
Vector2 moveAmount = position - startMovingPos;
|
Vector2 moveAmount = position - startMovingPos;
|
||||||
moveAmount = Map.VectorToWorldGrid(moveAmount);
|
moveAmount = Submarine.VectorToWorldGrid(moveAmount);
|
||||||
moveAmount.Y = -moveAmount.Y;
|
moveAmount.Y = -moveAmount.Y;
|
||||||
//started moving the selected entities
|
//started moving the selected entities
|
||||||
if (moveAmount != Vector2.Zero)
|
if (moveAmount != Vector2.Zero)
|
||||||
@@ -358,7 +358,7 @@ namespace Subsurface
|
|||||||
List<MapEntity> foundEntities = new List<MapEntity>();
|
List<MapEntity> foundEntities = new List<MapEntity>();
|
||||||
foreach (MapEntity e in mapEntityList)
|
foreach (MapEntity e in mapEntityList)
|
||||||
{
|
{
|
||||||
if (Map.RectContains(e.rect, pos)) foundEntities.Add(e);
|
if (Submarine.RectContains(e.rect, pos)) foundEntities.Add(e);
|
||||||
}
|
}
|
||||||
return foundEntities;
|
return foundEntities;
|
||||||
}
|
}
|
||||||
@@ -367,7 +367,7 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
foreach (MapEntity e in mapEntityList)
|
foreach (MapEntity e in mapEntityList)
|
||||||
{
|
{
|
||||||
if (Map.RectContains(e.rect, pos)) return e;
|
if (Submarine.RectContains(e.rect, pos)) return e;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -379,11 +379,11 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
List<MapEntity> foundEntities = new List<MapEntity>();
|
List<MapEntity> foundEntities = new List<MapEntity>();
|
||||||
|
|
||||||
Rectangle selectionRect = Map.AbsRect(pos, size);
|
Rectangle selectionRect = Submarine.AbsRect(pos, size);
|
||||||
|
|
||||||
foreach (MapEntity e in mapEntityList)
|
foreach (MapEntity e in mapEntityList)
|
||||||
{
|
{
|
||||||
if (Map.RectsOverlap(selectionRect, e.rect))
|
if (Submarine.RectsOverlap(selectionRect, e.rect))
|
||||||
foundEntities.Add(e);
|
foundEntities.Add(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,23 +73,23 @@ namespace Subsurface
|
|||||||
|
|
||||||
public virtual void UpdatePlacing(SpriteBatch spriteBatch, Camera cam)
|
public virtual void UpdatePlacing(SpriteBatch spriteBatch, Camera cam)
|
||||||
{
|
{
|
||||||
Vector2 placeSize = Map.gridSize;
|
Vector2 placeSize = Submarine.gridSize;
|
||||||
|
|
||||||
if (placePosition == Vector2.Zero)
|
if (placePosition == Vector2.Zero)
|
||||||
{
|
{
|
||||||
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
|
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
|
||||||
placePosition = Map.MouseToWorldGrid(cam);
|
placePosition = Submarine.MouseToWorldGrid(cam);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Vector2 position = Map.MouseToWorldGrid(cam);
|
Vector2 position = Submarine.MouseToWorldGrid(cam);
|
||||||
|
|
||||||
if (resizeHorizontal) placeSize.X = position.X - placePosition.X;
|
if (resizeHorizontal) placeSize.X = position.X - placePosition.X;
|
||||||
if (resizeVertical) placeSize.Y = placePosition.Y - position.Y;
|
if (resizeVertical) placeSize.Y = placePosition.Y - position.Y;
|
||||||
|
|
||||||
Rectangle newRect = Map.AbsRect(placePosition, placeSize);
|
Rectangle newRect = Submarine.AbsRect(placePosition, placeSize);
|
||||||
newRect.Width = (int)Math.Max(newRect.Width, Map.gridSize.X);
|
newRect.Width = (int)Math.Max(newRect.Width, Submarine.gridSize.X);
|
||||||
newRect.Height = (int)Math.Max(newRect.Height, Map.gridSize.Y);
|
newRect.Height = (int)Math.Max(newRect.Height, Submarine.gridSize.Y);
|
||||||
|
|
||||||
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Released)
|
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Released)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
using System;
|
using System.Security.Cryptography;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Subsurface
|
namespace Subsurface
|
||||||
{
|
{
|
||||||
class MapHash
|
class Md5Hash
|
||||||
{
|
{
|
||||||
private string md5Hash;
|
private string md5Hash;
|
||||||
private string shortHash;
|
private string shortHash;
|
||||||
@@ -29,14 +26,14 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapHash(string md5Hash)
|
public Md5Hash(string md5Hash)
|
||||||
{
|
{
|
||||||
this.md5Hash = md5Hash;
|
this.md5Hash = md5Hash;
|
||||||
|
|
||||||
shortHash = GetShortHash(md5Hash);
|
shortHash = GetShortHash(md5Hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapHash(XDocument doc)
|
public Md5Hash(XDocument doc)
|
||||||
{
|
{
|
||||||
string docString = Regex.Replace(doc.ToString(), @"\s+", "");
|
string docString = Regex.Replace(doc.ToString(), @"\s+", "");
|
||||||
// step 1, calculate MD5 hash from input
|
// step 1, calculate MD5 hash from input
|
||||||
@@ -111,7 +111,7 @@ namespace Subsurface
|
|||||||
Vector2 simAmount = ConvertUnits.ToSimUnits(amount);
|
Vector2 simAmount = ConvertUnits.ToSimUnits(amount);
|
||||||
foreach (Body b in bodies)
|
foreach (Body b in bodies)
|
||||||
{
|
{
|
||||||
b.SetTransform(b.Position + simAmount, 0.0f);
|
b.SetTransform(b.Position + simAmount, b.Rotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,15 +203,15 @@ namespace Subsurface
|
|||||||
bodies = new List<Body>();
|
bodies = new List<Body>();
|
||||||
|
|
||||||
Body newBody = BodyFactory.CreateRectangle(Game1.world,
|
Body newBody = BodyFactory.CreateRectangle(Game1.world,
|
||||||
ConvertUnits.ToSimUnits(rect.Width * Math.Sqrt(2.0) - Map.gridSize.X),
|
ConvertUnits.ToSimUnits(rect.Width * Math.Sqrt(2.0) - Submarine.gridSize.X),
|
||||||
ConvertUnits.ToSimUnits(10),
|
ConvertUnits.ToSimUnits(10),
|
||||||
1.5f);
|
1.5f);
|
||||||
|
|
||||||
newBody.BodyType = BodyType.Static;
|
newBody.BodyType = BodyType.Static;
|
||||||
Vector2 stairPos = new Vector2(Position.X, rect.Y - rect.Height + rect.Width / 2.0f);
|
Vector2 stairPos = new Vector2(Position.X, rect.Y - rect.Height + rect.Width / 2.0f);
|
||||||
stairPos += new Vector2(
|
stairPos += new Vector2(
|
||||||
(StairDirection == Direction.Right) ? -Map.gridSize.X*1.5f : Map.gridSize.X*1.5f,
|
(StairDirection == Direction.Right) ? -Submarine.gridSize.X*1.5f : Submarine.gridSize.X*1.5f,
|
||||||
- Map.gridSize.Y*2.0f);
|
- Submarine.gridSize.Y*2.0f);
|
||||||
|
|
||||||
|
|
||||||
newBody.Position = ConvertUnits.ToSimUnits(stairPos);
|
newBody.Position = ConvertUnits.ToSimUnits(stairPos);
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
public override void UpdatePlacing(SpriteBatch spriteBatch, Camera cam)
|
public override void UpdatePlacing(SpriteBatch spriteBatch, Camera cam)
|
||||||
{
|
{
|
||||||
Vector2 position = Map.MouseToWorldGrid(cam);
|
Vector2 position = Submarine.MouseToWorldGrid(cam);
|
||||||
//Vector2 placeSize = size;
|
//Vector2 placeSize = size;
|
||||||
|
|
||||||
Rectangle newRect = new Rectangle((int)position.X, (int)position.Y, (int)size.X, (int)size.Y);
|
Rectangle newRect = new Rectangle((int)position.X, (int)position.Y, (int)size.X, (int)size.Y);
|
||||||
@@ -118,7 +118,7 @@ namespace Subsurface
|
|||||||
if (placePosition == Vector2.Zero)
|
if (placePosition == Vector2.Zero)
|
||||||
{
|
{
|
||||||
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
|
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
|
||||||
placePosition = Map.MouseToWorldGrid(cam);
|
placePosition = Submarine.MouseToWorldGrid(cam);
|
||||||
|
|
||||||
newRect.X = (int)position.X;
|
newRect.X = (int)position.X;
|
||||||
newRect.Y = (int)position.Y;
|
newRect.Y = (int)position.Y;
|
||||||
@@ -131,7 +131,7 @@ namespace Subsurface
|
|||||||
if (resizeHorizontal) placeSize.X = position.X - placePosition.X;
|
if (resizeHorizontal) placeSize.X = position.X - placePosition.X;
|
||||||
if (resizeVertical) placeSize.Y = placePosition.Y - position.Y;
|
if (resizeVertical) placeSize.Y = placePosition.Y - position.Y;
|
||||||
|
|
||||||
newRect = Map.AbsRect(placePosition, placeSize);
|
newRect = Submarine.AbsRect(placePosition, placeSize);
|
||||||
|
|
||||||
//newRect.Width = (int)Math.Max(newRect.Width, Map.gridSize.X);
|
//newRect.Width = (int)Math.Max(newRect.Width, Map.gridSize.X);
|
||||||
//newRect.Height = (int)Math.Max(newRect.Height, Map.gridSize.Y);
|
//newRect.Height = (int)Math.Max(newRect.Height, Map.gridSize.Y);
|
||||||
|
|||||||
@@ -0,0 +1,564 @@
|
|||||||
|
using FarseerPhysics;
|
||||||
|
using FarseerPhysics.Collision;
|
||||||
|
using FarseerPhysics.Dynamics;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Subsurface
|
||||||
|
{
|
||||||
|
public enum Direction : byte
|
||||||
|
{
|
||||||
|
None = 0, Left = 1, Right = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
class Submarine
|
||||||
|
{
|
||||||
|
static string SaveFolder;
|
||||||
|
Md5Hash hash;
|
||||||
|
|
||||||
|
public static List<Submarine> SavedSubmarines = new List<Submarine>();
|
||||||
|
|
||||||
|
private static Submarine loaded;
|
||||||
|
|
||||||
|
//public static Map Loaded
|
||||||
|
//{
|
||||||
|
// get { return loaded; }
|
||||||
|
// set { loaded = value; }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
public static readonly Vector2 gridSize = new Vector2(16.0f, 16.0f);
|
||||||
|
|
||||||
|
private static Vector2 lastPickedPosition;
|
||||||
|
private static float lastPickedFraction;
|
||||||
|
|
||||||
|
private Rectangle borders;
|
||||||
|
|
||||||
|
private string filePath;
|
||||||
|
private string name;
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return name; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2 LastPickedPosition
|
||||||
|
{
|
||||||
|
get { return lastPickedPosition; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float LastPickedFraction
|
||||||
|
{
|
||||||
|
get { return lastPickedFraction; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Md5Hash Hash
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (hash != null) return hash;
|
||||||
|
|
||||||
|
XDocument doc = OpenDoc(filePath);
|
||||||
|
hash = new Md5Hash(doc);
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Submarine Loaded
|
||||||
|
{
|
||||||
|
get { return loaded; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Rectangle Borders
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (loaded==null) ? Rectangle.Empty : loaded.borders;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 Center
|
||||||
|
{
|
||||||
|
get { return new Vector2(borders.X+borders.Width/2, borders.Y - borders.Height/2); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FilePath
|
||||||
|
{
|
||||||
|
get { return filePath; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Draw(SpriteBatch spriteBatch, bool editing = false)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MapEntity.mapEntityList.Count(); i++ )
|
||||||
|
{
|
||||||
|
MapEntity.mapEntityList[i].Draw(spriteBatch, editing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DrawFront(SpriteBatch spriteBatch, bool editing = false)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MapEntity.mapEntityList.Count(); i++)
|
||||||
|
{
|
||||||
|
if (MapEntity.mapEntityList[i].sprite == null || MapEntity.mapEntityList[i].sprite.Depth < 0.5f)
|
||||||
|
MapEntity.mapEntityList[i].Draw(spriteBatch, editing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DrawBack(SpriteBatch spriteBatch, bool editing = false)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MapEntity.mapEntityList.Count(); i++)
|
||||||
|
{
|
||||||
|
if (MapEntity.mapEntityList[i].sprite == null || MapEntity.mapEntityList[i].sprite.Depth >= 0.5f)
|
||||||
|
MapEntity.mapEntityList[i].Draw(spriteBatch, editing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2 MouseToWorldGrid(Camera cam)
|
||||||
|
{
|
||||||
|
Vector2 position = new Vector2(PlayerInput.GetMouseState.X, PlayerInput.GetMouseState.Y);
|
||||||
|
position = cam.ScreenToWorld(position);
|
||||||
|
|
||||||
|
return VectorToWorldGrid(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2 VectorToWorldGrid(Vector2 position)
|
||||||
|
{
|
||||||
|
position.X = (float)Math.Floor(Convert.ToDouble(position.X / gridSize.X)) * gridSize.X;
|
||||||
|
position.Y = (float)Math.Ceiling(Convert.ToDouble(position.Y / gridSize.Y)) * gridSize.Y;
|
||||||
|
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Rectangle AbsRect(Vector2 pos, Vector2 size)
|
||||||
|
{
|
||||||
|
if (size.X < 0.0f)
|
||||||
|
{
|
||||||
|
pos.X += size.X;
|
||||||
|
size.X = -size.X;
|
||||||
|
}
|
||||||
|
if (size.Y < 0.0f)
|
||||||
|
{
|
||||||
|
pos.Y -= size.Y;
|
||||||
|
size.Y = -size.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Rectangle((int)pos.X, (int)pos.Y, (int)size.X, (int)size.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool RectContains(Rectangle rect, Vector2 pos)
|
||||||
|
{
|
||||||
|
return (pos.X > rect.X && pos.X < rect.X + rect.Width
|
||||||
|
&& pos.Y < rect.Y && pos.Y > rect.Y - rect.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool RectsOverlap(Rectangle rect1, Rectangle rect2, bool inclusive=true)
|
||||||
|
{
|
||||||
|
if (inclusive)
|
||||||
|
{
|
||||||
|
return !(rect1.X > rect2.X + rect2.Width || rect1.X + rect1.Width < rect2.X ||
|
||||||
|
rect1.Y < rect2.Y - rect2.Height || rect1.Y - rect1.Height > rect2.Y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return !(rect1.X >= rect2.X + rect2.Width || rect1.X + rect1.Width <= rect2.X ||
|
||||||
|
rect1.Y <= rect2.Y - rect2.Height || rect1.Y - rect1.Height >= rect2.Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Move(Vector2 amount, float deltaTime)
|
||||||
|
{
|
||||||
|
if (amount == Vector2.Zero) return;
|
||||||
|
|
||||||
|
Level.Loaded.Move(-amount, deltaTime);
|
||||||
|
|
||||||
|
//foreach (MapEntity e in Structure.mapEntityList)
|
||||||
|
//{
|
||||||
|
// e.Move(amount);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//amount = ConvertUnits.ToSimUnits(amount*deltaTime);
|
||||||
|
//foreach (Character c in Character.characterList)
|
||||||
|
//{
|
||||||
|
// if (c.animController.CurrentHull != null) continue;
|
||||||
|
// foreach (Limb l in c.animController.limbs)
|
||||||
|
// {
|
||||||
|
// l.body.SetTransform(l.body.Position - amount, l.body.Rotation);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Body PickBody(Vector2 rayStart, Vector2 rayEnd, List<Body> ignoredBodies = null)
|
||||||
|
{
|
||||||
|
float closestFraction = 1.0f;
|
||||||
|
Body closestBody = null;
|
||||||
|
Game1.world.RayCast((fixture, point, normal, fraction) =>
|
||||||
|
{
|
||||||
|
if (fixture == null || fixture.CollisionCategories == Category.None) return -1;
|
||||||
|
if (ignoredBodies != null && ignoredBodies.Contains(fixture.Body)) return -1;
|
||||||
|
|
||||||
|
Structure structure = fixture.Body.UserData as Structure;
|
||||||
|
if (structure != null && (structure.IsPlatform || !structure.HasBody)) return -1;
|
||||||
|
|
||||||
|
if (fraction < closestFraction)
|
||||||
|
{
|
||||||
|
closestFraction = fraction;
|
||||||
|
if (fixture.Body!=null) closestBody = fixture.Body;
|
||||||
|
}
|
||||||
|
return fraction;
|
||||||
|
}
|
||||||
|
, rayStart, rayEnd);
|
||||||
|
|
||||||
|
lastPickedPosition = rayStart + (rayEnd - rayStart) * closestFraction;
|
||||||
|
lastPickedFraction = closestFraction;
|
||||||
|
return closestBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Body CheckVisibility(Vector2 rayStart, Vector2 rayEnd)
|
||||||
|
{
|
||||||
|
Body closestBody = null;
|
||||||
|
float closestFraction = 1.0f;
|
||||||
|
|
||||||
|
if (Vector2.Distance(rayStart,rayEnd)<0.01f)
|
||||||
|
{
|
||||||
|
closestFraction = 0.01f;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Game1.world.RayCast((fixture, point, normal, fraction) =>
|
||||||
|
{
|
||||||
|
if (fixture == null || fixture.CollisionCategories != Physics.CollisionWall) return -1;
|
||||||
|
|
||||||
|
Structure structure = fixture.Body.UserData as Structure;
|
||||||
|
if (structure != null)
|
||||||
|
{
|
||||||
|
if (structure.IsPlatform || structure.StairDirection != Direction.None) return -1;
|
||||||
|
int sectionIndex = structure.FindSectionIndex(ConvertUnits.ToDisplayUnits(point));
|
||||||
|
if (sectionIndex > -1 && structure.SectionHasHole(sectionIndex)) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fraction < closestFraction)
|
||||||
|
{
|
||||||
|
closestBody = fixture.Body;
|
||||||
|
closestFraction = fraction;
|
||||||
|
}
|
||||||
|
return closestFraction;
|
||||||
|
}
|
||||||
|
, rayStart, rayEnd);
|
||||||
|
|
||||||
|
|
||||||
|
lastPickedPosition = rayStart + (rayEnd - rayStart) * closestFraction;
|
||||||
|
lastPickedFraction = closestFraction;
|
||||||
|
return closestBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Body PickBody(Vector2 point)
|
||||||
|
{
|
||||||
|
Body foundBody = null;
|
||||||
|
AABB aabb = new AABB(point, point);
|
||||||
|
|
||||||
|
Game1.world.QueryAABB(p =>
|
||||||
|
{
|
||||||
|
foundBody = p.Body;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}, ref aabb);
|
||||||
|
|
||||||
|
return foundBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool InsideWall(Vector2 point)
|
||||||
|
{
|
||||||
|
Body foundBody = PickBody(point);
|
||||||
|
if (foundBody==null) return false;
|
||||||
|
|
||||||
|
Structure wall = foundBody.UserData as Structure;
|
||||||
|
if (wall == null || wall.IsPlatform) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
SaveAs(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveAs(string filePath)
|
||||||
|
{
|
||||||
|
//if (filePath=="")
|
||||||
|
//{
|
||||||
|
// DebugConsole.ThrowError("No save file selected");
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
XDocument doc = new XDocument(new XElement((XName)name));
|
||||||
|
|
||||||
|
foreach (MapEntity e in MapEntity.mapEntityList)
|
||||||
|
{
|
||||||
|
e.Save(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
hash = new Md5Hash(doc);
|
||||||
|
doc.Root.Add(new XAttribute("md5hash", hash.MD5Hash));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SaveUtil.CompressStringToFile(filePath, doc.ToString());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Saving submarine ''" + filePath + "'' failed!", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//doc.Save(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SaveCurrent(string savePath)
|
||||||
|
{
|
||||||
|
if (loaded==null)
|
||||||
|
{
|
||||||
|
loaded = new Submarine(savePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loaded.SaveAs(savePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Preload(string folder)
|
||||||
|
{
|
||||||
|
SaveFolder = folder;
|
||||||
|
|
||||||
|
//string[] mapFilePaths;
|
||||||
|
Unload();
|
||||||
|
SavedSubmarines.Clear();
|
||||||
|
|
||||||
|
if (!Directory.Exists(SaveFolder))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(SaveFolder);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
DebugConsole.ThrowError("Directory ''"+SaveFolder+"'' not found and creating the directory failed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] filePaths;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
filePaths = Directory.GetFiles(SaveFolder);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Couldn't open directory ''" + SaveFolder + "''!", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string path in filePaths)
|
||||||
|
{
|
||||||
|
//Map savedMap = new Map(mapPath);
|
||||||
|
SavedSubmarines.Add(new Submarine(path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Submarine(string filePath, string hash="")
|
||||||
|
{
|
||||||
|
this.filePath = filePath;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
name = Path.GetFileNameWithoutExtension(filePath);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error loading map " + filePath + "!", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (hash != "")
|
||||||
|
{
|
||||||
|
this.hash = new Md5Hash(hash);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//XDocument doc = OpenDoc(filePath);
|
||||||
|
|
||||||
|
//string md5Hash = ToolBox.GetAttributeString(doc.Root, "md5hash", "");
|
||||||
|
//if (md5Hash == "" || md5Hash.Length < 16)
|
||||||
|
//{
|
||||||
|
// DebugConsole.ThrowError("Couldn't find a valid MD5 hash in the map file");
|
||||||
|
//}
|
||||||
|
|
||||||
|
//this.mapHash = new MapHash(md5Hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private XDocument OpenDoc(string file)
|
||||||
|
{
|
||||||
|
XDocument doc = null;
|
||||||
|
string extension = "";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
extension = Path.GetExtension(file);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Couldn't load submarine ''" + file + "! (Unrecognized file extension)");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extension == ".gz")
|
||||||
|
{
|
||||||
|
Stream stream = SaveUtil.DecompressFiletoStream(file);
|
||||||
|
if (stream == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Loading submarine ''" + file + "'' failed!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
stream.Position = 0;
|
||||||
|
doc = XDocument.Load(stream); //ToolBox.TryLoadXml(file);
|
||||||
|
stream.Close();
|
||||||
|
stream.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Loading submarine ''" + file + "'' failed!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (extension == ".xml")
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
doc = XDocument.Load(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Loading submarine ''" + file + "'' failed!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Couldn't load submarine ''" + file + "! (Unrecognized file extension)");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Load()
|
||||||
|
{
|
||||||
|
//string file = filePath;
|
||||||
|
|
||||||
|
XDocument doc = OpenDoc(filePath);
|
||||||
|
if (doc == null) return;
|
||||||
|
|
||||||
|
foreach (XElement element in doc.Root.Elements())
|
||||||
|
{
|
||||||
|
string typeName = element.Name.ToString();
|
||||||
|
|
||||||
|
Type t;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Get the type of a specified class.
|
||||||
|
t = Type.GetType("Subsurface." + typeName + ", Subsurface", true, true);
|
||||||
|
if (t == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error in " + filePath + "! Could not find a entity of the type ''" + typeName + "''.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error in " + filePath + "! Could not find a entity of the type ''" + typeName + "''.", e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MethodInfo loadMethod = t.GetMethod("Load");
|
||||||
|
loadMethod.Invoke(t, new object[] { element });
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Could not find the method ''Load'' in " + t + ".", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
borders = new Rectangle(0, 0, 1, 1);
|
||||||
|
foreach (Hull hull in Hull.hullList)
|
||||||
|
{
|
||||||
|
if (hull.Rect.X < borders.X || borders.X == 0) borders.X = hull.Rect.X;
|
||||||
|
if (hull.Rect.Y > borders.Y || borders.Y == 0) borders.Y = hull.Rect.Y;
|
||||||
|
|
||||||
|
if (hull.Rect.X + hull.Rect.Width > borders.X + borders.Width) borders.Width = hull.Rect.X + hull.Rect.Width - borders.X;
|
||||||
|
if (hull.Rect.Y - hull.Rect.Height < borders.Y - borders.Height) borders.Height = borders.Y - (hull.Rect.Y - hull.Rect.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
MapEntity.LinkAll();
|
||||||
|
foreach (Item item in Item.itemList)
|
||||||
|
{
|
||||||
|
foreach (ItemComponent ic in item.components)
|
||||||
|
{
|
||||||
|
ic.OnMapLoaded();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loaded = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Submarine Load(string file)
|
||||||
|
{
|
||||||
|
Unload();
|
||||||
|
|
||||||
|
Submarine sub = new Submarine(file);
|
||||||
|
sub.Load();
|
||||||
|
|
||||||
|
return sub;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Unload()
|
||||||
|
{
|
||||||
|
if (loaded == null) return;
|
||||||
|
loaded.Clear();
|
||||||
|
loaded = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Clear()
|
||||||
|
{
|
||||||
|
if (Game1.GameScreen.Cam != null) Game1.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||||
|
|
||||||
|
Entity.RemoveAll();
|
||||||
|
|
||||||
|
PhysicsBody.list.Clear();
|
||||||
|
|
||||||
|
Ragdoll.list.Clear();
|
||||||
|
|
||||||
|
Game1.world.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -972,5 +972,17 @@ namespace Voronoi2
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<GraphEdge> MakeVoronoiGraph(List<Vector2> sites, int width, int height)
|
||||||
|
{
|
||||||
|
double[] xVal = new double[sites.Count];
|
||||||
|
double[] yVal = new double[sites.Count];
|
||||||
|
for (int i = 0; i < sites.Count; i++)
|
||||||
|
{
|
||||||
|
xVal[i] = sites[i].X;
|
||||||
|
yVal[i] = sites[i].Y;
|
||||||
|
}
|
||||||
|
return generateVoronoi(xVal, yVal, 0, width, 0, height);
|
||||||
|
}
|
||||||
|
|
||||||
} // Voronoi Class End
|
} // Voronoi Class End
|
||||||
} // namespace Voronoi2 End
|
} // namespace Voronoi2 End
|
||||||
@@ -50,7 +50,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
using FarseerPhysics.Dynamics;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
using Subsurface;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
@@ -119,6 +121,8 @@ namespace Voronoi2
|
|||||||
public List<GraphEdge> edges;
|
public List<GraphEdge> edges;
|
||||||
public Site site;
|
public Site site;
|
||||||
|
|
||||||
|
public List<Body> bodies;
|
||||||
|
|
||||||
public Vector2 Center
|
public Vector2 Center
|
||||||
{
|
{
|
||||||
get { return new Vector2((float)site.coord.x, (float)site.coord.y); }
|
get { return new Vector2((float)site.coord.x, (float)site.coord.y); }
|
||||||
@@ -127,6 +131,8 @@ namespace Voronoi2
|
|||||||
public VoronoiCell(Site site)
|
public VoronoiCell(Site site)
|
||||||
{
|
{
|
||||||
edges = new List<GraphEdge>();
|
edges = new List<GraphEdge>();
|
||||||
|
|
||||||
|
bodies = new List<Body>();
|
||||||
this.site = site;
|
this.site = site;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,6 +141,23 @@ namespace Voronoi2
|
|||||||
{
|
{
|
||||||
public Vector2 point1, point2;
|
public Vector2 point1, point2;
|
||||||
public Site site1, site2;
|
public Site site1, site2;
|
||||||
|
public VoronoiCell cell1, cell2;
|
||||||
|
|
||||||
|
public VoronoiCell AdjacentCell(VoronoiCell cell)
|
||||||
|
{
|
||||||
|
if (cell1==cell)
|
||||||
|
{
|
||||||
|
return cell2;
|
||||||
|
}
|
||||||
|
else if (cell2==cell)
|
||||||
|
{
|
||||||
|
return cell1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// للترتيب
|
// للترتيب
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ namespace Subsurface
|
|||||||
if (e.GetType()!=typeof(WayPoint)) continue;
|
if (e.GetType()!=typeof(WayPoint)) continue;
|
||||||
if (e == this) continue;
|
if (e == this) continue;
|
||||||
|
|
||||||
if (!Map.RectContains(e.Rect, position)) continue;
|
if (!Submarine.RectContains(e.Rect, position)) continue;
|
||||||
|
|
||||||
linkedTo.Add(e);
|
linkedTo.Add(e);
|
||||||
e.linkedTo.Add(this);
|
e.linkedTo.Add(this);
|
||||||
@@ -123,7 +123,7 @@ namespace Subsurface
|
|||||||
Rectangle rect = new Rectangle(
|
Rectangle rect = new Rectangle(
|
||||||
int.Parse(element.Attribute("x").Value),
|
int.Parse(element.Attribute("x").Value),
|
||||||
int.Parse(element.Attribute("y").Value),
|
int.Parse(element.Attribute("y").Value),
|
||||||
(int)Map.gridSize.X, (int)Map.gridSize.Y);
|
(int)Submarine.gridSize.X, (int)Submarine.gridSize.Y);
|
||||||
|
|
||||||
WayPoint w = new WayPoint(rect);
|
WayPoint w = new WayPoint(rect);
|
||||||
|
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ namespace Subsurface.Networking
|
|||||||
TimeSpan duration = new TimeSpan(0,(int)durationMinutes,0);
|
TimeSpan duration = new TimeSpan(0,(int)durationMinutes,0);
|
||||||
|
|
||||||
//int gameModeIndex = inc.ReadInt32();
|
//int gameModeIndex = inc.ReadInt32();
|
||||||
Game1.GameSession = new GameSession(Map.Loaded);
|
Game1.GameSession = new GameSession(Submarine.Loaded);
|
||||||
Game1.GameSession.StartShift(duration, 1);
|
Game1.GameSession.StartShift(duration, 1);
|
||||||
|
|
||||||
myCharacter = ReadCharacterData(inc);
|
myCharacter = ReadCharacterData(inc);
|
||||||
@@ -323,7 +323,7 @@ namespace Subsurface.Networking
|
|||||||
|
|
||||||
public void EndGame(string endMessage)
|
public void EndGame(string endMessage)
|
||||||
{
|
{
|
||||||
Map.Unload();
|
Submarine.Unload();
|
||||||
|
|
||||||
Game1.NetLobbyScreen.Select();
|
Game1.NetLobbyScreen.Select();
|
||||||
|
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ namespace Subsurface.Networking
|
|||||||
int seed = DateTime.Now.Millisecond;
|
int seed = DateTime.Now.Millisecond;
|
||||||
Game1.random = new Random(seed);
|
Game1.random = new Random(seed);
|
||||||
|
|
||||||
Map selectedMap = Game1.NetLobbyScreen.SelectedMap as Map;
|
Submarine selectedMap = Game1.NetLobbyScreen.SelectedMap as Submarine;
|
||||||
|
|
||||||
//selectedMap.Load();
|
//selectedMap.Load();
|
||||||
|
|
||||||
@@ -307,7 +307,7 @@ namespace Subsurface.Networking
|
|||||||
msg.Write(seed);
|
msg.Write(seed);
|
||||||
|
|
||||||
msg.Write(Game1.NetLobbyScreen.SelectedMap.Name);
|
msg.Write(Game1.NetLobbyScreen.SelectedMap.Name);
|
||||||
msg.Write(Game1.NetLobbyScreen.SelectedMap.MapHash.MD5Hash);
|
msg.Write(Game1.NetLobbyScreen.SelectedMap.Hash.MD5Hash);
|
||||||
|
|
||||||
msg.Write(Game1.NetLobbyScreen.GameDuration.TotalMinutes);
|
msg.Write(Game1.NetLobbyScreen.GameDuration.TotalMinutes);
|
||||||
|
|
||||||
@@ -339,7 +339,7 @@ namespace Subsurface.Networking
|
|||||||
|
|
||||||
public void EndGame(string endMessage)
|
public void EndGame(string endMessage)
|
||||||
{
|
{
|
||||||
Map.Unload();
|
Submarine.Unload();
|
||||||
|
|
||||||
gameStarted = false;
|
gameStarted = false;
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ namespace Subsurface.Particles
|
|||||||
|
|
||||||
velocity = speed;
|
velocity = speed;
|
||||||
|
|
||||||
this.rotation = rotation + ToolBox.RandomFloat(prefab.startRotationMin, prefab.startRotationMax);
|
this.rotation = rotation + ToolBox.RandomFloatLocal(prefab.startRotationMin, prefab.startRotationMax);
|
||||||
prevRotation = rotation;
|
prevRotation = rotation;
|
||||||
|
|
||||||
float rand = (float)Game1.localRandom.NextDouble();
|
float rand = (float)Game1.localRandom.NextDouble();
|
||||||
@@ -132,7 +132,7 @@ namespace Subsurface.Particles
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Map.InsideWall(new Vector2(drawPosition.X, -drawPosition.Y)))
|
if (Submarine.InsideWall(new Vector2(drawPosition.X, -drawPosition.Y)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace Subsurface.Particles
|
|||||||
|
|
||||||
public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation=0.0f)
|
public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation=0.0f)
|
||||||
{
|
{
|
||||||
if (!Map.RectContains(cam.WorldView, ConvertUnits.ToDisplayUnits(position))) return null;
|
if (!Submarine.RectContains(cam.WorldView, ConvertUnits.ToDisplayUnits(position))) return null;
|
||||||
if (particleCount >= MaxParticles) return null;
|
if (particleCount >= MaxParticles) return null;
|
||||||
|
|
||||||
if (particles[particleCount] == null) particles[particleCount] = new Particle();
|
if (particles[particleCount] == null) particles[particleCount] = new Particle();
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
//Directory.CreateDirectory(Path.GetDirectoryName(filePath) + "\\temp");
|
//Directory.CreateDirectory(Path.GetDirectoryName(filePath) + "\\temp");
|
||||||
|
|
||||||
Map.Loaded.SaveAs(tempPath + "\\map.gz");
|
Submarine.Loaded.SaveAs(tempPath + "\\map.gz");
|
||||||
|
|
||||||
Game1.GameSession.Save(tempPath + "\\gamesession.xml");
|
Game1.GameSession.Save(tempPath + "\\gamesession.xml");
|
||||||
//Game1.GameSession.crewManager.Save(directory+"\\crew.xml");
|
//Game1.GameSession.crewManager.Save(directory+"\\crew.xml");
|
||||||
@@ -39,7 +39,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
DecompressToDirectory(filePath, tempPath, null);
|
DecompressToDirectory(filePath, tempPath, null);
|
||||||
|
|
||||||
Map selectedMap = Map.Load(tempPath +"\\map.gz");
|
Submarine selectedMap = Submarine.Load(tempPath +"\\map.gz");
|
||||||
Game1.GameSession = new GameSession(selectedMap, filePath, tempPath + "\\gamesession.xml");
|
Game1.GameSession = new GameSession(selectedMap, filePath, tempPath + "\\gamesession.xml");
|
||||||
|
|
||||||
Directory.Delete(tempPath, true);
|
Directory.Delete(tempPath, true);
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ namespace Subsurface
|
|||||||
null, null, null, null,
|
null, null, null, null,
|
||||||
cam.Transform);
|
cam.Transform);
|
||||||
|
|
||||||
Map.Draw(spriteBatch, true);
|
Submarine.Draw(spriteBatch, true);
|
||||||
|
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
|
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
graphics.Clear(new Color(0.051f, 0.149f, 0.271f, 1.0f));
|
graphics.Clear(new Color(0.051f, 0.149f, 0.271f, 1.0f));
|
||||||
|
|
||||||
Map.Draw(spriteBatch, true);
|
Submarine.Draw(spriteBatch, true);
|
||||||
|
|
||||||
if (!characterMode)
|
if (!characterMode)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -57,16 +57,16 @@ namespace Subsurface
|
|||||||
|
|
||||||
AmbientSoundManager.Update();
|
AmbientSoundManager.Update();
|
||||||
|
|
||||||
//Vector2 targetMovement = Vector2.Zero;
|
if (Game1.GameSession.Level!=null)
|
||||||
//if (PlayerInput.KeyDown(Keys.I)) targetMovement.Y += 1.0f;
|
{
|
||||||
//if (PlayerInput.KeyDown(Keys.K)) targetMovement.Y -= 1.0f;
|
Vector2 targetMovement = Vector2.Zero;
|
||||||
//if (PlayerInput.KeyDown(Keys.J)) targetMovement.X -= 1.0f;
|
if (PlayerInput.KeyDown(Keys.I)) targetMovement.Y += 1.0f;
|
||||||
//if (PlayerInput.KeyDown(Keys.L)) targetMovement.X += 1.0f;
|
if (PlayerInput.KeyDown(Keys.K)) targetMovement.Y -= 1.0f;
|
||||||
|
if (PlayerInput.KeyDown(Keys.J)) targetMovement.X -= 1.0f;
|
||||||
|
if (PlayerInput.KeyDown(Keys.L)) targetMovement.X += 1.0f;
|
||||||
|
|
||||||
//foreach (MapEntity e in Structure.mapEntityList)
|
Game1.GameSession.Submarine.Move(targetMovement*1000.0f, (float)deltaTime);
|
||||||
//{
|
}
|
||||||
// e.Move(targetMovement);
|
|
||||||
//}
|
|
||||||
|
|
||||||
if (Game1.GameSession!=null) Game1.GameSession.Update((float)deltaTime);
|
if (Game1.GameSession!=null) Game1.GameSession.Update((float)deltaTime);
|
||||||
//EventManager.Update(gameTime);
|
//EventManager.Update(gameTime);
|
||||||
@@ -170,8 +170,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
if (y<0)
|
if (y<0)
|
||||||
{
|
{
|
||||||
backgroundTop.SourceRect = new Rectangle(x, y, 1024, 1024);
|
backgroundTop.SourceRect = new Rectangle(x, y, 1024, Math.Min(-y,1024));
|
||||||
backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(Game1.GraphicsWidth, Math.Min(1024 - y, Game1.GraphicsHeight)),
|
backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(Game1.GraphicsWidth, Math.Min(-y, Game1.GraphicsHeight)),
|
||||||
Vector2.Zero, Color.White);
|
Vector2.Zero, Color.White);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,9 +184,7 @@ namespace Subsurface
|
|||||||
null, null, null, null,
|
null, null, null, null,
|
||||||
cam.Transform);
|
cam.Transform);
|
||||||
|
|
||||||
if (Game1.Level!=null) Game1.Level.Render(spriteBatch);
|
Submarine.DrawBack(spriteBatch);
|
||||||
|
|
||||||
Map.DrawBack(spriteBatch);
|
|
||||||
|
|
||||||
foreach (Character c in Character.characterList) c.Draw(spriteBatch);
|
foreach (Character c in Character.characterList) c.Draw(spriteBatch);
|
||||||
|
|
||||||
@@ -257,10 +255,18 @@ namespace Subsurface
|
|||||||
null, null, null, null,
|
null, null, null, null,
|
||||||
cam.Transform);
|
cam.Transform);
|
||||||
|
|
||||||
Map.DrawFront(spriteBatch);
|
Submarine.DrawFront(spriteBatch);
|
||||||
|
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
|
|
||||||
|
if (Game1.GameSession != null && Game1.GameSession.Level != null)
|
||||||
|
{
|
||||||
|
Game1.GameSession.Level.Render(graphics, cam);
|
||||||
|
Game1.GameSession.Level.SetObserverPosition(cam.WorldViewCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Game1.Level != null) Game1.Level.Render(graphics, cam);
|
||||||
|
|
||||||
LightManager.DrawFow(graphics,cam);
|
LightManager.DrawFow(graphics,cam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,12 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
class LobbyScreen : Screen
|
class LobbyScreen : Screen
|
||||||
{
|
{
|
||||||
|
enum PanelTab { Crew = 0, Map = 1, Hire = 2 }
|
||||||
|
|
||||||
GUIFrame leftPanel;
|
GUIFrame leftPanel;
|
||||||
GUIFrame[] rightPanel;
|
GUIFrame[] rightPanel;
|
||||||
|
|
||||||
GUIFrame shiftPanel;
|
GUIButton startButton;
|
||||||
|
|
||||||
int selectedRightPanel;
|
int selectedRightPanel;
|
||||||
|
|
||||||
@@ -26,6 +28,8 @@ namespace Subsurface
|
|||||||
|
|
||||||
Character previewCharacter;
|
Character previewCharacter;
|
||||||
|
|
||||||
|
Level selectedLevel;
|
||||||
|
|
||||||
public LobbyScreen()
|
public LobbyScreen()
|
||||||
{
|
{
|
||||||
Rectangle panelRect = new Rectangle(
|
Rectangle panelRect = new Rectangle(
|
||||||
@@ -44,62 +48,55 @@ namespace Subsurface
|
|||||||
"", Color.Transparent, Color.White, Alignment.Left, leftPanel);
|
"", Color.Transparent, Color.White, Alignment.Left, leftPanel);
|
||||||
moneyText.TextGetter = GetMoney;
|
moneyText.TextGetter = GetMoney;
|
||||||
|
|
||||||
GUIButton button = new GUIButton(new Rectangle(0, 60, 100, 30), "Crew", GUI.style, Alignment.CenterX, leftPanel);
|
|
||||||
button.UserData = 0;
|
|
||||||
|
GUIButton button = new GUIButton(new Rectangle(0, 60, 100, 30), "Map", GUI.style, Alignment.Left, leftPanel);
|
||||||
|
button.UserData = PanelTab.Map;
|
||||||
button.OnClicked = SelectRightPanel;
|
button.OnClicked = SelectRightPanel;
|
||||||
|
|
||||||
button = new GUIButton(new Rectangle(0, 100, 100, 30), "Hire", GUI.style, Alignment.CenterX, leftPanel);
|
button = new GUIButton(new Rectangle(0, 100, 100, 30), "Crew", GUI.style, Alignment.Left, leftPanel);
|
||||||
button.UserData = 1;
|
button.UserData = PanelTab.Crew;
|
||||||
button.OnClicked = SelectRightPanel;
|
button.OnClicked = SelectRightPanel;
|
||||||
|
|
||||||
//--------------------------------------
|
button = new GUIButton(new Rectangle(0, 140, 100, 30), "Hire", GUI.style, Alignment.Left, leftPanel);
|
||||||
|
button.UserData = PanelTab.Hire;
|
||||||
|
button.OnClicked = SelectRightPanel;
|
||||||
|
|
||||||
|
//---------------------------------------------------------------
|
||||||
|
//---------------------------------------------------------------
|
||||||
|
|
||||||
panelRect = new Rectangle(
|
panelRect = new Rectangle(
|
||||||
panelRect.X + panelRect.Width + (int)(GUI.style.largePadding.X),
|
panelRect.X + panelRect.Width + (int)(GUI.style.largePadding.X),
|
||||||
panelRect.Y,
|
(int)GUI.style.largePadding.Y,
|
||||||
Game1.GraphicsWidth - panelRect.Width - (int)(GUI.style.largePadding.X * 3.0f),
|
Game1.GraphicsWidth - panelRect.Width - (int)(GUI.style.largePadding.X * 3.0f),
|
||||||
(int)(Game1.GraphicsHeight * 0.3f) - (int)(GUI.style.largePadding.Y * 1.5f));
|
Game1.GraphicsHeight - (int)(GUI.style.largePadding.Y * 2));
|
||||||
|
|
||||||
shiftPanel = new GUIFrame(panelRect, GUI.style.backGroundColor);
|
rightPanel = new GUIFrame[3];
|
||||||
shiftPanel.Padding = GUI.style.smallPadding;
|
|
||||||
|
|
||||||
GUITextBlock dayText = new GUITextBlock(new Rectangle(0, 0, 200, 25),
|
rightPanel[(int)PanelTab.Crew] = new GUIFrame(panelRect, GUI.style.backGroundColor);
|
||||||
"", Color.Transparent, Color.White, Alignment.Left, shiftPanel);
|
rightPanel[(int)PanelTab.Crew].Padding = GUI.style.smallPadding;
|
||||||
dayText.TextGetter = GetDay;
|
|
||||||
|
|
||||||
GUIProgressBar progressBar = new GUIProgressBar(new Rectangle(0, 30, 200, 20), Color.Green, 0.0f, shiftPanel);
|
new GUITextBlock(new Rectangle(0, 0, 200, 25), "Crew:", Color.Transparent, Color.White, Alignment.Left, rightPanel[(int)PanelTab.Crew]);
|
||||||
progressBar.ProgressGetter = GetWeekProgress;
|
|
||||||
|
|
||||||
|
characterList = new GUIListBox(new Rectangle(0, 30, 300, 0), Color.White, rightPanel[(int)PanelTab.Crew]);
|
||||||
button = new GUIButton(new Rectangle(0,0,100,30), "Start", GUI.style,
|
|
||||||
(Alignment.Right | Alignment.Bottom), shiftPanel);
|
|
||||||
button.OnClicked = StartShift;
|
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
|
||||||
//---------------------------------------------------------------
|
|
||||||
|
|
||||||
rightPanel = new GUIFrame[2];
|
|
||||||
|
|
||||||
panelRect = new Rectangle(
|
|
||||||
panelRect.X,
|
|
||||||
panelRect.Y + panelRect.Height + (int)(GUI.style.largePadding.Y),
|
|
||||||
panelRect.Width,
|
|
||||||
(int)(Game1.GraphicsHeight * 0.7f) - (int)(GUI.style.largePadding.Y * 1.5f));
|
|
||||||
|
|
||||||
rightPanel[0] = new GUIFrame(panelRect, GUI.style.backGroundColor);
|
|
||||||
rightPanel[0].Padding = GUI.style.smallPadding;
|
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 0, 200, 25), "Crew:", Color.Transparent, Color.White, Alignment.Left, rightPanel[0]);
|
|
||||||
|
|
||||||
characterList = new GUIListBox(new Rectangle(0, 30, 300, 0), Color.White, rightPanel[0]);
|
|
||||||
characterList.OnSelected = SelectCharacter;
|
characterList.OnSelected = SelectCharacter;
|
||||||
|
|
||||||
//---------------------------------------
|
//---------------------------------------
|
||||||
|
|
||||||
rightPanel[1] = new GUIFrame(panelRect, GUI.style.backGroundColor);
|
rightPanel[(int)PanelTab.Map] = new GUIFrame(panelRect, GUI.style.backGroundColor);
|
||||||
rightPanel[1].Padding = GUI.style.smallPadding;
|
rightPanel[(int)PanelTab.Map].Padding = GUI.style.smallPadding;
|
||||||
|
|
||||||
hireList = new GUIListBox(new Rectangle(0, 30, 300, 0), Color.White, Alignment.Left, rightPanel[1]);
|
startButton = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", GUI.style,
|
||||||
|
Alignment.BottomRight, rightPanel[(int)PanelTab.Map]);
|
||||||
|
startButton.OnClicked = StartShift;
|
||||||
|
startButton.Enabled = false;
|
||||||
|
|
||||||
|
//---------------------------------------
|
||||||
|
|
||||||
|
rightPanel[(int)PanelTab.Hire] = new GUIFrame(panelRect, GUI.style.backGroundColor);
|
||||||
|
rightPanel[(int)PanelTab.Hire].Padding = GUI.style.smallPadding;
|
||||||
|
|
||||||
|
hireList = new GUIListBox(new Rectangle(0, 30, 300, 0), Color.White, Alignment.Left, rightPanel[(int)PanelTab.Hire]);
|
||||||
hireList.OnSelected = HireCharacter;
|
hireList.OnSelected = HireCharacter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,7 +165,22 @@ namespace Subsurface
|
|||||||
previewCharacter.animController.UpdateAnim((float)Physics.step);
|
previewCharacter.animController.UpdateAnim((float)Physics.step);
|
||||||
Game1.world.Step((float)Physics.step);
|
Game1.world.Step((float)Physics.step);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelectLocation(Location location, LocationConnection connection)
|
||||||
|
{
|
||||||
|
GUIComponent locationPanel = rightPanel[(int)PanelTab.Map].GetChild("selectedlocation");
|
||||||
|
|
||||||
|
if (locationPanel != null) rightPanel[(int)PanelTab.Map].RemoveChild(locationPanel);
|
||||||
|
|
||||||
|
locationPanel = new GUIFrame(new Rectangle(0, 0, rightPanel[(int)PanelTab.Map].Rect.Width / 2 - 40, 190), Color.Transparent, rightPanel[(int)PanelTab.Map]);
|
||||||
|
locationPanel.UserData = "selectedlocation";
|
||||||
|
|
||||||
|
new GUITextBlock(new Rectangle(0,0,100,20), location.Name, Color.Transparent, Color.White, Alignment.TopLeft, locationPanel);
|
||||||
|
|
||||||
|
startButton.Enabled = true;
|
||||||
|
|
||||||
|
selectedLevel = connection.Level;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateCharacterLists()
|
private void UpdateCharacterLists()
|
||||||
@@ -220,7 +232,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
leftPanel.Update((float)deltaTime);
|
leftPanel.Update((float)deltaTime);
|
||||||
rightPanel[selectedRightPanel].Update((float)deltaTime);
|
rightPanel[selectedRightPanel].Update((float)deltaTime);
|
||||||
shiftPanel.Update((float)deltaTime);
|
//shiftPanel.Update((float)deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
|
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
|
||||||
@@ -239,10 +251,17 @@ namespace Subsurface
|
|||||||
spriteBatch.Begin();
|
spriteBatch.Begin();
|
||||||
|
|
||||||
leftPanel.Draw(spriteBatch);
|
leftPanel.Draw(spriteBatch);
|
||||||
shiftPanel.Draw(spriteBatch);
|
|
||||||
|
|
||||||
rightPanel[selectedRightPanel].Draw(spriteBatch);
|
rightPanel[selectedRightPanel].Draw(spriteBatch);
|
||||||
|
|
||||||
|
if (selectedRightPanel == (int)PanelTab.Map)
|
||||||
|
{
|
||||||
|
Game1.GameSession.map.Draw(spriteBatch, new Rectangle(
|
||||||
|
rightPanel[selectedRightPanel].Rect.Right - 20 - 400,
|
||||||
|
rightPanel[selectedRightPanel].Rect.Y + 20,
|
||||||
|
400, 400));
|
||||||
|
}
|
||||||
|
|
||||||
GUI.Draw((float)deltaTime, spriteBatch, null);
|
GUI.Draw((float)deltaTime, spriteBatch, null);
|
||||||
|
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
@@ -352,7 +371,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
private bool StartShift(GUIButton button, object selection)
|
private bool StartShift(GUIButton button, object selection)
|
||||||
{
|
{
|
||||||
Game1.GameSession.StartShift(TimeSpan.Zero);
|
Game1.GameSession.StartShift(TimeSpan.Zero, selectedLevel);
|
||||||
Game1.GameScreen.Select();
|
Game1.GameScreen.Select();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ namespace Subsurface
|
|||||||
new GUITextBlock(new Rectangle(0, 30, 0, 30), "Selected map:", Color.Transparent, Color.Black, Alignment.Left, menuTabs[(int)Tabs.NewGame]);
|
new GUITextBlock(new Rectangle(0, 30, 0, 30), "Selected map:", Color.Transparent, Color.Black, Alignment.Left, menuTabs[(int)Tabs.NewGame]);
|
||||||
mapList = new GUIListBox(new Rectangle(0, 60, 200, 400), Color.White, menuTabs[(int)Tabs.NewGame]);
|
mapList = new GUIListBox(new Rectangle(0, 60, 200, 400), Color.White, menuTabs[(int)Tabs.NewGame]);
|
||||||
|
|
||||||
foreach (Map map in Map.SavedMaps)
|
foreach (Submarine map in Submarine.SavedSubmarines)
|
||||||
{
|
{
|
||||||
GUITextBlock textBlock = new GUITextBlock(
|
GUITextBlock textBlock = new GUITextBlock(
|
||||||
new Rectangle(0, 0, 0, 25),
|
new Rectangle(0, 0, 0, 25),
|
||||||
@@ -76,7 +76,7 @@ namespace Subsurface
|
|||||||
textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f);
|
textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f);
|
||||||
textBlock.UserData = map;
|
textBlock.UserData = map;
|
||||||
}
|
}
|
||||||
if (Map.SavedMaps.Count > 0) mapList.Select(Map.SavedMaps[0]);
|
if (Submarine.SavedSubmarines.Count > 0) mapList.Select(Submarine.SavedSubmarines[0]);
|
||||||
|
|
||||||
|
|
||||||
button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", GUI.style, Alignment.Right | Alignment.Bottom, menuTabs[(int)Tabs.NewGame]);
|
button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", GUI.style, Alignment.Right | Alignment.Bottom, menuTabs[(int)Tabs.NewGame]);
|
||||||
@@ -173,7 +173,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
private bool StartGame(GUIButton button, object obj)
|
private bool StartGame(GUIButton button, object obj)
|
||||||
{
|
{
|
||||||
Map selectedMap = mapList.SelectedData as Map;
|
Submarine selectedMap = mapList.SelectedData as Submarine;
|
||||||
if (selectedMap == null) return false;
|
if (selectedMap == null) return false;
|
||||||
|
|
||||||
Game1.GameSession = new GameSession(selectedMap, GameModePreset.list.Find(gm => gm.Name == "Single Player"));
|
Game1.GameSession = new GameSession(selectedMap, GameModePreset.list.Find(gm => gm.Name == "Single Player"));
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ namespace Subsurface
|
|||||||
|
|
||||||
public bool isServer;
|
public bool isServer;
|
||||||
|
|
||||||
public Map SelectedMap
|
public Submarine SelectedMap
|
||||||
{
|
{
|
||||||
get { return mapList.SelectedData as Map; }
|
get { return mapList.SelectedData as Submarine; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -135,9 +135,9 @@ namespace Subsurface
|
|||||||
mapList.OnSelected = SelectMap;
|
mapList.OnSelected = SelectMap;
|
||||||
mapList.Enabled = (Game1.Server!=null);
|
mapList.Enabled = (Game1.Server!=null);
|
||||||
|
|
||||||
if (Map.SavedMaps.Count>0)
|
if (Submarine.SavedSubmarines.Count>0)
|
||||||
{
|
{
|
||||||
foreach (Map map in Map.SavedMaps)
|
foreach (Submarine map in Submarine.SavedSubmarines)
|
||||||
{
|
{
|
||||||
GUITextBlock textBlock = new GUITextBlock(
|
GUITextBlock textBlock = new GUITextBlock(
|
||||||
new Rectangle(0, 0, 0, 25),
|
new Rectangle(0, 0, 0, 25),
|
||||||
@@ -245,10 +245,10 @@ namespace Subsurface
|
|||||||
{
|
{
|
||||||
if (Game1.Server != null) Game1.Server.UpdateNetLobby(obj);
|
if (Game1.Server != null) Game1.Server.UpdateNetLobby(obj);
|
||||||
|
|
||||||
Map map = (Map)obj;
|
Submarine map = (Submarine)obj;
|
||||||
|
|
||||||
//map already loaded
|
//map already loaded
|
||||||
if (Map.Loaded!=null && map.FilePath == Map.Loaded.FilePath) return true;
|
if (Submarine.Loaded!=null && map.FilePath == Submarine.Loaded.FilePath) return true;
|
||||||
|
|
||||||
map.Load();
|
map.Load();
|
||||||
|
|
||||||
@@ -281,13 +281,13 @@ namespace Subsurface
|
|||||||
Game1.GameScreen.Cam.MoveCamera((float)deltaTime);
|
Game1.GameScreen.Cam.MoveCamera((float)deltaTime);
|
||||||
|
|
||||||
Vector2 pos = new Vector2(
|
Vector2 pos = new Vector2(
|
||||||
Map.Borders.X + Map.Borders.Width / 2,
|
Submarine.Borders.X + Submarine.Borders.Width / 2,
|
||||||
Map.Borders.Y - Map.Borders.Height / 2);
|
Submarine.Borders.Y - Submarine.Borders.Height / 2);
|
||||||
|
|
||||||
camAngle += (float)deltaTime / 10.0f;
|
camAngle += (float)deltaTime / 10.0f;
|
||||||
Vector2 offset = (new Vector2(
|
Vector2 offset = (new Vector2(
|
||||||
(float)Math.Cos(camAngle) * (Map.Borders.Width / 2.0f),
|
(float)Math.Cos(camAngle) * (Submarine.Borders.Width / 2.0f),
|
||||||
(float)Math.Sin(camAngle) * (Map.Borders.Height / 2.0f)));
|
(float)Math.Sin(camAngle) * (Submarine.Borders.Height / 2.0f)));
|
||||||
|
|
||||||
pos += offset * 0.8f;
|
pos += offset * 0.8f;
|
||||||
|
|
||||||
@@ -466,7 +466,7 @@ namespace Subsurface
|
|||||||
|
|
||||||
public void WriteData(NetOutgoingMessage msg)
|
public void WriteData(NetOutgoingMessage msg)
|
||||||
{
|
{
|
||||||
Map selectedMap = mapList.SelectedData as Map;
|
Submarine selectedMap = mapList.SelectedData as Submarine;
|
||||||
|
|
||||||
if (selectedMap==null)
|
if (selectedMap==null)
|
||||||
{
|
{
|
||||||
@@ -476,7 +476,7 @@ namespace Subsurface
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
msg.Write(Path.GetFileName(selectedMap.Name));
|
msg.Write(Path.GetFileName(selectedMap.Name));
|
||||||
msg.Write(selectedMap.MapHash.MD5Hash);
|
msg.Write(selectedMap.Hash.MD5Hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.Write(modeList.SelectedIndex);
|
msg.Write(modeList.SelectedIndex);
|
||||||
@@ -486,7 +486,7 @@ namespace Subsurface
|
|||||||
public bool TrySelectMap(string mapName, string md5Hash)
|
public bool TrySelectMap(string mapName, string md5Hash)
|
||||||
{
|
{
|
||||||
|
|
||||||
Map map = Map.SavedMaps.Find(m => m.Name == mapName);
|
Submarine map = Submarine.SavedSubmarines.Find(m => m.Name == mapName);
|
||||||
if (map==null)
|
if (map==null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("The map ''" + mapName + "'' has been selected by the server.");
|
DebugConsole.ThrowError("The map ''" + mapName + "'' has been selected by the server.");
|
||||||
@@ -495,10 +495,10 @@ namespace Subsurface
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (map.MapHash.MD5Hash!=md5Hash)
|
if (map.Hash.MD5Hash!=md5Hash)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Your version of the map file ''"+map.Name+"'' doesn't match the server's version!");
|
DebugConsole.ThrowError("Your version of the map file ''"+map.Name+"'' doesn't match the server's version!");
|
||||||
DebugConsole.ThrowError("Your file: "+map.Name+"(MD5 hash : "+map.MapHash.MD5Hash+")");
|
DebugConsole.ThrowError("Your file: "+map.Name+"(MD5 hash : "+map.Hash.MD5Hash+")");
|
||||||
DebugConsole.ThrowError("Server's file: " + mapName + "(MD5 hash : " + md5Hash + ")");
|
DebugConsole.ThrowError("Server's file: " + mapName + "(MD5 hash : " + md5Hash + ")");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,7 +127,9 @@
|
|||||||
<Compile Include="Map\Level.cs" />
|
<Compile Include="Map\Level.cs" />
|
||||||
<Compile Include="Map\Lights\ConvexHull.cs" />
|
<Compile Include="Map\Lights\ConvexHull.cs" />
|
||||||
<Compile Include="Map\Lights\LightManager.cs" />
|
<Compile Include="Map\Lights\LightManager.cs" />
|
||||||
<Compile Include="Map\MapHash.cs" />
|
<Compile Include="Map\Location.cs" />
|
||||||
|
<Compile Include="Map\Map.cs" />
|
||||||
|
<Compile Include="Map\Md5Hash.cs" />
|
||||||
<Compile Include="Map\Voronoi.cs" />
|
<Compile Include="Map\Voronoi.cs" />
|
||||||
<Compile Include="Map\VoronoiElements.cs" />
|
<Compile Include="Map\VoronoiElements.cs" />
|
||||||
<Compile Include="Physics\PhysicsBody.cs" />
|
<Compile Include="Physics\PhysicsBody.cs" />
|
||||||
@@ -161,7 +163,7 @@
|
|||||||
<Compile Include="Items\Components\Projectile.cs" />
|
<Compile Include="Items\Components\Projectile.cs" />
|
||||||
<Compile Include="Map\MapEntity.cs" />
|
<Compile Include="Map\MapEntity.cs" />
|
||||||
<Compile Include="Map\MapEntityPrefab.cs" />
|
<Compile Include="Map\MapEntityPrefab.cs" />
|
||||||
<Compile Include="Map\Map.cs" />
|
<Compile Include="Map\Submarine.cs" />
|
||||||
<Compile Include="Map\Structure.cs" />
|
<Compile Include="Map\Structure.cs" />
|
||||||
<Compile Include="Map\StructurePrefab.cs" />
|
<Compile Include="Map\StructurePrefab.cs" />
|
||||||
<Compile Include="Map\WaterRenderer.cs" />
|
<Compile Include="Map\WaterRenderer.cs" />
|
||||||
|
|||||||
+11
-1
@@ -25,10 +25,20 @@ namespace Subsurface
|
|||||||
|
|
||||||
public static float RandomFloat(float minimum, float maximum)
|
public static float RandomFloat(float minimum, float maximum)
|
||||||
{
|
{
|
||||||
return (float)Game1.localRandom.NextDouble() * (maximum - minimum) + minimum;
|
return (float)Game1.random.NextDouble() * (maximum - minimum) + minimum;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int RandomInt(int minimum, int maximum)
|
public static int RandomInt(int minimum, int maximum)
|
||||||
|
{
|
||||||
|
return Game1.random.Next(maximum - minimum) + minimum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float RandomFloatLocal(float minimum, float maximum)
|
||||||
|
{
|
||||||
|
return (float)Game1.localRandom.NextDouble() * (maximum - minimum) + minimum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int RandomIntLocal(int minimum, int maximum)
|
||||||
{
|
{
|
||||||
return Game1.localRandom.Next(maximum - minimum) + minimum;
|
return Game1.localRandom.Next(maximum - minimum) + minimum;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user