/// <summary> /// Prüft, ob eine der erlaubten Shapes enthalten ist. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="direction"></param> /// <param name="message"></param> /// <param name="nothing"></param> /// <param name="shapes"></param> /// <returns></returns> private bool IsAllowedShape(int x, int y, Compass direction, out string message, bool nothing, params TileShape[] shapes) { Index2 index = GetCellIndex(x, y, direction); // Auf Definition prüfen if (IsNothing(index.X, index.Y)) { if (nothing) { message = string.Empty; return(true); } message = GetCellName(direction) + " is not defined"; return(false); } // Finde Treffer TileShape tile = Tiles[index.X, index.Y].Shape; foreach (TileShape shape in shapes) { if (shape == tile) { message = string.Empty; return(true); } } message = GetCellName(direction) + " has no valid shape"; return(false); }
/// <summary>Returns the minimal region that covers at least the specified cells.</summary> public static CellRegion BoundingRegion(TileShape 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 CellLayer(TileShape shape, Size size) { Size = size; bounds = new Rectangle(0, 0, Size.Width, Size.Height); Shape = shape; entries = new T[size.Width * size.Height]; }
public Rectangle TemplateBounds(TerrainTemplateInfo template, Size tileSize, TileShape tileShape) { 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 = tileShape == TileShape.Rectangle ? x : (x - y) / 2f; var v = tileShape == TileShape.Rectangle ? 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); }
protected MapViewer(int width, int height, TileShape tileTopology, bool torus) { Width = width; Height = height; TileTopology = tileTopology; Torus = torus; ResetMap(); }
public Tile(string id, int index, TileShape shape, bool isblocked = false, int height = 0) { this.ID = id; this.index = index; this.shape = shape; this.isBlocked = isblocked; this.Height = height; }
public GameBase(TileShape _tileShape = TileShape.SQUARE, PosType _posType = PosType.GridPos, LandType _landType = LandType.BasicLand) { turnNumber = 0; tileShape = _tileShape; posType = _posType; landType = _landType; }
internal Map(TileShape topology, int x, int y, bool torus, int provinces = 0, int nations = 0, Random r = null) { Torus = torus; R = r ?? new Random(); MapTopology = Shape.Square; Tiles = new Tile[x, y]; float[,] heightMap = new GenerateHeight(x, y, torus).HeightMap; for (x = 0; x < Tiles.GetLength(0); x++) { for (y = 0; y < Tiles.GetLength(1); y++) { Tiles[x, y] = new Tile(topology, x, y, 1 + x + y * Tiles.GetLength(0), heightMap[x, y], 0); } } for (x = 0; x < Tiles.GetLength(0); x++) { for (y = 0; y < Tiles.GetLength(1); y++) { for (int n = 0; n < Tiles[x, y].Neighbours.Length; n++) { Tiles[x, y].Neighbours[n] = GetNeighbour(x, y, n); } } } if (provinces == 0) { provinces = x; } Provinces = new Province[provinces]; for (int n = 0; n < provinces; n++) { Provinces[n] = new Province(this, x * y / provinces * 2, n); } Provinces = Provinces.Where(p => p.Tiles[0] != null).ToArray(); for (int n = 0; n < Provinces.Length; n++) { Provinces[n].Id = n; } if (nations == 0) { nations = (int)Math.Sqrt(provinces); } Nations = new Nation[nations]; for (int n = 0; n < nations; n++) { Nations[n] = new Nation(this, provinces / nations * 2, n); } Nations = Nations.Where(p => p.Provinces.Count > 0).ToArray(); for (int n = 0; n < Nations.Length; n++) { Nations[n].Id = n; } }
public CellRegion(TileShape shape, CPos topLeft, CPos bottomRight) { this.shape = shape; TopLeft = topLeft; BottomRight = bottomRight; mapTopLeft = TopLeft.ToMPos(shape); mapBottomRight = BottomRight.ToMPos(shape); }
public CellRegion(TileShape shape, CPos topLeft, CPos bottomRight) { this.shape = shape; TopLeft = topLeft; BottomRight = bottomRight; mapTopLeft = Map.CellToMap(shape, TopLeft); mapBottomRight = Map.CellToMap(shape, BottomRight); }
public void SetNeighbors(MarinusMap map, TileShape tileShape) { if (tileShape == TileShape.SQUARE) { SetNeighborsSquare(map); } else { SetNeighborsHex(map); } }
public MapAbstract(IGame _game, int _N = 5, bool _wrapEastWest = true, bool _wrapNorthSouth = true) { game = _game; wrapEastWest = _wrapEastWest; wrapNorthSouth = _wrapNorthSouth; tileShape = game.tileShape; occupants = new Dictionary <IPos, IOccupant>(); dim = 1 + (int)Mathf.Pow(2, _N); lands = MakeLands(_N); }
public void setMapLoc(TileShape _tileShape) { switch (_tileShape) { case TileShape.SQUARE: mapLoc = new Loc(gridLoc.coordinates); break; case TileShape.HEX: float x = Mathf.Sqrt(3) * (gridLoc.x() - 0.5f * (gridLoc.y() % 2f)) / 1.9f; float y = (3 / 2) * gridLoc.y() / 1.3f; mapLoc = new Loc(x, y); break; } }
public GameObject getGridDisplay(TileShape shape) { switch (shape) { case TileShape.Square: return(squareDisplay); case TileShape.Hexagon: return(hexDisplay); case TileShape.Triangle: return(triangleDisplay); } return(null); }
// Use this for initialization void Start() { TileShape tileShape = TileShape.SQUARE; Loc loci = new Loc(0, 0); Loc locj = new Loc(5, 5); Intersection i = new IntersectionBasic(loci, tileShape); Intersection j = new IntersectionBasic(locj, tileShape); drawer = goDrawer.GetComponentInChildren <GEDrawerBasic>(); //Vector3 vi = new Vector3(i.pos.gameLoc.x, i.pos.gameLoc.y+1, i.pos.gameLoc.z); //Vector3 vj = new Vector3(j.pos.gameLoc.x, j.pos.gameLoc.y+1, j.pos.gameLoc.z); Vector3 vi = i.pos.gameLoc; Vector3 vj = j.pos.gameLoc; drawer.InstantiateGo(drawer.pfIntersection, vi, Color.black); drawer.InstantiateGo(drawer.pfIntersection, vj, Color.black); drawer.DrawLine(i.pos.gameLoc, j.pos.gameLoc, Color.white); }
internal Tile(TileShape topology, int x, int y, int id, float height, float waterHeight, Tile[] tiles = null) { WaterHeight = waterHeight; X = x; Y = y; Id = id; TileTopology = topology; Neighbours = TileTopology == TileShape.Triangular ? new Tile[3] : TileTopology == TileShape.Square ? new Tile[4] : TileTopology == TileShape.Hex ? new Tile[6] : null; if (tiles != null) { for (int n = 0; n < Neighbours.Length; n++) { Neighbours[n] = tiles[n]; } } Height = height; }
public TileChoise(TileShape tileShape, TileCriteria upCriteria = TileCriteria.DontCare, TileCriteria downCriteria = TileCriteria.DontCare, TileCriteria leftCriteria = TileCriteria.DontCare, TileCriteria rightCriteria = TileCriteria.DontCare, TileCriteria upLeftCriteria = TileCriteria.DontCare, TileCriteria downLeftCriteria = TileCriteria.DontCare, TileCriteria upRightCriteria = TileCriteria.DontCare, TileCriteria downRightCriteria = TileCriteria.DontCare) { m_upCriteria = upCriteria; m_downCriteria = downCriteria; m_leftCriteria = leftCriteria; m_rightCriteria = rightCriteria; m_upLeftCriteria = upLeftCriteria; m_downLeftCriteria = downLeftCriteria; m_upRightCriteria = upRightCriteria; m_downRightCriteria = downRightCriteria; m_tileShape = tileShape; }
public static CPos CellToMap(TileShape shape, CPos cell) { if (shape == TileShape.Rectangle) { return(cell); } // Convert from diamond 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 = (cell.X - cell.Y) / 2; var v = cell.X + cell.Y; return(new CPos(u, v)); }
protected void Generate2DGrid(TileShape tileShape) { mDebug.Log("Generating map.pathMap...", false); pathMap = new Dictionary <string, Pos>(); for (int x = 0; x < xDim; x++) { for (int y = 0; y < yDim; y++) { Loc l = new Loc(x, y); Pos p = new Pos(l, game); mDebug.Log("New Pos is called" + p.gridLoc.key(), false); pathMap[p.gridLoc.key()] = p; } } foreach (string k in pathMap.Keys) { Pos p = pathMap[k]; p.SetNeighbors(this, tileShape); } mDebug.Log("...Finished map.pathMap", false); }
public static CPos MapToCell(TileShape shape, CPos map) { if (shape == TileShape.Rectangle) { return(map); } // Convert from rectangular map position to diamond 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 = (map.Y & 1) == 1 ? 1 : 0; var y = (map.Y - offset) / 2 - map.X; var x = map.Y - y; return(new CPos(x, y)); }
/// <summary> /// Initializes a new map created by the editor or importer. /// The map will not recieve a valid UID until after it has been saved and reloaded. /// </summary> public Map(TileSet tileset, int width, int height) { containsTest = Contains; var size = new Size(width, height); var tileShape = Game.ModData.Manifest.TileShape; var tileRef = new TerrainTile(tileset.Templates.First().Key, (byte)0); Title = "Name your map here"; Description = "Describe your map here"; Author = "Your name here"; MapSize = new int2(size); Tileset = tileset.Id; Videos = new MapVideos(); Options = new MapOptions(); MapResources = Exts.Lazy(() => new CellLayer <ResourceTile>(tileShape, size)); MapTiles = Exts.Lazy(() => { var ret = new CellLayer <TerrainTile>(tileShape, size); ret.Clear(tileRef); return(ret); }); MapHeight = Exts.Lazy(() => { var ret = new CellLayer <byte>(tileShape, size); ret.Clear(0); return(ret); }); SpawnPoints = Exts.Lazy(() => new CPos[0]); TileShape = tileShape; MaximumTerrainHeight = Game.ModData.Manifest.MaximumTerrainHeight; PostInit(); }
private IList <Tile> BuildRectangle(int columnCount, int rowCount, TileShape tileShape) { var rectangle = new List <Tile>(); var increment = tileShape.DoubleIncrement ? 2 : 1; for (var rowIndex = 0; rowIndex < rowCount; rowIndex++) { var row = rowIndex * increment; for (var colIndex = 0; colIndex < columnCount; colIndex++) { var col = colIndex * increment; var cubicCoordinates = CubicCoordinates.FromOffset( new OffsetCoordinates(col: col, row: row) ); rectangle.Add(new Tile( cubicCoordinates: cubicCoordinates, tileShape: tileShape, terrain: Terrain.Water )); } } return(rectangle); }
public TileSet(TileShape shape, Vector2 unit, IEnumerable <Tile> tiles, IEnumerable <EntityType> types) { Shape = shape; UnitSize = unit; if (tiles != null) { foreach (Tile t in tiles) { if (DefaultTile == ushort.MaxValue) { DefaultTile = t.Id; } map[t.Id] = t; } } if (types != null) { foreach (EntityType et in types) { entities[et.Id] = et; } } }
public CellLayer(TileShape shape, Size size) { Size = size; Shape = shape; entries = new T[size.Width * size.Height]; }
// The standard constructor for most purposes public Map(string path) { Path = path; Container = GlobalFileSystem.OpenPackage(path, null, int.MaxValue); AssertExists("map.yaml"); AssertExists("map.bin"); var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml"), path)); FieldLoader.Load(this, yaml); // Support for formats 1-3 dropped 2011-02-11. // Use release-20110207 to convert older maps to format 4 // Use release-20110511 to convert older maps to format 5 // Use release-20141029 to convert older maps to format 6 if (MapFormat < 6) { throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path)); } var nd = yaml.ToDictionary(); // Format 6 -> 7 combined the Selectable and UseAsShellmap flags into the Class enum if (MapFormat < 7) { MiniYaml useAsShellmap; if (nd.TryGetValue("UseAsShellmap", out useAsShellmap) && bool.Parse(useAsShellmap.Value)) { Visibility = MapVisibility.Shellmap; } else if (Type == "Mission" || Type == "Campaign") { Visibility = MapVisibility.MissionSelector; } } SpawnPoints = Exts.Lazy(() => { var spawns = new List <CPos>(); foreach (var kv in ActorDefinitions.Where(d => d.Value.Value == "mpspawn")) { var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary()); spawns.Add(s.InitDict.Get <LocationInit>().Value(null)); } return(spawns.ToArray()); }); RuleDefinitions = MiniYaml.NodesOrEmpty(yaml, "Rules"); SequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Sequences"); VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences"); WeaponDefinitions = MiniYaml.NodesOrEmpty(yaml, "Weapons"); VoiceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Voices"); NotificationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Notifications"); TranslationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Translations"); PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players"); ActorDefinitions = MiniYaml.NodesOrEmpty(yaml, "Actors"); SmudgeDefinitions = MiniYaml.NodesOrEmpty(yaml, "Smudges"); MapTiles = Exts.Lazy(LoadMapTiles); MapResources = Exts.Lazy(LoadResourceTiles); MapHeight = Exts.Lazy(LoadMapHeight); TileShape = Game.ModData.Manifest.TileShape; SubCellOffsets = Game.ModData.Manifest.SubCellOffsets; LastSubCell = (SubCell)(SubCellOffsets.Length - 1); DefaultSubCell = (SubCell)Game.ModData.Manifest.SubCellDefaultIndex; if (Container.Exists("map.png")) { using (var dataStream = Container.GetContent("map.png")) CustomPreview = new Bitmap(dataStream); } PostInit(); // The Uid is calculated from the data on-disk, so // format changes must be flushed to disk. // TODO: this isn't very nice if (MapFormat < 7) { Save(path); } Uid = ComputeHash(); }
// The standard constructor for most purposes public Map(string path) { Path = path; Container = GlobalFileSystem.OpenPackage(path, null, int.MaxValue); AssertExists("map.yaml"); AssertExists("map.bin"); var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml"), path)); FieldLoader.Load(this, yaml); // Support for formats 1-3 dropped 2011-02-11. // Use release-20110207 to convert older maps to format 4 // Use release-20110511 to convert older maps to format 5 // Use release-20141029 to convert older maps to format 6 if (MapFormat < 6) throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path)); var nd = yaml.ToDictionary(); // Format 6 -> 7 combined the Selectable and UseAsShellmap flags into the Class enum if (MapFormat < 7) { MiniYaml useAsShellmap; if (nd.TryGetValue("UseAsShellmap", out useAsShellmap) && bool.Parse(useAsShellmap.Value)) Visibility = MapVisibility.Shellmap; else if (Type == "Mission" || Type == "Campaign") Visibility = MapVisibility.MissionSelector; } SpawnPoints = Exts.Lazy(() => { var spawns = new List<CPos>(); foreach (var kv in ActorDefinitions.Where(d => d.Value.Value == "mpspawn")) { var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary()); spawns.Add(s.InitDict.Get<LocationInit>().Value(null)); } return spawns.ToArray(); }); RuleDefinitions = MiniYaml.NodesOrEmpty(yaml, "Rules"); SequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Sequences"); VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences"); WeaponDefinitions = MiniYaml.NodesOrEmpty(yaml, "Weapons"); VoiceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Voices"); NotificationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Notifications"); TranslationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Translations"); PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players"); ActorDefinitions = MiniYaml.NodesOrEmpty(yaml, "Actors"); SmudgeDefinitions = MiniYaml.NodesOrEmpty(yaml, "Smudges"); MapTiles = Exts.Lazy(LoadMapTiles); MapResources = Exts.Lazy(LoadResourceTiles); MapHeight = Exts.Lazy(LoadMapHeight); TileShape = Game.ModData.Manifest.TileShape; SubCellOffsets = Game.ModData.Manifest.SubCellOffsets; LastSubCell = (SubCell)(SubCellOffsets.Length - 1); DefaultSubCell = (SubCell)Game.ModData.Manifest.SubCellDefaultIndex; if (Container.Exists("map.png")) using (var dataStream = Container.GetContent("map.png")) CustomPreview = new Bitmap(dataStream); PostInit(); // The Uid is calculated from the data on-disk, so // format changes must be flushed to disk. // TODO: this isn't very nice if (MapFormat < 7) Save(path); Uid = ComputeHash(); }
public Rectangle TemplateBounds(TerrainTemplateInfo template, Size tileSize, TileShape tileShape) { 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 = tileShape == TileShape.Rectangle ? x : (x - y) / 2f; var v = tileShape == TileShape.Rectangle ? 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 Manifest(string mod) { var path = new[] { "mods", mod, "mod.yaml" }.Aggregate(Path.Combine); var yaml = new MiniYaml(null, MiniYaml.FromFile(path)).ToDictionary(); Mod = FieldLoader.Load<ModMetadata>(yaml["Metadata"]); Mod.Id = mod; // TODO: Use fieldloader Folders = YamlList(yaml, "Folders"); MapFolders = YamlDictionary(yaml, "MapFolders"); Packages = YamlDictionary(yaml, "Packages"); Rules = YamlList(yaml, "Rules"); ServerTraits = YamlList(yaml, "ServerTraits"); Sequences = YamlList(yaml, "Sequences"); VoxelSequences = YamlList(yaml, "VoxelSequences"); Cursors = YamlList(yaml, "Cursors"); Chrome = YamlList(yaml, "Chrome"); Assemblies = YamlList(yaml, "Assemblies"); ChromeLayout = YamlList(yaml, "ChromeLayout"); Weapons = YamlList(yaml, "Weapons"); Voices = YamlList(yaml, "Voices"); Notifications = YamlList(yaml, "Notifications"); Music = YamlList(yaml, "Music"); Movies = YamlList(yaml, "Movies"); Translations = YamlList(yaml, "Translations"); TileSets = YamlList(yaml, "TileSets"); ChromeMetrics = YamlList(yaml, "ChromeMetrics"); PackageContents = YamlList(yaml, "PackageContents"); LuaScripts = YamlList(yaml, "LuaScripts"); Missions = YamlList(yaml, "Missions"); LoadScreen = yaml["LoadScreen"]; LobbyDefaults = yaml["LobbyDefaults"]; if (yaml.ContainsKey("ContentInstaller")) ContentInstaller = FieldLoader.Load<InstallData>(yaml["ContentInstaller"]); Fonts = yaml["Fonts"].ToDictionary(my => { var nd = my.ToDictionary(); return Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value)); }); if (yaml.ContainsKey("TileSize")) TileSize = FieldLoader.GetValue<Size>("TileSize", yaml["TileSize"].Value); if (yaml.ContainsKey("TileShape")) TileShape = FieldLoader.GetValue<TileShape>("TileShape", yaml["TileShape"].Value); // Allow inherited mods to import parent maps. var compat = new List<string>(); compat.Add(mod); if (yaml.ContainsKey("SupportsMapsFrom")) foreach (var c in yaml["SupportsMapsFrom"].Value.Split(',')) compat.Add(c.Trim()); MapCompatibility = compat.ToArray(); }
// Support upgrading format 5 maps to a more // recent version by defining upgradeForMod. public Map(string path, string upgradeForMod) { Path = path; Container = GlobalFileSystem.OpenPackage(path, null, int.MaxValue); AssertExists("map.yaml"); AssertExists("map.bin"); var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml"))); FieldLoader.Load(this, yaml); // Support for formats 1-3 dropped 2011-02-11. // Use release-20110207 to convert older maps to format 4 // Use release-20110511 to convert older maps to format 5 if (MapFormat < 5) throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path)); // Format 5 -> 6 enforces the use of RequiresMod if (MapFormat == 5) { if (upgradeForMod == null) throw new InvalidDataException("Map format {0} is not supported, but can be upgraded.\n File: {1}".F(MapFormat, path)); Console.WriteLine("Upgrading {0} from Format 5 to Format 6", path); // TODO: This isn't very nice, but there is no other consistent way // of finding the mod early during the engine initialization. RequiresMod = upgradeForMod; } var nd = yaml.ToDictionary(); // Load players foreach (var my in nd["Players"].ToDictionary().Values) { var player = new PlayerReference(my); Players.Add(player.Name, player); } Actors = Exts.Lazy(() => { var ret = new Dictionary<string, ActorReference>(); foreach (var kv in nd["Actors"].ToDictionary()) ret.Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.ToDictionary())); return ret; }); // Smudges Smudges = Exts.Lazy(() => { var ret = new List<SmudgeReference>(); foreach (var name in nd["Smudges"].ToDictionary().Keys) { var vals = name.Split(' '); var loc = vals[1].Split(','); ret.Add(new SmudgeReference(vals[0], new int2( Exts.ParseIntegerInvariant(loc[0]), Exts.ParseIntegerInvariant(loc[1])), Exts.ParseIntegerInvariant(vals[2]))); } return ret; }); RuleDefinitions = MiniYaml.NodesOrEmpty(yaml, "Rules"); SequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Sequences"); VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences"); WeaponDefinitions = MiniYaml.NodesOrEmpty(yaml, "Weapons"); VoiceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Voices"); NotificationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Notifications"); TranslationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Translations"); MapTiles = Exts.Lazy(() => LoadMapTiles()); MapResources = Exts.Lazy(() => LoadResourceTiles()); TileShape = Game.modData.Manifest.TileShape; // The Uid is calculated from the data on-disk, so // format changes must be flushed to disk. // TODO: this isn't very nice if (MapFormat < 6) Save(path); Uid = ComputeHash(); if (Container.Exists("map.png")) CustomPreview = new Bitmap(Container.GetContent("map.png")); PostInit(); }
private IList <Tile> BuildRegularHexagon(int sideLength, bool centerOrigin, TileShape tileShape = null) { var hexagon = new List <Tile>(); var increment = TileShape.Hexagon.DoubleIncrement ? 2 : 1; var maxLength = (2 * sideLength) - 1; var centerOffset = centerOrigin ? ((sideLength * increment) - 1) : 0; if (tileShape == null) { tileShape = TileShape.Hexagon; } // Build top portion of hexagon var rowLength = sideLength - 1; var rowIndex = -1; while (rowLength < (maxLength - 1)) { rowLength++; rowIndex++; var topRow = (rowIndex * increment) - centerOffset; var colOffset = Convert.ToInt32(Math.Floor((maxLength - rowLength) / 2.0)); // TODO: Fix bug where column offset produces fractional value for (var colIndex = 0; colIndex < rowLength; colIndex++) { var col = ((colIndex + colOffset) * increment) - centerOffset; hexagon.Add(new Tile( cubicCoordinates: CubicCoordinates.FromOffset( new OffsetCoordinates(row: topRow, col: col) ), tileShape: tileShape, terrain: Terrain.Water )); } } // Build middle row of hexagon rowIndex++; rowLength = maxLength; var middleRow = (rowIndex * increment) - centerOffset; for (var colIndex = 0; colIndex < rowLength; colIndex++) { var col = (colIndex * increment) - centerOffset; hexagon.Add(new Tile( cubicCoordinates: CubicCoordinates.FromOffset( new OffsetCoordinates(row: middleRow, col: col) ), tileShape: tileShape, terrain: Terrain.Water )); } // Build bottom portion of hexagon while (rowLength > sideLength) { rowLength--; rowIndex++; var bottomRow = (rowIndex * increment) - centerOffset; var colOffset = Convert.ToInt32(Math.Floor((maxLength - rowLength) / 2.0)); // TODO: Fix bug where column offset produces fractional value for (var colIndex = 0; colIndex < rowLength; colIndex++) { var col = ((colIndex + colOffset) * increment) - centerOffset; hexagon.Add(new Tile( cubicCoordinates: CubicCoordinates.FromOffset( new OffsetCoordinates(row: bottomRow, col: col) ), tileShape: tileShape, terrain: Terrain.Water )); } } // return the hexagon tiles return(hexagon); }
public Manifest(string mod) { var path = Platform.ResolvePath(".", "mods", mod, "mod.yaml"); yaml = new MiniYaml(null, MiniYaml.FromFile(path)).ToDictionary(); Mod = FieldLoader.Load <ModMetadata>(yaml["Metadata"]); Mod.Id = mod; // TODO: Use fieldloader Folders = YamlList(yaml, "Folders", true); MapFolders = YamlDictionary(yaml, "MapFolders", true); Packages = YamlDictionary(yaml, "Packages", true); Rules = YamlList(yaml, "Rules", true); Sequences = YamlList(yaml, "Sequences", true); VoxelSequences = YamlList(yaml, "VoxelSequences", true); Cursors = YamlList(yaml, "Cursors", true); Chrome = YamlList(yaml, "Chrome", true); Assemblies = YamlList(yaml, "Assemblies", true); ChromeLayout = YamlList(yaml, "ChromeLayout", true); Weapons = YamlList(yaml, "Weapons", true); Voices = YamlList(yaml, "Voices", true); Notifications = YamlList(yaml, "Notifications", true); Music = YamlList(yaml, "Music", true); Translations = YamlList(yaml, "Translations", true); TileSets = YamlList(yaml, "TileSets", true); ChromeMetrics = YamlList(yaml, "ChromeMetrics", true); Missions = YamlList(yaml, "Missions", true); ServerTraits = YamlList(yaml, "ServerTraits"); if (!yaml.TryGetValue("LoadScreen", out LoadScreen)) { throw new InvalidDataException("`LoadScreen` section is not defined."); } if (!yaml.TryGetValue("LobbyDefaults", out LobbyDefaults)) { throw new InvalidDataException("`LobbyDefaults` section is not defined."); } Fonts = yaml["Fonts"].ToDictionary(my => { var nd = my.ToDictionary(); return(Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value))); }); if (yaml.ContainsKey("TileSize")) { TileSize = FieldLoader.GetValue <Size>("TileSize", yaml["TileSize"].Value); } if (yaml.ContainsKey("TileShape")) { TileShape = FieldLoader.GetValue <TileShape>("TileShape", yaml["TileShape"].Value); } if (yaml.ContainsKey("MaximumTerrainHeight")) { MaximumTerrainHeight = FieldLoader.GetValue <byte>("MaximumTerrainHeight", yaml["MaximumTerrainHeight"].Value); } if (yaml.ContainsKey("SubCells")) { var subcells = yaml["SubCells"].ToDictionary(); // Read (x,y,z) offset (relative to cell center) pairs for positioning subcells if (subcells.ContainsKey("Offsets")) { SubCellOffsets = FieldLoader.GetValue <WVec[]>("Offsets", subcells["Offsets"].Value); } if (subcells.ContainsKey("DefaultIndex")) { SubCellDefaultIndex = FieldLoader.GetValue <int>("DefaultIndex", subcells["DefaultIndex"].Value); } else // Otherwise set the default subcell index to the middle subcell entry { SubCellDefaultIndex = SubCellOffsets.Length / 2; } } // Validate default index - 0 for no subcells, otherwise > 1 & <= subcell count (offset triples count - 1) if (SubCellDefaultIndex < (SubCellOffsets.Length > 1 ? 1 : 0) || SubCellDefaultIndex >= SubCellOffsets.Length) { throw new InvalidDataException("Subcell default index must be a valid index into the offset triples and must be greater than 0 for mods with subcells"); } // Allow inherited mods to import parent maps. var compat = new List <string>(); compat.Add(mod); if (yaml.ContainsKey("SupportsMapsFrom")) { foreach (var c in yaml["SupportsMapsFrom"].Value.Split(',')) { compat.Add(c.Trim()); } } MapCompatibility = compat.ToArray(); if (yaml.ContainsKey("SpriteFormats")) { SpriteFormats = FieldLoader.GetValue <string[]>("SpriteFormats", yaml["SpriteFormats"].Value); } }
void TileInfoUI(TileAtlas atlas, TileInfo tile) { GUILayout.BeginVertical("HelpBox"); EditorGUI.indentLevel++; TileEditorInfo info = GetTileEditorInfo(tile.id); EditorGUILayout.BeginHorizontal(); info.isRevealed = EditorGUILayout.Foldout(info.isRevealed, "ID:" + tile.id + " " + tile.name); GUILayout.FlexibleSpace(); Sprite mainSprite = tile.GetSprite(); if (mainSprite != null) { DrawOnGUISprite(mainSprite); } if (GUILayout.Button("remove", GUILayout.MaxWidth(80))) { atlas.RemoveTile(tile.id); atlas.BumpMajor(); } EditorGUILayout.EndHorizontal(); if (info.isRevealed) { string old = EditorGUILayout.TextField("Name", tile.name); if (old != tile.name) { tile.name = old; atlas.BumpMinor(); } if (tile.tileGO == null) { TileShape shape = (TileShape)EditorGUILayout.EnumPopup("Shape", tile.shape); if (shape != tile.shape) { tile.shape = shape; atlas.BumpMinor(); } bool isVertical; if (TileShapeHelper.IsTriangle(tile.shape)) { isVertical = EditorGUILayout.Toggle("Triangle can stretch vertically", tile.isVertical); isVertical = !EditorGUILayout.Toggle("Triangle can stretch horizontally", !tile.isVertical); } else { isVertical = tile.shape == TileShape.LEFT_ONEWAY || tile.shape == TileShape.RIGHT_ONEWAY; } if (tile.isVertical != isVertical) { tile.isVertical = isVertical; atlas.BumpMinor(); } bool isTrigger = EditorGUILayout.Toggle("Is trigger?", tile.isTrigger); if (isTrigger != tile.isTrigger) { tile.isTrigger = isTrigger; atlas.BumpMinor(); } int layer = EditorGUILayout.LayerField("Layer", tile.layer); if (layer != tile.layer) { tile.layer = layer; atlas.BumpMinor(); } string tag = EditorGUILayout.TagField("Tag", tile.tag); if (tag != tile.tag) { tile.tag = tag; atlas.BumpMinor(); } } else { if (tile.shape != TileShape.EMPTY) { tile.shape = TileShape.EMPTY; atlas.BumpMinor(); } } GameObject obj = EditorGUILayout.ObjectField("Tile GO", tile.tileGO, typeof(GameObject), false) as GameObject; if (tile.tileGO != obj) { tile.tileGO = obj; atlas.BumpMajor(); } if (tile.tileGO != null) { bool val = EditorGUILayout.Toggle("Tile GO is detached", tile.isGODetached); if (val != tile.isGODetached) { tile.isGODetached = val; atlas.BumpMinor(); } } bool isTriangle = TileShapeHelper.IsTriangle(tile.shape); if (isTriangle) { TriangleSpriteChooser(tile, tile.idSpriteInfo, 0); if (tile.subIdSpriteInfo != null) { for (int i = 0; i < tile.subIdSpriteInfo.Length; i++) { TriangleSpriteChooser(tile, tile.subIdSpriteInfo [i], i); } } } else { Sprite sprite = (Sprite)EditorGUILayout.ObjectField("Main sprite", tile.idSpriteInfo.importedSprite, typeof(Sprite), false); if (tile.idSpriteInfo.importedSprite != sprite) { tile.idSpriteInfo.importedSprite = sprite; atlas.BumpMinor(); } if (tile.subIdSpriteInfo != null) { for (int i = 0; i < tile.subIdSpriteInfo.Length; i++) { if (tile.subIdSpriteInfo [i] != null) { sprite = (Sprite)EditorGUILayout.ObjectField("Sub id sprite " + i, tile.subIdSpriteInfo [i].importedSprite, typeof(Sprite), false); if (sprite != tile.subIdSpriteInfo[i].importedSprite) { tile.subIdSpriteInfo [i].importedSprite = sprite; atlas.BumpMinor(); } } } } } if (GUILayout.Button("Add sub id sprite")) { tile.AddSubId(); atlas.BumpMinor(); } if (GUILayout.Button("Remove sub id sprite")) { tile.RemoveSubId(); atlas.BumpMajor(); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.EndHorizontal(); } EditorGUI.indentLevel--; GUILayout.EndVertical(); if (GUI.changed) { EditorUtility.SetDirty(target); } }
public static Map GenerateMap(TileShape topology, int width, int height, bool torus, int provinces, int nations, Random r = null) { return(new Map(topology, width, height, torus, provinces, nations, r)); }
public Manifest(string mod) { var path = Platform.ResolvePath(".", "mods", mod, "mod.yaml"); var yaml = new MiniYaml(null, MiniYaml.FromFile(path)).ToDictionary(); Mod = FieldLoader.Load<ModMetadata>(yaml["Metadata"]); Mod.Id = mod; // TODO: Use fieldloader Folders = YamlList(yaml, "Folders", true); MapFolders = YamlDictionary(yaml, "MapFolders", true); Packages = YamlDictionary(yaml, "Packages", true); Rules = YamlList(yaml, "Rules", true); Sequences = YamlList(yaml, "Sequences", true); VoxelSequences = YamlList(yaml, "VoxelSequences", true); Cursors = YamlList(yaml, "Cursors", true); Chrome = YamlList(yaml, "Chrome", true); Assemblies = YamlList(yaml, "Assemblies", true); ChromeLayout = YamlList(yaml, "ChromeLayout", true); Weapons = YamlList(yaml, "Weapons", true); Voices = YamlList(yaml, "Voices", true); Notifications = YamlList(yaml, "Notifications", true); Music = YamlList(yaml, "Music", true); Movies = YamlList(yaml, "Movies", true); Translations = YamlList(yaml, "Translations", true); TileSets = YamlList(yaml, "TileSets", true); ChromeMetrics = YamlList(yaml, "ChromeMetrics", true); Missions = YamlList(yaml, "Missions", true); ServerTraits = YamlList(yaml, "ServerTraits"); LoadScreen = yaml["LoadScreen"]; LobbyDefaults = yaml["LobbyDefaults"]; if (yaml.ContainsKey("ContentInstaller")) ContentInstaller = FieldLoader.Load<InstallData>(yaml["ContentInstaller"]); Fonts = yaml["Fonts"].ToDictionary(my => { var nd = my.ToDictionary(); return Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value)); }); if (yaml.ContainsKey("TileSize")) TileSize = FieldLoader.GetValue<Size>("TileSize", yaml["TileSize"].Value); if (yaml.ContainsKey("TileShape")) TileShape = FieldLoader.GetValue<TileShape>("TileShape", yaml["TileShape"].Value); if (yaml.ContainsKey("SubCells")) { var subcells = yaml["SubCells"].ToDictionary(); // Read (x,y,z) offset (relative to cell center) pairs for positioning subcells if (subcells.ContainsKey("Offsets")) SubCellOffsets = FieldLoader.GetValue<WVec[]>("Offsets", subcells["Offsets"].Value); if (subcells.ContainsKey("DefaultIndex")) SubCellDefaultIndex = FieldLoader.GetValue<int>("DefaultIndex", subcells["DefaultIndex"].Value); else // Otherwise set the default subcell index to the middle subcell entry SubCellDefaultIndex = SubCellOffsets.Length / 2; } // Validate default index - 0 for no subcells, otherwise > 1 & <= subcell count (offset triples count - 1) if (SubCellDefaultIndex < (SubCellOffsets.Length > 1 ? 1 : 0) || SubCellDefaultIndex >= SubCellOffsets.Length) throw new InvalidDataException("Subcell default index must be a valid index into the offset triples and must be greater than 0 for mods with subcells"); // Allow inherited mods to import parent maps. var compat = new List<string>(); compat.Add(mod); if (yaml.ContainsKey("SupportsMapsFrom")) foreach (var c in yaml["SupportsMapsFrom"].Value.Split(',')) compat.Add(c.Trim()); MapCompatibility = compat.ToArray(); if (yaml.ContainsKey("SpriteFormats")) SpriteFormats = FieldLoader.GetValue<string[]>("SpriteFormats", yaml["SpriteFormats"].Value); }
public static CPos MapToCell(TileShape shape, CPos map) { if (shape == TileShape.Rectangle) return map; // Convert from rectangular map position to diamond 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 = (map.Y & 1) == 1 ? 1 : 0; var y = (map.Y - offset) / 2 - map.X; var x = map.Y - y; return new CPos(x, y); }
// Support upgrading format 5 maps to a more // recent version by defining upgradeForMod. public Map(string path, string upgradeForMod) { Path = path; Container = GlobalFileSystem.OpenPackage(path, null, int.MaxValue); AssertExists("map.yaml"); AssertExists("map.bin"); var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml"))); FieldLoader.Load(this, yaml); // Support for formats 1-3 dropped 2011-02-11. // Use release-20110207 to convert older maps to format 4 // Use release-20110511 to convert older maps to format 5 if (MapFormat < 5) { throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path)); } // Format 5 -> 6 enforces the use of RequiresMod if (MapFormat == 5) { if (upgradeForMod == null) { throw new InvalidDataException("Map format {0} is not supported, but can be upgraded.\n File: {1}".F(MapFormat, path)); } Console.WriteLine("Upgrading {0} from Format 5 to Format 6", path); // TODO: This isn't very nice, but there is no other consistent way // of finding the mod early during the engine initialization. RequiresMod = upgradeForMod; } var nd = yaml.ToDictionary(); // Load players foreach (var my in nd["Players"].ToDictionary().Values) { var player = new PlayerReference(my); Players.Add(player.Name, player); } Actors = Exts.Lazy(() => { var ret = new Dictionary <string, ActorReference>(); foreach (var kv in nd["Actors"].ToDictionary()) { ret.Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.ToDictionary())); } return(ret); }); // Smudges Smudges = Exts.Lazy(() => { var ret = new List <SmudgeReference>(); foreach (var name in nd["Smudges"].ToDictionary().Keys) { var vals = name.Split(' '); var loc = vals[1].Split(','); ret.Add(new SmudgeReference(vals[0], new int2( Exts.ParseIntegerInvariant(loc[0]), Exts.ParseIntegerInvariant(loc[1])), Exts.ParseIntegerInvariant(vals[2]))); } return(ret); }); RuleDefinitions = MiniYaml.NodesOrEmpty(yaml, "Rules"); SequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Sequences"); VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences"); WeaponDefinitions = MiniYaml.NodesOrEmpty(yaml, "Weapons"); VoiceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Voices"); NotificationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Notifications"); TranslationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Translations"); MapTiles = Exts.Lazy(() => LoadMapTiles()); MapResources = Exts.Lazy(() => LoadResourceTiles()); TileShape = Game.modData.Manifest.TileShape; // The Uid is calculated from the data on-disk, so // format changes must be flushed to disk. // TODO: this isn't very nice if (MapFormat < 6) { Save(path); } Uid = ComputeHash(); if (Container.Exists("map.png")) { CustomPreview = new Bitmap(Container.GetContent("map.png")); } PostInit(); }
public static CPos CellToMap(TileShape shape, CPos cell) { if (shape == TileShape.Rectangle) return cell; // Convert from diamond 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 = (cell.X - cell.Y) / 2; var v = cell.X + cell.Y; return new CPos(u, v); }
public Board CreateBoard( Guid id, BoardType boardType, TileShape tileShape, int columnsOrSideLength, int?rows = null, double?landToWaterRatio = null ) { // Determine shape and tile layout var useTileShape = tileShape; var useBoardType = boardType; // Validate column count if (columnsOrSideLength < 3) { throw new Exception("Not enough tile column(s) were specified"); } // Validate row count if ((rows != null ? rows : columnsOrSideLength) < 3) { throw new Exception("Not enough row column(s) were specified"); } // regular polygon boards enforce an odd number of column(s) if (useBoardType.CenterOrigin && ((columnsOrSideLength & 1) < 1)) { throw new Exception("Board types with centered origin require an odd number of column(s)"); } // Array to store rows of tiles (board) IList <Tile> tiles = new List <Tile>(); // Build Rectangular board (fixed number of tiles per row) if (useBoardType.Equals(BoardType.Rectangle)) { // Calculate width and height var columnCount = columnsOrSideLength; var rowCount = (int)((rows != null) ? rows : columnsOrSideLength); // Default to width (length of side) tiles = BuildRectangle(columnCount, rowCount, useTileShape); } // Build Regular polygon / convex shape board if (useBoardType.Equals(BoardType.RegularPolygon)) { var sideLength = columnsOrSideLength; if (useTileShape.Equals(TileShape.Square)) { tiles = BuildSquare(sideLength, useBoardType.CenterOrigin); } if (useTileShape.Equals(TileShape.Octagon)) { tiles = BuildRegularOctagon(sideLength, useBoardType.CenterOrigin); } if (useTileShape.Equals(TileShape.Hexagon) || useTileShape.Equals(TileShape.Circle)) { tiles = BuildRegularHexagon(sideLength, useBoardType.CenterOrigin, useTileShape); } } // Get a terrain type for each tile var impassableTerrain = Terrain.List().Where(x => !x.Passable); var passableTerrain = Terrain.List().Where(x => x.Passable); foreach (var tile in tiles) { var terrain = GetRandomTerrain(landToWaterRatio, impassableTerrain, passableTerrain); tile.SetTerrain(terrain); } // Create new board var board = new Board( boardType: useBoardType, id: id, tiles: tiles, tileShape: useTileShape ); // return the board return(board); }
/// <summary> /// Initializes a new map created by the editor or importer. /// The map will not recieve a valid UID until after it has been saved and reloaded. /// </summary> public Map(TileSet tileset, int width, int height) { var size = new Size(width, height); var tileShape = Game.ModData.Manifest.TileShape; var tileRef = new TerrainTile(tileset.Templates.First().Key, (byte)0); Title = "Name your map here"; Description = "Describe your map here"; Author = "Your name here"; MapSize = new int2(size); Tileset = tileset.Id; Videos = new MapVideos(); Options = new MapOptions(); MapResources = Exts.Lazy(() => new CellLayer<ResourceTile>(tileShape, size)); MapTiles = Exts.Lazy(() => { var ret = new CellLayer<TerrainTile>(tileShape, size); ret.Clear(tileRef); return ret; }); MapHeight = Exts.Lazy(() => { var ret = new CellLayer<byte>(tileShape, size); ret.Clear(0); return ret; }); SpawnPoints = Exts.Lazy(() => new CPos[0]); TileShape = tileShape; MaximumTerrainHeight = Game.ModData.Manifest.MaximumTerrainHeight; PostInit(); }