public static int[,] Extract(Map m, Func<int, int, int> f) { var result = new int[m.MapSize, m.MapSize]; var types = new int[m.MapSize, m.MapSize]; var d = new Dictionary<int, Node>(); var n = 1; for( var j = m.YOffset; j < m.YOffset + m.Height; j++ ) for (var i = m.XOffset; i < m.XOffset + m.Width; i++) { types[i, j] = f(i, j); var k = n; foreach (var a in Neighbors) if (types[i + a.X, j + a.Y] == types[i, j]) k = (k == n) ? result[i + a.X, j + a.Y] : Union( d, k, result[i+a.X, j+a.Y] ); result[i,j] = k; if (k == n) MakeSet(d, n++); } for (var j = m.YOffset; j < m.YOffset + m.Height; j++) for (var i = m.XOffset; i < m.XOffset + m.Width; i++) result[i, j] = Find(d, result[i, j]); return result; }
public TerrainRenderer(World world, WorldRenderer wr) { this.world = world; this.map = world.Map; var tileSize = new Size( Game.CellSize, Game.CellSize ); var tileMapping = new Cache<TileReference<ushort,byte>, Sprite>( x => Game.modData.SheetBuilder.Add(world.TileSet.GetBytes(x), tileSize)); var vertices = new Vertex[4 * map.Bounds.Height * map.Bounds.Width]; terrainSheet = tileMapping[map.MapTiles.Value[map.Bounds.Left, map.Bounds.Top]].sheet; int nv = 0; var terrainPalette = wr.Palette("terrain").Index; for( int j = map.Bounds.Top; j < map.Bounds.Bottom; j++ ) for( int i = map.Bounds.Left; i < map.Bounds.Right; i++ ) { var tile = tileMapping[map.MapTiles.Value[i, j]]; // TODO: move GetPaletteIndex out of the inner loop. Util.FastCreateQuad(vertices, Game.CellSize * new float2(i, j), tile, terrainPalette, nv, tile.size); nv += 4; if (tileMapping[map.MapTiles.Value[i, j]].sheet != terrainSheet) throw new InvalidOperationException("Terrain sprites span multiple sheets"); } vertexBuffer = Game.Renderer.Device.CreateVertexBuffer( vertices.Length ); vertexBuffer.SetData( vertices, nv ); }
void MapList_SelectedIndexChanged(object sender, EventArgs e) { if (MapList.SelectedItems.Count == 1) { txtNew.Text = MapList.SelectedItems[0].Text; txtNew.Tag = MapList.SelectedItems[0].Tag; var map = new Map(txtNew.Tag as string); txtTitle.Text = map.Title; txtAuthor.Text = map.Author; txtTheater.Text = map.Tileset; txtDesc.Text = map.Description; pbMinimap.Image = null; try { pbMinimap.Image = Minimap.AddStaticResources(map, Minimap.TerrainBitmap(map, true)); } catch (Exception ed) { Console.WriteLine("No map preview image found: {0}", ed.ToString()); } finally { } } }
public UnitInfluence( World world ) { map = world.Map; influence = new InfluenceNode[world.Map.MapSize.X, world.Map.MapSize.Y]; world.ActorRemoved += a => Remove( a, a.TraitOrDefault<IOccupySpace>() ); }
public SmudgeRenderer( Renderer renderer, Map map ) { this.spriteRenderer = new SpriteRenderer( renderer, true ); this.map = map; smudgeSprites = smudgeSpriteNames.SelectMany(f => SpriteSheetBuilder.LoadAllSprites(f)).ToArray(); }
protected MapPreviewWidget(MapPreviewWidget other) : base(other) { lastMap = other.lastMap; Map = other.Map; SpawnColors = other.SpawnColors; }
// Add the static resources defined in the map; if the map lives // in a world use AddCustomTerrain instead public static Bitmap AddStaticResources(Map map, Bitmap terrainBitmap) { Bitmap terrain = new Bitmap(terrainBitmap); var tileset = Rules.TileSets[map.Tileset]; var bitmapData = terrain.LockBits(new Rectangle(0, 0, terrain.Width, terrain.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); unsafe { int* c = (int*)bitmapData.Scan0; for (var x = 0; x < map.Bounds.Width; x++) for (var y = 0; y < map.Bounds.Height; y++) { var mapX = x + map.Bounds.Left; var mapY = y + map.Bounds.Top; if (map.MapResources.Value[mapX, mapY].type == 0) continue; var res = Rules.Info["world"].Traits.WithInterface<ResourceTypeInfo>() .Where(t => t.ResourceType == map.MapResources.Value[mapX, mapY].type) .Select(t => t.TerrainType).FirstOrDefault(); if (res == null) continue; *(c + (y * bitmapData.Stride >> 2) + x) = tileset.Terrain[res].Color.ToArgb(); } } terrain.UnlockBits(bitmapData); return terrain; }
public void Bind(Map m, TileSet ts, Palette p) { Map = m; TileSet = ts; Palette = p; Brush = null; Chunks.Clear(); }
public void Bind(Map m, TileSet ts, Palette p) { Map = m; TileSet = ts; Palette = p; PlayerPalettes = null; Chunks.Clear(); Tool = null; }
public static Dictionary<int2, Color> GetSpawnColors(OrderManager orderManager, Map map) { var spawns = map.GetSpawnPoints(); return orderManager.LobbyInfo.Clients .Where( c => c.SpawnPoint != 0 ) .ToDictionary( c => spawns[c.SpawnPoint - 1], c => c.ColorRamp.GetColor(0)); }
public static Dictionary<int2, Session.Client> GetSpawnClients(OrderManager orderManager, Map map) { var spawns = map.GetSpawnPoints(); return orderManager.LobbyInfo.Clients .Where(c => c.SpawnPoint != 0) .ToDictionary( c => spawns[c.SpawnPoint - 1], c => c); }
internal MapChooserLogic(Widget widget, string initialMap, Action onExit, Action<Map> onSelect) { map = Game.modData.AvailableMaps[WidgetUtils.ChooseInitialMap(initialMap)]; widget.Get<ButtonWidget>("BUTTON_OK").OnClick = () => { Ui.CloseWindow(); onSelect(map); }; widget.Get<ButtonWidget>("BUTTON_CANCEL").OnClick = () => { Ui.CloseWindow(); onExit(); }; scrollpanel = widget.Get<ScrollPanelWidget>("MAP_LIST"); scrollpanel.ScrollVelocity = 40f; scrollpanel.Layout = new GridLayout(scrollpanel); itemTemplate = scrollpanel.Get<ScrollItemWidget>("MAP_TEMPLATE"); var gameModeDropdown = widget.GetOrNull<DropDownButtonWidget>("GAMEMODE_FILTER"); if (gameModeDropdown != null) { var selectableMaps = Game.modData.AvailableMaps.Where(m => m.Value.Selectable).ToList(); var gameModes = selectableMaps .GroupBy(m => m.Value.Type) .Select(g => Pair.New(g.Key, g.Count())).ToList(); // 'all game types' extra item gameModes.Insert(0, Pair.New(null as string, selectableMaps.Count())); Func<Pair<string, int>, string> showItem = x => "{0} ({1})".F(x.First ?? "All Game Types", x.Second); Func<Pair<string, int>, ScrollItemWidget, ScrollItemWidget> setupItem = (ii, template) => { var item = ScrollItemWidget.Setup(template, () => gameMode == ii.First, () => { gameMode = ii.First; EnumerateMaps(onSelect); }); item.Get<LabelWidget>("LABEL").GetText = () => showItem(ii); return item; }; gameModeDropdown.OnClick = () => gameModeDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, gameModes, setupItem); gameModeDropdown.GetText = () => showItem(gameModes.First(m => m.First == gameMode)); } var randomMapButton = widget.GetOrNull<ButtonWidget>("RANDOMMAP_BUTTON"); if (randomMapButton != null) { randomMapButton.OnClick = () => { var kv = visibleMaps.Random(Game.CosmeticRandom); map = kv.Value; scrollpanel.ScrollToItem(kv.Key); }; randomMapButton.IsDisabled = () => visibleMaps == null || visibleMaps.Count == 0; } EnumerateMaps(onSelect); }
public static void UpgradeMap(string[] args) { var map = new Map(args[1]); var engineDate = Exts.ParseIntegerInvariant(args[2]); Game.modData = new ModData(map.RequiresMod); UpgradeWeaponRules(engineDate, ref map.WeaponDefinitions, null, 0); UpgradeActorRules(engineDate, ref map.RuleDefinitions, null, 0); map.Save(args[1]); }
public static void Initialize( Map map ) { exts = new[] { "." + map.Theater.Substring( 0, 3 ).ToLowerInvariant(), ".shp", ".tem", ".sno", ".int" }; sprites = new Cache<string, Sprite[]>( LoadSprites ); }
protected MapPreviewWidget(MapPreviewWidget other) : base(other) { lastMap = other.lastMap; Map = other.Map; SpawnClients = other.SpawnClients; ShowSpawnPoints = other.ShowSpawnPoints; TooltipTemplate = other.TooltipTemplate; TooltipContainer = other.TooltipContainer; tooltipContainer = Lazy.New(() => Ui.Root.Get<TooltipContainerWidget>(TooltipContainer)); }
public UnitInfluence( Actor self ) { map = self.World.Map; var size = self.World.Map.MapSize; influence = new List<Actor>[size, size]; for (int i = 0; i < size; i++) for (int j = 0; j < size; j++) influence[ i, j ] = new List<Actor>(); self.World.ActorRemoved += a => Remove( a, a.traits.GetOrDefault<IOccupySpace>() ); }
public void Bind(Map m, TileSet ts, TileSetRenderer tsr, Palette p, Palette pp) { Map = m; TileSet = ts; TileSetRenderer = tsr; Palette = p; PlayerPalette = pp; playerPalettes = null; Chunks.Clear(); currentTool = null; }
public override void Draw() { var map = Map(); if( map == null ) return; if (lastMap != map) { lastMap = map; // Update image data var preview = PreviewCache[map]; if( mapChooserSheet == null || mapChooserSheet.Size.Width != preview.Width || mapChooserSheet.Size.Height != preview.Height ) mapChooserSheet = new Sheet(new Size( preview.Width, preview.Height ) ); mapChooserSheet.Texture.SetData( preview ); mapChooserSprite = new Sprite( mapChooserSheet, new Rectangle( 0, 0, map.Bounds.Width, map.Bounds.Height ), TextureChannel.Alpha ); } // Update map rect PreviewScale = Math.Min(RenderBounds.Width * 1.0f / map.Bounds.Width, RenderBounds.Height * 1.0f / map.Bounds.Height); var size = Math.Max(map.Bounds.Width, map.Bounds.Height); var dw = (int)(PreviewScale * (size - map.Bounds.Width)) / 2; var dh = (int)(PreviewScale * (size - map.Bounds.Height)) / 2; MapRect = new Rectangle(RenderBounds.X + dw, RenderBounds.Y + dh, (int)(map.Bounds.Width * PreviewScale), (int)(map.Bounds.Height * PreviewScale)); Game.Renderer.RgbaSpriteRenderer.DrawSprite( mapChooserSprite, new float2(MapRect.Location), new float2( MapRect.Size ) ); if (ShowSpawnPoints) { var colors = SpawnColors(); var spawnPoints = map.GetSpawnPoints().ToList(); foreach (var p in spawnPoints) { var owned = colors.ContainsKey(p); var pos = ConvertToPreview(p); var sprite = ChromeProvider.GetImage("spawnpoints", owned ? "owned" : "unowned"); var offset = new int2(-sprite.bounds.Width/2, -sprite.bounds.Height/2); if (owned) WidgetUtils.FillRectWithColor(new Rectangle(pos.X + offset.X + 2, pos.Y + offset.Y + 2, 12, 12), colors[p]); Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos + offset); if ((pos - Viewport.LastMousePos).LengthSquared < 64) { OnTooltip(spawnPoints.IndexOf(p) + 1, pos); } } } }
public ActorMap(World world, ActorMapInfo info) { this.info = info; map = world.Map; influence = new InfluenceNode[world.Map.MapSize.X, world.Map.MapSize.Y]; cols = world.Map.MapSize.X / info.BinSize + 1; rows = world.Map.MapSize.Y / info.BinSize + 1; actors = new List<Actor>[rows * cols]; for (var j = 0; j < rows; j++) for (var i = 0; i < cols; i++) actors[j * cols + i] = new List<Actor>(); }
public override void DrawInner() { if (UnownedSpawn == null) UnownedSpawn = ChromeProvider.GetImage("spawnpoints", "unowned"); if (OwnedSpawn == null) OwnedSpawn = ChromeProvider.GetImage("spawnpoints", "owned"); var map = Map(); if( map == null ) return; if (lastMap != map) { lastMap = map; // Update image data var preview = PreviewCache[map]; if( mapChooserSheet == null || mapChooserSheet.Size.Width != preview.Width || mapChooserSheet.Size.Height != preview.Height ) mapChooserSheet = new Sheet(new Size( preview.Width, preview.Height ) ); mapChooserSheet.Texture.SetData( preview ); mapChooserSprite = new Sprite( mapChooserSheet, new Rectangle( 0, 0, map.Bounds.Width, map.Bounds.Height ), TextureChannel.Alpha ); // Update map rect PreviewScale = Math.Min(RenderBounds.Width * 1.0f / map.Bounds.Width, RenderBounds.Height * 1.0f / map.Bounds.Height); var size = Math.Max(map.Bounds.Width, map.Bounds.Height); var dw = (int)(PreviewScale * (size - map.Bounds.Width)) / 2; var dh = (int)(PreviewScale * (size - map.Bounds.Height)) / 2; MapRect = new Rectangle(RenderBounds.X + dw, RenderBounds.Y + dh, (int)(map.Bounds.Width * PreviewScale), (int)(map.Bounds.Height * PreviewScale)); } Game.Renderer.RgbaSpriteRenderer.DrawSprite( mapChooserSprite, new float2(MapRect.Location), new float2( MapRect.Size ) ); // Overlay spawnpoints var colors = SpawnColors(); foreach (var p in map.SpawnPoints) { var pos = ConvertToPreview(map, p); var sprite = UnownedSpawn; var offset = new int2(-UnownedSpawn.bounds.Width/2, -UnownedSpawn.bounds.Height/2); if (colors.ContainsKey(p)) { sprite = OwnedSpawn; offset = new int2(-OwnedSpawn.bounds.Width/2, -OwnedSpawn.bounds.Height/2); WidgetUtils.FillRectWithColor(new Rectangle(pos.X + offset.X + 2, pos.Y + offset.Y + 2, 12, 12), colors[p]); } Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos + offset); } }
public void Run(Action<string> emitError, Action<string> emitWarning, Map map) { var sequences = MiniYaml.MergeLiberal(map.SequenceDefinitions, Game.modData.Manifest.Sequences.Select(s => MiniYaml.FromFile(s)) .Aggregate(MiniYaml.MergeLiberal)); foreach (var actorInfo in map.Rules.Actors) foreach (var renderInfo in actorInfo.Value.Traits.WithInterface<RenderSimpleInfo>()) { var image = renderInfo.Image ?? actorInfo.Value.Name; if (!sequences.Any(s => s.Key == image.ToLowerInvariant()) && !actorInfo.Value.Name.Contains("^")) emitWarning("Sprite image {0} from actor {1} has no sequence definition.".F(image, actorInfo.Value.Name)); } }
public BuildingInfluence( World world ) { map = world.Map; blocked = new bool[map.MapSize.X, map.MapSize.Y]; influence = new Actor[map.MapSize.X, map.MapSize.Y]; world.ActorAdded += a => { if (a.HasTrait<Building>()) ChangeInfluence(a, a.Trait<Building>(), true); }; world.ActorRemoved += a => { if (a.HasTrait<Building>()) ChangeInfluence(a, a.Trait<Building>(), false); }; }
public BuildingInfluence( Actor self ) { map = self.World.Map; blocked = new bool[map.MapSize, map.MapSize]; influence = new Actor[map.MapSize, map.MapSize]; self.World.ActorAdded += a => { if (a.traits.Contains<Building>()) ChangeInfluence(a, a.traits.Get<Building>(), true); }; self.World.ActorRemoved += a => { if (a.traits.Contains<Building>()) ChangeInfluence(a, a.traits.Get<Building>(), false); }; }
static void UpgradeMaps(string mod) { var MapFolderPath = new string[] { Environment.CurrentDirectory, "mods", mod, "maps" } .Aggregate(Path.Combine); foreach (var path in ModData.FindMapsIn(MapFolderPath)) { var map = new Map(path); // Touch the lazy bits to initialize them map.Actors.Force(); map.Smudges.Force(); map.MapTiles.Force(); map.MapResources.Force(); map.Save(path); } }
internal MapChooserLogic([ObjectCreator.Param] Widget widget, [ObjectCreator.Param] string initialMap, [ObjectCreator.Param] Action onExit, [ObjectCreator.Param] Action<Map> onSelect) { map = Game.modData.AvailableMaps[WidgetUtils.ChooseInitialMap(initialMap)]; widget.GetWidget<ButtonWidget>("BUTTON_OK").OnClick = () => { Widget.CloseWindow(); onSelect(map); }; widget.GetWidget<ButtonWidget>("BUTTON_CANCEL").OnClick = () => { Widget.CloseWindow(); onExit(); }; scrollpanel = widget.GetWidget<ScrollPanelWidget>("MAP_LIST"); itemTemplate = scrollpanel.GetWidget<ScrollItemWidget>("MAP_TEMPLATE"); var gameModeDropdown = widget.GetWidget<DropDownButtonWidget>("GAMEMODE_FILTER"); if (gameModeDropdown != null) { var selectableMaps = Game.modData.AvailableMaps.Where(m => m.Value.Selectable); var gameModes = selectableMaps .GroupBy(m => m.Value.Type) .Select(g => Pair.New(g.Key, g.Count())).ToList(); // 'all game types' extra item gameModes.Insert( 0, Pair.New( null as string, selectableMaps.Count() ) ); Func<Pair<string,int>, string> showItem = x => "{0} ({1})".F( x.First ?? "All Game Types", x.Second ); Func<Pair<string,int>, ScrollItemWidget, ScrollItemWidget> setupItem = (ii, template) => { var item = ScrollItemWidget.Setup(template, () => gameMode == ii.First, () => { gameMode = ii.First; EnumerateMaps(); }); item.GetWidget<LabelWidget>("LABEL").GetText = () => showItem(ii); return item; }; gameModeDropdown.OnClick = () => gameModeDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, gameModes, setupItem); gameModeDropdown.GetText = () => showItem(gameModes.First(m => m.First == gameMode)); } EnumerateMaps(); }
public static void SelectSpawnPoint(OrderManager orderManager, MapPreviewWidget mapPreview, Map map, MouseInput mi) { if (map == null || mi.Button != MouseButton.Left || orderManager.LocalClient.State == Session.ClientState.Ready) return; var selectedSpawn = map.GetSpawnPoints() .Select((sp, i) => Pair.New(mapPreview.ConvertToPreview(sp), i)) .Where(a => (a.First - mi.Location).LengthSquared < 64) .Select(a => a.Second + 1) .FirstOrDefault(); var owned = orderManager.LobbyInfo.Clients.Any(c => c.SpawnPoint == selectedSpawn); if (selectedSpawn == 0 || !owned) { var locals = orderManager.LobbyInfo.Clients.Where(c => c.Index == orderManager.LocalClient.Index || (Game.IsHost && c.Bot != null)); var playerToMove = locals.Where(c => (selectedSpawn == 0) ^ (c.SpawnPoint == 0)).FirstOrDefault(); orderManager.IssueOrder(Order.Command("spawn {0} {1}".F((playerToMove ?? orderManager.LocalClient).Index, selectedSpawn))); } }
public TerrainRenderer(World world, WorldRenderer wr) { this.world = world; this.map = world.Map; var terrainPalette = wr.Palette("terrain").Index; var vertices = new Vertex[4 * map.Bounds.Height * map.Bounds.Width]; int nv = 0; for (var j = map.Bounds.Top; j < map.Bounds.Bottom; j++) for (var i = map.Bounds.Left; i < map.Bounds.Right; i++) { var tile = wr.Theater.TileSprite(map.MapTiles.Value[i, j]); Util.FastCreateQuad(vertices, Game.CellSize * new float2(i, j), tile, terrainPalette, nv, tile.size); nv += 4; } vertexBuffer = Game.Renderer.Device.CreateVertexBuffer(vertices.Length); vertexBuffer.SetData(vertices, nv); }
internal MapChooserDelegate( [ObjectCreator.Param( "widget" )] Widget bg, [ObjectCreator.Param] OrderManager orderManager, [ObjectCreator.Param] string mapName ) { if (mapName != null) Map = Game.modData.AvailableMaps[mapName]; else Map = Game.modData.AvailableMaps.FirstOrDefault(m => m.Value.Selectable).Value; bg.GetWidget<MapPreviewWidget>("MAPCHOOSER_MAP_PREVIEW").Map = () => Map; bg.GetWidget<LabelWidget>("CURMAP_TITLE").GetText = () => Map.Title; bg.GetWidget<LabelWidget>("CURMAP_AUTHOR").GetText = () => Map.Author; bg.GetWidget<LabelWidget>("CURMAP_DESC").GetText = () => Map.Description; bg.GetWidget<LabelWidget>("CURMAP_DESC_LABEL").IsVisible = () => Map.Description != null; bg.GetWidget<LabelWidget>("CURMAP_SIZE").GetText = () => "{0}x{1}".F(Map.Bounds.Width, Map.Bounds.Height); bg.GetWidget<LabelWidget>("CURMAP_THEATER").GetText = () => Rules.TileSets[Map.Tileset].Name; bg.GetWidget<LabelWidget>("CURMAP_PLAYERS").GetText = () => Map.PlayerCount.ToString(); bg.GetWidget<ButtonWidget>("BUTTON_OK").OnMouseUp = mi => { orderManager.IssueOrder(Order.Command("map " + Map.Uid)); Widget.CloseWindow(); return true; }; bg.GetWidget<ButtonWidget>("BUTTON_CANCEL").OnMouseUp = mi => { Widget.CloseWindow(); return true; }; bg.GetWidget("BUTTON_INSTALL").IsVisible = () => false; //bg.GetWidget<ButtonWidget>("BUTTON_INSTALL").OnMouseUp = mi => InstallMap(); scrollpanel = bg.GetWidget<ScrollPanelWidget>("MAP_LIST"); itemTemplate = scrollpanel.GetWidget<ContainerWidget>("MAP_TEMPLATE"); EnumerateMaps(); }
public TerrainRenderer(World world, WorldRenderer wr) { this.world = world; this.map = world.Map; Size tileSize = new Size( Game.CellSize, Game.CellSize ); var tileMapping = new Cache<TileReference<ushort,byte>, Sprite>( x => Game.modData.SheetBuilder.Add(world.TileSet.GetBytes(x), tileSize)); Vertex[] vertices = new Vertex[4 * map.Bounds.Height * map.Bounds.Width]; ushort[] indices = new ushort[6 * map.Bounds.Height * map.Bounds.Width]; terrainSheet = tileMapping[map.MapTiles[map.Bounds.Left, map.Bounds.Top]].sheet; int nv = 0; int ni = 0; for( int j = map.Bounds.Top; j < map.Bounds.Bottom; j++ ) for( int i = map.Bounds.Left; i < map.Bounds.Right; i++ ) { Sprite tile = tileMapping[map.MapTiles[i, j]]; // TODO: The zero below should explicitly refer to the terrain palette, but this code is called // before the palettes are created. Therefore assumes that "terrain" is the first palette to be defined Util.FastCreateQuad(vertices, indices, Game.CellSize * new float2(i, j), tile, 0, nv, ni, tile.size); nv += 4; ni += 6; if (tileMapping[map.MapTiles[i, j]].sheet != terrainSheet) throw new InvalidOperationException("Terrain sprites span multiple sheets"); } vertexBuffer = Game.Renderer.Device.CreateVertexBuffer( vertices.Length ); vertexBuffer.SetData( vertices, nv ); indexBuffer = Game.Renderer.Device.CreateIndexBuffer( indices.Length ); indexBuffer.SetData( indices, ni ); }
public TerrainRenderer(World world, Renderer renderer, WorldRenderer wr) { this.renderer = renderer; this.map = world.Map; Size tileSize = new Size( Game.CellSize, Game.CellSize ); var tileMapping = new Cache<TileReference, Sprite>( x => SheetBuilder.SharedInstance.Add(world.TileSet.GetBytes(x), tileSize)); Vertex[] vertices = new Vertex[4 * map.Height * map.Width]; ushort[] indices = new ushort[6 * map.Height * map.Width]; int nv = 0; int ni = 0; for( int j = map.YOffset ; j < map.YOffset + map.Height ; j++ ) for( int i = map.XOffset ; i < map.XOffset + map.Width; i++ ) { Sprite tile = tileMapping[map.MapTiles[i, j]]; // TODO: The zero below should explicitly refer to the terrain palette, but this code is called // before the palettes are created Util.FastCreateQuad(vertices, indices, Game.CellSize * new float2(i, j), tile, 0, nv, ni, tile.size); nv += 4; ni += 6; } terrainSheet = tileMapping[map.MapTiles[map.XOffset, map.YOffset]].sheet; vertexBuffer = renderer.Device.CreateVertexBuffer( vertices.Length ); vertexBuffer.SetData( vertices ); indexBuffer = renderer.Device.CreateIndexBuffer( indices.Length ); indexBuffer.SetData( indices ); overlayRenderer = new SmudgeRenderer( renderer, map ); }