public static GlobalPos GetNeighborMapCoords(GlobalPos pos, HexDirection direction) { switch (direction) { case HexDirection.TOP_LEFT: return new GlobalPos(pos.X - 1, pos.Y + (pos.X & 1)); case HexDirection.TOP: return new GlobalPos(pos.X, pos.Y + 1); case HexDirection.TOP_RIGHT: return new GlobalPos(pos.X + 1, pos.Y + (pos.X & 1)); case HexDirection.BOTTOM_RIGHT: return new GlobalPos(pos.X + 1, pos.Y - (pos.X & 1 ^ 1)); case HexDirection.BOTTOM: return new GlobalPos(pos.X, pos.Y - 1); case HexDirection.BOTTOM_LEFT: return new GlobalPos(pos.X - 1, pos.Y - (pos.X & 1 ^ 1)); } throw new System.ArgumentException("Invalid direction", "direction"); }
public static GlobalPos GetNeighborMapCoords(GlobalPos pos, TurnedHexDirection direction) { switch (direction) { case TurnedHexDirection.LEFT_TOP: return new GlobalPos(pos.X - (pos.Y & 1 ^ 1), pos.Y + 1); case TurnedHexDirection.RIGHT_TOP: return new GlobalPos(pos.X + (pos.Y & 1), pos.Y + 1); case TurnedHexDirection.RIGHT: return new GlobalPos(pos.X + 1, pos.Y); case TurnedHexDirection.RIGHT_BOTTOM: return new GlobalPos(pos.X + (pos.Y & 1), pos.Y - 1); case TurnedHexDirection.LEFT_BOTTOM: return new GlobalPos(pos.X - (pos.Y & 1 ^ 1), pos.Y - 1); case TurnedHexDirection.LEFT: return new GlobalPos(pos.X - 1, pos.Y); } throw new System.ArgumentException("Invalid turned direction", "direction"); }
public static ushort Distance(GlobalPos coords1, GlobalPos coords2, bool turnedHexes) { int q1, r1, s1, q2, r2, s2; if (turnedHexes) { q1 = coords1.X - (coords1.Y + (coords1.Y & 1 ^ 1) >> 1); r1 = coords1.Y; s1 = -q1 - r1; q2 = coords2.X - (coords2.Y + (coords2.Y & 1 ^ 1) >> 1); r2 = coords2.Y; s2 = -q2 - r2; } else { q1 = coords1.X; r1 = coords1.Y - (coords1.X + (coords1.X & 1 ^ 1) >> 1); s1 = -q1 - r1; q2 = coords2.X; r2 = coords2.Y - (coords2.X + (coords2.X & 1 ^ 1) >> 1); s2 = -q2 - r2; } return (ushort)(UnityEngine.Mathf.Abs(q1 - q2) + UnityEngine.Mathf.Abs(r1 - r2) + UnityEngine.Mathf.Abs(s1 - s2) >> 1); }
//C#6.0 EBD public bool Contains(GlobalPos coords) { return coords.Y >= 0 && coords.Y < Height && coords.X >= 0 && coords.X < Width; }
public static void OnPlayerMoveOnGlobal(GlobalPos pos)//C#6.0 EBD { PlayerMovedOnGlobal(pos); }
/// <summary> /// Определяет, прилегают ли к друг другу данные координаты. /// </summary> /// <returns><c>true</c> если прилегают, иначе <c>false</c>.</returns> /// <param name="mapCoords1">1 координаты.</param> /// <param name="mapCoords2">2 координаты.</param> public static bool IsMapCoordsAdjacent(GlobalPos coords1, GlobalPos coords2, bool turnedHexes) { if (turnedHexes) for (byte i = 0; i < 6; ++i) { if (GetNeighborMapCoords(coords1, (TurnedHexDirection)i) == coords2) return true; } else for (byte i = 0; i < 6; ++i) { if (GetNeighborMapCoords(coords1, (HexDirection)i) == coords2) return true; } return false; }
//C#6.0 EBD public TerrainType GetHexTerrain(GlobalPos pos) { return (CurrentMap as Chunk).TerrainMatrix[pos.Y - ChunkY * ChunkSize, pos.X - ChunkX * ChunkSize]; }
/// <summary> /// Переход на локальную карту. /// </summary> void GotoLocalMap() { GlobalMapPos = Player.GlobalPos; LocalPos pos = new LocalPos((ushort)(GlobalMapPos.X - ChunkX * ChunkSize), (ushort)(GlobalMapPos.Y - ChunkY * ChunkSize)); //TODO new? if (LocalMaps[pos.Y, pos.X] == null) LocalMaps[pos.Y, pos.X] = CreateLocalMap(CashedChunks[1, 1].HeightMatrix[pos.Y, pos.X], CashedChunks[1, 1].ForestMatrix[pos.Y, pos.X], (CashedChunks[1, 1].TerrainMatrix[pos.Y, pos.X] & TerrainType.RIVER) != TerrainType.NONE); CurrentMap = LocalMaps[pos.Y, pos.X]; (CurrentMap as LocalMap).Activate(); //TEMP Player.GlobalPos.X = (LocalMapSize.X >> 1); Player.GlobalPos.Y = (LocalMapSize.Y >> 1); // EventManager.OnEntitySpawn(Player); Visualizer.RenderWholeMap(CurrentMap as LocalMap); }
/// <summary> /// Необходимо вызывать, когда игрок переходит на другой хекс. /// </summary> void OnPlayerGotoGlobalHex(GlobalPos pos) { int chunkX = Mathf.FloorToInt((float)pos.X / ChunkSize), chunkY = Mathf.FloorToInt((float)pos.Y / ChunkSize); if (chunkX != ChunkX || chunkY != ChunkY) { Debug.Log("Cashing chunks."); sbyte dx = (sbyte)(ChunkX - chunkX), dy = (sbyte)(ChunkY - chunkY); if (dx != 0) for (sbyte y = -1; y < 2; ++y) SaveChunk(ChunkY + y, ChunkX + dx, CashedChunks[y + 1, dx + 1]); if (dy != 0) for (sbyte x = -1; x < 2; ++x) SaveChunk(ChunkY + dy, ChunkX + x, CashedChunks[dy + 1, x + 1]); SaveCurrentChunkLocalMaps(); Chunk[,] bufCashe = new Chunk[3, 3]; for (sbyte y = -1; y < 2; ++y) for (sbyte x = -1; x < 2; ++x) bufCashe[y + 1, x + 1] = GetChunk(chunkY + y, chunkX + x); if (!TryLoadFiledChunkLocalMaps(chunkY, chunkX)) for (ushort y = 0; y < ChunkSize; ++y) for (ushort x = 0; x < ChunkSize; ++x) LocalMaps[y, x] = null; CashedChunks = bufCashe; ChunkY = chunkY; ChunkX = chunkX; CurrentMap = CashedChunks[1, 1]; } Visualizer.RenderVisibleHexes(pos, Player.ViewRange, CashedChunks, ChunkY, ChunkX); Visualizer.DestroyAllBlues();//TODO Временно for (byte i = 0; i < 6; ++i) Visualizer.HighlightHex(HexNavigHelper.GetNeighborMapCoords(pos, (HexDirection)i)); }
public void MoveTo(GlobalPos pos, float moveAnimTime) { MakingTurn = true; MoveTime = moveAnimTime; GlobalPos = pos; //EventManager.OnPlayerMove(mapCoords); //TODO Временно //Временно закоммент. см. HexInteraction 21 }
//C#6.0 EBD public static Vector2 GetTransformPosFromMapPos(GlobalPos pos) { return new Vector2(pos.X * GlobalHexSpriteSize.x * 0.75f, pos.Y * GlobalHexSpriteSize.y + (pos.X & 1) * GlobalHexSpriteSize.y * 0.5f); }
/// <summary> /// Рекурсивно заносит в очередь на отображение хексы. /// </summary> /// <param name="mapPosition">Координаты в матрице.</param> /// <param name="distance">Оставшееся расстояние для распространения.</param> void SpreadRender(GlobalPos pos, byte distance) { Chunk map; ushort chunkSize = CashedChunks[1, 1].Width; float chunkX = (float)pos.X / chunkSize, chunkY = (float)pos.Y / chunkSize; chunkX = Mathf.Floor(chunkX); chunkY = Mathf.Floor(chunkY); map = CashedChunks[(int)(chunkY - ChunkY + 1), (int)(chunkX - ChunkX + 1)]; LocalPos inchunkPos; inchunkPos.X = (ushort)(pos.X - chunkSize * chunkX); inchunkPos.Y = (ushort)(pos.Y - chunkSize * chunkY); short index = (short)RenderedHexes.FindIndex(x => x.Pos == pos); if (index == -1) { ListType hex = new ListType { Hex = new GameObject("hex"), InSign = true }; hex.Hex.transform.position = GetTransformPosFromMapPos(pos); hex.Hex.transform.parent = transform; hex.Pos = pos; hex.Hex.AddComponent<SpriteRenderer>(); hex.Hex.AddComponent<Fader>(); MakeHexGraphics(hex, inchunkPos, map); RenderedHexes.Add(hex); } else { if (RenderedHexes[index].InSign) return; else RenderedHexes[index].InSign = true; } if (distance != 0) { SignQueue.Enqueue(new QueueType { Pos = HexNavigHelper.GetNeighborMapCoords(pos, HexDirection.TOP_LEFT), Distance = (byte)(distance - 1) }); SignQueue.Enqueue(new QueueType { Pos = HexNavigHelper.GetNeighborMapCoords(pos, HexDirection.TOP), Distance = (byte)(distance - 1) }); SignQueue.Enqueue(new QueueType { Pos = HexNavigHelper.GetNeighborMapCoords(pos, HexDirection.TOP_RIGHT), Distance = (byte)(distance - 1) }); SignQueue.Enqueue(new QueueType { Pos = HexNavigHelper.GetNeighborMapCoords(pos, HexDirection.BOTTOM_RIGHT), Distance = (byte)(distance - 1) }); SignQueue.Enqueue(new QueueType { Pos = HexNavigHelper.GetNeighborMapCoords(pos, HexDirection.BOTTOM), Distance = (byte)(distance - 1) }); SignQueue.Enqueue(new QueueType { Pos = HexNavigHelper.GetNeighborMapCoords(pos, HexDirection.BOTTOM_LEFT), Distance = (byte)(distance - 1) }); } }
/// <summary> /// Отображает только хексы в поле зрения игрока. /// </summary> /// <param name="mapPosition">Координаты в матрице.</param> /// <param name="distance">Дальность обзора.</param> /// <param name="currentMap">Активная карта.</param> public void RenderVisibleHexes(GlobalPos pos, byte distance, Chunk[,] cashedChunks, int chunkY, int chunkX) { CashedChunks = cashedChunks; ChunkX = chunkX; ChunkY = chunkY; RenderedHexes.ForEach(hex => hex.InSign = false); SignQueue.Enqueue(new QueueType { Pos = pos, Distance = distance }); while (SignQueue.Count != 0) { QueueType buf = SignQueue.Dequeue(); SpreadRender(buf.Pos, buf.Distance); } for (ushort i = 0; i < RenderedHexes.Count; ++i) if (!RenderedHexes[i].InSign) { for (ushort j = 0; j < RenderedHexes[i].Hex.transform.childCount; ++j) RenderedHexes[i].Hex.transform.GetChild(j).gameObject.GetComponent<Fader>().FadeAndDestroyObject(FadeTime); RenderedHexes[i].Hex.GetComponent<Fader>().FadeAndDestroyObject(FadeTime); RenderedHexes.RemoveAt(i); if (i != 0) i--; } }
/// <summary> /// Накладывает на хекс спрайт. /// </summary> /// <param name="mapCoords">Координаты хекса.</param> /// <param name="highlightHexSprite">Спрайт.</param> public void HighlightHex(GlobalPos pos) { BluesType hex = new BluesType { Hex = Instantiate(InteractableHex, GetTransformPosFromMapPos(pos), Quaternion.identity) as GameObject, InSign = true }; hex.Hex.GetComponent<HexInteraction>().Pos = pos; RenderedBlues.Add(hex); }