//Procedural generation public void Generate(BinaryNoiseFunc nonEmpty, BinaryNoiseFunc snow, bool cutEdges) { for (int i = 0; i < cellTypeCounts.Length; i++) { cellTypeCounts[i] = 0; } for (int y = 0; y < sz; y++) { for (int x = 0; x < sz; x++) { if (cutEdges && (x == 0 || y == 0 || x == sz - 1 || y == sz - 1)) { continue; } HexXY c = position + new HexXY(x, y); Vector2 p = c.ToPlaneCoordinates(); TerrainCellType type; if (nonEmpty.Get(p)) { if (snow.Get(p)) { type = TerrainCellType.Grass; } else { type = TerrainCellType.DryGround; } } else { type = TerrainCellType.Empty; } cellTypes[x, y] = type; ++cellTypeCounts[(int)type]; } } for (int x = 0; x < sz; x++) { for (int y = 0; y < sz; y++) { pfBlockedMap[x, y] = cellTypes[x, y] == TerrainCellType.Empty ? PFBlockType.EdgeBlocked : PFBlockType.Unblocked; } } }
//Trace first straight line dest and move there void MovePart() { //Debug.Log("MOVEPART " + p); uint?pathLen = Pathfinder.FindPath(pos, dest.Value, pathStorage, distToStop, 10); if (pathLen.HasValue && pathLen.Value > 0) { HexXY firstPathCell = pathStorage[0]; if (!blockedCells.Contains(firstPathCell) && Level.S.GetPFBlockedMap(firstPathCell) != WorldBlock.PFBlockType.Unblocked) { //Even first cell is blocked, just rotate there dest = null; isWalking = false; Interfacing.PerformInterfaceStop(graphicsHandle, pos); Interfacing.PerformInterfaceUpdateRotation(graphicsHandle, (uint)HexXY.neighbours.IndexOf(pathStorage[0] - pos)); } else { //Try to trace a line to these //First line that will be blocked will determine max straight-line destination //Path to first cell should not be blocked so start with second if (pathLen.Value == 1) { interDest = pathStorage[0]; interFracDest = interDest.ToPlaneCoordinates(); } else { for (int i = 1; i < pathLen.Value; i++) { HexXY inter = pathStorage[i]; //Check if straight line backwards is blocked Vector2 linePos = inter.ToPlaneCoordinates(); Vector2 lineDir = (fracPos - linePos).normalized; bool isLineBlocked = false; HexXY traced = inter; do { float minDist = float.MaxValue; float lineShift = 0; HexXY nextTraced = new HexXY(0, 0); for (int n = 0; n < 6; n++) { HexXY np = traced + HexXY.neighbours[n]; Vector2 v = np.ToPlaneCoordinates() - linePos; float lineLen = Vector2.Dot(v, lineDir); if (lineLen < 0) { continue; } float dist = (lineDir * lineLen - v).magnitude; if (dist < 0.8f) //Line intersects cell np (circle approximated, not hexagon though, and larger (should be less than cos(60)) so it will not cut walls) { if (!blockedCells.Contains(np) && Level.S.GetPFBlockedMap(np) != WorldBlock.PFBlockType.Unblocked) { isLineBlocked = true; break; } if (dist < minDist) { minDist = dist; nextTraced = np; lineShift = lineLen; } } } traced = nextTraced; linePos += lineShift * lineDir; } while (!isLineBlocked && traced != pos); if (isLineBlocked) //Choose the previous cell { interDest = pathStorage[i - 1]; interFracDest = interDest.ToPlaneCoordinates(); break; } //Got to the last cell - use it if (i == pathLen.Value - 1) { interDest = inter; interFracDest = interDest.ToPlaneCoordinates(); } } } float timeToGetThere = (fracPos - interFracDest).magnitude / speed; Interfacing.PerformInterfaceMovePrecise(graphicsHandle, interFracDest, timeToGetThere); isWalking = true; } } else { dest = null; isWalking = false; Interfacing.PerformInterfaceStop(graphicsHandle, pos); } }