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.Down)) 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
|
||||
{
|
||||
|
||||
@@ -219,9 +219,9 @@ namespace Subsurface
|
||||
//check if there's a wall between the target and the character
|
||||
Vector2 rayStart = character.animController.limbs[0].SimPosition;
|
||||
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;
|
||||
return;
|
||||
@@ -230,11 +230,11 @@ namespace Subsurface
|
||||
Structure wall = closestBody.UserData as Structure;
|
||||
if (wall == null)
|
||||
{
|
||||
wallAttackPos = Map.LastPickedPosition;
|
||||
wallAttackPos = Submarine.LastPickedPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
int sectionIndex = wall.FindSectionIndex(ConvertUnits.ToDisplayUnits(Map.LastPickedPosition));
|
||||
int sectionIndex = wall.FindSectionIndex(ConvertUnits.ToDisplayUnits(Submarine.LastPickedPosition));
|
||||
|
||||
float sectionDamage = wall.SectionDamage(sectionIndex);
|
||||
for (int i = sectionIndex - 2; i <= sectionIndex + 2; i++)
|
||||
@@ -377,7 +377,7 @@ namespace Subsurface
|
||||
Vector2 rayStart = character.animController.limbs[0].SimPosition;
|
||||
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;
|
||||
|
||||
//if (targetCharacter != null)
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Subsurface
|
||||
{
|
||||
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)
|
||||
@@ -90,7 +90,7 @@ namespace Subsurface
|
||||
|
||||
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;
|
||||
float steeringSpeed = (newSteering + host.Steering).Length();
|
||||
@@ -113,7 +113,7 @@ namespace Subsurface
|
||||
if (rayCastTimer <= 0.0f)
|
||||
{
|
||||
rayCastTimer = RayCastInterval;
|
||||
Body closestBody = Map.CheckVisibility(host.Position, ahead);
|
||||
Body closestBody = Submarine.CheckVisibility(host.Position, ahead);
|
||||
if (closestBody == null)
|
||||
{
|
||||
avoidSteering = Vector2.Zero;
|
||||
@@ -124,7 +124,7 @@ namespace Subsurface
|
||||
Structure closestStructure = closestBody.UserData as Structure;
|
||||
if (closestStructure!=null)
|
||||
{
|
||||
Vector2 obstaclePosition = Map.LastPickedPosition;
|
||||
Vector2 obstaclePosition = Submarine.LastPickedPosition;
|
||||
if (closestStructure.IsHorizontal)
|
||||
{
|
||||
obstaclePosition.Y = closestStructure.SimPosition.Y;
|
||||
@@ -134,7 +134,7 @@ namespace Subsurface
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
if (p!=null) p.Size *= 2.0f;
|
||||
|
||||
Game1.particleManager.CreateParticle("bubbles",
|
||||
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)
|
||||
|
||||
@@ -314,7 +314,7 @@ namespace Subsurface
|
||||
|
||||
Game1.particleManager.CreateParticle("blood",
|
||||
SimPosition,
|
||||
particleVel * ToolBox.RandomFloat(1.0f, 3.0f));
|
||||
particleVel * ToolBox.RandomFloatLocal(1.0f, 3.0f));
|
||||
}
|
||||
|
||||
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.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)
|
||||
|
||||
@@ -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="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"/>
|
||||
</Wearable>
|
||||
|
||||
|
||||
@@ -197,6 +197,10 @@ namespace Subsurface
|
||||
case "editchar":
|
||||
Game1.EditCharacterScreen.Select();
|
||||
break;
|
||||
case "freecamera":
|
||||
Character.Controlled = null;
|
||||
Game1.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||
break;
|
||||
case "editwater":
|
||||
case "water":
|
||||
if (Game1.Client== null)
|
||||
@@ -205,7 +209,8 @@ namespace Subsurface
|
||||
}
|
||||
break;
|
||||
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;
|
||||
case "fowenabled":
|
||||
case "fow":
|
||||
@@ -218,12 +223,12 @@ namespace Subsurface
|
||||
break;
|
||||
case "savemap":
|
||||
if (commands.Length < 2) break;
|
||||
Map.SaveCurrent("Content/SavedMaps/" + commands[1]);
|
||||
Submarine.SaveCurrent("Content/SavedMaps/" + commands[1]);
|
||||
NewMessage("map saved", Color.Green);
|
||||
break;
|
||||
case "loadmap":
|
||||
if (commands.Length < 2) break;
|
||||
Map.Load("Content/SavedMaps/" + commands[1]);
|
||||
Submarine.Load("Content/SavedMaps/" + commands[1]);
|
||||
break;
|
||||
case "savegame":
|
||||
SaveUtil.SaveGame(SaveUtil.SaveFolder+"save");
|
||||
|
||||
@@ -32,8 +32,8 @@ namespace Subsurface
|
||||
for (int i = 0; i < amount; i++)
|
||||
{
|
||||
Vector2 position = (randomWayPoint == null) ? Vector2.Zero : randomWayPoint.SimPosition;
|
||||
position.X += ToolBox.RandomFloat(-0.5f,0.5f);
|
||||
position.Y += ToolBox.RandomFloat(-0.5f,0.5f);
|
||||
position.X += ToolBox.RandomFloatLocal(-0.5f,0.5f);
|
||||
position.Y += ToolBox.RandomFloatLocal(-0.5f,0.5f);
|
||||
monsters[i] = new Character(characterFile, position);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,13 @@ using Microsoft.Xna.Framework.Input;
|
||||
namespace Subsurface
|
||||
{
|
||||
[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
|
||||
@@ -258,15 +264,15 @@ namespace Subsurface
|
||||
|
||||
public static void Draw(float deltaTime, SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
//spriteBatch.DrawString(font,
|
||||
// "FPS: " + (int)Game1.frameCounter.AverageFramesPerSecond
|
||||
// + " - render: "+Game1.renderTimeElapsed,
|
||||
// new Vector2(10, 10), Color.White);
|
||||
spriteBatch.DrawString(font,
|
||||
"FPS: " + (int)Game1.frameCounter.AverageFramesPerSecond
|
||||
+ " - render: " + Game1.renderTimeElapsed,
|
||||
new Vector2(10, 10), Color.White);
|
||||
|
||||
//spriteBatch.DrawString(font,
|
||||
// "Physics: " + Game1.world.UpdateTime
|
||||
// + " - bodies: " + Game1.world.BodyList.Count,
|
||||
// new Vector2(10, 30), Color.White);
|
||||
spriteBatch.DrawString(font,
|
||||
"Physics: " + Game1.world.UpdateTime
|
||||
+ " - bodies: " + Game1.world.BodyList.Count,
|
||||
new Vector2(10, 30), Color.White);
|
||||
|
||||
|
||||
if (Character.Controlled != null && cam!=null) Character.Controlled.DrawHud(spriteBatch, cam);
|
||||
|
||||
@@ -15,10 +15,12 @@ namespace Subsurface
|
||||
/// </summary>
|
||||
class Game1 : Game
|
||||
{
|
||||
GraphicsDeviceManager graphics;
|
||||
public static GraphicsDeviceManager graphics;
|
||||
static int graphicsWidth, graphicsHeight;
|
||||
static SpriteBatch spriteBatch;
|
||||
|
||||
public static GraphicsDevice CurrGraphicsDevice;
|
||||
|
||||
public static FrameCounter frameCounter;
|
||||
|
||||
public static readonly Version version = Assembly.GetEntryAssembly().GetName().Version;
|
||||
@@ -46,7 +48,7 @@ namespace Subsurface
|
||||
public static Random localRandom;
|
||||
public static Random random;
|
||||
|
||||
private Stopwatch renderTimer;
|
||||
//private Stopwatch renderTimer;
|
||||
public static int renderTimeElapsed;
|
||||
|
||||
|
||||
@@ -55,6 +57,7 @@ namespace Subsurface
|
||||
get { return GameScreen.Cam; }
|
||||
}
|
||||
|
||||
|
||||
public static int GraphicsWidth
|
||||
{
|
||||
get { return graphicsWidth; }
|
||||
@@ -68,7 +71,7 @@ namespace Subsurface
|
||||
public Game1()
|
||||
{
|
||||
graphics = new GraphicsDeviceManager(this);
|
||||
|
||||
|
||||
graphicsWidth = 1280;
|
||||
graphicsHeight = 720;
|
||||
|
||||
@@ -76,13 +79,13 @@ namespace Subsurface
|
||||
graphics.PreferredBackBufferWidth = graphicsWidth;
|
||||
graphics.PreferredBackBufferHeight = graphicsHeight;
|
||||
Content.RootDirectory = "Content";
|
||||
|
||||
|
||||
//graphics.SynchronizeWithVerticalRetrace = false;
|
||||
//graphics.ApplyChanges();
|
||||
|
||||
frameCounter = new FrameCounter();
|
||||
|
||||
renderTimer = new Stopwatch();
|
||||
//renderTimer = new Stopwatch();
|
||||
|
||||
IsMouseVisible = true;
|
||||
|
||||
@@ -107,6 +110,8 @@ namespace Subsurface
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
CurrGraphicsDevice = GraphicsDevice;
|
||||
|
||||
particleManager = new ParticleManager("Content/Particles/prefabs.xml", Cam);
|
||||
|
||||
GameMode.Init();
|
||||
@@ -145,7 +150,7 @@ namespace Subsurface
|
||||
|
||||
AmbientSoundManager.Init("Content/Sounds/Sounds.xml");
|
||||
|
||||
Map.PreloadMaps("Content/SavedMaps");
|
||||
Submarine.Preload("Content/SavedMaps");
|
||||
GameScreen = new GameScreen(graphics.GraphicsDevice);
|
||||
MainMenuScreen = new MainMenuScreen(this);
|
||||
LobbyScreen = new LobbyScreen();
|
||||
@@ -209,7 +214,7 @@ namespace Subsurface
|
||||
/// </summary>
|
||||
protected override void Draw(GameTime gameTime)
|
||||
{
|
||||
renderTimer.Restart();
|
||||
//renderTimer.Restart();
|
||||
|
||||
double deltaTime = gameTime.ElapsedGameTime.TotalSeconds;
|
||||
|
||||
@@ -217,8 +222,8 @@ namespace Subsurface
|
||||
|
||||
Screen.Selected.Draw(deltaTime, GraphicsDevice, spriteBatch);
|
||||
|
||||
renderTimeElapsed = (int)renderTimer.Elapsed.Ticks;
|
||||
renderTimer.Stop();
|
||||
//renderTimeElapsed = (int)renderTimer.Elapsed.Ticks;
|
||||
//renderTimer.Stop();
|
||||
}
|
||||
|
||||
protected override void OnExiting(object sender, EventArgs args)
|
||||
|
||||
@@ -27,15 +27,29 @@ namespace Subsurface
|
||||
|
||||
private string savePath;
|
||||
|
||||
private Map selectedMap;
|
||||
private Submarine submarine;
|
||||
|
||||
public GameSession(Map selectedMap, GameModePreset gameModePreset)
|
||||
:this(selectedMap, gameModePreset.Instantiate())
|
||||
private Level level;
|
||||
|
||||
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);
|
||||
|
||||
@@ -43,6 +57,8 @@ namespace Subsurface
|
||||
|
||||
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;
|
||||
if (Game1.Client!=null || Game1.Server!=null)
|
||||
{
|
||||
@@ -67,7 +83,7 @@ namespace Subsurface
|
||||
//startTime = DateTime.Now;
|
||||
//endTime = startTime + gameDuration;
|
||||
|
||||
this.selectedMap = selectedMap;
|
||||
this.submarine = selectedMap;
|
||||
|
||||
//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)
|
||||
{
|
||||
XDocument doc = ToolBox.TryLoadXml(filePath);
|
||||
@@ -95,14 +111,31 @@ namespace Subsurface
|
||||
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)
|
||||
{
|
||||
//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 (level!=null)
|
||||
{
|
||||
submarine.Move(level.StartPosition - submarine.Center, 1.0f);
|
||||
}
|
||||
|
||||
//crewManager.StartShift();
|
||||
taskManager.StartShift(scriptedEventCount);
|
||||
}
|
||||
@@ -122,7 +155,7 @@ namespace Subsurface
|
||||
|
||||
SaveUtil.SaveGame(savePath);
|
||||
}
|
||||
|
||||
|
||||
taskManager.EndShift();
|
||||
//gameMode.End();
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ namespace Subsurface.Items.Components
|
||||
{
|
||||
base.Move(amount);
|
||||
|
||||
LinkedGap.Move(amount);
|
||||
//LinkedGap.Move(amount);
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
Rectangle hullRect = new Rectangle(
|
||||
miniMap.X + (int)((hull.Rect.X - Map.Borders.X) * size),
|
||||
miniMap.Y - (int)((hull.Rect.Y - Map.Borders.Y) * size),
|
||||
miniMap.X + (int)((hull.Rect.X - Submarine.Borders.X) * size),
|
||||
miniMap.Y - (int)((hull.Rect.Y - Submarine.Borders.Y) * size),
|
||||
(int)(hull.Rect.Width * size),
|
||||
(int)(hull.Rect.Height * size));
|
||||
|
||||
@@ -71,8 +71,8 @@ namespace Subsurface.Items.Components
|
||||
if (c.animController.CurrentHull!=null) continue;
|
||||
|
||||
Rectangle characterRect = new Rectangle(
|
||||
miniMap.X + (int)((c.Position.X - Map.Borders.X) * size),
|
||||
miniMap.Y - (int)((c.Position.Y - Map.Borders.Y) * size),
|
||||
miniMap.X + (int)((c.Position.X - Submarine.Borders.X) * size),
|
||||
miniMap.Y - (int)((c.Position.Y - Submarine.Borders.Y) * size),
|
||||
5, 5);
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, characterRect, Color.White, true);
|
||||
|
||||
@@ -109,8 +109,8 @@ namespace Subsurface.Items.Components
|
||||
ignoredBodies.Add(limb.body.FarseerBody);
|
||||
}
|
||||
|
||||
Body targetBody = Map.PickBody(TransformedBarrelPos, targetPosition, ignoredBodies);
|
||||
pickedPosition = Map.LastPickedPosition;
|
||||
Body targetBody = Submarine.PickBody(TransformedBarrelPos, targetPosition, ignoredBodies);
|
||||
pickedPosition = Submarine.LastPickedPosition;
|
||||
|
||||
if (targetBody==null || targetBody.UserData==null) return true;
|
||||
|
||||
|
||||
@@ -6,8 +6,7 @@ using System.Xml.Linq;
|
||||
namespace Subsurface.Items.Components
|
||||
{
|
||||
class ConnectionPanel : ItemComponent
|
||||
{
|
||||
|
||||
{
|
||||
public List<Connection> connections;
|
||||
|
||||
Character user;
|
||||
@@ -31,10 +30,20 @@ namespace Subsurface.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public override void Move(Vector2 amount)
|
||||
{
|
||||
base.Move(amount);
|
||||
}
|
||||
//public override void Move(Vector2 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)
|
||||
{
|
||||
|
||||
@@ -35,6 +35,15 @@ namespace Subsurface.Items.Components
|
||||
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)
|
||||
{
|
||||
if (connection == null) return null;
|
||||
|
||||
@@ -287,8 +287,9 @@ namespace Subsurface
|
||||
|
||||
if (itemList != null && body!=null)
|
||||
{
|
||||
Vector2 pos = new Vector2(rect.X + rect.Width / 2.0f, rect.Y - rect.Height / 2.0f);
|
||||
body.SetTransform(ConvertUnits.ToSimUnits(pos), 0.0f);
|
||||
amount = ConvertUnits.ToSimUnits(amount);
|
||||
//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)
|
||||
{
|
||||
@@ -679,7 +680,7 @@ namespace Subsurface
|
||||
{
|
||||
Rectangle transformedTrigger = item.TransformTrigger(trigger);
|
||||
|
||||
if (!Map.RectContains(transformedTrigger, displayPos))continue;
|
||||
if (!Submarine.RectContains(transformedTrigger, displayPos))continue;
|
||||
|
||||
|
||||
Vector2 triggerCenter =
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Subsurface
|
||||
|
||||
public override void UpdatePlacing(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
Vector2 position = Map.MouseToWorldGrid(cam);
|
||||
Vector2 position = Submarine.MouseToWorldGrid(cam);
|
||||
|
||||
if (!resizeHorizontal && !resizeVertical)
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Subsurface
|
||||
for (int i = 0; i<range*10; i++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -90,8 +90,8 @@ namespace Subsurface
|
||||
|
||||
public override bool Contains(Vector2 position)
|
||||
{
|
||||
return (Map.RectContains(rect, position) &&
|
||||
!Map.RectContains(new Rectangle(rect.X + 4, rect.Y - 4, rect.Width - 8, rect.Height - 8), position));
|
||||
return (Submarine.RectContains(rect, position) &&
|
||||
!Submarine.RectContains(new Rectangle(rect.X + 4, rect.Y - 4, rect.Width - 8, rect.Height - 8), position));
|
||||
}
|
||||
|
||||
private void FindHulls()
|
||||
@@ -102,7 +102,7 @@ namespace Subsurface
|
||||
|
||||
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 (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));
|
||||
|
||||
Game1.particleManager.CreateParticle("watersplash",
|
||||
new Vector2(pos.X, pos.Y - ToolBox.RandomFloat(0.0f, 0.1f)),
|
||||
new Vector2(flowForce.X * ToolBox.RandomFloat(0.005f, 0.007f), flowForce.Y * ToolBox.RandomFloat(0.005f, 0.007f)));
|
||||
new Vector2(pos.X, pos.Y - ToolBox.RandomFloatLocal(0.0f, 0.1f)),
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
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,
|
||||
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);
|
||||
|
||||
|
||||
@@ -150,8 +150,8 @@ namespace Subsurface
|
||||
|
||||
public override bool Contains(Vector2 position)
|
||||
{
|
||||
return (Map.RectContains(rect, position) &&
|
||||
!Map.RectContains(new Rectangle(rect.X + 8, rect.Y - 8, rect.Width - 16, rect.Height - 16), position));
|
||||
return (Submarine.RectContains(rect, position) &&
|
||||
!Submarine.RectContains(new Rectangle(rect.X + 8, rect.Y - 8, rect.Width - 16, rect.Height - 16), position));
|
||||
}
|
||||
|
||||
public int GetWaveIndex(Vector2 position)
|
||||
@@ -189,7 +189,7 @@ namespace Subsurface
|
||||
if (EditWater)
|
||||
{
|
||||
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
if (Map.RectContains(rect, position))
|
||||
if (Submarine.RectContains(rect, position))
|
||||
{
|
||||
if (PlayerInput.LeftButtonDown())
|
||||
{
|
||||
@@ -210,7 +210,7 @@ namespace Subsurface
|
||||
for (int i = 0; i < waveY.Length; 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",
|
||||
ConvertUnits.ToSimUnits(new Vector2(rect.X + WaveWidth * i,surface + waveY[i])),
|
||||
@@ -390,12 +390,12 @@ namespace Subsurface
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (Map.RectContains(w.rect, position)) return w;
|
||||
if (Submarine.RectContains(w.rect, position)) return w;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -6,109 +6,548 @@ using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using Voronoi2;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class Level
|
||||
{
|
||||
public static Level Loaded
|
||||
{
|
||||
get { return loaded; }
|
||||
}
|
||||
|
||||
static Level loaded;
|
||||
|
||||
private int seed;
|
||||
|
||||
List<Body> bodies;
|
||||
private int siteInterval;
|
||||
|
||||
const int gridCellWidth = 1000;
|
||||
List<VoronoiCell>[,] cellGrid;
|
||||
|
||||
//List<Body> bodies;
|
||||
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;
|
||||
|
||||
Voronoi voronoi = new Voronoi(1.0);
|
||||
this.siteInterval = siteInterval;
|
||||
|
||||
List<PointF> sites = new List<PointF>();
|
||||
Random rand = new Random(seed);
|
||||
borders = new Rectangle(0, 0, width, height);
|
||||
}
|
||||
|
||||
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>();
|
||||
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;
|
||||
VoronoiCell cell = cells.Find(c => c.site == site);
|
||||
Site site = (i == 0) ? ge.site1 : ge.site2;
|
||||
|
||||
VoronoiCell cell = cellGrid[
|
||||
(int)Math.Floor(site.coord.x / gridCellWidth),
|
||||
(int)Math.Floor(site.coord.y / gridCellWidth)].Find(c => c.site == site);
|
||||
|
||||
if (cell == null)
|
||||
{
|
||||
cell = new VoronoiCell(site);
|
||||
cellGrid[(int)Math.Floor(cell.Center.X / gridCellWidth), (int)Math.Floor(cell.Center.Y / gridCellWidth)].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)
|
||||
{
|
||||
//List of vectors defining my custom poly
|
||||
List<Vector2> vlist = new List<Vector2>();
|
||||
n = (n + 30) % 255;
|
||||
|
||||
tempVertices.Clear();
|
||||
foreach (GraphEdge ge in cell.edges)
|
||||
{
|
||||
if (!vlist.Contains(ge.point1)) vlist.Add(ge.point1);
|
||||
if (!vlist.Contains(ge.point2)) vlist.Add(ge.point2);
|
||||
if (ge.point1 == ge.point2) continue;
|
||||
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;
|
||||
|
||||
int triangleCount = tempVertices.Count - 2;
|
||||
|
||||
for (int i = 0; i < vlist.Count; i++ )
|
||||
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];
|
||||
double[] yVal = new double[sites.Count];
|
||||
for (int i = 0; i < sites.Count; i++)
|
||||
for (int i = 0; i < bodyVertices.Count; i++)
|
||||
{
|
||||
xVal[i] = sites[i].X;
|
||||
yVal[i] = sites[i].Y;
|
||||
bodyVertices[i] = ConvertUnits.ToSimUnits(bodyVertices[i]);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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>
|
||||
{
|
||||
private Vector2 center;
|
||||
@@ -119,24 +558,24 @@ namespace Subsurface
|
||||
}
|
||||
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.Y - center.Y >= 0 || b.Y - center.Y >= 0) return Math.Sign(a.Y - b.Y);
|
||||
return Math.Sign(b.Y - a.Y);
|
||||
if (a.Y - center.Y >= 0 || b.Y - center.Y >= 0) return Math.Sign(b.Y-a.Y);
|
||||
return Math.Sign(a.Y-b.Y);
|
||||
}
|
||||
|
||||
// compute the cross product of vectors (center -> a) x (center -> b)
|
||||
float det = (a.X - center.X) * (b.Y - center.Y) - (b.X - center.X) * (a.Y - center.Y);
|
||||
if (det < 0) return 1;
|
||||
if (det > 0) return -1;
|
||||
if (det < 0) return -1;
|
||||
if (det > 0) return 1;
|
||||
|
||||
// points a and b are on the same line from the center
|
||||
// check which point is closer to the center
|
||||
float d1 = (a.X - center.X) * (a.X - center.X) + (a.Y - center.Y) * (a.Y - center.Y);
|
||||
float d2 = (b.X - center.X) * (b.X - center.X) + (b.Y - center.Y) * (b.Y - center.Y);
|
||||
return Math.Sign(d1 - d2);
|
||||
return Math.Sign(d2-d1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
37
Subsurface/Map/Location.cs
Normal file
37
Subsurface/Map/Location.cs
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,539 +1,239 @@
|
||||
using FarseerPhysics;
|
||||
using FarseerPhysics.Collision;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
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;
|
||||
using System.Text;
|
||||
using Voronoi2;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
public enum Direction : byte
|
||||
{
|
||||
None = 0, Left = 1, Right = 2
|
||||
}
|
||||
|
||||
class Map
|
||||
{
|
||||
static string MapFolder;
|
||||
MapHash mapHash;
|
||||
private List<Level> levels;
|
||||
|
||||
public static List<Map> SavedMaps = new List<Map>();
|
||||
private List<Location> locations;
|
||||
|
||||
private static Map 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 MapHash MapHash
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mapHash != null) return mapHash;
|
||||
|
||||
XDocument doc = OpenDoc(filePath);
|
||||
mapHash = new MapHash(doc);
|
||||
|
||||
return mapHash;
|
||||
}
|
||||
}
|
||||
|
||||
public static Map Loaded
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
private List<LocationConnection> connections;
|
||||
|
||||
public static Body PickBody(Vector2 rayStart, Vector2 rayEnd, List<Body> ignoredBodies = null)
|
||||
private int seed;
|
||||
private int size;
|
||||
|
||||
private Location currentLocation;
|
||||
private Location selectedLocation;
|
||||
|
||||
public Map(int seed, int size)
|
||||
{
|
||||
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;
|
||||
this.seed = seed;
|
||||
|
||||
Structure structure = fixture.Body.UserData as Structure;
|
||||
if (structure != null && (structure.IsPlatform || !structure.HasBody)) return -1;
|
||||
this.size = size;
|
||||
|
||||
if (fraction < closestFraction)
|
||||
{
|
||||
closestFraction = fraction;
|
||||
if (fixture.Body!=null) closestBody = fixture.Body;
|
||||
}
|
||||
return fraction;
|
||||
}
|
||||
, rayStart, rayEnd);
|
||||
levels = new List<Level>();
|
||||
|
||||
lastPickedPosition = rayStart + (rayEnd - rayStart) * closestFraction;
|
||||
lastPickedFraction = closestFraction;
|
||||
return closestBody;
|
||||
}
|
||||
locations = new List<Location>();
|
||||
|
||||
connections = new List<LocationConnection>();
|
||||
|
||||
public static Body CheckVisibility(Vector2 rayStart, Vector2 rayEnd)
|
||||
{
|
||||
Body closestBody = null;
|
||||
float closestFraction = 1.0f;
|
||||
GenerateLocations();
|
||||
|
||||
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=="")
|
||||
//for (int i = 0; i<10; i++)
|
||||
//{
|
||||
// DebugConsole.ThrowError("No save file selected");
|
||||
// return;
|
||||
// Vector2 pos = new Vector2((float)Game1.random.NextDouble() * size, (float)Game1.random.NextDouble() * size);
|
||||
|
||||
// Location location =
|
||||
// locations.Add(location);
|
||||
//}
|
||||
XDocument doc = new XDocument(new XElement((XName)name));
|
||||
|
||||
foreach (MapEntity e in MapEntity.mapEntityList)
|
||||
{
|
||||
e.Save(doc);
|
||||
}
|
||||
//for (int i = 0; i < 10; i++)
|
||||
//{
|
||||
|
||||
mapHash = new MapHash(doc);
|
||||
doc.Root.Add(new XAttribute("md5hash", mapHash.MD5Hash));
|
||||
// int closestIndex = 0;
|
||||
// float closestDistance = 0.0f;
|
||||
// for (int j = 0; j<10; j++)
|
||||
// {
|
||||
// if (j == i) continue;
|
||||
|
||||
try
|
||||
{
|
||||
SaveUtil.CompressStringToFile(filePath, doc.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Saving map ''" + filePath + "'' failed!", e);
|
||||
}
|
||||
// //ignore if already connected
|
||||
// bool alreadyConnected = false;
|
||||
// foreach (LocationConnection connection in connections)
|
||||
// {
|
||||
// if (connection.Locations.Contains(locations[i]) && connection.Locations.Contains(locations[j]))
|
||||
// {
|
||||
// alreadyConnected = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (alreadyConnected) continue;
|
||||
|
||||
//doc.Save(filePath);
|
||||
// float dist = Vector2.Distance(locations[i].MapPosition, locations[j].MapPosition);
|
||||
// if (closestDistance > 0.0f && dist > closestDistance) continue;
|
||||
|
||||
// closestDistance = dist;
|
||||
// closestIndex = j;
|
||||
// }
|
||||
|
||||
|
||||
// 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);
|
||||
return;
|
||||
sites.Add(new Vector2((float)Game1.random.NextDouble() * size, (float)Game1.random.NextDouble() * size));
|
||||
}
|
||||
|
||||
loaded.SaveAs(savePath);
|
||||
}
|
||||
|
||||
public static void PreloadMaps(string mapFolder)
|
||||
{
|
||||
MapFolder = mapFolder;
|
||||
|
||||
//string[] mapFilePaths;
|
||||
Unload();
|
||||
SavedMaps.Clear();
|
||||
|
||||
if (!Directory.Exists(MapFolder))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(MapFolder);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
DebugConsole.ThrowError("Directory ''Content/SavedMaps'' not found and creating the directory failed.");
|
||||
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)
|
||||
{
|
||||
XDocument doc = null;
|
||||
string extension = "";
|
||||
|
||||
try
|
||||
{
|
||||
extension = Path.GetExtension(file);
|
||||
}
|
||||
catch
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't load map ''" + file + "! (Unrecognized file extension)");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (extension == ".gz")
|
||||
{
|
||||
Stream stream = SaveUtil.DecompressFiletoStream(file);
|
||||
if (stream == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Loading map ''" + file + "'' failed!");
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
stream.Position = 0;
|
||||
doc = XDocument.Load(stream); //ToolBox.TryLoadXml(file);
|
||||
stream.Close();
|
||||
stream.Dispose();
|
||||
}
|
||||
|
||||
catch
|
||||
{
|
||||
DebugConsole.ThrowError("Loading map ''" + file + "'' failed!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if (extension == ".xml")
|
||||
{
|
||||
try
|
||||
{
|
||||
doc = XDocument.Load(file);
|
||||
}
|
||||
|
||||
catch
|
||||
{
|
||||
DebugConsole.ThrowError("Loading map ''" + file + "'' failed!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't load map ''" + 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 Map Load(string file)
|
||||
{
|
||||
Unload();
|
||||
|
||||
Map map = new Map(file);
|
||||
map.Load();
|
||||
|
||||
return map;
|
||||
List<GraphEdge> edges = voronoi.MakeVoronoiGraph(sites, size, size);
|
||||
|
||||
sites.Clear();
|
||||
foreach (GraphEdge edge in edges)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
|
||||
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];
|
||||
if (connection2.Locations[1] == connection.Locations[0]) connection2.Locations[1] = connection.Locations[1];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void Unload()
|
||||
public void Draw(SpriteBatch spriteBatch, Rectangle rect)
|
||||
{
|
||||
if (loaded == null) return;
|
||||
loaded.Clear();
|
||||
loaded = null;
|
||||
}
|
||||
GUI.DrawRectangle(spriteBatch, rect, Color.DarkBlue, true);
|
||||
|
||||
private void Clear()
|
||||
Vector2 scale = new Vector2((float)rect.Width/ size, (float)rect.Height/size);
|
||||
|
||||
float maxDist = 20.0f;
|
||||
float closestDist = 0.0f;
|
||||
Location highlightedLocation = null;
|
||||
foreach (Location location in locations)
|
||||
{
|
||||
Vector2 pos = location.MapPosition * scale;
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X + (int)pos.X, rect.Y + (int)pos.Y, 5, 5), Color.White, true);
|
||||
|
||||
if (currentLocation == location)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X + (int)pos.X - 4, rect.Y + (int)pos.Y - 4, 5+8, 5+8), Color.Red, false);
|
||||
}
|
||||
|
||||
float dist = Vector2.Distance(PlayerInput.MousePosition, new Vector2(rect.X + pos.X, rect.Y + pos.Y));
|
||||
if (dist < maxDist && (highlightedLocation == null || dist < closestDist))
|
||||
{
|
||||
closestDist = dist;
|
||||
highlightedLocation = location;
|
||||
}
|
||||
}
|
||||
|
||||
if (highlightedLocation!=null)
|
||||
{
|
||||
Vector2 pos = highlightedLocation.MapPosition * scale;
|
||||
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);
|
||||
}
|
||||
|
||||
if (selectedLocation != null)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
Vector2 rectCorner = new Vector2(rect.X, rect.Y);
|
||||
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))
|
||||
{
|
||||
GUI.DrawLine(spriteBatch,
|
||||
connection.Locations[0].MapPosition * scale + rectCorner +Vector2.One,
|
||||
connection.Locations[1].MapPosition * scale + rectCorner + Vector2.One, Color.White);
|
||||
|
||||
if (PlayerInput.LeftButtonClicked())
|
||||
if(selectedLocation!=highlightedLocation && highlightedLocation!=null)
|
||||
{
|
||||
//currentLocation = highlightedLocation;
|
||||
Game1.LobbyScreen.SelectLocation(highlightedLocation, connection);
|
||||
selectedLocation = highlightedLocation;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedLocation != currentLocation &&
|
||||
(connection.Locations.Contains(selectedLocation) && connection.Locations.Contains(currentLocation)))
|
||||
{
|
||||
GUI.DrawLine(spriteBatch,
|
||||
connection.Locations[0].MapPosition * scale + rectCorner + Vector2.One,
|
||||
connection.Locations[1].MapPosition * scale + rectCorner + Vector2.One, Color.White);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class LocationConnection
|
||||
{
|
||||
Location[] locations;
|
||||
Level level;
|
||||
|
||||
public Location[] Locations
|
||||
{
|
||||
if (Game1.GameScreen.Cam != null) Game1.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||
|
||||
Entity.RemoveAll();
|
||||
|
||||
PhysicsBody.list.Clear();
|
||||
|
||||
Ragdoll.list.Clear();
|
||||
|
||||
Game1.world.Clear();
|
||||
get { return locations; }
|
||||
}
|
||||
|
||||
public Level Level
|
||||
{
|
||||
get { return level; }
|
||||
}
|
||||
|
||||
public LocationConnection(Location location1, Location location2, Level level)
|
||||
{
|
||||
locations = new Location[] { location1, location2 };
|
||||
this.level = level;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace Subsurface
|
||||
|
||||
public virtual bool Contains(Vector2 position)
|
||||
{
|
||||
return (Map.RectContains(rect, position));
|
||||
return (Submarine.RectContains(rect, position));
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
Vector2 moveAmount = position - startMovingPos;
|
||||
moveAmount = Map.VectorToWorldGrid(moveAmount);
|
||||
moveAmount = Submarine.VectorToWorldGrid(moveAmount);
|
||||
|
||||
if (moveAmount != Vector2.Zero)
|
||||
{
|
||||
@@ -235,7 +235,7 @@ namespace Subsurface
|
||||
selectionSize.Y = selectionPos.Y - position.Y;
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -315,7 +315,7 @@ namespace Subsurface
|
||||
if (startMovingPos != Vector2.Zero)
|
||||
{
|
||||
Vector2 moveAmount = position - startMovingPos;
|
||||
moveAmount = Map.VectorToWorldGrid(moveAmount);
|
||||
moveAmount = Submarine.VectorToWorldGrid(moveAmount);
|
||||
moveAmount.Y = -moveAmount.Y;
|
||||
//started moving the selected entities
|
||||
if (moveAmount != Vector2.Zero)
|
||||
@@ -358,7 +358,7 @@ namespace Subsurface
|
||||
List<MapEntity> foundEntities = new List<MapEntity>();
|
||||
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;
|
||||
}
|
||||
@@ -367,7 +367,7 @@ namespace Subsurface
|
||||
{
|
||||
foreach (MapEntity e in mapEntityList)
|
||||
{
|
||||
if (Map.RectContains(e.rect, pos)) return e;
|
||||
if (Submarine.RectContains(e.rect, pos)) return e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -379,11 +379,11 @@ namespace Subsurface
|
||||
{
|
||||
List<MapEntity> foundEntities = new List<MapEntity>();
|
||||
|
||||
Rectangle selectionRect = Map.AbsRect(pos, size);
|
||||
Rectangle selectionRect = Submarine.AbsRect(pos, size);
|
||||
|
||||
foreach (MapEntity e in mapEntityList)
|
||||
{
|
||||
if (Map.RectsOverlap(selectionRect, e.rect))
|
||||
if (Submarine.RectsOverlap(selectionRect, e.rect))
|
||||
foundEntities.Add(e);
|
||||
}
|
||||
|
||||
|
||||
@@ -73,23 +73,23 @@ namespace Subsurface
|
||||
|
||||
public virtual void UpdatePlacing(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
Vector2 placeSize = Map.gridSize;
|
||||
Vector2 placeSize = Submarine.gridSize;
|
||||
|
||||
if (placePosition == Vector2.Zero)
|
||||
{
|
||||
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
|
||||
placePosition = Map.MouseToWorldGrid(cam);
|
||||
placePosition = Submarine.MouseToWorldGrid(cam);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 position = Map.MouseToWorldGrid(cam);
|
||||
Vector2 position = Submarine.MouseToWorldGrid(cam);
|
||||
|
||||
if (resizeHorizontal) placeSize.X = position.X - placePosition.X;
|
||||
if (resizeVertical) placeSize.Y = placePosition.Y - position.Y;
|
||||
|
||||
Rectangle newRect = Map.AbsRect(placePosition, placeSize);
|
||||
newRect.Width = (int)Math.Max(newRect.Width, Map.gridSize.X);
|
||||
newRect.Height = (int)Math.Max(newRect.Height, Map.gridSize.Y);
|
||||
Rectangle newRect = Submarine.AbsRect(placePosition, placeSize);
|
||||
newRect.Width = (int)Math.Max(newRect.Width, Submarine.gridSize.X);
|
||||
newRect.Height = (int)Math.Max(newRect.Height, Submarine.gridSize.Y);
|
||||
|
||||
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Released)
|
||||
{
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class MapHash
|
||||
class Md5Hash
|
||||
{
|
||||
private string md5Hash;
|
||||
private string shortHash;
|
||||
@@ -29,14 +26,14 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
public MapHash(string md5Hash)
|
||||
public Md5Hash(string md5Hash)
|
||||
{
|
||||
this.md5Hash = md5Hash;
|
||||
|
||||
shortHash = GetShortHash(md5Hash);
|
||||
}
|
||||
|
||||
public MapHash(XDocument doc)
|
||||
public Md5Hash(XDocument doc)
|
||||
{
|
||||
string docString = Regex.Replace(doc.ToString(), @"\s+", "");
|
||||
// step 1, calculate MD5 hash from input
|
||||
@@ -111,7 +111,7 @@ namespace Subsurface
|
||||
Vector2 simAmount = ConvertUnits.ToSimUnits(amount);
|
||||
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>();
|
||||
|
||||
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),
|
||||
1.5f);
|
||||
|
||||
newBody.BodyType = BodyType.Static;
|
||||
Vector2 stairPos = new Vector2(Position.X, rect.Y - rect.Height + rect.Width / 2.0f);
|
||||
stairPos += new Vector2(
|
||||
(StairDirection == Direction.Right) ? -Map.gridSize.X*1.5f : Map.gridSize.X*1.5f,
|
||||
- Map.gridSize.Y*2.0f);
|
||||
(StairDirection == Direction.Right) ? -Submarine.gridSize.X*1.5f : Submarine.gridSize.X*1.5f,
|
||||
- Submarine.gridSize.Y*2.0f);
|
||||
|
||||
|
||||
newBody.Position = ConvertUnits.ToSimUnits(stairPos);
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace Subsurface
|
||||
|
||||
public override void UpdatePlacing(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
Vector2 position = Map.MouseToWorldGrid(cam);
|
||||
Vector2 position = Submarine.MouseToWorldGrid(cam);
|
||||
//Vector2 placeSize = size;
|
||||
|
||||
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 (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed)
|
||||
placePosition = Map.MouseToWorldGrid(cam);
|
||||
placePosition = Submarine.MouseToWorldGrid(cam);
|
||||
|
||||
newRect.X = (int)position.X;
|
||||
newRect.Y = (int)position.Y;
|
||||
@@ -131,7 +131,7 @@ namespace Subsurface
|
||||
if (resizeHorizontal) placeSize.X = position.X - placePosition.X;
|
||||
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.Height = (int)Math.Max(newRect.Height, Map.gridSize.Y);
|
||||
|
||||
564
Subsurface/Map/Submarine.cs
Normal file
564
Subsurface/Map/Submarine.cs
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
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
|
||||
} // namespace Voronoi2 End
|
||||
@@ -50,7 +50,9 @@
|
||||
*/
|
||||
|
||||
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Subsurface;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -119,6 +121,8 @@ namespace Voronoi2
|
||||
public List<GraphEdge> edges;
|
||||
public Site site;
|
||||
|
||||
public List<Body> bodies;
|
||||
|
||||
public Vector2 Center
|
||||
{
|
||||
get { return new Vector2((float)site.coord.x, (float)site.coord.y); }
|
||||
@@ -127,6 +131,8 @@ namespace Voronoi2
|
||||
public VoronoiCell(Site site)
|
||||
{
|
||||
edges = new List<GraphEdge>();
|
||||
|
||||
bodies = new List<Body>();
|
||||
this.site = site;
|
||||
}
|
||||
}
|
||||
@@ -135,6 +141,23 @@ namespace Voronoi2
|
||||
{
|
||||
public Vector2 point1, point2;
|
||||
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 == this) continue;
|
||||
|
||||
if (!Map.RectContains(e.Rect, position)) continue;
|
||||
if (!Submarine.RectContains(e.Rect, position)) continue;
|
||||
|
||||
linkedTo.Add(e);
|
||||
e.linkedTo.Add(this);
|
||||
@@ -123,7 +123,7 @@ namespace Subsurface
|
||||
Rectangle rect = new Rectangle(
|
||||
int.Parse(element.Attribute("x").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);
|
||||
|
||||
|
||||
@@ -240,7 +240,7 @@ namespace Subsurface.Networking
|
||||
TimeSpan duration = new TimeSpan(0,(int)durationMinutes,0);
|
||||
|
||||
//int gameModeIndex = inc.ReadInt32();
|
||||
Game1.GameSession = new GameSession(Map.Loaded);
|
||||
Game1.GameSession = new GameSession(Submarine.Loaded);
|
||||
Game1.GameSession.StartShift(duration, 1);
|
||||
|
||||
myCharacter = ReadCharacterData(inc);
|
||||
@@ -323,7 +323,7 @@ namespace Subsurface.Networking
|
||||
|
||||
public void EndGame(string endMessage)
|
||||
{
|
||||
Map.Unload();
|
||||
Submarine.Unload();
|
||||
|
||||
Game1.NetLobbyScreen.Select();
|
||||
|
||||
|
||||
@@ -270,7 +270,7 @@ namespace Subsurface.Networking
|
||||
int seed = DateTime.Now.Millisecond;
|
||||
Game1.random = new Random(seed);
|
||||
|
||||
Map selectedMap = Game1.NetLobbyScreen.SelectedMap as Map;
|
||||
Submarine selectedMap = Game1.NetLobbyScreen.SelectedMap as Submarine;
|
||||
|
||||
//selectedMap.Load();
|
||||
|
||||
@@ -307,7 +307,7 @@ namespace Subsurface.Networking
|
||||
msg.Write(seed);
|
||||
|
||||
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);
|
||||
|
||||
@@ -339,7 +339,7 @@ namespace Subsurface.Networking
|
||||
|
||||
public void EndGame(string endMessage)
|
||||
{
|
||||
Map.Unload();
|
||||
Submarine.Unload();
|
||||
|
||||
gameStarted = false;
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Subsurface.Particles
|
||||
|
||||
velocity = speed;
|
||||
|
||||
this.rotation = rotation + ToolBox.RandomFloat(prefab.startRotationMin, prefab.startRotationMax);
|
||||
this.rotation = rotation + ToolBox.RandomFloatLocal(prefab.startRotationMin, prefab.startRotationMax);
|
||||
prevRotation = rotation;
|
||||
|
||||
float rand = (float)Game1.localRandom.NextDouble();
|
||||
@@ -132,7 +132,7 @@ namespace Subsurface.Particles
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Map.InsideWall(new Vector2(drawPosition.X, -drawPosition.Y)))
|
||||
if (Submarine.InsideWall(new Vector2(drawPosition.X, -drawPosition.Y)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace Subsurface.Particles
|
||||
|
||||
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 (particles[particleCount] == null) particles[particleCount] = new Particle();
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Subsurface
|
||||
|
||||
//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.crewManager.Save(directory+"\\crew.xml");
|
||||
@@ -39,7 +39,7 @@ namespace Subsurface
|
||||
|
||||
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");
|
||||
|
||||
Directory.Delete(tempPath, true);
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace Subsurface
|
||||
null, null, null, null,
|
||||
cam.Transform);
|
||||
|
||||
Map.Draw(spriteBatch, true);
|
||||
Submarine.Draw(spriteBatch, true);
|
||||
|
||||
spriteBatch.End();
|
||||
|
||||
|
||||
@@ -229,7 +229,7 @@ namespace Subsurface
|
||||
|
||||
graphics.Clear(new Color(0.051f, 0.149f, 0.271f, 1.0f));
|
||||
|
||||
Map.Draw(spriteBatch, true);
|
||||
Submarine.Draw(spriteBatch, true);
|
||||
|
||||
if (!characterMode)
|
||||
{
|
||||
|
||||
@@ -57,16 +57,16 @@ namespace Subsurface
|
||||
|
||||
AmbientSoundManager.Update();
|
||||
|
||||
//Vector2 targetMovement = Vector2.Zero;
|
||||
//if (PlayerInput.KeyDown(Keys.I)) targetMovement.Y += 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;
|
||||
if (Game1.GameSession.Level!=null)
|
||||
{
|
||||
Vector2 targetMovement = Vector2.Zero;
|
||||
if (PlayerInput.KeyDown(Keys.I)) targetMovement.Y += 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)
|
||||
//{
|
||||
// e.Move(targetMovement);
|
||||
//}
|
||||
Game1.GameSession.Submarine.Move(targetMovement*1000.0f, (float)deltaTime);
|
||||
}
|
||||
|
||||
if (Game1.GameSession!=null) Game1.GameSession.Update((float)deltaTime);
|
||||
//EventManager.Update(gameTime);
|
||||
@@ -170,8 +170,8 @@ namespace Subsurface
|
||||
|
||||
if (y<0)
|
||||
{
|
||||
backgroundTop.SourceRect = new Rectangle(x, y, 1024, 1024);
|
||||
backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(Game1.GraphicsWidth, Math.Min(1024 - y, Game1.GraphicsHeight)),
|
||||
backgroundTop.SourceRect = new Rectangle(x, y, 1024, Math.Min(-y,1024));
|
||||
backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(Game1.GraphicsWidth, Math.Min(-y, Game1.GraphicsHeight)),
|
||||
Vector2.Zero, Color.White);
|
||||
}
|
||||
}
|
||||
@@ -183,10 +183,8 @@ namespace Subsurface
|
||||
BlendState.AlphaBlend,
|
||||
null, null, null, null,
|
||||
cam.Transform);
|
||||
|
||||
if (Game1.Level!=null) Game1.Level.Render(spriteBatch);
|
||||
|
||||
Map.DrawBack(spriteBatch);
|
||||
Submarine.DrawBack(spriteBatch);
|
||||
|
||||
foreach (Character c in Character.characterList) c.Draw(spriteBatch);
|
||||
|
||||
@@ -257,10 +255,18 @@ namespace Subsurface
|
||||
null, null, null, null,
|
||||
cam.Transform);
|
||||
|
||||
Map.DrawFront(spriteBatch);
|
||||
|
||||
Submarine.DrawFront(spriteBatch);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,12 @@ namespace Subsurface
|
||||
{
|
||||
class LobbyScreen : Screen
|
||||
{
|
||||
enum PanelTab { Crew = 0, Map = 1, Hire = 2 }
|
||||
|
||||
GUIFrame leftPanel;
|
||||
GUIFrame[] rightPanel;
|
||||
|
||||
GUIFrame shiftPanel;
|
||||
GUIButton startButton;
|
||||
|
||||
int selectedRightPanel;
|
||||
|
||||
@@ -26,6 +28,8 @@ namespace Subsurface
|
||||
|
||||
Character previewCharacter;
|
||||
|
||||
Level selectedLevel;
|
||||
|
||||
public LobbyScreen()
|
||||
{
|
||||
Rectangle panelRect = new Rectangle(
|
||||
@@ -44,62 +48,55 @@ namespace Subsurface
|
||||
"", Color.Transparent, Color.White, Alignment.Left, leftPanel);
|
||||
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 = new GUIButton(new Rectangle(0, 100, 100, 30), "Hire", GUI.style, Alignment.CenterX, leftPanel);
|
||||
button.UserData = 1;
|
||||
button = new GUIButton(new Rectangle(0, 100, 100, 30), "Crew", GUI.style, Alignment.Left, leftPanel);
|
||||
button.UserData = PanelTab.Crew;
|
||||
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.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),
|
||||
(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);
|
||||
shiftPanel.Padding = GUI.style.smallPadding;
|
||||
rightPanel = new GUIFrame[3];
|
||||
|
||||
GUITextBlock dayText = new GUITextBlock(new Rectangle(0, 0, 200, 25),
|
||||
"", Color.Transparent, Color.White, Alignment.Left, shiftPanel);
|
||||
dayText.TextGetter = GetDay;
|
||||
rightPanel[(int)PanelTab.Crew] = new GUIFrame(panelRect, GUI.style.backGroundColor);
|
||||
rightPanel[(int)PanelTab.Crew].Padding = GUI.style.smallPadding;
|
||||
|
||||
GUIProgressBar progressBar = new GUIProgressBar(new Rectangle(0, 30, 200, 20), Color.Green, 0.0f, shiftPanel);
|
||||
progressBar.ProgressGetter = GetWeekProgress;
|
||||
new GUITextBlock(new Rectangle(0, 0, 200, 25), "Crew:", Color.Transparent, Color.White, Alignment.Left, 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 = new GUIListBox(new Rectangle(0, 30, 300, 0), Color.White, rightPanel[(int)PanelTab.Crew]);
|
||||
characterList.OnSelected = SelectCharacter;
|
||||
|
||||
//---------------------------------------
|
||||
|
||||
rightPanel[1] = new GUIFrame(panelRect, GUI.style.backGroundColor);
|
||||
rightPanel[1].Padding = GUI.style.smallPadding;
|
||||
rightPanel[(int)PanelTab.Map] = new GUIFrame(panelRect, GUI.style.backGroundColor);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -168,7 +165,22 @@ namespace Subsurface
|
||||
previewCharacter.animController.UpdateAnim((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()
|
||||
@@ -220,7 +232,7 @@ namespace Subsurface
|
||||
|
||||
leftPanel.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)
|
||||
@@ -239,10 +251,17 @@ namespace Subsurface
|
||||
spriteBatch.Begin();
|
||||
|
||||
leftPanel.Draw(spriteBatch);
|
||||
shiftPanel.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);
|
||||
|
||||
spriteBatch.End();
|
||||
@@ -352,7 +371,7 @@ namespace Subsurface
|
||||
|
||||
private bool StartShift(GUIButton button, object selection)
|
||||
{
|
||||
Game1.GameSession.StartShift(TimeSpan.Zero);
|
||||
Game1.GameSession.StartShift(TimeSpan.Zero, selectedLevel);
|
||||
Game1.GameScreen.Select();
|
||||
|
||||
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]);
|
||||
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(
|
||||
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.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]);
|
||||
@@ -173,7 +173,7 @@ namespace Subsurface
|
||||
|
||||
private bool StartGame(GUIButton button, object obj)
|
||||
{
|
||||
Map selectedMap = mapList.SelectedData as Map;
|
||||
Submarine selectedMap = mapList.SelectedData as Submarine;
|
||||
if (selectedMap == null) return false;
|
||||
|
||||
Game1.GameSession = new GameSession(selectedMap, GameModePreset.list.Find(gm => gm.Name == "Single Player"));
|
||||
|
||||
@@ -30,9 +30,9 @@ namespace Subsurface
|
||||
|
||||
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.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(
|
||||
new Rectangle(0, 0, 0, 25),
|
||||
@@ -245,10 +245,10 @@ namespace Subsurface
|
||||
{
|
||||
if (Game1.Server != null) Game1.Server.UpdateNetLobby(obj);
|
||||
|
||||
Map map = (Map)obj;
|
||||
Submarine map = (Submarine)obj;
|
||||
|
||||
//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();
|
||||
|
||||
@@ -281,13 +281,13 @@ namespace Subsurface
|
||||
Game1.GameScreen.Cam.MoveCamera((float)deltaTime);
|
||||
|
||||
Vector2 pos = new Vector2(
|
||||
Map.Borders.X + Map.Borders.Width / 2,
|
||||
Map.Borders.Y - Map.Borders.Height / 2);
|
||||
Submarine.Borders.X + Submarine.Borders.Width / 2,
|
||||
Submarine.Borders.Y - Submarine.Borders.Height / 2);
|
||||
|
||||
camAngle += (float)deltaTime / 10.0f;
|
||||
Vector2 offset = (new Vector2(
|
||||
(float)Math.Cos(camAngle) * (Map.Borders.Width / 2.0f),
|
||||
(float)Math.Sin(camAngle) * (Map.Borders.Height / 2.0f)));
|
||||
(float)Math.Cos(camAngle) * (Submarine.Borders.Width / 2.0f),
|
||||
(float)Math.Sin(camAngle) * (Submarine.Borders.Height / 2.0f)));
|
||||
|
||||
pos += offset * 0.8f;
|
||||
|
||||
@@ -466,7 +466,7 @@ namespace Subsurface
|
||||
|
||||
public void WriteData(NetOutgoingMessage msg)
|
||||
{
|
||||
Map selectedMap = mapList.SelectedData as Map;
|
||||
Submarine selectedMap = mapList.SelectedData as Submarine;
|
||||
|
||||
if (selectedMap==null)
|
||||
{
|
||||
@@ -476,7 +476,7 @@ namespace Subsurface
|
||||
else
|
||||
{
|
||||
msg.Write(Path.GetFileName(selectedMap.Name));
|
||||
msg.Write(selectedMap.MapHash.MD5Hash);
|
||||
msg.Write(selectedMap.Hash.MD5Hash);
|
||||
}
|
||||
|
||||
msg.Write(modeList.SelectedIndex);
|
||||
@@ -486,7 +486,7 @@ namespace Subsurface
|
||||
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)
|
||||
{
|
||||
DebugConsole.ThrowError("The map ''" + mapName + "'' has been selected by the server.");
|
||||
@@ -495,10 +495,10 @@ namespace Subsurface
|
||||
}
|
||||
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 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 + ")");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,9 @@
|
||||
<Compile Include="Map\Level.cs" />
|
||||
<Compile Include="Map\Lights\ConvexHull.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\VoronoiElements.cs" />
|
||||
<Compile Include="Physics\PhysicsBody.cs" />
|
||||
@@ -161,7 +163,7 @@
|
||||
<Compile Include="Items\Components\Projectile.cs" />
|
||||
<Compile Include="Map\MapEntity.cs" />
|
||||
<Compile Include="Map\MapEntityPrefab.cs" />
|
||||
<Compile Include="Map\Map.cs" />
|
||||
<Compile Include="Map\Submarine.cs" />
|
||||
<Compile Include="Map\Structure.cs" />
|
||||
<Compile Include="Map\StructurePrefab.cs" />
|
||||
<Compile Include="Map\WaterRenderer.cs" />
|
||||
|
||||
@@ -25,10 +25,20 @@ namespace Subsurface
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user