/// <summary> /// Write the sector data to the provided Map instance, using the provided co-ordinates on the map as the top left /// of the sector, rotated by the provided rotation. /// </summary> public void WriteToMap(Map map, IntVector2 top_left, IntVector2.Rotation rotation) { IntVector2 read_position = new IntVector2(0, 0); for (read_position.y = 0; read_position.y < Height; ++read_position.y) { for (read_position.x = 0; read_position.x < Width; ++read_position.x) { Map.Tile tile = m_tiles[read_position.x, read_position.y]; IntVector2 write_position = read_position.Rotated(rotation) + getRotatedWriteTranslation(rotation); map.SetTile(write_position.x + top_left.x, write_position.y + top_left.y, tile); } } }
/// <summary> /// Get the translation to be applied to rotated sectors to ensure that they are written in the correct location. /// </summary> /// <param name="rotation"></param> /// <returns></returns> private static IntVector2 getRotatedWriteTranslation(IntVector2.Rotation rotation) { switch (rotation) { case IntVector2.Rotation.deg0: return(new IntVector2(0, 0)); case IntVector2.Rotation.deg90: return(new IntVector2(Width - 1, 0)); case IntVector2.Rotation.deg180: return(new IntVector2(Width - 1, Height - 1)); case IntVector2.Rotation.deg270: return(new IntVector2(0, Height - 1)); default: throw new ArgumentOutOfRangeException("Unrecognised IntVector2 rotation " + rotation); } }
/// <summary> /// Fill the provided map with randomly-chosen, randomly-rotated sectors, guaranteeing an entrance sector, /// an exit sector, and a specified number of objective sectors. /// </summary> public void FillMap(Map map, int num_objectives) { IntVector2.Rotation[] rotations = (IntVector2.Rotation[])Enum.GetValues(typeof(IntVector2.Rotation)); // Choose sectors to make up the map. SectorChoice[,] sector_choices = new SectorChoice[map.Width / Sector.Width, map.Height / Sector.Height]; // - Build a list of sector slots in the map that need to be filled. List <IntVector2> empty_slots = new List <IntVector2>(); for (int x = 0; x < sector_choices.GetLength(0); ++x) { for (int y = 0; y < sector_choices.GetLength(1); ++y) { empty_slots.Add(new IntVector2(x, y)); } } // - Randomise the order of the list, and turn it into a queue. empty_slots.Shuffle(); Queue <IntVector2> slot_queue = new Queue <IntVector2>(empty_slots); // - Work through the queue, assigning sectors to all empty slots. IntVector2 current_slot; // -- Add an entrance and an exit sector. current_slot = slot_queue.Dequeue(); sector_choices[current_slot.x, current_slot.y] = new SectorChoice( m_sectorData.getRandomEntranceSector(), rotations[UnityEngine.Random.Range(0, rotations.Length)] ); current_slot = slot_queue.Dequeue(); sector_choices[current_slot.x, current_slot.y] = new SectorChoice( m_sectorData.getRandomExitSector(), rotations[UnityEngine.Random.Range(0, rotations.Length)] ); // -- Add the required number of objective sectors. for (int i = 0; i < num_objectives; ++i) { current_slot = slot_queue.Dequeue(); sector_choices[current_slot.x, current_slot.y] = new SectorChoice( m_sectorData.getRandomObjectiveSector(), rotations[UnityEngine.Random.Range(0, rotations.Length)] ); } // -- Fill any remaining sector slots with random miscellaneous sectors. while (slot_queue.Count > 0) { current_slot = slot_queue.Dequeue(); sector_choices[current_slot.x, current_slot.y] = new SectorChoice( m_sectorData.getRandomMiscSector(), rotations[UnityEngine.Random.Range(0, rotations.Length)] ); } //Write m_sectorData to map. for (int x = 0; x < sector_choices.GetLength(0); ++x) { for (int y = 0; y < sector_choices.GetLength(1); ++y) { Sector sector = sector_choices[x, y].Sector; IntVector2.Rotation rotation = sector_choices[x, y].Rotation; sector.WriteToMap(map, new IntVector2(x * Sector.Width, y * Sector.Height), rotation); } } }
public SectorChoice(Sector sector, IntVector2.Rotation rotation) { Sector = sector; Rotation = rotation; }