/// <summary>Returns the minimal region that covers at least the specified cells.</summary> public static CellRegion BoundingRegion(MapGridType shape, IEnumerable <CPos> cells) { if (cells == null || !cells.Any()) { throw new ArgumentException("cells must not be null or empty.", "cells"); } var minU = int.MaxValue; var minV = int.MaxValue; var maxU = int.MinValue; var maxV = int.MinValue; foreach (var cell in cells) { var uv = cell.ToMPos(shape); if (minU > uv.U) { minU = uv.U; } if (maxU < uv.U) { maxU = uv.U; } if (minV > uv.V) { minV = uv.V; } if (maxV < uv.V) { maxV = uv.V; } } return(new CellRegion(shape, new MPos(minU, minV).ToCPos(shape), new MPos(maxU, maxV).ToCPos(shape))); }
public Rectangle TemplateBounds(TerrainTemplateInfo template, Size tileSize, MapGridType mapGrid) { Rectangle?templateRect = null; var i = 0; for (var y = 0; y < template.Size.Y; y++) { for (var x = 0; x < template.Size.X; x++) { var tile = new TerrainTile(template.Id, (byte)(i++)); var tileInfo = tileset.GetTileInfo(tile); // Empty tile if (tileInfo == null) { continue; } var sprite = TileSprite(tile); var u = mapGrid == MapGridType.Rectangular ? x : (x - y) / 2f; var v = mapGrid == MapGridType.Rectangular ? y : (x + y) / 2f; var tl = new float2(u * tileSize.Width, (v - 0.5f * tileInfo.Height) * tileSize.Height) - 0.5f * sprite.Size; var rect = new Rectangle((int)(tl.X + sprite.Offset.X), (int)(tl.Y + sprite.Offset.Y), (int)sprite.Size.X, (int)sprite.Size.Y); templateRect = templateRect.HasValue ? Rectangle.Union(templateRect.Value, rect) : rect; } } return(templateRect.HasValue ? templateRect.Value : Rectangle.Empty); }
public CellLayer(MapGridType gridType, Size size) { Size = size; bounds = new Rectangle(0, 0, Size.Width, Size.Height); GridType = gridType; entries = new T[size.Width * size.Height]; }
/// <summary>Returns the minimal region that covers at least the specified cells.</summary> public static CellRegion BoundingRegion(MapGridType shape, IEnumerable <CPos> cells) { if (cells == null || !cells.Any()) { throw new ArgumentException("cells must not be null or empty.", "cells"); } var minX = int.MaxValue; var minY = int.MaxValue; var maxX = int.MinValue; var maxY = int.MinValue; foreach (var cell in cells) { if (minX > cell.X) { minX = cell.X; } if (maxX < cell.X) { maxX = cell.X; } if (minY > cell.Y) { minY = cell.Y; } if (maxY < cell.Y) { maxY = cell.Y; } } return(new CellRegion(shape, new CPos(minX, minY), new CPos(maxX, maxY))); }
public int ZPosition(WPos pos, int offset, MapGridType gridtype) { if (gridtype == MapGridType.Rectangular) { return(pos.Z + offset); //убираем зависимость Y координаты от ряда в котором рендерится спрайт. } return(pos.Y + pos.Z + offset); }
public CellRegion(MapGridType gridType, CPos topLeft, CPos bottomRight) { this.gridType = gridType; TopLeft = topLeft; BottomRight = bottomRight; mapTopLeft = TopLeft.ToMPos(gridType); mapBottomRight = BottomRight.ToMPos(gridType); }
public MapPreview(string uid, MapGridType gridType, MapCache cache) { this.cache = cache; Uid = uid; Title = "Unknown Map"; Type = "Unknown"; Author = "Unknown Author"; PlayerCount = 0; Bounds = Rectangle.Empty; SpawnPoints = NoSpawns; GridType = gridType; Status = MapStatus.Unavailable; Class = MapClassification.Unknown; }
public CellRamp(MapGridType type, WRot orientation, RampCornerHeight tl = RampCornerHeight.Low, RampCornerHeight tr = RampCornerHeight.Low, RampCornerHeight br = RampCornerHeight.Low, RampCornerHeight bl = RampCornerHeight.Low, RampSplit split = RampSplit.Flat) { Orientation = orientation; if (type == MapGridType.RectangularIsometric) { Corners = new[] { new WVec(0, -724, 724 * (int)tl), new WVec(724, 0, 724 * (int)tr), new WVec(0, 724, 724 * (int)br), new WVec(-724, 0, 724 * (int)bl), }; } else { Corners = new[] { new WVec(-512, -512, 512 * (int)tl), new WVec(512, -512, 512 * (int)tr), new WVec(512, 512, 512 * (int)br), new WVec(-512, 512, 512 * (int)bl) }; } if (split == RampSplit.X) { Polygons = new[] { new[] { Corners[0], Corners[1], Corners[3] }, new[] { Corners[1], Corners[2], Corners[3] } }; } else if (split == RampSplit.Y) { Polygons = new[] { new[] { Corners[0], Corners[1], Corners[2] }, new[] { Corners[0], Corners[2], Corners[3] } }; } else { Polygons = new[] { Corners } }; // Initial value must be asigned before HeightOffset can be called CenterHeightOffset = 0; CenterHeightOffset = HeightOffset(0, 0); }
public int2 ConvertToPreview(CPos cell, MapGridType gridType) { var preview = Preview(); var point = cell.ToMPos(gridType); var cellWidth = gridType == MapGridType.RectangularIsometric ? 2 : 1; var dx = (int)(previewScale * cellWidth * (point.U - preview.Bounds.Left)); var dy = (int)(previewScale * (point.V - preview.Bounds.Top)); // Odd rows are shifted right by 1px if ((point.V & 1) == 1) { dx += 1; } return(new int2(mapRect.X + dx, mapRect.Y + dy)); }
public CPos ToCPos(MapGridType gridType) { if (gridType == MapGridType.Rectangular) { return(new CPos(U, V)); } // Convert from rectangular map position to RectangularIsometric cell position // - The staggered rows make this fiddly (hint: draw a diagram!) // (a) Consider the relationships: // - +1u (even -> odd) adds (1, -1) to (x, y) // - +1v (even -> odd) adds (1, 0) to (x, y) // - +1v (odd -> even) adds (0, 1) to (x, y) // (b) Therefore: // - au + 2bv adds (a + b) to (x, y) // - a correction factor is added if v is odd var offset = (V & 1) == 1 ? 1 : 0; var y = (V - offset) / 2 - U; var x = V - y; return(new CPos(x, y)); }
public MPos ToMPos(MapGridType gridType) { if (gridType == MapGridType.Rectangular) { return(new MPos(X, Y)); } // Convert from RectangularIsometric cell (x, y) position to rectangular map position (u, v) // - The staggered rows make this fiddly (hint: draw a diagram!) // (a) Consider the relationships: // - +1x (even -> odd) adds (0, 1) to (u, v) // - +1x (odd -> even) adds (1, 1) to (u, v) // - +1y (even -> odd) adds (-1, 1) to (u, v) // - +1y (odd -> even) adds (0, 1) to (u, v) // (b) Therefore: // - ax + by adds (a - b)/2 to u (only even increments count) // - ax + by adds a + b to v var u = (X - Y) / 2; var v = X + Y; return(new MPos(u, v)); }
public MapPreview(ModData modData, string uid, MapGridType gridType, MapCache cache) { this.cache = cache; this.modData = modData; Uid = uid; innerData = new InnerData { Title = "Unknown Map", Categories = new[] { "Unknown" }, Author = "Unknown Author", TileSet = "unknown", Players = null, PlayerCount = 0, SpawnPoints = NoSpawns, GridType = gridType, Bounds = Rectangle.Empty, Preview = null, Status = MapStatus.Unavailable, Class = MapClassification.Unknown, Visibility = MapVisibility.Lobby, }; }
public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassification classification, string[] mapCompatibility, MapGridType gridType) { Dictionary <string, MiniYaml> yaml; using (var yamlStream = p.GetStream("map.yaml")) { if (yamlStream == null) { throw new FileNotFoundException("Required file map.yaml not present in this map"); } yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml", stringPool: cache.StringPool)).ToDictionary(); } Package = p; parentPackage = parent; var newData = innerData.Clone(); newData.GridType = gridType; newData.Class = classification; if (yaml.TryGetValue("MapFormat", out var temp)) { var format = FieldLoader.GetValue <int>("MapFormat", temp.Value); if (format != Map.SupportedMapFormat) { throw new InvalidDataException($"Map format {format} is not supported."); } } if (yaml.TryGetValue("Title", out temp)) { newData.Title = temp.Value; } if (yaml.TryGetValue("Categories", out temp)) { newData.Categories = FieldLoader.GetValue <string[]>("Categories", temp.Value); } if (yaml.TryGetValue("Tileset", out temp)) { newData.TileSet = temp.Value; } if (yaml.TryGetValue("Author", out temp)) { newData.Author = temp.Value; } if (yaml.TryGetValue("Bounds", out temp)) { newData.Bounds = FieldLoader.GetValue <Rectangle>("Bounds", temp.Value); } if (yaml.TryGetValue("Visibility", out temp)) { newData.Visibility = FieldLoader.GetValue <MapVisibility>("Visibility", temp.Value); } string requiresMod = string.Empty; if (yaml.TryGetValue("RequiresMod", out temp)) { requiresMod = temp.Value; } if (yaml.TryGetValue("MapFormat", out temp)) { newData.MapFormat = FieldLoader.GetValue <int>("MapFormat", temp.Value); } newData.Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ? MapStatus.Available : MapStatus.Unavailable; try { // Actor definitions may change if the map format changes if (yaml.TryGetValue("Actors", out var actorDefinitions)) { var spawns = new List <CPos>(); foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn")) { var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary()); spawns.Add(s.Get <LocationInit>().Value); } newData.SpawnPoints = spawns.ToArray(); } else { newData.SpawnPoints = Array.Empty <CPos>(); } } catch (Exception) { newData.SpawnPoints = Array.Empty <CPos>(); newData.Status = MapStatus.Unavailable; } try { // Player definitions may change if the map format changes if (yaml.TryGetValue("Players", out var playerDefinitions)) { newData.Players = new MapPlayers(playerDefinitions.Nodes); newData.PlayerCount = newData.Players.Players.Count(x => x.Value.Playable); } } catch (Exception) { newData.Status = MapStatus.Unavailable; } newData.SetCustomRules(modData, this, yaml); if (p.Contains("map.png")) { using (var dataStream = p.GetStream("map.png")) newData.Preview = new Png(dataStream); } // Assign the new data atomically innerData = newData; }
public ProjectedCellLayer(MapGridType gridType, Size size) : base(gridType, size) { }
public static CellLayer <T> CreateInstance(Func <MPos, T> initialCellValueFactory, Size size, MapGridType mapGridType) { var cellLayer = new CellLayer <T>(mapGridType, size); for (var v = 0; v < size.Height; v++) { for (var u = 0; u < size.Width; u++) { var mpos = new MPos(u, v); cellLayer[mpos] = initialCellValueFactory(mpos); } } return(cellLayer); }
public int2 ConvertToPreview(CPos cell, MapGridType gridType) { var preview = Preview(); var point = cell.ToMPos(gridType); var cellWidth = gridType == MapGridType.RectangularIsometric ? 2 : 1; var dx = (int)(previewScale * cellWidth * (point.U - preview.Bounds.Left)); var dy = (int)(previewScale * (point.V - preview.Bounds.Top)); // Odd rows are shifted right by 1px if ((point.V & 1) == 1) dx += 1; return new int2(mapRect.X + dx, mapRect.Y + dy); }
public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassification classification, string[] mapCompatibility, MapGridType gridType) { Dictionary <string, MiniYaml> yaml; using (var yamlStream = p.GetStream("map.yaml")) { if (yamlStream == null) { throw new FileNotFoundException("Required file map.yaml not present in this map"); } yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml")).ToDictionary(); } Package = p; parentPackage = parent; var newData = innerData.Clone(); newData.GridType = gridType; newData.Class = classification; MiniYaml temp; if (yaml.TryGetValue("MapFormat", out temp)) { var format = FieldLoader.GetValue <int>("MapFormat", temp.Value); if (format != Map.SupportedMapFormat) { throw new InvalidDataException("Map format {0} is not supported.".F(format)); } } if (yaml.TryGetValue("Title", out temp)) { newData.Title = temp.Value; } if (yaml.TryGetValue("Categories", out temp)) { newData.Categories = FieldLoader.GetValue <string[]>("Categories", temp.Value); } if (yaml.TryGetValue("Tileset", out temp)) { newData.TileSet = temp.Value; } if (yaml.TryGetValue("Author", out temp)) { newData.Author = temp.Value; } if (yaml.TryGetValue("Bounds", out temp)) { newData.Bounds = FieldLoader.GetValue <Rectangle>("Bounds", temp.Value); } if (yaml.TryGetValue("Visibility", out temp)) { newData.Visibility = FieldLoader.GetValue <MapVisibility>("Visibility", temp.Value); } string requiresMod = string.Empty; if (yaml.TryGetValue("RequiresMod", out temp)) { requiresMod = temp.Value; } newData.Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ? MapStatus.Available : MapStatus.Unavailable; try { // Actor definitions may change if the map format changes MiniYaml actorDefinitions; if (yaml.TryGetValue("Actors", out actorDefinitions)) { var spawns = new List <CPos>(); foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn")) { var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary()); spawns.Add(s.InitDict.Get <LocationInit>().Value(null)); } newData.SpawnPoints = spawns.ToArray(); } else { newData.SpawnPoints = new CPos[0]; } } catch (Exception) { newData.SpawnPoints = new CPos[0]; newData.Status = MapStatus.Unavailable; } try { // Player definitions may change if the map format changes MiniYaml playerDefinitions; if (yaml.TryGetValue("Players", out playerDefinitions)) { newData.Players = new MapPlayers(playerDefinitions.Nodes); newData.PlayerCount = newData.Players.Players.Count(x => x.Value.Playable); } } catch (Exception) { newData.Status = MapStatus.Unavailable; } newData.SetRulesetGenerator(modData, () => { var ruleDefinitions = LoadRuleSection(yaml, "Rules"); var weaponDefinitions = LoadRuleSection(yaml, "Weapons"); var voiceDefinitions = LoadRuleSection(yaml, "Voices"); var musicDefinitions = LoadRuleSection(yaml, "Music"); var notificationDefinitions = LoadRuleSection(yaml, "Notifications"); var sequenceDefinitions = LoadRuleSection(yaml, "Sequences"); var modelSequenceDefinitions = LoadRuleSection(yaml, "ModelSequences"); var rules = Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions, voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions, modelSequenceDefinitions); var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions, weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions); return(Pair.New(rules, flagged)); }); if (p.Contains("map.png")) { using (var dataStream = p.GetStream("map.png")) newData.Preview = new Bitmap(dataStream); } // Assign the new data atomically innerData = newData; }
public MapGrid(MapGridType mapGridType) { GridType = mapGridType; }
public Rectangle TemplateBounds(TerrainTemplateInfo template, Size tileSize, MapGridType mapGrid) { Rectangle? templateRect = null; var i = 0; for (var y = 0; y < template.Size.Y; y++) { for (var x = 0; x < template.Size.X; x++) { var tile = new TerrainTile(template.Id, (byte)(i++)); var tileInfo = tileset.GetTileInfo(tile); // Empty tile if (tileInfo == null) continue; var sprite = TileSprite(tile); var u = mapGrid == MapGridType.Rectangular ? x : (x - y) / 2f; var v = mapGrid == MapGridType.Rectangular ? y : (x + y) / 2f; var tl = new float2(u * tileSize.Width, (v - 0.5f * tileInfo.Height) * tileSize.Height) - 0.5f * sprite.Size; var rect = new Rectangle((int)(tl.X + sprite.Offset.X), (int)(tl.Y + sprite.Offset.Y), (int)sprite.Size.X, (int)sprite.Size.Y); templateRect = templateRect.HasValue ? Rectangle.Union(templateRect.Value, rect) : rect; } } return templateRect.HasValue ? templateRect.Value : Rectangle.Empty; }
public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassification classification, string[] mapCompatibility, MapGridType gridType) { Dictionary<string, MiniYaml> yaml; using (var yamlStream = p.GetStream("map.yaml")) { if (yamlStream == null) throw new FileNotFoundException("Required file map.yaml not present in this map"); yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml")).ToDictionary(); } Package = p; parentPackage = parent; var newData = innerData.Clone(); newData.GridType = gridType; newData.Class = classification; MiniYaml temp; if (yaml.TryGetValue("MapFormat", out temp)) { var format = FieldLoader.GetValue<int>("MapFormat", temp.Value); if (format != Map.SupportedMapFormat) throw new InvalidDataException("Map format {0} is not supported.".F(format)); } if (yaml.TryGetValue("Title", out temp)) newData.Title = temp.Value; if (yaml.TryGetValue("Categories", out temp)) newData.Categories = FieldLoader.GetValue<string[]>("Categories", temp.Value); if (yaml.TryGetValue("Tileset", out temp)) newData.TileSet = temp.Value; if (yaml.TryGetValue("Author", out temp)) newData.Author = temp.Value; if (yaml.TryGetValue("Bounds", out temp)) newData.Bounds = FieldLoader.GetValue<Rectangle>("Bounds", temp.Value); if (yaml.TryGetValue("Visibility", out temp)) newData.Visibility = FieldLoader.GetValue<MapVisibility>("Visibility", temp.Value); string requiresMod = string.Empty; if (yaml.TryGetValue("RequiresMod", out temp)) requiresMod = temp.Value; newData.Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ? MapStatus.Available : MapStatus.Unavailable; try { // Actor definitions may change if the map format changes MiniYaml actorDefinitions; if (yaml.TryGetValue("Actors", out actorDefinitions)) { var spawns = new List<CPos>(); foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn")) { var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary()); spawns.Add(s.InitDict.Get<LocationInit>().Value(null)); } newData.SpawnPoints = spawns.ToArray(); } else newData.SpawnPoints = new CPos[0]; } catch (Exception) { newData.SpawnPoints = new CPos[0]; newData.Status = MapStatus.Unavailable; } try { // Player definitions may change if the map format changes MiniYaml playerDefinitions; if (yaml.TryGetValue("Players", out playerDefinitions)) { newData.Players = new MapPlayers(playerDefinitions.Nodes); newData.PlayerCount = newData.Players.Players.Count(x => x.Value.Playable); } } catch (Exception) { newData.Status = MapStatus.Unavailable; } newData.SetRulesetGenerator(modData, () => { var ruleDefinitions = LoadRuleSection(yaml, "Rules"); var weaponDefinitions = LoadRuleSection(yaml, "Weapons"); var voiceDefinitions = LoadRuleSection(yaml, "Voices"); var musicDefinitions = LoadRuleSection(yaml, "Music"); var notificationDefinitions = LoadRuleSection(yaml, "Notifications"); var sequenceDefinitions = LoadRuleSection(yaml, "Sequences"); var rules = Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions, voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions); var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions, weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions); return Pair.New(rules, flagged); }); if (p.Contains("map.png")) using (var dataStream = p.GetStream("map.png")) newData.Preview = new Bitmap(dataStream); // Assign the new data atomically innerData = newData; }
public CellLayer(MapGridType gridType, Size size) : base(gridType, size) { }