Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Linq;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Content;
- using Microsoft.Xna.Framework.Graphics;
- using Microsoft.Xna.Framework.Input;
- using Microsoft.Xna.Framework.Audio;
- using Microsoft.Xna.Framework.Media;
- using SmlEngine.Sprites.Base;
- using SmlEngine.Sprites.Camera;
- using SmlEngine.Sprites.Collections;
- using SmlEngine.Sprites.Settings;
- using SmlEngine.Graphics;
- using SmlEngine.UI.Managers;
- using SmlEngine.Sprites.Base.WorldMap;
- using SmlEngine.Extensions;
- using SmlEngine.IO;
- namespace SmlEngine.Sprites.Collections
- {
- /// <summary>
- /// An overhead map to signify levels.
- /// </summary>
- public class World : IName
- {
- #region Properties and Fields
- public string Name { get; set; }
- public InputManager Input { get; set; }
- public IList<Layer> Layers { get; private set; } // unused
- public List<WorldPlayer> Players { get; private set; }
- public Camera2D Camera { get; private set; }
- public int Score { get; set; }
- public bool IsRunning { get; set; }
- public bool HandleInput { get; set; } // Set to false to stop handling input, useful when fading
- private bool isContentLoaded;
- private Vector2 windowSize;
- public WorldPlayer ActivePlayer
- {
- get;
- private set;
- }
- public int ActivePlayerIndex
- {
- get
- {
- if (ActivePlayer == null) return -1;
- return Players.IndexOf(ActivePlayer);
- }
- }
- public bool IsLoaded { get; private set; }
- private SpriteFont testFont;
- private Song worldMusic; // temporary
- private SoundEffect jumpSound; // temporary
- #region World Settings
- public string worldName { get; private set; }
- public string worldAuthor { get; private set; }
- // public object Project <-- will be implemented later
- public Vector2 worldOrigin { get; private set; }
- public Vector2 worldSize { get; private set; }
- public string worldFolder { get; private set; }
- #endregion
- #region Jumping
- private bool IsJumping = false;
- private Vector2 jumpDistancePerFrame;
- private int jumpedFor = 0;
- #endregion
- #region Object Lists
- public QuadTree<WorldMapTile> staticTiles = new QuadTree<WorldMapTile>(new Vector2(64, 64));
- public QuadTree<WorldAnimatedTile> animatedTiles = new QuadTree<WorldAnimatedTile>(new Vector2(64, 64));
- public QuadTree<PathTile> pathTiles = new QuadTree<PathTile>(new Vector2(64, 64));
- public QuadTree<LevelTile> levelTiles = new QuadTree<LevelTile>(new Vector2(64, 64));
- public QuadTree<PipeTile> pipeTiles = new QuadTree<PipeTile>(new Vector2(64, 64));
- #endregion
- #region Section Data
- public bool isCameraLocked;
- public int Section { get; set; }
- public string FileName { get; private set; }
- #endregion
- #region Preloaded Custom Tile Lists
- private Dictionary<string, WorldMapTile> loadedCustomTiles = new Dictionary<string, WorldMapTile>();
- private Dictionary<string, WorldAnimatedTile> loadedCustomAnimTiles = new Dictionary<string, WorldAnimatedTile>();
- private Dictionary<string, LevelTile> loadedCustomLevelTiles = new Dictionary<string, LevelTile>();
- private Dictionary<string, PathTile> loadedCustomPathTiles = new Dictionary<string, PathTile>();
- #endregion
- #region Exit Settings
- private int exitIndex; // how many exits are loaded
- private Dictionary<int, List<PathTile>> pathsByExit = new Dictionary<int,List<PathTile>>(); // stores references to path tiles by exit number
- private int revealingExitIndex = -3; // which exit is being revealed, -3 is the code for no exit is being revealed
- private int revealingTileIndex = -1; // which tile in the exit is being revealed
- private LevelTile currentLevel; // which level tile is currently entered
- private bool unlockCurrentTile; // whether we should unlock the current tile
- #endregion
- #region Border Text
- public string LevelDisplayText = "";
- public string CoinDisplayText
- {
- get
- {
- if (ActivePlayer == null) return "";
- return ActivePlayer.Coins.ToString();
- }
- }
- public string LivesDisplayText
- {
- get
- {
- if (ActivePlayer == null) return "";
- return ActivePlayer.Lives.ToString();
- }
- }
- #endregion
- #region Pipes and Section Switching
- public event LevelEnteredEventHandler LevelEntered;
- private LevelTile tileEntering;
- public PipeTile pipeEntering;
- #endregion
- #endregion
- #region Methods
- #region Constructors
- public World(Vector2 c_windowSize)
- {
- Camera = new Camera2D();
- Layers = new List<Layer>();
- Players = new List<WorldPlayer>();
- windowSize = c_windowSize;
- this.IsRunning = false;
- this.HandleInput = true;
- }
- #endregion
- #region Loading
- public void Load(string world_path)
- {
- System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
- stopWatch.Start();
- if (IsLoaded) return;
- if (File.Exists(world_path))
- {
- this.FileName = world_path;
- worldFolder = world_path.Substring(0, world_path.LastIndexOf(@"\"));
- DataReader dataReader = new DataReader(world_path);
- if (!dataReader.SectionExists("[world]")) { throw new Exception("The world file at " + world_path + " is corrupt."); }
- LoadHeader(dataReader);
- LoadStaticTiles(dataReader);
- LoadAnimatedTiles(dataReader);
- LoadPathTiles(dataReader);
- LoadWorldPlayers(dataReader);
- LoadLevelTiles(dataReader);
- LoadPipeTiles(dataReader);
- IsLoaded = true;
- }
- else
- {
- throw new FileNotFoundException(string.Format("The world file at {0} could not be found.", world_path));
- }
- stopWatch.Stop();
- System.Diagnostics.Trace.WriteLine("World load: " + stopWatch.ElapsedMilliseconds);
- }
- private void LoadHeader(DataReader dataReader)
- {
- var header = dataReader.ReadFullSection("[world]");
- if (header == null) throw new Exception(string.Format("The world file at {0} is corrupt or invalid.", dataReader.FilePath));
- worldName = header["name"];
- worldAuthor = header["author"];
- // worldProject = <-- will be implemented later
- worldOrigin = GetVector(header["start"]);
- worldSize = GetVector(header["size"]);
- }
- private void LoadStaticTiles(DataReader dataReader)
- {
- string[] tile_entries = dataReader.ReadAllLinesInSection("[static]");
- string[] tile_entry;
- int tile_id;
- string tile_filePath = "";
- int tileX;
- int tileY;
- Vector2 quadTreePos;
- foreach (string tile in tile_entries)
- {
- tile_entry = tile.Split(',');
- if (!Int32.TryParse(tile_entry[0], out tile_id)) // If this tile is custom
- {
- tile_filePath = String.Concat(worldFolder, @"\", tile_entry[1]);
- tile_id = -1;
- }
- tileX = int.Parse(tile_entry[1]);
- tileY = int.Parse(tile_entry[2]);
- WorldMapTile lt, t;
- if (tile_id != -1)
- {
- t = WorldObjectSet.LoadWorldMapTile(tile_id);
- }
- else
- {
- // Custom tile
- if (!IsCustomTileLoaded(tile_filePath))
- {
- // All custom tiles are preloaded, and then cloned as necessary.
- lt = WorldObjectSet.LoadCustomStaticTile(worldFolder, tile_filePath);
- loadedCustomTiles.Add(tile_filePath, lt);
- }
- t = (WorldMapTile)loadedCustomTiles[tile_filePath].Clone();
- }
- t.Position = new Vector2(tileX, tileY);
- staticTiles.Add(t);
- }
- // Clearing out the (pre-)loaded tiles
- loadedCustomTiles.Clear();
- }
- private void LoadAnimatedTiles(DataReader dataReader)
- {
- dataReader.SetIndexToSection("[anim]");
- string[] atile_entry;
- int atile_id;
- int atileX;
- int atileY;
- string a_filePath = "";
- Vector2 quadTreePos;
- while ((atile_entry = dataReader.ReadNextEntry()) != null)
- {
- if (!Int32.TryParse(atile_entry[0], out atile_id)) // Custom tile
- {
- a_filePath = String.Concat(worldFolder, @"\", atile_entry[1]);
- atile_id = -1;
- }
- atileX = int.Parse(atile_entry[1]);
- atileY = int.Parse(atile_entry[2]);
- WorldAnimatedTile a = null, la;
- if (atile_id >= 0)
- {
- a = WorldObjectSet.LoadWorldAnimatedTile(atile_id);
- }
- else
- {
- if (!IsCustomAnimatedTileLoaded(a_filePath))
- {
- la = WorldObjectSet.LoadCustomAnimatedTile(worldFolder, a_filePath);
- loadedCustomAnimTiles.Add(a_filePath, la);
- }
- a = (WorldAnimatedTile)loadedCustomAnimTiles[a_filePath].Clone();
- }
- a.SetData(new Vector2(atileX, atileY));
- quadTreePos = a.Position.FloorDivide(64);
- animatedTiles.Add(a);
- }
- loadedCustomAnimTiles.Clear();
- }
- private void LoadPathTiles(DataReader dataReader)
- {
- string[] path_entry;
- int path_id;
- string path_cconfig = "";
- int path_X = 0;
- int path_Y = 0;
- int path_exitNumber = 0;
- Vector2 p_quadTreePos;
- dataReader.SetIndexToSection("[path]");
- while ((path_entry = dataReader.ReadNextEntry()) != null)
- {
- path_exitNumber = 0;
- if (!Int32.TryParse(path_entry[0], out path_id))
- {
- path_cconfig = worldFolder + @"\" + path_entry[2];
- path_id = -1;
- }
- path_X = Int32.Parse(path_entry[1]);
- path_Y = Int32.Parse(path_entry[2]);
- path_exitNumber = Int32.Parse(path_entry[3]);
- PathTile p = null, lp;
- if (path_id != -1)
- {
- p = WorldObjectSet.LoadPathTile(path_id);
- }
- else
- {
- if (!IsCustomPathTileLoaded(path_cconfig))
- {
- lp = WorldObjectSet.LoadCustomPathTile(worldFolder, path_cconfig);
- loadedCustomPathTiles.Add(path_cconfig, lp);
- }
- p = (PathTile)loadedCustomPathTiles[path_cconfig].Clone();
- }
- p.SetData(new Vector2(path_X, path_Y), path_exitNumber);
- p_quadTreePos = p.Position.FloorDivide(64);
- pathTiles.Add(p);
- if (!pathsByExit.ContainsKey(path_exitNumber)) { pathsByExit.Add(path_exitNumber, new List<PathTile>()); }
- pathsByExit[path_exitNumber].Add(p);
- }
- }
- private void LoadLevelTiles(DataReader dataReader)
- {
- var tiles = dataReader.ReadFullMultiSection("[level]");
- if (tiles != null)
- {
- foreach (var tile in tiles)
- {
- #region Data Loading
- int id;
- string configPath = "";
- Vector2 position;
- bool revealed;
- string filePath;
- string displayName;
- int exitNumber;
- string[] exitData;
- List<Exit> level_exits = new List<Exit>();
- int revealOn;
- bool isSMB3Style = false;
- if (!Int32.TryParse(tile["id"], out id))
- {
- configPath = worldFolder + @"\" + tile["id"];
- id = -1;
- }
- position = GetVector(tile["position"]);
- revealed = tile["reveal"] == "yes" ? true : false;
- filePath = tile["path"];
- displayName = tile["display"];
- exitNumber = Int32.Parse(tile["exits"]);
- if (tile["exitdata"] != "smb3")
- {
- exitData = tile["exitdata"].Split(',');
- if (exitData.Length > 4) throw new Exception(string.Format("There were too many defined exits for this level tile (level tile #{0})", tiles.IndexOf(tile)));
- foreach (string s in exitData)
- {
- level_exits.Add(new Exit(s));
- }
- }
- else
- {
- isSMB3Style = true;
- }
- revealOn = int.Parse(tile["revealOn"]);
- #endregion
- LevelTile l = null;
- if (id >= 0)
- {
- l = WorldObjectSet.LoadLevelTile(id);
- }
- else
- {
- if (!IsCustomLevelTileLoaded(configPath))
- {
- if (!isSMB3Style)
- {
- loadedCustomLevelTiles.Add(configPath, WorldObjectSet.LoadCustomLevelTile(worldFolder, configPath));
- }
- else
- {
- loadedCustomLevelTiles.Add(configPath, WorldObjectSet.LoadCustomSMB3LevelTile(worldFolder, configPath));
- }
- l = (LevelTile)loadedCustomLevelTiles[configPath].Clone();
- }
- }
- if (!isSMB3Style)
- {
- l.SetData(position, "", filePath, level_exits);
- l.SetData(revealOn);
- }
- else
- {
- (l as SMB3LevelTile).SetData(position, "", filePath);
- }
- l.LevelName = displayName;
- Vector2 quadtreePos = l.Position.FloorDivide(64);
- levelTiles.Add(l);
- if (!pathsByExit.ContainsKey(revealOn)) pathsByExit.Add(revealOn, new List<PathTile>());
- pathsByExit[revealOn].Add(l);
- }
- }
- }
- private void LoadWorldPlayers(DataReader dataReader)
- {
- dataReader.SetIndexToSection("[player]");
- string[] player_entry;
- int player_ID;
- string config_path = "";
- int player_X;
- int player_Y;
- while ((player_entry = dataReader.ReadNextEntry()) != null)
- {
- if (!Int32.TryParse(player_entry[0], out player_ID)) // custom player
- {
- config_path = player_entry[0];
- player_ID = -1;
- }
- player_X = Int32.Parse(player_entry[1]);
- player_Y = Int32.Parse(player_entry[2]);
- WorldPlayer p = null;
- if (player_ID >= 0)
- {
- p = WorldObjectSet.LoadWorldPlayer(player_ID);
- }
- else
- {
- p = WorldObjectSet.LoadCustomWorldPlayer(worldFolder, config_path);
- }
- p.Position = new Vector2(player_X, player_Y);
- Players.Add(p);
- if (ActivePlayer == null) ActivePlayer = p;
- }
- }
- private void LoadPipeTiles(DataReader dataReader)
- {
- var pipes = dataReader.ReadFullMultiSection("[pipe]");
- if (pipes != null)
- {
- int pipeID;
- string pipeCustomConfigPath = "";
- Vector2 pipePosition;
- string pipeDisplayName;
- int pipeDestinationSection = -1;
- string pipeDestinationFileName = "";
- Vector2 pipeDestinationPosition;
- int pipeRevealOnExit;
- foreach (var pipe in pipes)
- {
- if (!int.TryParse(pipe["id"], out pipeID))
- {
- pipeCustomConfigPath = pipe["id"];
- pipeID = -1;
- }
- pipePosition = GetVector(pipe["position"]);
- pipeDisplayName = pipe["display"];
- pipeDestinationPosition = GetVector(pipe["destination"]);
- pipeRevealOnExit = int.Parse(pipe["revealOn"]);
- // load the destination section/filename
- if (pipe.ContainsKey("section"))
- {
- pipeDestinationSection = Int32.Parse(pipe["section"]);
- }
- else if (pipe.ContainsKey("filename"))
- {
- pipeDestinationFileName = string.Concat(worldFolder, pipe["filename"]);
- pipeDestinationSection = -1;
- }
- PipeTile p = null;
- if (pipeID >= 0)
- {
- p = WorldObjectSet.LoadPipeTile(pipeID);
- }
- else
- {
- p = WorldObjectSet.LoadCustomPipeTile(worldFolder, pipeCustomConfigPath);
- }
- p.SetData(pipePosition, pipeRevealOnExit);
- p.DisplayName = pipeDisplayName;
- p.DestinationWorldSection = pipeDestinationSection;
- p.DestinationFileName = pipeDestinationFileName;
- p.DestinationPosition = pipeDestinationPosition;
- pipeTiles.Add(p);
- if (!pathsByExit.ContainsKey(p.exitNumber))
- {
- pathsByExit.Add(p.exitNumber, new List<PathTile>());
- }
- pathsByExit[p.exitNumber].Add(p);
- }
- }
- }
- public void LoadContent(ContentManager Content, GraphicsDevice Graphics)
- {
- System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
- stopWatch.Start();
- if (!isContentLoaded)
- {
- foreach (WorldMapTile t in staticTiles)
- {
- t.LoadContent(Content, Graphics);
- }
- foreach (WorldAnimatedTile a in animatedTiles)
- {
- a.LoadContent(Content, Graphics);
- }
- foreach (var path in pathTiles)
- {
- path.LoadContent(Content, Graphics);
- }
- foreach (LevelTile l in levelTiles)
- {
- if (l is SMB3LevelTile)
- {
- (l as SMB3LevelTile).LoadContent(Graphics, Content);
- }
- else
- {
- l.LoadContent(Graphics, Content);
- }
- }
- foreach (var i in pipeTiles)
- {
- i.LoadContent(Content, Graphics);
- }
- foreach (WorldPlayer player in Players)
- {
- player.LoadContent(Graphics, Content);
- }
- testFont = Content.Load<SpriteFont>(@"world\testFont");
- worldMusic = Content.Load<Song>(@"sound_test\music");
- jumpSound = Content.Load<SoundEffect>(@"sound_test\smw_scroll");
- MediaPlayer.Volume = 0.5f;
- MediaPlayer.Play(worldMusic);
- isContentLoaded = true;
- stopWatch.Stop();
- System.Diagnostics.Trace.WriteLine("World load content: " + stopWatch.ElapsedMilliseconds);
- }
- }
- private string GetValue(string input)
- {
- return input.Split('=')[1].TrimStart();
- }
- //private object GetMatchingObjectByIndex(object[] inputs, object[] outputs, string input)
- //{
- // if (inputs.Length != outputs.Length) throw new ArgumentException("Could not get matching object by index, parameters were not the same length.");
- // int index = Array.IndexOf(inputs, input);
- // if (index == -1) return null;
- // return outputs[index];
- //}
- private static Vector2 GetVector(string input)
- {
- String[] v = input.Split(',');
- v[0] = v[0].Trim();
- return new Vector2(float.Parse(v[0]), float.Parse(v[1]));
- }
- private bool IsCustomTileLoaded(string file_path)
- {
- return loadedCustomAnimTiles.ContainsKey(file_path);
- }
- private bool IsCustomAnimatedTileLoaded(string file_path)
- {
- return loadedCustomAnimTiles.ContainsKey(file_path);
- }
- private bool IsCustomPathTileLoaded(string path)
- {
- return loadedCustomPathTiles.ContainsKey(path);
- }
- private bool IsCustomLevelTileLoaded(string path)
- {
- return loadedCustomLevelTiles.ContainsKey(path);
- }
- #endregion
- #region Update and Draw
- public void UpdateCamera()
- {
- if (!isCameraLocked && ActivePlayer != null)
- {
- if (IsJumping)
- {
- if (jumpedFor == 30)
- {
- IsJumping = false;
- jumpDistancePerFrame = Vector2.Zero;
- jumpedFor = 0;
- }
- Camera.Position += jumpDistancePerFrame;
- jumpedFor++;
- }
- else
- {
- Vector2 halfPlayer = new Vector2(ActivePlayer.Size.X / 2, ActivePlayer.Size.Y / 2);
- Vector2 halfWindow = windowSize / 2;
- Camera.Position = ActivePlayer.Position + halfPlayer;
- Camera.Position = new Vector2(Camera.Position.X - halfWindow.X, Camera.Position.Y - halfWindow.Y);
- }
- }
- }
- public void Update(GameTime gameTime)
- {
- if (!this.IsRunning) return;
- UpdateCamera();
- #region Fading Checks
- //if (fadeStep < 0) // fade in
- //{
- // if (fadeLevel > 0) fadeLevel += fadeStep;
- // else
- // {
- // fadeStep = 0;
- // tileEntering = null;
- // if (revealingExitIndex >= 0)
- // {
- // internalStartReveal(revealingExitIndex);
- // }
- // if (unlockCurrentTile)
- // {
- // internalUnlockTile();
- // unlockCurrentTile = false;
- // }
- // //OnFadeCompleted(new FadeCompletedEventArgs(FadeType.In));
- // }
- //}
- //else if (fadeStep > 0) // fade out
- //{
- // if (fadeLevel < 60) fadeLevel += fadeStep;
- // else
- // {
- // fadeStep = 0;
- // if (tileEntering != null) OnLevelEntered(tileEntering);
- // //OnFadeCompleted(new FadeCompletedEventArgs(FadeType.Out));
- // }
- //}
- #endregion
- #region Reveal Checks
- if (revealingExitIndex != -3 && revealingTileIndex >= 0) // if we're revealing
- {
- if (pathsByExit[revealingExitIndex][revealingTileIndex].IsRevealed) // if this tile is done revealing and we're not at the end of the list
- {
- revealingTileIndex++;
- pathsByExit[revealingExitIndex][revealingTileIndex].Reveal();
- }
- else if (revealingTileIndex == pathsByExit[revealingExitIndex].Count - 1)
- {
- revealingExitIndex = -3;
- revealingTileIndex = -1;
- }
- }
- #endregion
- #region Tile Updating
- pathTiles.Update(gameTime);
- levelTiles.Update(gameTime);
- pipeTiles.Update(gameTime);
- #endregion
- if (ActivePlayer != null)
- {
- PathTile currentPath = GetPath(ActivePlayer.tilePosition);
- if (LevelDisplayText == "" && (currentPath != null && currentPath is LevelTile))
- {
- LevelDisplayText = (currentPath as LevelTile).LevelName;
- }
- else if (LevelDisplayText == "" && (currentPath != null && currentPath is PipeTile))
- {
- LevelDisplayText = (currentPath as PipeTile).DisplayName;
- }
- else if (currentPath == null || ((!(currentPath is LevelTile)) && (!(currentPath is PipeTile))))
- {
- LevelDisplayText = "";
- }
- }
- #region Input Handling
- //if (!Players.Any() || ActivePlayer == null) return;
- if (HandleInput)
- {
- if (!ActivePlayer.IsMoving && !IsJumping && revealingExitIndex == -3)
- {
- var keymap = Input.Current.KeyboardState;
- Vector2 tilePos = ActivePlayer.tilePosition;
- Vector2 distance = Vector2.Zero;
- if (keymap.IsKeyDown(Keys.Up)) { distance = GetDistanceToNextPathStop(ActivePlayer.tilePosition, Direction.Top); ActivePlayer.Move(distance); }
- else if (keymap.IsKeyDown(Keys.Down)) { distance = GetDistanceToNextPathStop(ActivePlayer.tilePosition, Direction.Bottom); ActivePlayer.Move(distance); }
- else if (keymap.IsKeyDown(Keys.Left)) { distance = GetDistanceToNextPathStop(ActivePlayer.tilePosition, Direction.Left); ActivePlayer.Move(distance); }
- else if (keymap.IsKeyDown(Keys.Right)) { distance = GetDistanceToNextPathStop(ActivePlayer.tilePosition, Direction.Right); ActivePlayer.Move(distance); }
- if (Input.IsNewKeyPress(Keys.J) && !IsJumping) Jump();
- if (Input.IsNewKeyPress(Keys.Q)) internalStartReveal(0); // temporary
- }
- if (Input.IsNewKeyPress(Keys.X) && !IsJumping)
- {
- PathTile p = GetPath(ActivePlayer.tilePosition);
- if (p is LevelTile)
- {
- OnLevelEntered((LevelTile)p);
- }
- else if (p is PipeTile && !ActivePlayer.IsMoving)
- {
- PipeTile pipe = (PipeTile)p;
- int section = pipe.DestinationWorldSection;
- string filename = pipe.DestinationFileName;
- if ((section == this.Section || section == -1) && filename == this.FileName) // same world
- {
- Vector2 oldPosition = ActivePlayer.Position;
- ActivePlayer.Position = pipe.DestinationPosition;
- Jump(oldPosition, ActivePlayer.Position);
- }
- else
- {
- pipe.PlayerToSend = ActivePlayer;
- pipeEntering = pipe;
- }
- }
- }
- }
- foreach (WorldPlayer p in Players) p.Update(gameTime);
- #endregion
- }
- public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
- {
- if (!this.IsRunning) return;
- spriteBatch.End();
- spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, Camera.GetTransformation());
- staticTiles.Draw(gameTime, spriteBatch);
- animatedTiles.Draw(gameTime, spriteBatch);
- pathTiles.Draw(gameTime, spriteBatch);
- levelTiles.Draw(gameTime, spriteBatch);
- pipeTiles.Draw(gameTime, spriteBatch);
- if (!unlockCurrentTile)
- {
- foreach (WorldPlayer p in Players)
- {
- p.Draw(gameTime, spriteBatch);
- }
- }
- //spriteBatch.DrawRectangle(GetScreenBounds(), (Color.Black * (fadeLevel * 0.01667f)));
- //spriteBatch.DrawString(testFont, "Now opening: New Pipe Network", new Vector2(30, 30) + Camera.Position, Color.White);
- spriteBatch.End();
- spriteBatch.Begin();
- }
- #endregion
- #region Public Methods
- public void Start()
- {
- IsRunning = true;
- }
- public void Stop()
- {
- IsRunning = false;
- }
- public void Jump(int playerIndex)
- {
- if (playerIndex < 0 || playerIndex > Players.Count - 1)
- {
- throw new ArgumentOutOfRangeException("playerIndex", string.Format("The world tried to focus a player that did not exist ({0})", playerIndex));
- }
- if (ActivePlayer.Position == Players[playerIndex].Position)
- {
- return;
- }
- IsJumping = true;
- Vector2 v1 = ActivePlayer.Position;
- Vector2 v2 = Players[playerIndex].Position;
- jumpDistancePerFrame = ((v2 - v1) / 30);
- ActivePlayer = Players[playerIndex];
- Players.ForEach(p => p.Velocity = Vector2.Zero);
- jumpSound.Play();
- }
- public void Jump(Vector2 a, Vector2 b)
- {
- if (a == b) return;
- IsJumping = true;
- jumpDistancePerFrame = ((b - a) / 30);
- }
- public void Jump()
- {
- if (Players.Count == 1) return;
- if (ActivePlayerIndex == Players.Count - 1) Jump(0);
- else Jump(ActivePlayerIndex + 1);
- }
- public void StartReveal(int exitIndex)
- {
- revealingExitIndex = exitIndex;
- }
- private void internalStartReveal(int exitIndex)
- {
- if (exitIndex >= 0 && exitIndex < pathsByExit.Count)
- {
- revealingExitIndex = exitIndex;
- if (pathsByExit[exitIndex].Any())
- {
- int i;
- LevelTile l = GetLevelTileByExit(exitIndex, out i);
- if (l != null && l.Exits[i].Cleared == false)
- {
- l.Exits[i] = new Exit(exitIndex, l.Exits[i].ExitDirection, true);
- revealingTileIndex = 0;
- pathsByExit[exitIndex][0].Reveal();
- }
- else
- {
- revealingExitIndex = -3;
- revealingTileIndex = -1;
- }
- }
- }
- }
- public void UnlockTile()
- {
- unlockCurrentTile = true;
- }
- private void internalUnlockTile()
- {
- if (currentLevel != null && currentLevel is SMB3LevelTile)
- {
- (currentLevel as SMB3LevelTile).Unlock();
- }
- }
- public WorldPlayer GetPlayer(int index)
- {
- if (index < Players.Count)
- {
- return Players[index];
- }
- return null;
- }
- public void AddPlayer(WorldPlayer player, Vector2 position)
- {
- player.Position = position;
- Players.Add(player);
- ActivePlayer = player;
- }
- public void ClearSwap()
- {
- pipeEntering = null;
- }
- public void ReloadContent(GraphicsDevice gd, ContentManager cm)
- {
- UnloadContent();
- foreach (WorldMapTile t in staticTiles)
- {
- t.LoadContent(cm, gd);
- }
- foreach (WorldAnimatedTile va in animatedTiles) va.LoadContent(cm, gd);
- foreach (var p in pathTiles) p.LoadContent(cm, gd);
- foreach (var l in levelTiles)
- {
- if (l is SMB3LevelTile) (l as SMB3LevelTile).LoadContent(cm, gd);
- else l.LoadContent(cm, gd);
- }
- foreach (var p in pipeTiles) p.LoadContent(cm, gd);
- Players.ForEach(pl => pl.LoadContent(gd, cm));
- }
- public void UnloadContent()
- {
- foreach (WorldMapTile t in staticTiles) t.UnloadContent();
- foreach (WorldAnimatedTile a in animatedTiles) a.UnloadContent();
- foreach (var v in pathTiles) v.UnloadContent();
- foreach (var v in levelTiles) v.UnloadContent();
- foreach (var v in pipeTiles) v.UnloadContent();
- Players.ForEach(pl => pl.UnloadContent());
- }
- #endregion
- #region Section and Pipe Methods
- //private void SetSectionToSwap(int newSectionIndex, Vector2 newDestination, int playerSwapIndex)
- //{
- // SwapSectionIndex = newSectionIndex;
- // SwapDestination = newDestination;
- // SwapWorldPlayerIndex = playerSwapIndex;
- //}
- //public void FinishSwap()
- //{
- // SwapSectionIndex = -1;
- // SwapWorldPlayerIndex = -1;
- //}
- //public void FadeIn()
- //{
- // if (fadeLevel != 0)
- // {
- // fadeStep = -1;
- // }
- //}
- //public void FadeOut()
- //{
- // if (fadeLevel != 60)
- // {
- // fadeStep = 1;
- // }
- //}
- public void UpdateFocusedPlayer()
- {
- //if (focusedPlayer >= Players.Count)
- //{
- // focusedPlayer = Players.Count - 1;
- //}
- }
- #endregion
- #region Helper Methods
- public PathTile GetPath(Vector2 tileLocation)
- {
- // TODO: only check rect intersections with bottom center point of WorldPlayer hitbox (prevents multiple tiles registered)
- Vector2 quadTreePos = tileLocation.FloorDivide(4);
- if (pathTiles.ContainsCell(quadTreePos))
- {
- foreach (PathTile p in pathTiles[quadTreePos])
- {
- if (p.tilePosition == tileLocation) return p;
- else if (!p.Size.ComparePoint(ActivePlayer.Size) && p.Area.GetIntersectionDepth(ActivePlayer.Area) != Vector2.Zero) return p;
- }
- }
- if (levelTiles.ContainsCell(quadTreePos))
- {
- foreach (LevelTile l in levelTiles[quadTreePos])
- {
- if (l.tilePosition == tileLocation) return l;
- else if (!l.Size.ComparePoint(ActivePlayer.Size) && l.Area.GetIntersectionDepth(ActivePlayer.Area) != Vector2.Zero) return l;
- }
- }
- if (pipeTiles.ContainsCell(quadTreePos))
- {
- foreach (PipeTile p in pipeTiles[quadTreePos])
- {
- if (p.tilePosition == tileLocation) return p;
- else if (!p.Size.ComparePoint(ActivePlayer.Size) && p.Area.GetIntersectionDepth(ActivePlayer.Area) != Vector2.Zero) return p;
- }
- }
- return null;
- }
- private WorldPlayer GetWorldPlayer(Vector2 tileLocation)
- {
- foreach (var player in Players)
- {
- if (player.tilePosition == tileLocation) return player;
- }
- return null;
- }
- private Vector2 GetDistanceToNextPathStop(Vector2 startPathTilePosition, Direction direction)
- {
- Vector2 offset = Vector2.Zero; // the number of tiles to go by
- Vector2 iteratorPosition = Vector2.Zero;
- PathTile p;
- // first, check if the player is on an SMB3LevelTile, and see if it can move
- if ((p = GetPath(startPathTilePosition)) != null)
- {
- if (p is SMB3LevelTile && (p as SMB3LevelTile).LockState == LockedState.Locked)
- {
- WorldPlayer player = GetWorldPlayer(startPathTilePosition);
- if (player != null && player.InvertDirection(player.LastMoveDirection) != direction)
- {
- return Vector2.Zero;
- }
- }
- }
- else return Vector2.Zero; // no path tile
- switch (direction)
- {
- case Direction.Top: // up (Y decreases)
- if (p.Direction == PathType.Horizontal) // || p.Direction == PathType.CornerTopLeft || p.Direction == PathType.CornerTopRight || p.Direction == PathType.TIntersectionFromBottom)
- {
- return Vector2.Zero;
- }
- iteratorPosition = new Vector2(startPathTilePosition.X, startPathTilePosition.Y - 1);
- p = GetPath(iteratorPosition);
- while (p != null)
- {
- if (p.IsNode)
- {
- offset.Y -= p.Size.Y;
- return offset;
- }
- if (p is SMB3LevelTile)
- {
- offset.Y -= p.Size.Y;
- return offset;
- }
- if (!p.IsRevealed)
- {
- return offset;
- }
- iteratorPosition.Y--;
- offset.Y -= p.Size.Y;
- p = GetPath(iteratorPosition);
- }
- break;
- case Direction.Bottom: // down (Y increases)
- if (p.Direction == PathType.Horizontal) // || p.Direction == PathType.CornerBottomLeft || p.Direction == PathType.CornerBottomRight || p.Direction == PathType.TIntersectionFromTop)
- {
- return Vector2.Zero;
- }
- iteratorPosition = new Vector2(startPathTilePosition.X, startPathTilePosition.Y + 1);
- p = GetPath(iteratorPosition);
- while (p != null)
- {
- if (p.IsNode)
- {
- offset.Y += p.Size.Y;
- return offset;
- }
- if (p is SMB3LevelTile)
- {
- offset.Y += p.Size.Y;
- return offset;
- }
- if (!p.IsRevealed)
- {
- return offset;
- }
- iteratorPosition.Y++;
- offset.Y += p.Size.Y;
- p = GetPath(iteratorPosition);
- }
- break;
- case Direction.Left: // left (X decreases)
- if (p.Direction == PathType.Vertical) // || p.Direction == PathType.CornerBottomLeft || p.Direction == PathType.CornerTopLeft || p.Direction == PathType.TIntersectionFromRight)
- {
- return Vector2.Zero;
- }
- iteratorPosition = new Vector2(startPathTilePosition.X - 1, startPathTilePosition.Y);
- p = GetPath(iteratorPosition);
- while (p != null)
- {
- if (p.IsNode)
- {
- offset.X -= p.Size.X;
- return offset;
- }
- if (p is SMB3LevelTile)
- {
- offset.X -= p.Size.X;
- return offset;
- }
- if (!p.IsRevealed)
- {
- return offset;
- }
- iteratorPosition.X--;
- offset.X -= p.Size.X;
- p = GetPath(iteratorPosition);
- }
- break;
- case Direction.Right: // right (X increases)
- if (p.Direction == PathType.Vertical) //|| p.Direction == PathType.CornerBottomRight || p.Direction == PathType.CornerTopRight || p.Direction == PathType.TIntersectionFromLeft)
- {
- return Vector2.Zero;
- }
- iteratorPosition = new Vector2(startPathTilePosition.X + 1, startPathTilePosition.Y);
- p = GetPath(iteratorPosition);
- while (p != null)
- {
- if (p.IsNode)
- {
- offset.X += p.Size.X;
- return offset;
- }
- if (p is SMB3LevelTile)
- {
- offset.X += p.Size.X;
- return offset;
- }
- if (!p.IsRevealed)
- {
- return offset;
- }
- iteratorPosition.X++;
- offset.X += p.Size.X;
- p = GetPath(iteratorPosition);
- }
- break;
- }
- return offset;
- }
- private Rectangle GetScreenBounds()
- {
- return new Rectangle((int)Camera.Position.X, (int)Camera.Position.Y, (int)windowSize.X, (int)windowSize.Y);
- }
- private Vector2? CheckForPathTile(Vector2 position, Direction dir)
- {
- Vector2 startTileSize = GetPath(position.FloorDivide(16)).Size;
- Rectangle r = new Rectangle((int)position.X, (int)position.Y, 1, 1);
- if (dir == Direction.Top) r.Y--;
- else if (dir == Direction.Bottom) r.Y++;
- else if (dir == Direction.Left) r.X--;
- else if (dir == Direction.Right) r.X++;
- Vector2 colRectCell = new Vector2(r.X, r.Y).FloorDivide(64);
- foreach (PathTile p in pathTiles[colRectCell])
- {
- Rectangle pRect = p.Position.ToRectangle(p.Size);
- Vector2 depth = r.GetIntersectionDepth(pRect);
- if (depth != Vector2.Zero) return p.Position;
- }
- foreach (LevelTile l in levelTiles[colRectCell])
- {
- Rectangle pRect = l.Position.ToRectangle(l.Size);
- Vector2 depth = r.GetIntersectionDepth(pRect);
- if (depth != Vector2.Zero) return l.Position;
- }
- return null;
- }
- protected virtual void OnLevelEntered(LevelTile e)
- {
- if (LevelEntered != null)
- LevelEntered(this, e);
- }
- #endregion
- #region Path Methods
- public void AssignPathToExitByBorder(PathTile p)
- {
- #region Field Initialization
- Dictionary<Direction, Vector2> offset = new Dictionary<Direction, Vector2>();
- offset.Add(Direction.Top, new Vector2(0, -1));
- offset.Add(Direction.Bottom, new Vector2(0, 1));
- offset.Add(Direction.Left, new Vector2(-1, 0));
- offset.Add(Direction.Right, new Vector2(1, 0));
- Dictionary<Direction, List<PathType>> movable_types = new Dictionary<Direction, List<PathType>>();
- movable_types.Add(Direction.Top, new List<PathType>() { PathType.CornerTopLeft, PathType.CornerTopRight, PathType.FourWayIntersection,
- PathType.TIntersectionFromBottom, PathType.TIntersectionFromLeft, PathType.TIntersectionFromRight, PathType.Vertical});
- movable_types.Add(Direction.Bottom, new List<PathType>() { PathType.CornerBottomLeft, PathType.CornerBottomRight, PathType.FourWayIntersection,
- PathType.TIntersectionFromLeft, PathType.TIntersectionFromRight, PathType.TIntersectionFromTop, PathType.Vertical});
- movable_types.Add(Direction.Left, new List<PathType>() { PathType.CornerBottomLeft, PathType.CornerTopLeft, PathType.FourWayIntersection,
- PathType.Horizontal, PathType.TIntersectionFromBottom, PathType.TIntersectionFromRight, PathType.TIntersectionFromTop});
- movable_types.Add(Direction.Right, new List<PathType>() { PathType.CornerBottomRight, PathType.CornerTopRight, PathType.FourWayIntersection,
- PathType.Horizontal, PathType.TIntersectionFromBottom, PathType.TIntersectionFromLeft, PathType.TIntersectionFromTop});
- Dictionary<PathType, List<Direction>> searchDirections = new Dictionary<PathType, List<Direction>>();
- searchDirections.Add(PathType.CornerBottomLeft, new List<Direction>() { Direction.Top, Direction.Right });
- searchDirections.Add(PathType.CornerBottomRight, new List<Direction>() { Direction.Top, Direction.Left });
- searchDirections.Add(PathType.CornerTopLeft, new List<Direction>() { Direction.Bottom, Direction.Right });
- searchDirections.Add(PathType.CornerTopRight, new List<Direction>() { Direction.Bottom, Direction.Left });
- searchDirections.Add(PathType.FourWayIntersection, new List<Direction>() { Direction.Top, Direction.Bottom, Direction.Left, Direction.Right });
- searchDirections.Add(PathType.Horizontal, new List<Direction>() { Direction.Left, Direction.Right });
- searchDirections.Add(PathType.TIntersectionFromBottom, new List<Direction>() { Direction.Bottom, Direction.Left, Direction.Right });
- searchDirections.Add(PathType.TIntersectionFromLeft, new List<Direction>() { Direction.Left, Direction.Top, Direction.Bottom });
- searchDirections.Add(PathType.TIntersectionFromRight, new List<Direction>() { Direction.Right, Direction.Top, Direction.Bottom });
- searchDirections.Add(PathType.TIntersectionFromTop, new List<Direction>() { Direction.Top, Direction.Left, Direction.Right });
- searchDirections.Add(PathType.Vertical, new List<Direction>() { Direction.Top, Direction.Bottom });
- #endregion
- foreach (Direction d in Enum.GetValues(typeof(Direction)))
- {
- if (searchDirections[p.Direction].Contains(d))
- {
- PathTile check_tile = GetPath(p.tilePosition + offset[d]);
- if (check_tile != null && movable_types[d].Contains(check_tile.Direction))
- {
- p.SetData(check_tile.exitNumber);
- if (!pathsByExit.ContainsKey(p.exitNumber)) pathsByExit.Add(p.exitNumber, new List<PathTile>());
- pathsByExit[p.exitNumber].Add(p);
- }
- }
- }
- }
- public List<PathTile> AssignBorderPathsToExit(PathTile p)
- {
- #region Field Initialization
- Dictionary<Direction, Vector2> offset = new Dictionary<Direction, Vector2>();
- offset.Add(Direction.Top, new Vector2(0, -1));
- offset.Add(Direction.Bottom, new Vector2(0, 1));
- offset.Add(Direction.Left, new Vector2(-1, 0));
- offset.Add(Direction.Right, new Vector2(1, 0));
- Dictionary<Direction, List<PathType>> movable_types = new Dictionary<Direction, List<PathType>>();
- movable_types.Add(Direction.Top, new List<PathType>() { PathType.CornerTopLeft, PathType.CornerTopRight, PathType.FourWayIntersection,
- PathType.TIntersectionFromBottom, PathType.TIntersectionFromLeft, PathType.TIntersectionFromRight, PathType.Vertical});
- movable_types.Add(Direction.Bottom, new List<PathType>() { PathType.CornerBottomLeft, PathType.CornerBottomRight, PathType.FourWayIntersection,
- PathType.TIntersectionFromLeft, PathType.TIntersectionFromRight, PathType.TIntersectionFromTop, PathType.Vertical});
- movable_types.Add(Direction.Left, new List<PathType>() { PathType.CornerBottomLeft, PathType.CornerTopLeft, PathType.FourWayIntersection,
- PathType.Horizontal, PathType.TIntersectionFromBottom, PathType.TIntersectionFromRight, PathType.TIntersectionFromTop});
- movable_types.Add(Direction.Right, new List<PathType>() { PathType.CornerBottomRight, PathType.CornerTopRight, PathType.FourWayIntersection,
- PathType.Horizontal, PathType.TIntersectionFromBottom, PathType.TIntersectionFromLeft, PathType.TIntersectionFromTop});
- Dictionary<PathType, List<Direction>> searchDirections = new Dictionary<PathType, List<Direction>>();
- searchDirections.Add(PathType.CornerBottomLeft, new List<Direction>() { Direction.Top, Direction.Right });
- searchDirections.Add(PathType.CornerBottomRight, new List<Direction>() { Direction.Top, Direction.Left });
- searchDirections.Add(PathType.CornerTopLeft, new List<Direction>() { Direction.Bottom, Direction.Right });
- searchDirections.Add(PathType.CornerTopRight, new List<Direction>() { Direction.Bottom, Direction.Left });
- searchDirections.Add(PathType.FourWayIntersection, new List<Direction>() { Direction.Top, Direction.Bottom, Direction.Left, Direction.Right });
- searchDirections.Add(PathType.Horizontal, new List<Direction>() { Direction.Left, Direction.Right });
- searchDirections.Add(PathType.TIntersectionFromBottom, new List<Direction>() { Direction.Bottom, Direction.Left, Direction.Right });
- searchDirections.Add(PathType.TIntersectionFromLeft, new List<Direction>() { Direction.Left, Direction.Top, Direction.Bottom });
- searchDirections.Add(PathType.TIntersectionFromRight, new List<Direction>() { Direction.Right, Direction.Top, Direction.Bottom });
- searchDirections.Add(PathType.TIntersectionFromTop, new List<Direction>() { Direction.Top, Direction.Left, Direction.Right });
- searchDirections.Add(PathType.Vertical, new List<Direction>() { Direction.Top, Direction.Bottom });
- #endregion
- List<PathTile> result = new List<PathTile>();
- foreach (Direction d in Enum.GetValues(typeof(Direction)))
- {
- if (searchDirections[p.Direction].Contains(d))
- {
- PathTile check_tile = GetPath(p.tilePosition + offset[d]);
- if (check_tile != null && movable_types[d].Contains(check_tile.Direction))
- {
- check_tile.SetData(p.exitNumber);
- if (!pathsByExit.ContainsKey(p.exitNumber)) pathsByExit.Add(p.exitNumber, new List<PathTile>());
- pathsByExit[p.exitNumber].Add(check_tile);
- result.Add(check_tile);
- }
- }
- }
- return result;
- }
- public void RebuildExitTree()
- {
- throw new NotImplementedException();
- }
- private LevelTile GetLevelTileByExit(int exitNumber, out int exitNumberinList)
- {
- foreach (LevelTile l in levelTiles)
- {
- foreach (Exit e in l.Exits)
- {
- if (e.Index == exitNumber) { exitNumberinList = l.Exits.IndexOf(e); return l; }
- }
- }
- exitNumberinList = -1;
- return null;
- }
- #endregion
- #endregion
- }
- public delegate void LevelEnteredEventHandler(object sender, LevelTile e);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement