void Attack(LivingBeing target) { State = AI_State.ATTACK; Target = target; TargetPos = Target.Pos; Animator.SetBool("Agressive", true); }
public virtual void Read(SymBinaryReader reader) { LocalPos buf; reader.Read(out buf.X); reader.Read(out buf.Y); Pos = buf; bool buf2; reader.Read(out buf2); Blocking_ = buf2; }
public static List<U16Vec2> MakePath(bool[,] blockMatrix, U16Vec2 from, U16Vec2 to, bool destIsBlocked) { UnityEngine.Debug.Assert(from != to); ushort height = (ushort)blockMatrix.GetLength(0); ushort width = (ushort)blockMatrix.GetLength(1); List<U16Vec2> path = new List<U16Vec2>(); List<DistCoordPair> queue = new List<DistCoordPair>(); queue.Add(new DistCoordPair() { Dist = 1, Coord = from }); do { U16Vec2 cur = queue[0].Coord; blockMatrix[cur.Y, cur.X] = true; path.Add(cur); if (queue[0].Dist == 0) return path; else { queue.RemoveAt(0); for (byte i = 0; i < 6; ++i) { S32Vec2 node = HexNavigHelper.GetNeighborMapCoords(cur, (TurnedHexDirection)i); if (node.Y >= 0 && node.Y < height && node.X >= 0 && node.X < width && !blockMatrix[node.Y, node.X]) { queue.Add(new DistCoordPair() { Dist = HexNavigHelper.Distance(node, to, true), Coord = (U16Vec2)node }); blockMatrix[node.Y, node.X] = true; } else if (destIsBlocked && node == to) return path; } queue.Sort((a, b) => a.Dist - b.Dist); } } while (queue.Count != 0); UnityEngine.Debug.Log("No path"); return null; }
void Update() { if (MakingTurn) { if (MoveTime > 0) { float tstep = MoveTime / Time.deltaTime; MoveTime -= Time.deltaTime; //TODO Возможно стоит сохранять значение из GetTransformPosFromMapPos(MapCoords,World.IsCurrentMapLocal())), так как это улучшит(?) производительность if (GameObject.FindWithTag("World/World").GetComponent<World>().IsCurrentMapLocal()) { float dstep = Vector2.Distance(transform.position, WorldVisualizer.GetTransformPosFromMapPos(NextMovePoint)) / tstep; transform.position = Vector2.MoveTowards(transform.position, WorldVisualizer.GetTransformPosFromMapPos(NextMovePoint), dstep); } else { float dstep = Vector2.Distance(transform.position, WorldVisualizer.GetTransformPosFromMapPos(GlobalPos)) / tstep; transform.position = Vector2.MoveTowards(transform.position, WorldVisualizer.GetTransformPosFromMapPos(GlobalPos), dstep); } EventManager.OnPlayerObjectMove(); } else if (Path.Count != 0) { NextMovePoint = Path.Pop(); MoveTime = MoveAnimTime; } else if (RemainingMoves == 0) { MakingTurn = false; EventManager.OnLivingBeingEndTurn(); } else if (!BluesRendered) { GameObject.FindWithTag("World/World").GetComponent<World>().RerenderBlueHexesOnLocal(); BluesRendered = true; } } }
void Update() { if (MakingTurn) { if (MoveTime > 0) { float tstep = MoveTime / Time.deltaTime; MoveTime -= Time.deltaTime; float dstep = Vector2.Distance(transform.position, WorldVisualizer.GetTransformPosFromMapPos(NextMovePoint)) / tstep; transform.position = Vector2.MoveTowards(transform.position, WorldVisualizer.GetTransformPosFromMapPos(NextMovePoint), dstep); } else if (MovePath.Count != 0) { MoveTime = MoveAnimTime; NextMovePoint = MovePath.Pop(); if (transform.position.x - WorldVisualizer.GetTransformPosFromMapPos(NextMovePoint).x > 0) transform.rotation = new Quaternion(0, 180, 0, 0); else transform.rotation = Quaternion.identity; } else { Animator.SetBool("Moving", false); if (RemainingMoves == 0) { MakingTurn = false; EventManager.OnLivingBeingEndTurn(); } else Think(); } } }
/// <summary> /// Подсчитывает сколько рядом "рек". /// </summary> /// <returns>Число хексов вокруг, занятых рекой.</returns> /// <param name="y"> y координата.</param> /// <param name="x"> x координата.</param> /// <param name="matrix">Карта рек.</param> /// Функция подсчитывает количство соседних клеток, помеченных как "Река" или находящихся в "стеке реки" /// TODO Проверить работу стека реки static byte RiverNeighbours(U16Vec2 pos, TerrainType[,] terrainMatrix) { ushort height = (ushort)terrainMatrix.GetLength(0); ushort width = (ushort)terrainMatrix.GetLength(1); byte k = (byte)(pos.X & 1); //TODO Провести рефакторинг. byte riversCount = 0; if (pos.Y > 0 && pos.X > 0 && ((terrainMatrix[pos.Y - (k ^ 1), pos.X - 1] & TerrainType.RIVER) != TerrainType.NONE || RiverStack.Contains(new U16Vec2((ushort)(pos.X - 1), (ushort)(pos.Y - (k ^ 1)))))) riversCount++; if (pos.X > 0 && pos.Y < height - 1 && ((terrainMatrix[pos.Y + k, pos.X - 1] & TerrainType.RIVER) != TerrainType.NONE || RiverStack.Contains(new U16Vec2((ushort)(pos.X - 1), (ushort)(pos.Y + k))))) riversCount++; if (pos.Y > 0 && ((terrainMatrix[pos.Y - 1, pos.X] & TerrainType.RIVER) != TerrainType.NONE || RiverStack.Contains(new U16Vec2(pos.X, (ushort)(pos.Y - 1))))) riversCount++; if (pos.Y < height - 1 && ((terrainMatrix[pos.Y + 1, pos.X] & TerrainType.RIVER) != TerrainType.NONE || RiverStack.Contains(new U16Vec2(pos.X, (ushort)(pos.Y + 1))))) riversCount++; if (pos.Y > 0 && pos.X < width - 1 && ((terrainMatrix[pos.Y - (k ^ 1), pos.X + 1] & TerrainType.RIVER) != TerrainType.NONE || RiverStack.Contains(new U16Vec2((ushort)(pos.X + 1), (ushort)(pos.Y - (k ^ 1)))))) riversCount++; if (pos.X < width - 1 && pos.Y < height - 1 && ((terrainMatrix[pos.Y + k, pos.X + 1] & TerrainType.RIVER) != TerrainType.NONE || RiverStack.Contains(new U16Vec2((ushort)(pos.X + 1), (ushort)(pos.Y + k))))) riversCount++; return riversCount; }
/// <summary> /// Выбирает направление распространения реки. /// </summary> /// <param name="y">y координата.</param> /// <param name="x">x координата.</param> /// <param name="heightMatrix">Карта высот.</param> /// <param name="matrix">Карта рек.</param> static void DirectRiver(U16Vec2 pos, float[,] heightMatrix, TerrainType[,] terrainMatrix, float flowHeightKoef) { ushort height = (ushort)heightMatrix.GetLength(0); ushort width = (ushort)heightMatrix.GetLength(1); RiverStack.Push(pos); if (pos.Y > 0 && pos.Y < height - 1 && pos.X > 0 && pos.X < width - 1) { byte limiter = 0; //Переменная, контролирующая проверку всех направлений и выход из цикла, если ни одно не подходит bool dirFound = false; byte k = (byte)(pos.X & 1); //Учитываем чётность/нечётность ряда хексов do //TODO Провести рефакторинг. { switch (Random.Range(0, 7))//Выбираем случайное направление { case (int)HexDirection.BOTTOM_LEFT: if ((limiter & 1) == 0 && !RiverStack.Contains(new U16Vec2((ushort)(pos.X - 1), (ushort)(pos.Y - (k ^ 1)))) && heightMatrix[pos.Y - (k ^ 1), pos.X - 1] * flowHeightKoef <= heightMatrix[pos.Y, pos.X] && (terrainMatrix[pos.Y - (k ^ 1), pos.X - 1] & TerrainType.RIVER) == TerrainType.NONE && RiverNeighbours(new U16Vec2((ushort)(pos.X - 1), (ushort)(pos.Y - (k ^ 1))), terrainMatrix) < 2) { DirectRiver(new U16Vec2((ushort)(pos.X - 1), (ushort)(pos.Y - (k ^ 1))), heightMatrix, terrainMatrix, flowHeightKoef); dirFound = true; } limiter |= 1; break; case (int)HexDirection.TOP_LEFT: if ((limiter & 2) == 0 && !RiverStack.Contains(new U16Vec2((ushort)(pos.X - 1), (ushort)(pos.Y + k))) && heightMatrix[pos.Y + k, pos.X - 1] * flowHeightKoef <= heightMatrix[pos.Y, pos.X] && (terrainMatrix[pos.Y + k, pos.X - 1] & TerrainType.RIVER) == TerrainType.NONE && RiverNeighbours(new U16Vec2((ushort)(pos.X - 1), (ushort)(pos.Y + k)), terrainMatrix) < 2) { DirectRiver(new U16Vec2((ushort)(pos.X - 1), (ushort)(pos.Y + k)), heightMatrix, terrainMatrix, flowHeightKoef); dirFound = true; } limiter |= 2; break; case (int)HexDirection.BOTTOM: if ((limiter & 4) == 0 && !RiverStack.Contains(new U16Vec2(pos.X, (ushort)(pos.Y - 1))) && heightMatrix[pos.Y - 1, pos.X] * flowHeightKoef <= heightMatrix[pos.Y, pos.X] && (terrainMatrix[pos.Y - 1, pos.X] & TerrainType.RIVER) == TerrainType.NONE && RiverNeighbours(new U16Vec2(pos.X, (ushort)(pos.Y - 1)), terrainMatrix) < 2) { DirectRiver(new U16Vec2(pos.X, (ushort)(pos.Y - 1)), heightMatrix, terrainMatrix, flowHeightKoef); dirFound = true; } limiter |= 4; break; case (int)HexDirection.TOP: if ((limiter & 8) == 0 && !RiverStack.Contains(new U16Vec2((ushort)pos.X, (ushort)(pos.Y + 1))) && heightMatrix[pos.Y + 1, pos.X] * flowHeightKoef <= heightMatrix[pos.Y, pos.X] && (terrainMatrix[pos.Y + 1, pos.X] & TerrainType.RIVER) == TerrainType.NONE && RiverNeighbours(new U16Vec2(pos.X, (ushort)(pos.Y + 1)), terrainMatrix) < 2) { DirectRiver(new U16Vec2(pos.X, (ushort)(pos.Y + 1)), heightMatrix, terrainMatrix, flowHeightKoef); dirFound = true; } limiter |= 8; break; case (int)HexDirection.BOTTOM_RIGHT: if ((limiter & 16) == 0 && !RiverStack.Contains(new U16Vec2((ushort)(pos.X + 1), (ushort)(pos.Y - (k ^ 1)))) && heightMatrix[pos.Y - (k ^ 1), pos.X + 1] * flowHeightKoef <= heightMatrix[pos.Y, pos.X] && (terrainMatrix[pos.Y - (k ^ 1), pos.X + 1] & TerrainType.RIVER) == TerrainType.NONE && RiverNeighbours(new U16Vec2((ushort)(pos.X + 1), (ushort)(pos.Y - (k ^ 1))), terrainMatrix) < 2) { DirectRiver(new U16Vec2((ushort)(pos.X + 1), (ushort)(pos.Y - (k ^ 1))), heightMatrix, terrainMatrix, flowHeightKoef); dirFound = true; } limiter |= 16; break; case (int)HexDirection.TOP_RIGHT: if ((limiter & 32) == 0 && !RiverStack.Contains(new U16Vec2((ushort)(pos.X + 1), (ushort)(pos.Y + k))) && heightMatrix[pos.Y + k, pos.X + 1] * flowHeightKoef <= heightMatrix[pos.Y, pos.X] && (terrainMatrix[pos.Y + k, pos.X + 1] & TerrainType.RIVER) == TerrainType.NONE && RiverNeighbours(new U16Vec2((ushort)(pos.X + 1), (ushort)(pos.Y + k)), terrainMatrix) < 2) { DirectRiver(new U16Vec2((ushort)(pos.X + 1), (ushort)(pos.Y + k)), heightMatrix, terrainMatrix, flowHeightKoef); dirFound = true; } limiter |= 32; break; } } while (!dirFound && limiter != 63); } }
void MoveObject(LocalPos from, LocalPos to) { KeyValuePair<ushort, Entity> obj = ObjectMatrix[from.Y, from.X].Single(o => o.Value.Pos != from); ObjectMatrix[to.Y, to.X].Add(obj.Key, obj.Value); ObjectMatrix[from.Y, from.X].Remove(obj.Key); }
public static event TwoLocalPosDelegate CreatureMoved = delegate { }; //TODO Возможно, это событие будет ненужно потом. public static void OnCreatureMove(LocalPos from, LocalPos to)//C#6.0 EBD { CreatureMoved(from, to); }
void HighlightHex(LocalPos pos) { BluesType hex = new BluesType { Hex = Instantiate(InteractableHex, GetTransformPosFromMapPos(pos), Quaternion.Euler(0, 0, 90)) as GameObject, InSign = true }; hex.Hex.GetComponent<HexInteraction>().Pos = pos; RenderedBlues.Add(hex); }
//UNDONE Sprite ChooseHexSprite(LocalPos pos, LocalMap map) { byte id = 0; for (byte i = 0; i < LocalMapParam.Terrains.Length; ++i) if ((map.TerrainMatrix[pos.Y, pos.X] & LocalMapParam.Terrains[i].TerrainType) != TerrainType.NONE) { for (byte j = 0; j < i; ++j, id += (byte)LocalMapParam.Terrains[j].Sprites.Length) ; id += (byte)Random.Range(0, LocalMapParam.Terrains[i].Sprites.Length); } map.HexSpriteID_Matrix[pos.Y, pos.X] = id; return AllLocalHexSprites[id]; }
//TODO К оптимизации. Sprite ChooseHexRoadSprite(Transform spriteTransform, LocalPos pos, Chunk map) { foreach (List<LocalPos> road in map.Roads) { byte id; short angle; short index = (short)road.IndexOf(pos); if (index != -1) { Vector2 inchunkPos = GetTransformPosFromMapPos((GlobalPos)pos); if (index == 0) { id = (byte)((map.TerrainMatrix[pos.Y, pos.X] & TerrainType.RIVER) != TerrainType.NONE ? Random.Range(0, GlobalMapParam.RoadStraightBridgeSprites.Length) + GlobalMapParam.RoadStraightSprites.Length + GlobalMapParam.RoadTurnSprites.Length : Random.Range(0, GlobalMapParam.RoadStraightSprites.Length)); angle = (short)(Mathf.Sign(road[1].X - pos.X) * Vector2.Angle(Vector2.down, GetTransformPosFromMapPos((GlobalPos)road[1]) - inchunkPos)); } else if (index == road.Count - 1) { id = (byte)((map.TerrainMatrix[pos.Y, pos.X] & TerrainType.RIVER) != TerrainType.NONE ? Random.Range(0, GlobalMapParam.RoadStraightBridgeSprites.Length) + GlobalMapParam.RoadStraightSprites.Length + GlobalMapParam.RoadTurnSprites.Length : Random.Range(0, GlobalMapParam.RoadStraightSprites.Length)); angle = (short)(Mathf.Sign(road[road.Count - 2].X - pos.X) * Vector2.Angle(Vector2.down, GetTransformPosFromMapPos((GlobalPos)road[road.Count - 2]) - inchunkPos)); } else { Vector2 prev = GetTransformPosFromMapPos((GlobalPos)road[index - 1]) - inchunkPos; Vector2 next = GetTransformPosFromMapPos((GlobalPos)road[index + 1]) - inchunkPos; if ((short)Vector2.Angle(prev, next) > 150) //(==180, !=120) { id = (byte)((map.TerrainMatrix[pos.Y, pos.X] & TerrainType.RIVER) != TerrainType.NONE ? Random.Range(0, GlobalMapParam.RoadStraightBridgeSprites.Length) + GlobalMapParam.RoadStraightSprites.Length + GlobalMapParam.RoadTurnSprites.Length : Random.Range(0, GlobalMapParam.RoadStraightSprites.Length)); angle = (short)(Mathf.Sign(road[index - 1].X - pos.X) * Vector2.Angle(Vector2.down, prev)); } else { id = (byte)((map.TerrainMatrix[pos.Y, pos.X] & TerrainType.RIVER) != TerrainType.NONE ? Random.Range(0, GlobalMapParam.RoadTurnBridgeSprites.Length) + GlobalMapParam.RoadStraightSprites.Length + GlobalMapParam.RoadTurnSprites.Length + GlobalMapParam.RoadStraightBridgeSprites.Length : Random.Range(0, GlobalMapParam.RoadTurnSprites.Length) + GlobalMapParam.RoadStraightSprites.Length); angle = (short)(Mathf.Sign(road[index - 1].X - pos.X) * Vector2.Angle(Vector2.down, prev)); if (Mathf.Approximately(prev.x, 0)) angle += (short)(240 * (Mathf.Sign(prev.y) == Mathf.Sign(next.x) ? 1 : 0)); else angle += (short)(240 * (Mathf.Sign(prev.x) != Mathf.Sign(next.y) ? 1 : 0)); } } } else continue; map.RoadSpriteID_Matrix[pos.Y, pos.X] = id; map.RoadSpriteRotationMatrix[pos.Y, pos.X] = angle; spriteTransform.Rotate(0, 0, angle); return AllRoadSprites[id]; ; } return null; }
public void RenderBluesHexes(LocalPos pos, byte distance, LocalMap map) { Debug.Assert(distance != 0); RenderedBlues.ForEach(hex => hex.InSign = false); for (byte i = 0; i < 6; ++i) { GlobalPos buf = HexNavigHelper.GetNeighborMapCoords(pos, (TurnedHexDirection)i); if (buf.X >= 0 && buf.Y >= 0 && buf.X < map.Width && buf.Y < map.Height && !map.IsBlocked((LocalPos)buf)) BluesSignQueue.Enqueue(new QueueType { Pos = buf, Distance = (byte)(distance - 1) }); } while (BluesSignQueue.Count != 0) { QueueType buf = BluesSignQueue.Dequeue(); SpreadBlues((LocalPos)buf.Pos, buf.Distance, map); } for (ushort i = 0; i < RenderedBlues.Count; ++i) if (!RenderedBlues[i].InSign) { Destroy(RenderedBlues[i].Hex); RenderedBlues.RemoveAt(i); if (i != 0) i--; } }
public void MoveTo(LocalPos pos) { State = AI_State.MOVE; TargetPos = pos; }
/// <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); }
public bool IsHexFree(LocalPos pos) { if (IsCurrentMapLocal())//Временно return (CurrentMap as LocalMap).Contains(pos) && !(CurrentMap as LocalMap).IsBlocked(pos); return true; }
/// <summary> /// Создаёт лес на хексе. /// </summary> /// <param name="hex">Хекс.</param> /// <param name="mapCoords">Координаты в матрице.</param> void MakeHexForest(ListType hex, LocalPos pos, Chunk map) { Vector2 spriteSize = hex.Hex.GetComponent<SpriteRenderer>().sprite.bounds.size; if (map.ForestMatrix[pos.Y, pos.X] >= 1) //TODO { float gridStepX = spriteSize.x / ForestGenGridSize; float gridStepY = spriteSize.y / ForestGenGridSize; Vector2 gridOrigin = new Vector2(hex.Hex.transform.position.x - spriteSize.x * 0.375f, hex.Hex.transform.position.y - spriteSize.y * 0.5f); //TODO new? byte treesCount = (byte)map.ForestMatrix[pos.Y, pos.X]; while (true) { if (treesCount > ForestGenGridSize * ForestGenGridSize) { for (float y = 0; y < spriteSize.y; y += gridStepY) for (float x = 0; x < spriteSize.x; x += gridStepX) { Vector2 v = new Vector2(Random.value * gridStepX, Random.value * gridStepY); //TODO new? GameObject tree = new GameObject("treeSprite"); tree.transform.position = new Vector2(gridOrigin.x + x + v.x, gridOrigin.y + y + v.y); tree.transform.parent = hex.Hex.transform; tree.AddComponent<SpriteRenderer>().sortingLayerName = "LandscapeObjects";// tree.GetComponent<SpriteRenderer>().sprite = GlobalMapParam.TreeSprites[Random.Range(0, GlobalMapParam.TreeSprites.Length)]; tree.GetComponent<SpriteRenderer>().material = DiffuseMaterial; tree.AddComponent<Fader>(); --treesCount; } } else { Vector2 v = Random.insideUnitCircle; v.x *= spriteSize.x * 0.5f; v.y *= spriteSize.y * 0.5f; GameObject tree = new GameObject("treeSprite"); tree.transform.position = new Vector2(hex.Hex.transform.position.x + v.x, hex.Hex.transform.position.y + v.y); tree.transform.parent = hex.Hex.transform; tree.AddComponent<SpriteRenderer>().sortingLayerName = "LandscapeObjects";// tree.GetComponent<SpriteRenderer>().sprite = GlobalMapParam.TreeSprites[Random.Range(0, GlobalMapParam.TreeSprites.Length)]; tree.GetComponent<SpriteRenderer>().material = DiffuseMaterial; tree.AddComponent<Fader>(); --treesCount; if (treesCount == 0) return; } } } }
//C#6.0 EBD public bool IsBlocked(LocalPos coords) { return ObjectMatrix[coords.Y, coords.X].Any(o => o.Value.Blocking); }
/// <summary> /// Создаёт спрайты, необходимые для отображения хекса. /// </summary> /// <param name="hex">Хекс.</param> /// <param name="mapCoords">Координаты в матрице.</param> void MakeHexGraphics(ListType hex, LocalPos pos, Chunk map) { if (map.HexSpriteID_Matrix[pos.Y, pos.X].HasValue /*?*/&& map.HexSpriteID_Matrix[pos.Y, pos.X] < AllGlobalHexSprites.Count) hex.Hex.GetComponent<SpriteRenderer>().sprite = AllGlobalHexSprites[map.HexSpriteID_Matrix[pos.Y, pos.X].Value]; else hex.Hex.GetComponent<SpriteRenderer>().sprite = ChooseHexSprite(pos, map); hex.Hex.GetComponent<SpriteRenderer>().sortingLayerName = "Landscape";// bool forestBlocked = false; if ((map.TerrainMatrix[pos.Y, pos.X] & TerrainType.RIVER) != TerrainType.NONE) { GameObject riverSprite = new GameObject("riverSprite"); riverSprite.transform.position = hex.Hex.transform.position; riverSprite.transform.parent = hex.Hex.transform; riverSprite.AddComponent<SpriteRenderer>().sortingLayerName = "LandscapeObjects"; riverSprite.GetComponent<SpriteRenderer>().material = DiffuseMaterial; if (map.RiverSpriteID_Matrix[pos.Y, pos.X].HasValue && map.RiverSpriteID_Matrix[pos.Y, pos.X] < AllRiverSprites.Count) { riverSprite.GetComponent<SpriteRenderer>().sprite = AllRiverSprites[map.RiverSpriteID_Matrix[pos.Y, pos.X].Value]; riverSprite.transform.Rotate(0, 0, map.RiverSpriteRotationMatrix[pos.Y, pos.X]); } else riverSprite.GetComponent<SpriteRenderer>().sprite = ChooseHexRiverSprite(riverSprite.transform, pos, map); riverSprite.AddComponent<Fader>(); forestBlocked = true; } if ((map.TerrainMatrix[pos.Y, pos.X] & TerrainType.BUILDING) != TerrainType.NONE) { GameObject clusterSprite = new GameObject("clusterSprite"); clusterSprite.transform.position = hex.Hex.transform.position; clusterSprite.transform.parent = hex.Hex.transform; clusterSprite.AddComponent<SpriteRenderer>().sortingLayerName = "Infrastructure"; clusterSprite.GetComponent<SpriteRenderer>().material = DiffuseMaterial; if (!map.ClusterSpriteID_Matrix[pos.Y, pos.X].HasValue || map.ClusterSpriteID_Matrix[pos.Y, pos.X] >= GlobalMapParam.RuinSprites.Length) map.ClusterSpriteID_Matrix[pos.Y, pos.X] = (byte)Random.Range(0, GlobalMapParam.RuinSprites.Length); clusterSprite.GetComponent<SpriteRenderer>().sprite = GlobalMapParam.RuinSprites[map.ClusterSpriteID_Matrix[pos.Y, pos.X].Value]; clusterSprite.AddComponent<Fader>(); forestBlocked = true; } if ((map.TerrainMatrix[pos.Y, pos.X] & TerrainType.ROAD) != TerrainType.NONE) { GameObject roadSprite = new GameObject("roadSprite"); roadSprite.transform.position = hex.Hex.transform.position; roadSprite.transform.parent = hex.Hex.transform; roadSprite.AddComponent<SpriteRenderer>().sortingLayerName = "Infrastructure"; roadSprite.GetComponent<SpriteRenderer>().material = DiffuseMaterial; if (map.RoadSpriteID_Matrix[pos.Y, pos.X].HasValue /*?*/ && map.RoadSpriteID_Matrix[pos.Y, pos.X] < AllRiverSprites.Count) { roadSprite.GetComponent<SpriteRenderer>().sprite = AllRoadSprites[map.RoadSpriteID_Matrix[pos.Y, pos.X].Value]; roadSprite.transform.Rotate(0, 0, map.RoadSpriteRotationMatrix[pos.Y, pos.X]); } else roadSprite.GetComponent<SpriteRenderer>().sprite = ChooseHexRoadSprite(roadSprite.transform, pos, map); roadSprite.AddComponent<Fader>(); forestBlocked = true; } if (!forestBlocked) MakeHexForest(hex, pos, map); hex.Hex.GetComponent<Fader>().FadeIn(FadeInTime); for (ushort j = 0; j < hex.Hex.transform.childCount; ++j) hex.Hex.transform.GetChild(j).gameObject.GetComponent<Fader>().FadeIn(FadeInTime); }
void MakeHexGraphics(ListType hex, LocalPos pos, LocalMap map) { if (map.HexSpriteID_Matrix[pos.Y, pos.X].HasValue /*?*/&& map.HexSpriteID_Matrix[pos.Y, pos.X] < AllLocalHexSprites.Count) hex.Hex.GetComponent<SpriteRenderer>().sprite = AllLocalHexSprites[map.HexSpriteID_Matrix[pos.Y, pos.X].Value]; else hex.Hex.GetComponent<SpriteRenderer>().sprite = ChooseHexSprite(pos, map); hex.Hex.GetComponent<SpriteRenderer>().sortingLayerName = "Landscape";// if ((map.TerrainMatrix[pos.Y, pos.X] & TerrainType.WATER) != TerrainType.NONE) //float offsetbuf=(LocalHexSpriteSize.pos.X-LocalHexSpriteSize.y)/2; for (byte i = 0; i < 6; ++i) //TODO К оптимизации. if (map.Contains(HexNavigHelper.GetNeighborMapCoords(pos, (TurnedHexDirection)i)) && (map.TerrainMatrix[HexNavigHelper.GetNeighborMapCoords(pos, (TurnedHexDirection)i).Y, HexNavigHelper.GetNeighborMapCoords(pos, (TurnedHexDirection)i).X] & TerrainType.WATER) == TerrainType.NONE) { GameObject bank = new GameObject("bankSprite"); bank.transform.position = hex.Hex.transform.position; bank.transform.parent = hex.Hex.transform; bank.AddComponent<SpriteRenderer>().sortingLayerName = "LandscapeObjects"; if ((TurnedHexDirection)i == TurnedHexDirection.LEFT || (TurnedHexDirection)i == TurnedHexDirection.RIGHT) { bank.GetComponent<SpriteRenderer>().sprite = LocalMapParam.BankSprites[Random.Range(0, LocalMapParam.BankSprites.Length)]; if ((TurnedHexDirection)i == TurnedHexDirection.RIGHT) bank.transform.Rotate(0, 0, 180); } else { bank.GetComponent<SpriteRenderer>().sprite = LocalMapParam.DiagBankSprites[Random.Range(0, LocalMapParam.DiagBankSprites.Length)]; switch ((TurnedHexDirection)i) { case TurnedHexDirection.RIGHT_TOP: bank.transform.Rotate(0, 180, 0); break; case TurnedHexDirection.RIGHT_BOTTOM: bank.transform.Rotate(180, 180, 0); break; case TurnedHexDirection.LEFT_BOTTOM: bank.transform.Rotate(180, 0, 0); break; } } //float offset=((TurnedHexDirection)i==TurnedHexDirection.LEFT_TOP||(TurnedHexDirection)i==TurnedHexDirection.LEFT_BOTTOM)? -offsetbuf:offsetbuf; //bank.transform.position = new Vector3(hex.Hex.transform.position.pos.X+offset,hex.Hex.transform.position.y,hex.Hex.transform.position.z); //bank.transform.Rotate(0, 0, (short)(Mathf.Sign(mapCoords.y - HexNavigHelper.GetNeighborMapCoords(mapCoords, (TurnedHexDirection)i).y) * Vector2.Angle(Vector2.left,new Vector2(GetTransformPosFromMapPos(HexNavigHelper.GetNeighborMapCoords(mapCoords, (TurnedHexDirection)i), true).pos.X-offset,GetTransformPosFromMapPos(HexNavigHelper.GetNeighborMapCoords(mapCoords, (TurnedHexDirection)i), true).y) - (Vector2)bank.transform.position))); bank.GetComponent<SpriteRenderer>().material = DiffuseMaterial; bank.AddComponent<Fader>(); } hex.Hex.GetComponent<Fader>().FadeIn(FadeInTime); for (ushort j = 0; j < hex.Hex.transform.childCount; ++j) hex.Hex.transform.GetChild(j).gameObject.GetComponent<Fader>().FadeIn(FadeInTime); }
void SpreadBlues(LocalPos pos, byte distance, LocalMap map) { short index = (short)RenderedBlues.FindIndex(x => x.Hex.GetComponent<HexInteraction>().Pos == pos); if (index == -1) HighlightHex(pos); else { if (RenderedBlues[index].InSign) return; else RenderedBlues[index].InSign = true; } if (distance != 0) { for (byte i = 0; i < 6; ++i) { GlobalPos buf = HexNavigHelper.GetNeighborMapCoords(pos, (TurnedHexDirection)i); if (buf.X >= 0 && buf.Y >= 0 && buf.X < map.Width && buf.Y < map.Height && !map.IsBlocked((LocalPos)buf)) BluesSignQueue.Enqueue(new QueueType { Pos = buf, Distance = (byte)(distance - 1) }); } } }
public static void MakeEqualHeightLine(float[,] matrix, U16Vec2[] vertices, float height) { foreach (U16Vec2 v in vertices) if (v.X >= matrix.GetLength(1) || v.Y >= matrix.GetLength(0)) throw new System.ArgumentOutOfRangeException("vertices", v.ToString(), "Vector is out of matrix length."); for (byte i = 0; i < vertices.Length - 1; ++i) { S32Vec2 v = vertices[i]; while (v != vertices[i + 1]) { matrix[v.Y, v.X] = height; v.Y += Mathf.Clamp(vertices[i + 1].Y - v.Y, -1, 1); v.X += Mathf.Clamp(vertices[i + 1].X - v.X, -1, 1); } } matrix[vertices[vertices.Length - 1].Y, vertices[vertices.Length - 1].X] = height; }
//C#6.0 EBD /// <summary> /// Вычисляет координаты в сцене из координат на карте. /// </summary> /// <returns>Координаты в сцене.</returns> /// <param name="mapCoords">Координаты на карте.</param> public static Vector2 GetTransformPosFromMapPos(LocalPos pos) { return new Vector2(pos.X * LocalHexSpriteSize.x + (pos.Y & 1) * LocalHexSpriteSize.x * 0.5f, pos.Y * LocalHexSpriteSize.y * 0.75f); }
static void DirectRoad(float[,] heightMatrix, TerrainType[,] terrainMatrix, U16Vec2 pos, U16Vec2 destination, List<U16Vec2> road, GlobalTerrainSettings.RoadsSettings roadsParam) { ushort height = (ushort)heightMatrix.GetLength(0); ushort width = (ushort)heightMatrix.GetLength(1); road.Add(pos); terrainMatrix[pos.Y, pos.X] |= TerrainType.ROAD; if (pos.Y > 0 && pos.Y < height - 1 && pos.X > 0 && pos.X < width - 1 && !(destination.X == pos.X && destination.Y == pos.Y)) { byte k = (byte)(pos.X & 1); //TODO Провести рефакторинг. float max = heightMatrix[pos.Y + k, pos.X - 1], avg = 0; float cur = heightMatrix[pos.Y + k, pos.X - 1]; avg += cur; cur = heightMatrix[pos.Y + 1, pos.X]; if (max < cur) max = cur; avg += cur; cur = heightMatrix[pos.Y + k, pos.X + 1]; if (max < cur) max = cur; avg += cur; cur = heightMatrix[pos.Y - 1 + k, pos.X + 1]; if (max < cur) max = cur; avg += cur; cur = heightMatrix[pos.Y - 1, pos.X]; if (max < cur) max = cur; avg += cur; cur = heightMatrix[pos.Y - 1 + k, pos.X - 1]; if (max < cur) max = cur; avg += cur; avg /= 6; max += 0.0001f; //! float weight = 0, buf; sbyte dx = 0, dy = 0; if (!road.Contains(new U16Vec2((ushort)(pos.X - 1), (ushort)(pos.Y + k))) && ((buf = (Mathf.Abs(destination.X - pos.X) - Mathf.Abs(destination.X - (pos.X - 1)) + Mathf.Abs(destination.Y - pos.Y) - Mathf.Abs(destination.Y - (pos.Y + k)) + 3) * (max - Mathf.Abs(heightMatrix[pos.Y + k, pos.X - 1] - avg))) * ((terrainMatrix[pos.Y + k, pos.X - 1] & TerrainType.ROAD) != TerrainType.NONE ? roadsParam.RoadMergeMultiplier : 1) * ((terrainMatrix[pos.Y, pos.X] & terrainMatrix[pos.Y + k, pos.X - 1] & TerrainType.RIVER) != TerrainType.NONE ? roadsParam.GoingAlongRiverMultiplier : 1) > weight)) { weight = buf; dx = -1; dy = (sbyte)k; } if (!road.Contains(new U16Vec2((ushort)(pos.X + 1), (ushort)(pos.Y + k))) && ((buf = (Mathf.Abs(destination.X - pos.X) - Mathf.Abs(destination.X - (pos.X + 1)) + Mathf.Abs(destination.Y - pos.Y) - Mathf.Abs(destination.Y - (pos.Y + k)) + 3) * (max - Mathf.Abs(heightMatrix[pos.Y + k, pos.X + 1] - avg))) * ((terrainMatrix[pos.Y + k, pos.X + 1] & TerrainType.ROAD) != TerrainType.NONE ? roadsParam.RoadMergeMultiplier : 1) * ((terrainMatrix[pos.Y, pos.X] & terrainMatrix[pos.Y + k, pos.X + 1] & TerrainType.RIVER) != TerrainType.NONE ? roadsParam.GoingAlongRiverMultiplier : 1) > weight)) { weight = buf; dx = 1; dy = (sbyte)k; } if (!road.Contains(new U16Vec2(pos.X, (ushort)(pos.Y + 1))) && ((buf = (Mathf.Abs(destination.Y - pos.Y) - Mathf.Abs(destination.Y - (pos.Y + 1)) + 3) * (max - Mathf.Abs(heightMatrix[pos.Y + 1, pos.X] - avg))) * ((terrainMatrix[pos.Y + 1, pos.X] & TerrainType.ROAD) != TerrainType.NONE ? roadsParam.RoadMergeMultiplier : 1) * ((terrainMatrix[pos.Y, pos.X] & terrainMatrix[pos.Y + 1, pos.X] & TerrainType.RIVER) != TerrainType.NONE ? roadsParam.GoingAlongRiverMultiplier : 1) > weight))//!После диагонали { weight = buf; dx = 0; dy = 1; } if (!road.Contains(new U16Vec2((ushort)(pos.X + 1), (ushort)(pos.Y - (k ^ 1)))) && ((buf = (Mathf.Abs(destination.X - pos.X) - Mathf.Abs(destination.X - (pos.X + 1)) + Mathf.Abs(destination.Y - pos.Y) - Mathf.Abs(destination.Y - (pos.Y - (k ^ 1))) + 3) * (max - Mathf.Abs(heightMatrix[pos.Y - (k ^ 1), pos.X + 1] - avg))) * ((terrainMatrix[pos.Y - (k ^ 1), pos.X + 1] & TerrainType.ROAD) != TerrainType.NONE ? roadsParam.RoadMergeMultiplier : 1) * ((terrainMatrix[pos.Y, pos.X] & terrainMatrix[pos.Y - (k ^ 1), pos.X + 1] & TerrainType.RIVER) != TerrainType.NONE ? roadsParam.GoingAlongRiverMultiplier : 1) > weight)) { weight = buf; dx = 1; dy = (sbyte)(-(k ^ 1)); } if (!road.Contains(new U16Vec2((ushort)(pos.X - 1), (ushort)(pos.Y - (k ^ 1)))) && ((buf = (Mathf.Abs(destination.X - pos.X) - Mathf.Abs(destination.X - (pos.X - 1)) + Mathf.Abs(destination.Y - pos.Y) - Mathf.Abs(destination.Y - (pos.Y - (k ^ 1))) + 3) * (max - Mathf.Abs(heightMatrix[pos.Y - (k ^ 1), pos.X - 1] - avg))) * ((terrainMatrix[pos.Y - (k ^ 1), pos.X - 1] & TerrainType.ROAD) != TerrainType.NONE ? roadsParam.RoadMergeMultiplier : 1) * ((terrainMatrix[pos.Y, pos.X] & terrainMatrix[pos.Y - (k ^ 1), pos.X - 1] & TerrainType.RIVER) != TerrainType.NONE ? roadsParam.GoingAlongRiverMultiplier : 1) > weight)) { weight = buf; dx = -1; dy = (sbyte)(-(k ^ 1)); } if (!road.Contains(new U16Vec2(pos.X, (ushort)(pos.Y - 1))) && ((buf = (Mathf.Abs(destination.Y - pos.Y) - Mathf.Abs(destination.Y - (pos.Y - 1)) + 3) * (max - Mathf.Abs(heightMatrix[pos.Y - 1, pos.X] - avg))) * ((terrainMatrix[pos.Y - 1, pos.X] & TerrainType.ROAD) != TerrainType.NONE ? roadsParam.RoadMergeMultiplier : 1) * ((terrainMatrix[pos.Y, pos.X] & terrainMatrix[pos.Y - 1, pos.X] & TerrainType.RIVER) != TerrainType.NONE ? roadsParam.GoingAlongRiverMultiplier : 1) > weight))//!После диагонали { weight = buf; dx = 0; dy = -1; } if (dx == 0 && dy == 0) throw new System.Exception("Infinite recursion detected. Try to check heightmap values."); DirectRoad(heightMatrix, terrainMatrix, new U16Vec2((ushort)(pos.X + dx), (ushort)(pos.Y + dy)), destination, road, roadsParam); } }
public void MoveTo(LocalPos pos) { List<LocalPos> buf = Pathfinder.MakePath((GameObject.FindWithTag("World/World").GetComponent<World>().CurrentMap as LocalMap).GetBlockMatrix(), Pos, pos, false);//TODO Тут? buf.Reverse(); Path = new Stack<LocalPos>(buf); Path.Pop(); LocalPos pBuf = Pos; Pos = pos; EventManager.OnCreatureMove(pBuf, pos); RemainingMoves -= (byte)Path.Count; EventManager.OnBluesUnrender(); }
static void SpreadCluster(Chunk map, U16Vec2 pos, byte remainingSize, List<U16Vec2> cluster) { ushort height = map.Height; ushort width = map.Width; cluster.Add(pos); map.TerrainMatrix[pos.Y, pos.X] |= TerrainType.BUILDING; if (pos.Y > 0 && pos.Y < height - 1 && pos.X > 0 && pos.X < width - 1 && remainingSize != 0) { byte k = (byte)(pos.X & 1); //TODO Провести рефакторинг. if ((map.TerrainMatrix[pos.Y - (k ^ 1), pos.X - 1] & (TerrainType.RIVER | TerrainType.BUILDING)) == TerrainType.NONE) SpreadCluster(map, new U16Vec2((ushort)(pos.X - 1), (ushort)(pos.Y - (k ^ 1))), (byte)(remainingSize - 1), cluster); if ((map.TerrainMatrix[pos.Y + k, pos.X - 1] & (TerrainType.RIVER | TerrainType.BUILDING)) == TerrainType.NONE) SpreadCluster(map, new U16Vec2((ushort)(pos.X - 1), (ushort)(pos.Y + k)), (byte)(remainingSize - 1), cluster); if ((map.TerrainMatrix[pos.Y - 1, pos.X] & (TerrainType.RIVER | TerrainType.BUILDING)) == TerrainType.NONE) SpreadCluster(map, new U16Vec2(pos.X, (ushort)(pos.Y - 1)), (byte)(remainingSize - 1), cluster); if ((map.TerrainMatrix[pos.Y + 1, pos.X] & (TerrainType.RIVER | TerrainType.BUILDING)) == TerrainType.NONE) SpreadCluster(map, new U16Vec2(pos.X, (ushort)(pos.Y + 1)), (byte)(remainingSize - 1), cluster); if ((map.TerrainMatrix[pos.Y - (k ^ 1), pos.X + 1] & (TerrainType.RIVER | TerrainType.BUILDING)) == TerrainType.NONE) SpreadCluster(map, new U16Vec2((ushort)(pos.X + 1), (ushort)(pos.Y - (k ^ 1))), (byte)(remainingSize - 1), cluster); if ((map.TerrainMatrix[pos.Y + k, pos.X + 1] & (TerrainType.RIVER | TerrainType.BUILDING)) == TerrainType.NONE) SpreadCluster(map, new U16Vec2((ushort)(pos.X + 1), (ushort)(pos.Y + k)), (byte)(remainingSize - 1), cluster); } }
void Think() { switch (State) { case AI_State.IDLE: if (AggressiveTo != AggrTarget.NONE) { LivingBeing target = FindTarget(); if (target != null) { Fighting = true; Attack(target); Think(); } else { GlobalPos pos; do pos = HexNavigHelper.GetNeighborMapCoords(Pos, (TurnedHexDirection)Random.Range(0, 6)); while (pos.X < 0 || pos.X >= Map.Width || pos.Y < 0 || pos.Y >= Map.Height || Map.IsBlocked((LocalPos)pos)); TargetPos = (LocalPos)pos; Move(); //MakingTurn = false; //EventManager.OnLivingBeingEndTurn(); } } else { GlobalPos pos; do pos = HexNavigHelper.GetNeighborMapCoords(Pos, (TurnedHexDirection)Random.Range(0, 6)); while (pos.X < 0 || pos.X >= Map.Width || pos.Y < 0 || pos.Y >= Map.Height || Map.IsBlocked((LocalPos)pos)); TargetPos = (LocalPos)pos; Move(); //MakingTurn = false; //EventManager.OnLivingBeingEndTurn(); } break; case AI_State.MOVE: if (TargetPos == Pos) Idle(); else Move(); break; case AI_State.ATTACK: if (AggressiveTo == AggrTarget.NONE) Idle(); else { if (TargetPos != Target.Pos) { TargetPos = Target.Pos; Path.Clear(); } if (HexNavigHelper.IsMapCoordsAdjacent(TargetPos, Pos, true)) { Path.Clear(); StartAttack(BaseWeapon.Damage, 0.75f);//TODO Временно 0.85f } else Move(); } break; } }