internal LevelPart Clone() { var cloneColList = new List<Rectangle>(); foreach (Rectangle rect in CollisionsMask) { cloneColList.Add(new Rectangle(rect.X, rect.Y, rect.Width, rect.Height)); } var clone = new LevelPart(Id, MaxRepeat, Dimensions) { InputId = InputId, InputYLoc = InputYLoc, OutputId = OutputId, OutputYLoc = OutputYLoc, IsStart = IsStart, IsEnd = IsEnd, BackgroundLayer = this.BackgroundLayer.Clone(), MiddleGroundLayer = this.MiddleGroundLayer.Clone(), ForegroundLayer = this.ForegroundLayer.Clone(), CollisionsMask = cloneColList }; return clone; }
/// <summary> /// Convert an OgmoLevel in a usable level /// </summary> /// <param name="context"></param> /// <param name="ogmoLevel"></param> /// <returns></returns> private static LevelPart Convert(OgmoLevel ogmoLevel) { // Get level dimensions Vector2 dimensions = new Vector2(ogmoLevel.Width, ogmoLevel.Height); // Get level infos int id = ogmoLevel.GetValue<OgmoIntegerValue>("id").Value; int maxRepeat = ogmoLevel.GetValue<OgmoIntegerValue>("max_repeat").Value; int input = -1; int output = -1; int inputY = -1; int outputY = -1; bool isStart = false; bool isEnd = false; LevelPart levelPart = new LevelPart(id, maxRepeat, dimensions); // Add gfx resources foreach (OgmoTileset tileSet in ogmoLevel.Project.Tilesets) { Application.MagicContentManager.AddTexture(tileSet.Name, tileSet.Texture); } foreach (OgmoObjectTemplate objTemplate in ogmoLevel.Project.ObjectTemplates) { Application.MagicContentManager.AddTexture(System.IO.Path.GetFileNameWithoutExtension(objTemplate.TextureFile), objTemplate.Texture); } //Layers for (int i = 0; i < ogmoLevel.Layers.Length; i++) { var olayer = ogmoLevel.Layers[i]; var olayersettings = ogmoLevel.Project.LayerSettings.Where(ls => ls.Name == olayer.Name).First(); // Background tiles if (olayer.Name == "background") { ExtractTileLayer(levelPart.BackgroundLayer, olayer, olayersettings); } // Background objects else if (olayer.Name == "background_objects") { ExtractObjectLayer(levelPart.BackgroundLayer, olayer, olayersettings); } //Collisions else if (olayer.Name == "collision") { levelPart.CollisionsMask = ExtractGridRectLayer(olayer, olayersettings); } // Middleground tiles else if (olayer.Name == "floor") { ExtractTileLayer(levelPart.MiddleGroundLayer, olayer, olayersettings); } // Game objects (static) else if (olayer.Name == "static_objects") { ExtractObjectLayer(levelPart.MiddleGroundLayer, olayer, olayersettings); } // Game objects else if (olayer.Name == "objects") { ExtractObjectLayer(levelPart.MiddleGroundLayer, olayer, olayersettings); } // Middleground tiles else if (olayer.Name == "foreground") { ExtractTileLayer(levelPart.ForegroundLayer, olayer, olayersettings); } } // Get input, output, start & end objects foreach (OgmoObjectEntity oent in levelPart.MiddleGroundLayer.Entities) { if (oent is OInput) { input = ((OInput)oent).Id; inputY = (int)((OInput)oent).Location.Y; } else if (oent is OOutput) { output = ((OOutput)oent).Id; outputY = (int)((OOutput)oent).Location.Y; } else if (oent is OShip) { isEnd = true; } else if (oent is OSpawn) { isStart = true; } } if (input == -1) throw new ArgumentException("Missing input door!"); if (output == -1) throw new ArgumentException("Missing output door!"); levelPart.InputId = input; levelPart.InputYLoc = inputY; levelPart.OutputId = output; levelPart.OutputYLoc = outputY; levelPart.IsStart = isStart; levelPart.IsEnd = isEnd; return levelPart; }
/// <summary> /// /// </summary> /// <param name="levelParts"></param> /// <param name="startPart"></param> /// <returns></returns> private static List<LevelPart> SelectAndOrderParts(List<LevelPart> levelParts, LevelPart startPart) { // TODO Find the right number int partsLeft = PartsCount; bool isBlocked = false; List<LevelPart> selectedParts = new List<LevelPart>(); List<int> invalidInputs = new List<int>(); List<int> invalidOutputs = new List<int>(); Random rand = new Random(DateTime.Now.Millisecond); // From the start part, build a level ! selectedParts.Add(startPart); while (partsLeft > 1 && isBlocked == false) { // Get the input or the output of the list int input = selectedParts.First().InputId; int output = selectedParts.Last().OutputId; // Draw a random part corresponding to those inputs/outputs var validParts = levelParts.Where(p => p.InputId == output || p.OutputId == input).ToList(); if (validParts.Count == 0) { isBlocked = true; continue; } int n = rand.Next(validParts.Count); var part = validParts[n]; // Try to insert it before or after the current list if (part.InputId == output) { selectedParts.Add(part); } else if (part.OutputId == input) { selectedParts.Insert(0, part); } else { throw new ArgumentException("WTF?!"); } // Remove the part from the pool levelParts.Remove(part); partsLeft--; } return selectedParts; }