public PathRequest(GridNode start, GridNode end, List<List<GridNode>> grid, Action<GridNode[], bool> callback) { pathStart = start; pathEnd = end; pathGrid = grid; this.callback = callback; }
public static void RequestPath(GridNode pathStart, GridNode pathEnd, List<List<GridNode>> pathGrid, Action<GridNode[], bool> callback) { PathRequest newRequest = new PathRequest(pathStart, pathEnd, pathGrid, callback); Instance.pathRequestQueue.Enqueue(newRequest); Instance.TryProcessNext(); }
public int getDistanceBetween(GridNode current, GridNode goal) { int dx = Math.Abs(goal.gridPositionX - current.gridPositionX); int dy = Math.Abs(goal.gridPositionY - current.gridPositionY); int h = (int)(10*Math.Sqrt(dx*dx + dy*dy)); return h; }
public int getManhattanHeuristic(GridNode current, GridNode goal) { int dx = Math.Abs(goal.gridPositionX - current.gridPositionX); int dy = Math.Abs(goal.gridPositionY - current.gridPositionY); int h = (int)(dx + dy); return h; }
public int getHeuristic(GridNode current, GridNode goal) { int dx = Math.Abs(goal.gridPositionX - current.gridPositionX); int dy = Math.Abs(goal.gridPositionY - current.gridPositionY); int h = (int)(10*(dx+dy)+(14-2*10)+Math.Min(dx,dy)); return h; }
public AStar(int width, int height) { w = width; h = height; //MAKE THE ARRAY OF COORDINATES SO THAT WE SEARCH THEM IN THE RIGHT ORDER coords = new System.Collections.Generic.List<Vector2>(); coords.Add(new Vector2(0,-1)); // UP coords.Add(new Vector2(1,0)); // RIGHT coords.Add(new Vector2(0,1)); // DOWN coords.Add(new Vector2(-1,0)); // LEFT if(allowDiagonals) { coords.Add(new Vector2(-1,-1)); // UP-LEFT coords.Add(new Vector2(1,-1)); // UP-RIGHT coords.Add(new Vector2(1,1)); // DOWN-RIGHT coords.Add(new Vector2(-1,1)); // DOWNLEFT } relCurrent = new Vector2(); relLast = new Vector2(); startNode = new GridNode(); endNode = new GridNode(); open = new NodeList(w*h); closed = new NodeList(w*h); createGrid(w,h); r = new RandomSeed(THE_SEED); }
// Use this for initialization void Start() { m_Grid = GameObject.FindGameObjectWithTag("Grid").GetComponent<Grid>(); m_target = m_Grid.GetRandGrid(); m_actor = GetComponent<IActor>(); m_path = new List<GridNode>(); }
// Use this for initialization protected void createGrid(MeshRenderer f) { // get the mesh renderer to calculate the floor bounds floor = f; floor_width = floor.bounds.size.x; floor_depth = floor.bounds.size.z; // init grid array grid = new GridNode[blockRows, blockColumns]; // calculate the block width & depth block_width = floor_width / blockRows; block_depth = floor_depth / blockColumns; // get the top left point to draw from Vector3 TopLeftPoint = new Vector3(transform.position.x - (floor_width/2), transform.position.y, transform.position.z + (floor_depth / 2)); // the current position of the new block in the loop Vector3 currentPosition = TopLeftPoint; // loop through to add the blocks (nodes) to the grid for (int i = 0; i < blockRows; i++) { for (int j = 0; j < blockColumns; j++) { grid[i, j] = new GridNode(currentPosition, new Vector2(block_width, block_depth)); // add a node at the current position currentPosition.x += block_width; // move to the right one block } // move to the next row currentPosition.x = TopLeftPoint.x; currentPosition.z -= block_depth; } }
// Update is called once per frame void Update() { Vector2 steering = Vector2.zero; GridNode m_current = m_Grid.GetGridForPosition(transform.position); if (!m_target.Passable || m_current == m_target || m_path.Count == 0) { m_target = m_Grid.GetRandGrid(); m_needToCalPath = true; } if (m_current != null && m_needToCalPath) { m_needToCalPath = false; if (m_path.Count > 0 && m_showPath) { m_path.First().Start = false; m_path.Last().End = false; foreach (GridNode node in m_path) { node.Path = false; } } AStar.GetShortestPath(m_current, m_target, m_Grid.diagnoal, out m_path); if (m_path.Count > 0 && m_showPath) { m_path.First().Start = true; m_path.Last().End = true; foreach (GridNode node in m_path) { node.Path = true; } } m_path_index = 1; } if (m_path.Count > 1) { GridNode seeking = m_path[m_path_index]; if (m_current == seeking) { m_path_index += 1; seeking = m_path[m_path_index]; } if (seeking == m_target) { Renderer renderer = seeking.GetComponent<Renderer>(); if (renderer != null) { steering = SteeringHelper.GetArriveSteering(m_actor, seeking.transform.position, renderer.bounds.size.x); } } else { steering = SteeringHelper.GetSeekSteering(m_actor, seeking.transform.position); } } m_actor.SetInput(steering.x, steering.y); }
public override void Start() { base.Start(); node = AstarPath.active.GetNearest(this.transform.position).node as GridNode; _bounds = new Bounds(transform.position, new Vector3(1.5f, 3f, 1.5f)); //_bounds.extents = new Vector3(1.5f, 3f, 1.5f); //gameObject.collider.enabled = false; }
int GetDistance(GridNode nodeA, GridNode nodeB) { int distX = Mathf.Abs(nodeA.gridX - nodeB.gridX); int distY = Mathf.Abs(nodeA.gridY - nodeB.gridY); if (distX > distY) return 14 * distY + 10 * (distX - distY); return 14 * distX + 10 * (distY - distX); }
public static List<int> connections(GridNode node) { Node[] nodes = node.connections; List<int> indexes = new List<int>(); foreach (Node n in new PerceivableNode(node)){ indexes.Add(n.GetNodeIndex()); } return indexes; }
public IEnumerator FindPath(GridNode start, GridNode end, List<List<GridNode>> grid) { List<GridNode> path; bool success = FindPathImmediate(start, end, grid, out path); yield return null; requestManager.FinishedProcessingPath(path.ToArray(), success); }
public void Arrive(GridNode i_seeking) { Vector2 steering = Vector2.zero; Renderer renderer = i_seeking.GetComponent<Renderer>(); if (renderer != null) { steering = SteeringHelper.GetArriveSteering(m_actor, i_seeking.transform.position, renderer.bounds.size.x); } m_actor.SetInput(steering.x, steering.y); }
/// <summary> /// Implement this method as an external command for Revit. /// </summary> /// <param name="commandData">An object that is passed to the external application /// which contains data related to the command, /// such as the application object and active view.</param> /// <param name="message">A message that can be set by the external application /// which will be displayed if a failure or cancellation is returned by /// the external command.</param> /// <param name="elements">A set of elements to which the external application /// can add elements that are to be highlighted in case of failure or cancellation.</param> /// <returns>Return the status of the external command. /// A result of Succeeded means that the API external method functioned as expected. /// Cancelled can be used to signify that the user cancelled the external operation /// at some point. Failure should be returned if the application is unable to proceed with /// the operation.</returns> public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { Autodesk.Revit.ApplicationServices.Application app = commandData.Application.Application; Document doc = commandData.Application.ActiveUIDocument.Document; Parameter param = null; Bitmap image = new Bitmap(doc.PathName + "_grayscale.bmp"); FilteredElementCollector collector = new FilteredElementCollector(doc); ICollection<Element> collection = collector.OfClass(typeof(DividedSurface)).ToElements(); foreach (Element element in collection) { DividedSurface ds = element as DividedSurface; GridNode gn = new GridNode(); for (int u = 0; u < ds.NumberOfUGridlines; u++) { gn.UIndex = u; for (int v = 0; v < ds.NumberOfVGridlines; v++) { gn.VIndex = v; if (ds.IsSeedNode(gn)) { FamilyInstance familyinstance = ds.GetTileFamilyInstance(gn, 0); if (familyinstance != null) { param = familyinstance.get_Parameter("Grayscale"); if (param == null) throw new Exception("Panel family must have a Grayscale instance parameter"); else { System.Drawing.Color pixelColor = new System.Drawing.Color(); try { pixelColor = image.GetPixel(image.Width - v, image.Height - u); double grayscale = 255 - ((pixelColor.R + pixelColor.G + pixelColor.B) / 3); if (grayscale == 0) { doc.Delete(familyinstance); } else { param.Set(grayscale / 255); } } catch (System.Exception) { // MessageBox.Show("Exception: " + u + ", " + v); } } } } } } } doc.Regenerate(); ; return Result.Succeeded; }
public int getIndex(GridNode findThisNode) { for(int i =0; i < size; i++) { if(data[i] == findThisNode) { return i; } } return -1; }
List<GridNode> RetracePath(GridNode start, GridNode end) { Stack<GridNode> path = new Stack<GridNode>(); GridNode curNode = end; //trace backwards while (curNode != null) { path.Push(curNode); curNode = curNode.parent; } return SimplifyPath(path); }
Vector3[] RetracePath(GridNode startNode, GridNode targetNode) { List<GridNode> path = new List<GridNode>(); GridNode currentNode = targetNode; while (currentNode != startNode) { path.Add(currentNode); currentNode = currentNode.parent; } Vector3[] waypoints = SimplifyPath(path); Array.Reverse(waypoints); return waypoints; }
public bool FindPathImmediate(GridNode start, GridNode end, List<List<GridNode>> grid, out List<GridNode> path) { path = new List<GridNode>(); bool success = false; if (start.walkable && end.walkable) { Heap<GridNode> openSet = new Heap<GridNode>(grid.Count * grid[0].Count); HashSet<GridNode> closedSet = new HashSet<GridNode>(); openSet.Add(start); while (openSet.Count > 0) { GridNode currentNode = openSet.RemoveFirst(); closedSet.Add(currentNode); //path found if (currentNode == end) { success = true; break; } foreach (GridNode neighbour in currentNode.GetNeighbours()) { if (!neighbour.walkable || closedSet.Contains(neighbour)) continue; int newNeighbourMoveCost = currentNode.gCost + GetDistanceManhatten(currentNode, neighbour); if (newNeighbourMoveCost < neighbour.gCost || !openSet.Contains(neighbour)) { neighbour.gCost = newNeighbourMoveCost; neighbour.hCost = GetDistanceManhatten(neighbour, end); neighbour.parent = currentNode; if (!openSet.Contains(neighbour)) openSet.Add(neighbour); else openSet.UpdateItem(neighbour); } } } } if (success) { path = RetracePath(start, end); } return success; }
//returns a list of surrounding nodes of a home node public List<GridNode> getNeighbours(GridNode home) { List<GridNode> list = new List<GridNode>(); int x = home.gridPositionX; int y = home.gridPositionY; for(int h = -1; h <= 1; h++){ for(int v = -1; v <= 1; v++){ if(withinArrayBounds(x+h, y+v)){ list.Add(grid[x+h,y+v]); } } } return list; }
public override Node[] CreateNodes (int number) { /*if (nodes != null && graphNodes != null && nodes.Length == number && graphNodes.Length == number) { Debug.Log ("Caching"); return nodes; }*/ GridNode[] tmp = new GridNode[number]; for (int i=0;i<number;i++) { tmp[i] = new GridNode (); tmp[i].penalty = initialPenalty; } nodes = tmp; return tmp as Node[]; }
public bool insert(GridNode value) { if (heapSize == size) { //HEAP IS FULL Debug.LogError("HEAP IS FULL!!"); return false; } else { heapSize++; data[heapSize - 1] = value; siftUp(heapSize - 1); return true; } }
public LongPathGrid(Vector3 terrainCentre, Vector2 terrainSize, int nodeRadius, LayerMask unwalkableLayer) { this.gridWorldSize = terrainSize; this.gridWorldCentre = terrainCentre; gridSizeX = Mathf.RoundToInt(gridWorldSize.x/(nodeRadius*2)); gridSizeY = Mathf.RoundToInt(gridWorldSize.y/(nodeRadius*2)); grid = new GridNode[gridSizeX,gridSizeY]; gridWorldOrigin = gridWorldCentre - Vector3.right * gridWorldSize.x/2 - Vector3.forward * gridWorldSize.y/2; for (int x = 0; x < gridSizeX; ++x) { for (int y = 0; y < gridSizeY; ++y) { Vector3 worldPoint = gridWorldOrigin + Vector3.right * (x * (nodeRadius * 2) + nodeRadius) + Vector3.forward * (y * (nodeRadius * 2) + nodeRadius); // bool walkable = !(Physics.CheckSphere(worldPoint, nodeRadius, unwalkableLayer)); bool walkable = EmptyBox(worldPoint, nodeRadius, unwalkableLayer); grid[x,y] = new GridNode(walkable, worldPoint,x,y); } } }
public List<GridNode> GetNeighbours(GridNode node) { List<GridNode> neighbours = new List<GridNode>(); for (int x = -1; x <= 1; ++x) { for (int y = -1; y <= 1; ++y) { if (x == 0 && y == 0) continue; int checkX = node.gridX + x; int checkY = node.gridY + y; if (checkX >= 0 && checkX < gridSizeX && checkY >= 0 && checkY < gridSizeY) { neighbours.Add(grid[checkX,checkY]); } } } return neighbours; }
//Trace a path backwards and return a list of nodes which make up the path private List<GridNode> retracePath(GridNode startNode, GridNode endNode) { //Instantiate list holding the path List<GridNode> path = new List<GridNode>(); //Traversal Variable GridNode currentNode = endNode; //Iterate through path until end was reached while(currentNode != startNode) { path.Add(currentNode); currentNode = currentNode.parent; } //Reverse List path.Reverse(); //Return List return path; }
//returns a node that is not blocked towards the player //used for when player clicks on blocked node public GridNode findNearestUnblockedNode(GridNode node, Vector3 playerPosition) { GridNode current = node; //if(current != null){ while(current.isBlock){ if(current.worldPosition != playerPosition){ if(current.worldPosition.x < playerPosition.x){ current = grid[current.gridPositionX+1, current.gridPositionY]; }else{ current = grid[current.gridPositionX-1, current.gridPositionY]; } if(current.worldPosition.z < playerPosition.z){ current = grid[current.gridPositionX, current.gridPositionY+1]; }else{ current = grid[current.gridPositionX, current.gridPositionY-1]; } } } //} return current; }
public void Enqueue(GridNode node,int score) { if(Count == 0){ minScore = score; maxScore = score; }else{ if(minScore > score){ minScore = score; } if(maxScore < score){ maxScore = score; } } Count++; if(!dictionary.ContainsKey(score)){ Queue<GridNode> queue = new Queue<GridNode>(); queue.Enqueue(node); dictionary.Add(score, queue); }else{ dictionary[score].Enqueue(node); } }
//Create grid public GridNode[,] generate() { //Instantiate 2D Node Array grid = new GridNode[gridSize.x, gridSize.y]; //Calculate 3D location of bottom left grid node bottomLeft = worldPosition - (Vector3.right * worldSize.x / 2) - (Vector3.up * worldSize.y / 2); //Iterate through entire grid for(int x = 0; x < gridSize.x; x++) { for(int y = 0; y < gridSize.y; y++) { //Calculate Node parameters Vector3 pos = bottomLeft + Vector3.right * (x * nodeDiameter + nodeRadius) + Vector3.up * (y * nodeDiameter + nodeRadius); //Position of Node in 3d Space bool walkable = !(Physics2D.OverlapCircle(pos, nodeRadius, unwalkableMask)); //Check if node is traversable //Create and store node with specified parameters grid[x, y] = new GridNode(pos, walkable, new Point(x, y)); } } //Return Grid return grid; }
public override bool IsValidConnection(GridNode n1, GridNode n2) { MyGridNode gnode1 = (MyGridNode)n1; MyGridNode gnode2 = (MyGridNode)n2; Vector3 npos1 = (Vector3)n1.position; Vector3 npos2 = (Vector3)n2.position; if (gnode1.isTrueWalkable && gnode2.isTrueWalkable) return true; else if (gnode1.isTrueWalkable && gnode2.isFallLane) { // connection from true walkable to fall lane below it. i.e. under ropes if (npos1.x == npos2.x && npos1.y > npos2.y) return true; // cliff drop offs if (gnode1.isSurface) { if (npos1.x > npos2.x && npos1.y == npos2.y) return true; if (npos1.x < npos2.x && npos1.y == npos2.y) return true; } } else if (gnode1.isFallLane && gnode2.isFallLane) { if (npos1.x == npos2.x && npos1.y > npos2.y) return true; } else if (gnode1.isFallLane && gnode2.isTrueWalkable) { // connection for falling down and landing on a rope, ladder or platform if (npos1.x == npos2.x && npos1.y > npos2.y) return true; } return false; }
public static List<string> RequestDividedSurfaceFamilyInstancesSelection(string message) { var ds = RequestDividedSurfaceSelection(message); var result = new List<string>(); var gn = new GridNode(); int u = 0; while (u < ds.NumberOfUGridlines) { gn.UIndex = u; int v = 0; while (v < ds.NumberOfVGridlines) { gn.VIndex = v; //"Reports whether a grid node is a "seed node," a node that is associated with one or more tiles." if (ds.IsSeedNode(gn)) { var fi = ds.GetTileFamilyInstance(gn, 0); if (fi != null) { //put the family instance into the tree result.Add(fi.UniqueId); } } v = v + 1; } u = u + 1; } return result; }
/// <summary> /// Sets the gridNode currently being drawn with /// </summary> public void setDrawNode(GridNode node) { drawNode = node; drawNode.setSelected(true); }
private List <GridNode> GetNeighbors(GridNode currentNode) { List <GridNode> neighbors = new List <GridNode>(); GridNode parentNode = currentNode.Parent; int x = currentNode.xNum, y = currentNode.yNum; //如果是起点,每个方向都需要搜索 if (parentNode == null) { int[,] dir = new int[8, 2] { { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 }, { -1, 1 } }; for (int i = 0; i < 8; ++i) { if (grid.GridMap[dir[i, 1] + x, dir[i, 1] + y].Walkable) { neighbors.Add(grid.GridMap[x, y]); } } } else {//对于非起点 int xDir = Mathf.Clamp(x - parentNode.xNum, -1, 1); int yDir = Mathf.Clamp(y - parentNode.yNum, -1, 1); GridNode neighbourUp = grid.GetNodeFromIndex(x, y + yDir); GridNode neighbourRight = grid.GetNodeFromIndex(x + xDir, y); GridNode neighbourDown = grid.GetNodeFromIndex(x, y - yDir); GridNode neighbourLeft = grid.GetNodeFromIndex(x - xDir, y); if (xDir != 0 && yDir != 0) { if (grid.IsWalkable(neighbourUp)) { neighbors.Add(neighbourUp); } if (grid.IsWalkable(neighbourRight)) { neighbors.Add(neighbourRight); } if (grid.IsWalkable(neighbourUp) || grid.IsWalkable(neighbourRight)) { //如果沿当前方向的下个位置可走 GridNode nextNode = grid.GetNodeFromIndex(x + xDir, y + yDir); if (grid.IsWalkable(nextNode)) { neighbors.Add(nextNode); } } if (!grid.IsWalkable(neighbourLeft) && grid.IsWalkable(neighbourUp)) { GridNode leftUp = grid.GetNodeFromIndex(x - xDir, y + yDir); if (grid.IsWalkable(leftUp)) { neighbors.Add(leftUp); } } if (!grid.IsWalkable(neighbourRight) && grid.IsWalkable(neighbourDown)) { GridNode rightDown = grid.GetNodeFromIndex(x + xDir, y - yDir); if (grid.IsWalkable(rightDown)) { neighbors.Add(rightDown); } } } else { if (xDir == 0) { if (grid.IsWalkable(neighbourUp)) { neighbors.Add(neighbourUp); if (!grid.IsWalkable(x + 1, y) && grid.IsWalkable(x + 1, y + yDir)) { neighbors.Add(grid.GridMap[x + 1, y + yDir]); } if (!grid.IsWalkable(x - 1, y) && grid.IsWalkable(x - 1, y + yDir)) { neighbors.Add(grid.GridMap[x - 1, y + yDir]); } } } else { if (grid.IsWalkable(neighbourRight)) { neighbors.Add(neighbourRight); if (!grid.IsWalkable(x, y + 1) && grid.IsWalkable(x + xDir, y + 1)) { neighbors.Add(grid.GridMap[x + xDir, y + 1]); } if (!grid.IsWalkable(x, y - 1) && grid.IsWalkable(x + xDir, y - 1)) { neighbors.Add(grid.GridMap[x + xDir, y - 1]); } } } } } return(neighbors); }
private GridNode GetJumpNode(GridNode currentNode, GridNode parentNode, int xDir, int yDir) { int x = currentNode.xNum, y = currentNode.yNum; if (currentNode == null || !grid.IsWalkable(currentNode)) { return(null); } if (currentNode == StartNode || currentNode == TargetNode) { return(currentNode); } if (xDir != 0 && yDir != 0) {//斜线方向 //斜方向有强迫邻居,该节点为跳点,但这里不认为斜线方向有障碍物能直接到达 /* * 1 2 * 3 4 */ //假设2是障碍物,不认为1能直接到达4. //if( (!grid.IsWalkable(currentNode.xNum-xDir, currentNode.yNum)&& grid.IsWalkable(currentNode.xNum - xDir, currentNode.yNum+yDir)) // || (!grid.IsWalkable(currentNode.xNum + xDir, currentNode.yNum)&& grid.IsWalkable(currentNode.xNum + xDir, currentNode.yNum + yDir)) ) //{ // return currentNode; //} //水平竖直方向分解,查看沿分解的水平/竖直方向能否到达一个跳点,如果能则该点也是跳点 if (GetJumpNode(grid.GetNodeFromIndex(x + xDir, y), currentNode, xDir, 0) != null || GetJumpNode(grid.GetNodeFromIndex(x, y + yDir), currentNode, 0, yDir) != null) { return(currentNode); } } else { //px(px为x为任一父节点)->x->n n有上下左右四个邻居节点是障碍节点,任何px到n最快路径是px->x->n,则n为x的强迫邻居节点,x为跳点 ( 节点y有强迫邻居则y为跳点) if (xDir != 0) { /* * 2 3 * 5 6 //当前节点为6(x,y),父节点为5 假设2(x-xDir,y+1)为障碍物,不允许5到3直接穿过,那么3(x,y+1)是6的强迫邻居,6为跳点 */ if ((grid.IsWalkable(grid.GetNodeFromIndex(x, y + 1)) && !grid.IsWalkable(grid.GetNodeFromIndex(x - xDir, y + 1))) || (grid.IsWalkable(grid.GetNodeFromIndex(x, y - 1)) && !grid.IsWalkable(grid.GetNodeFromIndex(x - xDir, y - 1)))) { return(currentNode); } } else { /* * 2 3 * 5 6 //当前节点为5(x,y),父节点为2 假设3(x+1,y-yDir)为障碍物,不允许2到6直接穿过,那么6(x+1,y)是5的强迫邻居,5为跳点 */ if ((grid.IsWalkable(grid.GetNodeFromIndex(x + 1, y)) && !grid.IsWalkable(grid.GetNodeFromIndex(x + 1, y - yDir))) || (grid.IsWalkable(grid.GetNodeFromIndex(x - 1, y)) && !grid.IsWalkable(grid.GetNodeFromIndex(x - 1, y - yDir)))) { return(currentNode); } } } if (grid.IsWalkable(x + xDir, y) || grid.IsWalkable(x, y + yDir)) { return(GetJumpNode(grid.GetNodeFromIndex(x + xDir, y + yDir), currentNode, xDir, yDir)); } return(null); }
float GetHCost(GridNode n1, GridNode n2) { return(GetDistance(n1, n2)); }
void Update() { if (Managers.GameManager.State == Enums.GameStates.Battle && !stun) { if (paused) { paused = false; anim.speed = animSpeed; } if (CustomInput.BoolFreshPress(CustomInput.UserInput.Up, playerNumber)) { if (currentNode.panelAllowed(Enums.Direction.Up, Type)) { directionToMove = Enums.Direction.Up; nextNode = currentNode.Up; } } else if (CustomInput.BoolFreshPress(CustomInput.UserInput.Down, playerNumber)) { if (currentNode.panelAllowed(Enums.Direction.Down, Type)) { directionToMove = Enums.Direction.Down; nextNode = currentNode.Down; } } else if (CustomInput.BoolFreshPress(CustomInput.UserInput.Left, playerNumber)) { if (currentNode.panelAllowed(Enums.Direction.Left, Type)) { directionToMove = Enums.Direction.Left; nextNode = currentNode.Left; } } else if (CustomInput.BoolFreshPress(CustomInput.UserInput.Right, playerNumber)) { if (currentNode.panelAllowed(Enums.Direction.Right, Type)) { directionToMove = Enums.Direction.Right; nextNode = currentNode.Right; } } else { directionToMove = Enums.Direction.None; } //get next state currState = machine.update(hit, animDone, directionToMove, hand.GetCurrentType(), hand.Empty(), playerNumber); //state clean up if (prevState != currState) { doOnce = false; animDone = false; attack = false; basicAttack = false; move = false; hit = false; if (weapon != null) { Destroy(weapon); } anim.SetInteger("state", (int)currState); } if (invunTimer > 0) { if (renderTimer > renderTime) { render = !render; renderTimer = 0; //GetComponent<Renderer>().enabled = render; } hit = false; renderTimer += Time.deltaTime; invunTimer -= Time.deltaTime; } else { //GetComponent<Renderer>().enabled = true; invun = false; } //run state switch (currState) { case Enums.PlayerState.Idle: Idle(); break; case Enums.PlayerState.MoveBegining: MoveBegining(); break; case Enums.PlayerState.MoveEnding: MoveEnding(); break; case Enums.PlayerState.Hit: Hit(); break; case Enums.PlayerState.Dead: Dead(); break; case Enums.PlayerState.BasicAttack: BasicAttack(); break; case Enums.PlayerState.HoriSwingMid: CardAnim(); break; case Enums.PlayerState.VertiSwingHeavy: CardAnim(); break; case Enums.PlayerState.ThrowLight: CardAnim(); break; case Enums.PlayerState.ThrowMid: CardAnim(); break; case Enums.PlayerState.Shoot: CardAnim(); break; case Enums.PlayerState.ChiAttack: CardAnim(); break; case Enums.PlayerState.ChiStationary: CardAnim(); break; case Enums.PlayerState.TauntGokuStretch: Taunt(); break; case Enums.PlayerState.TauntPointPoint: Taunt(); break; case Enums.PlayerState.TauntThumbsDown: Taunt(); break; case Enums.PlayerState.TauntWrasslemania: Taunt(); break; case Enums.PlayerState.TauntYaMoves: Taunt(); break; } if (move) { move = false; currentNode.clearOccupied(); currentNode = nextNode; currentNode.Owner = (this); transform.position = currentNode.transform.position; } if (useCard) { if (!hand.Empty()) { Enums.CardTypes type = hand.GetCurrentType(); if (type == Enums.CardTypes.SwordHori || type == Enums.CardTypes.SwordVert) { weapon = Instantiate(Katana); weapon.transform.position = weaponPoint.position; weapon.transform.localScale = weaponPoint.localScale; weapon.transform.parent = weaponPoint; weapon.transform.localEulerAngles = new Vector3(0, 0, 0); } else if (type == Enums.CardTypes.NaginataHori || type == Enums.CardTypes.NaginataVert) { weapon = Instantiate(Naginata); weapon.transform.position = weaponPoint.position; weapon.transform.localScale = weaponPoint.localScale; weapon.transform.parent = weaponPoint; weapon.transform.localEulerAngles = new Vector3(0, 0, 0); } else if (type == Enums.CardTypes.HammerHori || type == Enums.CardTypes.HammerVert) { weapon = Instantiate(Hammer); weapon.transform.position = weaponPoint.position; weapon.transform.localScale = weaponPoint.localScale; weapon.transform.parent = weaponPoint; weapon.transform.localEulerAngles = new Vector3(0, 0, 0); } else if (type == Enums.CardTypes.Fan) { weapon = Instantiate(Fan); weapon.transform.position = weaponPoint.position; weapon.transform.localScale = weaponPoint.localScale; weapon.transform.parent = weaponPoint; weapon.transform.localEulerAngles = new Vector3(0, 0, 0); } else if (type == Enums.CardTypes.Kanobo) { weapon = Instantiate(Kanobo); weapon.transform.position = weaponPoint.position; weapon.transform.localScale = weaponPoint.localScale; weapon.transform.parent = weaponPoint; weapon.transform.localEulerAngles = new Vector3(0, 0, 0); } else if (type == Enums.CardTypes.Tanto) { weapon = Instantiate(Tanto); weapon.transform.position = weaponPoint.position; weapon.transform.localScale = weaponPoint.localScale; weapon.transform.parent = weaponPoint; weapon.transform.localEulerAngles = new Vector3(0, 0, 0); } else if (type == Enums.CardTypes.Wakizashi) { weapon = Instantiate(Wakizashi); weapon.transform.position = weaponPoint.position; weapon.transform.localScale = weaponPoint.localScale; weapon.transform.parent = weaponPoint; weapon.transform.localEulerAngles = new Vector3(0, 0, 0); } else if (type == Enums.CardTypes.Tonfa) { weapon = Instantiate(Tonfa); weapon.transform.position = weaponPoint.position; weapon.transform.localScale = weaponPoint.localScale; weapon.transform.parent = weaponPoint; weapon.transform.localEulerAngles = new Vector3(0, 0, 0); } else if (type == Enums.CardTypes.BoStaff) { weapon = Instantiate(BoStaff); weapon.transform.position = weaponPoint.position; weapon.transform.localScale = weaponPoint.localScale; weapon.transform.parent = weaponPoint; weapon.transform.localEulerAngles = new Vector3(0, 0, 0); } useCard = false; hand.UseCurrent(this); CardUIEvent(); } } if (basicAttack) { basicAttack = false; Weapons.Hitbox b = Instantiate(bullet); AddElement.AddElementByEnum(b.gameObject, (Enums.Element)Random.Range(0, 5), true); b.Owner = this.gameObject; b.transform.position = Direction == Enums.Direction.Left ? currentNode.Left.transform.position : currentNode.Right.transform.position; b.CurrentNode = Direction == Enums.Direction.Left ? currentNode.Left : currentNode.Right; b.Direction = Direction; } if (damage > 0 && takeDamage) { takeDamage = false; TakeDamage(damage, damageElement); damage = 0; damageElement = Enums.Element.None; } prevState = currState; } else { if (!paused) { animSpeed = anim.speed; anim.speed = 0; paused = true; } if (stun) { if ((stunTimer += Time.deltaTime) > stunTime) { stunTimer = 0f; stun = false; } } } }
public static bool NeedsPath(GridNode startNode, GridNode endNode, int unitSize) { int dx, dy, error, ystep, x, y, t; int x0, y0, x1, y1; int compare1, compare2; int retX, retY; bool steep; //Tests if there is a direct path. If there is, no need to run AStar. x0 = startNode.gridX; y0 = startNode.gridY; x1 = endNode.gridX; y1 = endNode.gridY; if (y1 > y0) { compare1 = y1 - y0; } else { compare1 = y0 - y1; } if (x1 > x0) { compare2 = x1 - x0; } else { compare2 = x0 - x1; } steep = compare1 > compare2; if (steep) { t = x0; // swap x0 and y0 x0 = y0; y0 = t; t = x1; // swap x1 and y1 x1 = y1; y1 = t; } if (x0 > x1) { t = x0; // swap x0 and x1 x0 = x1; x1 = t; t = y0; // swap y0 and y1 y0 = y1; y1 = t; } dx = x1 - x0; dy = (y1 - y0); if (dy < 0) { dy = -dy; } error = dx / 2; ystep = (y0 < y1) ? 1 : -1; y = y0; GridNode.PrepareUnpassableCheck(unitSize); for (x = x0; x <= x1; x++) { retX = (steep ? y : x); retY = (steep ? x : y); currentNode = GridManager.Grid[GridManager.GetGridIndex(retX, retY)]; if (currentNode != null && currentNode.Unpassable()) { break; } else if (x == x1) { return(false); } error = error - dy; if (error < 0) { y += ystep; error += dx; } } return(true); }
/* * static int GetObstructionCount(int index1, int index2) * { * if (CheckInvalid(currentNode.NeighborNodes[index1])) { * if (CheckInvalid(currentNode.NeighborNodes[index2])) { * return 2; * } * return 1; * } * if (CheckInvalid(currentNode.NeighborNodes[index2])) * return 1; * return 0; * }*/ static bool CheckInvalid(GridNode gridNode) { return(gridNode.IsNull() || GridHeap.Closed(gridNode) || gridNode.Unpassable()); }
/// <summary> /// Finds a path and outputs it to <c>outputPath</c>. Note: outputPath is unpredictably changed. /// </summary> /// <returns> /// Returns <c>true</c> if path was found and necessary, <c>false</c> if path to End is impossible or not found. /// </returns> /// <param name="startNode">Start node.</param> /// <param name="endNode">End node.</param> /// <param name="outputPath">Return path.</param> public static bool FindRawPath(GridNode _startNode, GridNode _endNode, FastList <GridNode> _outputPath, int _unitHalfSize) { //TODO: Not critical but there's a lot of room for better organization //i.e. All these static variables and methods goes into individual singleton classes startNode = _startNode; endNode = _endNode; rawOutputPath = _outputPath; rawOutputPath.FastClear(); unitHalfSize = _unitHalfSize; StartNodeIndex = startNode.gridIndex; EndNodeIndex = endNode.gridIndex; #region Broadphase and Preperation if (endNode.Unwalkable && !AllowUnwalkableEndNode) { return(false); } if (startNode.Unwalkable) { return(false); } if (System.Object.ReferenceEquals(startNode, endNode)) { rawOutputPath.Add(endNode); return(true); } GridHeap.FastClear(); //POSBUG: Hash for end destination and frame count. *Most likely* won't overflow //Or no need to factor in frame count #endregion #region AStar Algorithm GridHeap.Add(startNode); GridNode.HeuristicTargetX = endNode.gridX; GridNode.HeuristicTargetY = endNode.gridY; GridNode.PrepareUnpassableCheck(unitHalfSize); //Prepare Unpassable check optimizations destinationIsReached = false; SearchCount = 0; CombineVersionSet = CombineIteration * GridManager.MaxIndex + endNode.gridIndex; if (lastGridIndex == endNode.gridIndex) { CombineVersionCheck = CombineVersionSet; } else { if (CombineVersionCheck != DefaultCombineVersion) { CombineIteration++; CombineVersionCheck = DefaultCombineVersion; } } lastGridIndex = endNode.gridIndex; while (GridHeap.Count > 0) { SearchCount++; rawNode = GridHeap.RemoveFirst(); if (rawNode.gridIndex == endNode.gridIndex) { //We found our way to the end node! DestinationReached(); return(true); } if (CombineVersionCheck != DefaultCombineVersion) { if (rawNode.CombinePathVersion == CombineVersionCheck) { //We found our way onto an existing path! DestinationReached(true); return(true); } } #if true #region Allows diagonal access when edges are blocked for (i = 0; i < 4; i++) { neighbor = rawNode.NeighborNodes[i]; if (CheckNeighborSearchable()) { if (neighbor.Unpassable() == false) { newMovementCostToNeighbor = rawNode.gCost + 100; ProcessNode(); } else if (neighbor.gridIndex == EndNodeIndex) { AddBestNode(); DestinationReached(); return(true); } } } for (int i = 4; i < 8; i++) { neighbor = rawNode.NeighborNodes[i]; if (CheckNeighborSearchable()) { if (neighbor.Unpassable() == false) { newMovementCostToNeighbor = rawNode.gCost + 141; ProcessNode(); } else if (neighbor.gridIndex == EndNodeIndex) { AddBestNode(); DestinationReached(); return(true); } } } GridHeap.Close(rawNode); #endregion #else hasInvalidEdge = false; for (int i = 0; i < 4; i++) { neighbor = currentNode.NeighborNodes[i]; if (CheckNeighborInvalid()) { hasInvalidEdge = true; } else { newMovementCostToNeighbor = currentNode.gCost + 100; AnalyzeNode(); } } if (hasInvalidEdge) { const int maxCornerObstructions = 2; #region inlining diagonals neighbor = currentNode.NeighborNodes[4]; if (!CheckNeighborInvalid()) { if (GetObstructionCount(0, 1) <= maxCornerObstructions) { newMovementCostToNeighbor = currentNode.gCost + 141; AnalyzeNode(); } } neighbor = currentNode.NeighborNodes[5]; if (!CheckNeighborInvalid()) { if (GetObstructionCount(0, 2) <= maxCornerObstructions) { newMovementCostToNeighbor = currentNode.gCost + 141; AnalyzeNode(); } } neighbor = currentNode.NeighborNodes[6]; if (!CheckNeighborInvalid()) { if (GetObstructionCount(3, 1) <= maxCornerObstructions) { newMovementCostToNeighbor = currentNode.gCost + 141; AnalyzeNode(); } } neighbor = currentNode.NeighborNodes[7]; if (!CheckNeighborInvalid()) { if (GetObstructionCount(3, 2) <= maxCornerObstructions) { newMovementCostToNeighbor = currentNode.gCost + 141; AnalyzeNode(); } } #endregion } else { //no need for specific stuff when edges are all valid for (int i = 4; i < 8; i++) { neighbor = currentNode.NeighborNodes[i]; if (CheckNeighborInvalid()) { } else { newMovementCostToNeighbor = currentNode.gCost + 141; AnalyzeNode(); } } } #endif } #endregion return(destinationIsReached); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { m_uiApp = commandData.Application; m_uiDoc = m_uiApp.ActiveUIDocument; // get the target element to be used for the Distance computation ElementSet collection = new ElementSet(); foreach (ElementId elementId in m_uiDoc.Selection.GetElementIds()) { collection.Insert(m_uiDoc.Document.GetElement(elementId)); } Parameter param = null; ElementSet es = new ElementSet(); foreach (ElementId elementId in m_uiDoc.Selection.GetElementIds()) { es.Insert(m_uiDoc.Document.GetElement(elementId)); } XYZ targetPoint = getTargetPoint(es); // get all the divided surfaces in the Revit document List <DividedSurface> dsList = GetElements <DividedSurface>(); foreach (DividedSurface ds in dsList) { GridNode gn = new GridNode(); int u = 0; while (u < ds.NumberOfUGridlines) { gn.UIndex = u; int v = 0; while (v < ds.NumberOfVGridlines) { gn.VIndex = v; if (ds.IsSeedNode(gn)) { FamilyInstance familyinstance = ds.GetTileFamilyInstance(gn, 0); if (familyinstance != null) { param = familyinstance.LookupParameter("Distance"); if (param == null) { throw new Exception("Panel family must have a Distance instance parameter"); } else { LocationPoint loc = familyinstance.Location as LocationPoint; XYZ panelPoint = loc.Point; double d = Math.Sqrt(Math.Pow((targetPoint.X - panelPoint.X), 2) + Math.Pow((targetPoint.Y - panelPoint.Y), 2) + Math.Pow((targetPoint.Z - panelPoint.Z), 2)); param.Set(d); } } } v++; } u++; } } return(Result.Succeeded); }
public void SetPosition(GridNode node) { headBlock.SetNode(node); }
// TODO: Joshua Implement // Check if valid attack // If valid, decrement other player's health by player's attack value // Return true // Otherwise just return false public bool canAttack(int player, int x, int y) { bool validAttack = false; bool validTerrain = false; GridNode targetNode = grid[x, y]; if (player == (int)Players.Player1) { for (int i = 0; i < 4; i++) { validAttack = movementCheck(player1Attack, i, player1X, player1Y, targetNode); if (validAttack) { break; } } } else { for (int i = 0; i < 4; i++) { validAttack = movementCheck(player2Attack, i, player2X, player2Y, targetNode); if (validAttack) { break; } } } if (validAttack) { if (player == (int)Players.Player1) { Debug.Log("Player 1 hits Player 2 for " + player1Attack + " damage! Player 2 health is now at " + (player2Health - player1Attack)); player2Health -= player1Attack; } else if (player == (int)Players.Player2) { Debug.Log("Player 2 hits Player 1 for " + player2Attack + " damage! Player 1 health is now at: " + (player1Health - player2Attack)); player1Health -= player2Attack; } else { Debug.Log("No player was hit..."); updatePowerupState(player); return(false); } updatePowerupState(player); return(true); } else { updatePowerupState(player); return(false); } }
public void Update(GridNode gridNode) { }
// Populating the entire pathfinding grid. public void PopulateGrid(int startX, int startY, int endX, int endY) { /* Since arrays cannot have negative indices, it is impossible to store coordinates as incides. Hence, we create a * min X and min Y offset, so the most 'bottom-left' existing coordinate is (0, 0). */ gridOffsetX = Mathf.Abs(startX); gridOffsetY = Mathf.Abs(startY); PlayerController.instance.SetGridOffset(gridOffsetX, gridOffsetY); // Getting dimension sizes for both axes to initialize the pathfinding grid. distanceX = Mathf.Abs(endX - startX); distanceY = Mathf.Abs(endY - startY); pathfindingGrid = new GridNode[distanceX, distanceY]; /* Costly operation but it runs only one time. Creates GridNode classes for each tile. GridNode contains information * such as position, walkability, pathfinding helpers and what unit is standing on top of it. */ for (int x = 0; x < distanceX; ++x) { for (int y = 0; y < distanceY; ++y) { Vector3Int tilePos = new Vector3Int(x + startX, y + startY, 0); pathfindingGrid[x, y] = new GridNode(false, (Vector2Int)tilePos, x, y); if (tilemap.GetTile(tilePos) is GroundTile) { pathfindingGrid[x, y] = new GridNode(true, (Vector2Int)tilePos, x, y); } } } // After placing presets, check for obstacles and update tile walkability for tiles that have those obstacles. foreach (Room room in RoomManager.instance.allRooms) { if (room.position.x == 0 && room.position.y == 0) { continue; } Tilemap roomTilemap = room.roomTilemap; BoundsInt tilemapBounds = roomTilemap.cellBounds; for (int x = tilemapBounds.min.x; x <= tilemapBounds.max.x; ++x) { for (int y = tilemapBounds.min.y; y <= tilemapBounds.max.y; ++y) { Vector3Int cellPos = new Vector3Int(x, y, 0); if (roomTilemap.HasTile(cellPos)) { Vector3 worldPos = roomTilemap.GetCellCenterWorld(cellPos); Vector3Int worldPosInt = new Vector3Int(Mathf.FloorToInt(worldPos.x), Mathf.FloorToInt(worldPos.y), 0); UpdateTileWalkability(worldPosInt, false, null); } } } ShopManager.instance.InvalidateShopTile(); } // Updating the starting tile of the player. This is just to be safe, not to hardcode the starting (0, 0) position of the player. foreach (GameObject player in GameObject.FindGameObjectsWithTag("Player")) { Vector3Int playerPos = new Vector3Int((int)player.transform.position.x + gridOffsetX, (int)player.transform.position.y + gridOffsetY, 0); GridNode tile = pathfindingGrid[playerPos.x, playerPos.y]; tile.isWalkable = false; tile.unitOnTop = player; } // Doing the same for all enemies. foreach (GameObject enemy in GameObject.FindGameObjectsWithTag("Enemy")) { Vector3Int enemyPos = new Vector3Int((int)enemy.transform.position.x + gridOffsetX, (int)enemy.transform.position.y + gridOffsetY, 0); GridNode tile = pathfindingGrid[enemyPos.x, enemyPos.y]; tile.isWalkable = false; tile.unitOnTop = enemy; } }
public static bool GetPathNodes(long StartX, long StartY, long EndX, long EndY, out GridNode startNode, out GridNode endNode) { startNode = GridManager.GetNode(StartX, StartY); if (startNode.Unwalkable) { for (i = 0; i < 8; i++) { currentNode = startNode.NeighborNodes[i]; if (System.Object.ReferenceEquals(currentNode, null) == false && currentNode.Unwalkable == false) { startNode = currentNode; break; } } if (startNode.Unwalkable) { endNode = null; return(false); } } endNode = GridManager.GetNode(EndX, EndY); if (endNode.Unwalkable) { if (AllowUnwalkableEndNode) { return(AlternativeNodeFinder.Instance.CheckValidNeighbor(endNode)); } for (i = 0; i < 8; i++) { currentNode = endNode.NeighborNodes[i]; if (System.Object.ReferenceEquals(currentNode, null) == false && currentNode.Unwalkable == false) { endNode = currentNode; break; } } if (endNode.Unwalkable) { return(false); } } return(true); }
// A* pathfinding algorithm modified to fit this project. public List <GridNode> Pathfinding(Vector3Int startCoord, Vector3Int endCoord, int gridSpeed, bool exploring, Tilemap whichTilemap) { // Empty path. List <GridNode> path = new List <GridNode>(); // Some checks if the end coordinate is out of bounds or if hovering above a non-movementTilemap tile Vector3Int start = new Vector3Int(gridOffsetX + startCoord.x, gridOffsetY + startCoord.y, 0); Vector3Int end = new Vector3Int(gridOffsetX + endCoord.x, gridOffsetY + endCoord.y, 0); if (end.x < 0 || end.x > pathfindingGrid.GetLength(0) || end.y < 0 || end.y > pathfindingGrid.GetLength(1)) { return(path); } if (!CanMove(endCoord, whichTilemap) && !exploring) { return(path); } int gridX = gridOffsetX + endCoord.x; int gridY = gridOffsetY + endCoord.y; if (!pathfindingGrid[gridX, gridY].isWalkable) { return(path); } GridNode startNode = pathfindingGrid[start.x, start.y]; GridNode endNode = pathfindingGrid[end.x, end.y]; // The Open list contains nodes for which we have already calculated the F cost (the lowest F cost node can/will be the next current node) List <GridNode> openSet = new List <GridNode>(); // The Closed list contains all the visited nodes (the whole path along with other visited nodes is in this list) HashSet <GridNode> closedSet = new HashSet <GridNode>(); openSet.Add(startNode); bool foundPath = false; while (openSet.Count > 0) { GridNode currentNode = openSet[0]; Vector3Int nodePos = new Vector3Int(currentNode.position.x, currentNode.position.y, 0); if (!foundPath) { for (int i = 0; i < openSet.Count; ++i) { // If the F cost of a set member is lower than our current node's, that is gonna be our next node. if (openSet[i].fCost < currentNode.fCost || (openSet[i].fCost == currentNode.fCost && openSet[i].hCost < currentNode.hCost)) { currentNode = openSet[i]; } } openSet.Remove(currentNode); closedSet.Add(currentNode); } // If we have reached the end, we can safely retrace the path and exit. Unless it exceeds our speed. if (currentNode == endNode) { path = RetracePath(startNode, endNode); if (!exploring) { int speedCounter = 0; foreach (GridNode node in path) { ++speedCounter; } if (speedCounter > gridSpeed) { return(new List <GridNode>()); } } return(path); } // Getting all neighbours from our current node. foreach (GridNode neighbour in GetNeighbours(currentNode)) { // The node does not interest us if we already have evaluated it or if it's not even walkable. if ((!neighbour.isWalkable) || closedSet.Contains(neighbour) || (!whichTilemap.HasTile((Vector3Int)neighbour.position) && !exploring)) { if (neighbour.position == (Vector2Int)endCoord) { neighbour.parent = currentNode; if (openSet.Count == 0) { return(new List <GridNode>()); } openSet[0] = neighbour; foundPath = true; break; } continue; } int newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour); /* If the new path to neighbour is shorter than the old path or if the neighbour hasn't been evaluated, calculate the F cost * and set the parent to current node (to trace path later).*/ if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour)) { neighbour.gCost = newMovementCostToNeighbour; neighbour.hCost = GetDistance(neighbour, endNode); neighbour.parent = currentNode; if (!openSet.Contains(neighbour)) { openSet.Add(neighbour); } } } } // If we have reached here, that means we haven't found a path to the end node, which simply means we are returning an empty list. return(path); }
public GridNode GetNode() { //Calculated closest side to raycast in first long xDif = OffsettedPos.x - XGrid; xDif = xDif.ClampOne(); long yDif = OffsettedPos.y - YGrid; yDif = yDif.ClampOne(); long nodeHalfWidth = FixedMath.One / 2; //Check to see if we should raycast towards corner first if ((xDif.Abs() >= nodeHalfWidth / 2) && (yDif.Abs() >= nodeHalfWidth / 2)) { dirX = FixedMath.RoundToInt(xDif); dirY = FixedMath.RoundToInt(yDif); } else { if (xDif.Abs() < yDif.Abs()) { dirX = 0; dirY = yDif.RoundToInt(); } else { dirX = xDif.RoundToInt(); dirY = 0; } } int layerStartX = dirX, layerStartY = dirY; int iterations = 0; // <- this is for debugging for (layer = 1; layer <= this.MaxTestDistance;) { GridNode checkNode = GridManager.GetNode(XGrid + dirX, YGrid + dirY); if (checkNode != null) { this.CheckPathNode(checkNode); if (this.castNodeFound) { return(this.closestNode); } } AdvanceRotation(); //If we make a full loop if (layerStartX == dirX && layerStartY == dirY) { layer++; //Advance a layer instead of rotation if (dirX > 0) { dirX = layer; } else if (dirX < 0) { dirX = -layer; } if (dirY > 0) { dirY = layer; } else if (dirY < 0) { dirY = -layer; } layerStartX = dirX; layerStartY = dirY; } iterations++; if (iterations > 500) { Debug.Log("tew many"); break; } } //If the cast node is found or the side has been checked, do not raycast on that side if (!castNodeFound) { return(null); } return(closestNode); }
public void ExecuteStep(GridNode cur_node, GridNode tar_node, EnemyLogic me, GameObject target) { }
// Check up, down, left, or right of the player's current position // j spaces up to their maximum movement and see if it matches the // place they are currently trying to move to // // This will be called up to 4 times so all 4 directions are checked private bool movementCheck(int movementAmount, int currentIteration, int currentPlayerX, int currentPlayerY, GridNode targetNode) { for (int i = 1; i <= movementAmount; i++) { switch (currentIteration) { case 0: // Index out of bounds check if ((currentPlayerX + i) >= gridSize) { continue; } if (grid[currentPlayerX + i, currentPlayerY].terrain == (int)Terrains.Mountains) { return(false); } // Tile check if ((currentPlayerX + i) == targetNode.x && currentPlayerY == targetNode.y) { return(true); } break; case 1: // Index out of bounds check if ((currentPlayerX - i) < 0) { continue; } if (grid[currentPlayerX - i, currentPlayerY].terrain == (int)Terrains.Mountains) { return(false); } // Tile check if ((currentPlayerX - i) == targetNode.x && currentPlayerY == targetNode.y) { return(true); } break; case 2: // Index out of bounds check if ((currentPlayerY + i) >= gridSize) { continue; } if (grid[currentPlayerX, currentPlayerY + i].terrain == (int)Terrains.Mountains) { return(false); } // Tile check if (currentPlayerX == targetNode.x && (currentPlayerY + i) == targetNode.y) { return(true); } break; case 3: // Index out of bounds check if ((currentPlayerY - i) < 0) { continue; } if (grid[currentPlayerX, currentPlayerY - i].terrain == (int)Terrains.Mountains) { return(false); } // Tile check if (currentPlayerX == targetNode.x && (currentPlayerY - i) == targetNode.y) { return(true); } break; } } return(false); }
bool TurnsPossible(GridNode P) { return(IsWall(P.X, P.Y + 2) || IsWall(P.X, P.Y - 2) || IsWall(P.X + 2, P.Y) || IsWall(P.X - 2, P.Y)); }
public void SetPosition(GridNode node, GridSystemManager gridSystem, TraversalDirection dir) { SetPositions(headBlock, node, gridSystem, dir); }
/// <summary> /// Implement this method as an external command for Revit. /// </summary> /// <param name="commandData">An object that is passed to the external application /// which contains data related to the command, /// such as the application object and active view.</param> /// <param name="message">A message that can be set by the external application /// which will be displayed if a failure or cancellation is returned by /// the external command.</param> /// <param name="elements">A set of elements to which the external application /// can add elements that are to be highlighted in case of failure or cancellation.</param> /// <returns>Return the status of the external command. /// A result of Succeeded means that the API external method functioned as expected. /// Cancelled can be used to signify that the user cancelled the external operation /// at some point. Failure should be returned if the application is unable to proceed with /// the operation.</returns> public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { Autodesk.Revit.ApplicationServices.Application app = commandData.Application.Application; Document doc = commandData.Application.ActiveUIDocument.Document; Transaction trans = new Transaction(doc, "Revit.SDK.Samples.ParameterValuesFromImage"); trans.Start(); Parameter param = null; Bitmap image = new Bitmap(doc.PathName + "_grayscale.bmp"); FilteredElementCollector collector = new FilteredElementCollector(doc); ICollection <Element> collection = collector.OfClass(typeof(DividedSurface)).ToElements(); foreach (Element element in collection) { DividedSurface ds = element as DividedSurface; GridNode gn = new GridNode(); for (int u = 0; u < ds.NumberOfUGridlines; u++) { gn.UIndex = u; for (int v = 0; v < ds.NumberOfVGridlines; v++) { gn.VIndex = v; if (ds.IsSeedNode(gn)) { FamilyInstance familyinstance = ds.GetTileFamilyInstance(gn, 0); if (familyinstance != null) { param = familyinstance.LookupParameter("Grayscale"); if (param == null) { trans.RollBack(); throw new Exception("Panel family must have a Grayscale instance parameter"); } else { System.Drawing.Color pixelColor = new System.Drawing.Color(); try { pixelColor = image.GetPixel(image.Width - v, image.Height - u); double grayscale = 255 - ((pixelColor.R + pixelColor.G + pixelColor.B) / 3); if (grayscale == 0) { doc.Delete(familyinstance.Id); } else { param.Set(grayscale / 255); } } catch (System.Exception) { // TaskDialog.Show("Revit", "Exception: " + u + ", " + v); } } } } } } } doc.Regenerate();; trans.Commit(); return(Result.Succeeded); }
protected override Size MeasureOverride(Size constraint) { var totalSize = constraint; var colCount = ColumnDefinitions.Count; var rowCount = RowDefinitions.Count; double totalStarsX = 0; double totalStarsY = 0; var emptyRows = rowCount == 0; var emptyCols = colCount == 0; var hasChildren = Children.Count > 0; if (emptyRows) { rowCount = 1; } if (emptyCols) { colCount = 1; } CreateMatrices(rowCount, colCount); if (emptyRows) { rowMatrix[0, 0] = new Segment(0, 0, double.PositiveInfinity, GridUnitType.Star); rowMatrix[0, 0].Stars = 1.0; totalStarsY += 1.0; } else { for (var i = 0; i < rowCount; i++) { var rowdef = RowDefinitions[i]; var height = rowdef.Height; rowdef.ActualHeight = double.PositiveInfinity; rowMatrix[i, i] = new Segment(0, rowdef.MinHeight, rowdef.MaxHeight, height.GridUnitType); if (height.GridUnitType == GridUnitType.Pixel) { rowMatrix[i, i].OfferedSize = Clamp(height.Value, rowMatrix[i, i].Min, rowMatrix[i, i].Max); rowMatrix[i, i].DesiredSize = rowMatrix[i, i].OfferedSize; rowdef.ActualHeight = rowMatrix[i, i].OfferedSize; } else if (height.GridUnitType == GridUnitType.Star) { rowMatrix[i, i].Stars = height.Value; totalStarsY += height.Value; } else if (height.GridUnitType == GridUnitType.Auto) { rowMatrix[i, i].OfferedSize = Clamp(0, rowMatrix[i, i].Min, rowMatrix[i, i].Max); rowMatrix[i, i].DesiredSize = rowMatrix[i, i].OfferedSize; } } } if (emptyCols) { colMatrix[0, 0] = new Segment(0, 0, double.PositiveInfinity, GridUnitType.Star); colMatrix[0, 0].Stars = 1.0; totalStarsX += 1.0; } else { for (var i = 0; i < colCount; i++) { var coldef = ColumnDefinitions[i]; var width = coldef.Width; coldef.ActualWidth = double.PositiveInfinity; colMatrix[i, i] = new Segment(0, coldef.MinWidth, coldef.MaxWidth, width.GridUnitType); if (width.GridUnitType == GridUnitType.Pixel) { colMatrix[i, i].OfferedSize = Clamp(width.Value, colMatrix[i, i].Min, colMatrix[i, i].Max); colMatrix[i, i].DesiredSize = colMatrix[i, i].OfferedSize; coldef.ActualWidth = colMatrix[i, i].OfferedSize; } else if (width.GridUnitType == GridUnitType.Star) { colMatrix[i, i].Stars = width.Value; totalStarsX += width.Value; } else if (width.GridUnitType == GridUnitType.Auto) { colMatrix[i, i].OfferedSize = Clamp(0, colMatrix[i, i].Min, colMatrix[i, i].Max); colMatrix[i, i].DesiredSize = colMatrix[i, i].OfferedSize; } } } var sizes = new List <GridNode>(); GridNode node; var separator = new GridNode(null, 0, 0, 0); int separatorIndex; sizes.Add(separator); // Pre-process the grid children so that we know what types of elements we have so // we can apply our special measuring rules. var gridWalker = new GridWalker(this, rowMatrix, colMatrix); for (var i = 0; i < 6; i++) { // These bools tell us which grid element type we should be measuring. i.e. // 'star/auto' means we should measure elements with a star row and auto col var autoAuto = i == 0; var starAuto = i == 1; var autoStar = i == 2; var starAutoAgain = i == 3; var nonStar = i == 4; var remainingStar = i == 5; if (hasChildren) { ExpandStarCols(totalSize); ExpandStarRows(totalSize); } foreach (var child in Children) { int col, row; int colspan, rowspan; double childSizeX = 0; double childSizeY = 0; var starCol = false; var starRow = false; var autoCol = false; var autoRow = false; col = Math.Min(GetColumn(child), colCount - 1); row = Math.Min(GetRow(child), rowCount - 1); colspan = Math.Min(GetColumnSpan(child), colCount - col); rowspan = Math.Min(GetRowSpan(child), rowCount - row); for (var r = row; r < row + rowspan; r++) { starRow |= rowMatrix[r, r].Type == GridUnitType.Star; autoRow |= rowMatrix[r, r].Type == GridUnitType.Auto; } for (var c = col; c < col + colspan; c++) { starCol |= colMatrix[c, c].Type == GridUnitType.Star; autoCol |= colMatrix[c, c].Type == GridUnitType.Auto; } // This series of if statements checks whether or not we should measure // the current element and also if we need to override the sizes // passed to the Measure call. // If the element has Auto rows and Auto columns and does not span Star // rows/cols it should only be measured in the auto_auto phase. // There are similar rules governing auto/star and star/auto elements. // NOTE: star/auto elements are measured twice. The first time with // an override for height, the second time without it. if (autoRow && autoCol && !starRow && !starCol) { if (!autoAuto) { continue; } childSizeX = double.PositiveInfinity; childSizeY = double.PositiveInfinity; } else if (starRow && autoCol && !starCol) { if (!(starAuto || starAutoAgain)) { continue; } if (starAuto && gridWalker.HasAutoStar) { childSizeY = double.PositiveInfinity; } childSizeX = double.PositiveInfinity; } else if (autoRow && starCol && !starRow) { if (!autoStar) { continue; } childSizeY = double.PositiveInfinity; } else if ((autoRow || autoCol) && !(starRow || starCol)) { if (!nonStar) { continue; } if (autoRow) { childSizeY = double.PositiveInfinity; } if (autoCol) { childSizeX = double.PositiveInfinity; } } else if (!(starRow || starCol)) { if (!nonStar) { continue; } } else { if (!remainingStar) { continue; } } for (var r = row; r < row + rowspan; r++) { childSizeY += rowMatrix[r, r].OfferedSize; } for (var c = col; c < col + colspan; c++) { childSizeX += colMatrix[c, c].OfferedSize; } child.Measure(new Size(childSizeX, childSizeY)); var desired = child.DesiredSize; // Elements distribute their height based on two rules: // 1) Elements with rowspan/colspan == 1 distribute their height first // 2) Everything else distributes in a LIFO manner. // As such, add all UIElements with rowspan/colspan == 1 after the separator in // the list and everything else before it. Then to process, just keep popping // elements off the end of the list. if (!starAuto) { node = new GridNode(rowMatrix, row + rowspan - 1, row, desired.Height); separatorIndex = sizes.IndexOf(separator); sizes.Insert(node.Row == node.Column ? separatorIndex + 1 : separatorIndex, node); } node = new GridNode(colMatrix, col + colspan - 1, col, desired.Width); separatorIndex = sizes.IndexOf(separator); sizes.Insert(node.Row == node.Column ? separatorIndex + 1 : separatorIndex, node); } sizes.Remove(separator); while (sizes.Count > 0) { node = sizes.Last(); node.Matrix[node.Row, node.Column].DesiredSize = Math.Max(node.Matrix[node.Row, node.Column].DesiredSize, node.Size); AllocateDesiredSize(rowCount, colCount); sizes.Remove(node); } sizes.Add(separator); } // Once we have measured and distributed all sizes, we have to store // the results. Every time we want to expand the rows/cols, this will // be used as the baseline. SaveMeasureResults(); sizes.Remove(separator); double gridSizeX = 0; double gridSizeY = 0; for (var c = 0; c < colCount; c++) { gridSizeX += colMatrix[c, c].DesiredSize; } for (var r = 0; r < rowCount; r++) { gridSizeY += rowMatrix[r, r].DesiredSize; } return(new Size(gridSizeX, gridSizeY)); }
public void Blockchange2(Player p, ushort x, ushort y, ushort z, byte type) { p.ClearBlockchange(); byte b = p.level.GetTile(x, y, z); p.SendBlockchange(x, y, z, b); Player.SendMessage(p, "Generating maze... this could take a while"); CatchPos first = (CatchPos)p.blockchangeObject; int width = Math.Max(x, first.X) - Math.Min(x, first.X); if (width % 2 != 0) { width++; x--; } width -= 2; int height = Math.Max(z, first.Z) - Math.Min(z, first.Z); if (height % 2 != 0) { height++; z--; } height -= 2; //substract 2 cause we will just make the inner. the outer wall is made seperately wall = new bool[width + 1, height + 1];//+1 cause we begin at 0 so we need one object more for (int w = 0; w <= width; w++) { for (int h = 0; h <= height; h++) { wall[w, h] = true; } } GridNode.maxX = width; GridNode.maxY = height; //Make a Stack Stack s = new Stack(width * height); //Random rand = new Random(DateTime.Now.Millisecond);//ha yeah randomized :P //lets begin in the lower left corner eh?(0,0) s.Push(new GridNode(0, 0)); wall[0, 0] = false; while (true) { GridNode node = (GridNode)s.Peek(); if (node.turnsPossible()) { GridNode[] nodearray = node.getRandomNext(); wall[nodearray[0].X, nodearray[0].Y] = false; wall[nodearray[1].X, nodearray[1].Y] = false; s.Push(nodearray[1]); //we get the next two nodes //the first is a middle node from which there shouldnt start a new corridor //the second is added to the stack. next try will be with this node //i hope this will work this time... } else { s.Pop();//if this node is a dead and it will be removed } if (s.Count < 1) { break;//if no nodes are free anymore we will end the generation here } } Player.SendMessage(p, "Maze is generated. now painting..."); //seems to be there are no more moves possible //paint that shit :P ushort minx = Math.Min(x, first.X); ushort minz = Math.Min(z, first.Z); ushort maxx = Math.Max(x, first.X); maxx++; ushort maxz = Math.Max(z, first.Z); maxz++; for (ushort xx = 0; xx <= width; xx++) { for (ushort zz = 0; zz <= height; zz++) { if (wall[xx, zz]) { p.level.Blockchange(p, (ushort)(xx + minx + 1), y, (ushort)(zz + minz + 1), Block.staircasefull); p.level.Blockchange(p, (ushort)(xx + minx + 1), (ushort)(y + 1), (ushort)(zz + minz + 1), Block.leaf); p.level.Blockchange(p, (ushort)(xx + minx + 1), (ushort)(y + 2), (ushort)(zz + minz + 1), Block.leaf); } } } p.ignorePermission = true; Command.all.Find("cuboid").Use(p, "walls"); p.manualChange(minx, y, minz, 0, Block.staircasefull); p.manualChange(maxx, y, maxz, 0, Block.staircasefull); Command.all.Find("cuboid").Use(p, "walls"); p.manualChange(minx, (ushort)(y + 1), minz, 0, Block.leaf); p.manualChange(maxx, (ushort)(y + 2), maxz, 0, Block.leaf); Player.SendMessage(p, "Maze painted. Build your entrance and exit yourself"); randomizer = 0; }
public override void Perform(Vec3U16[] marks, Player p, Level lvl, Brush brush) { width = Max.X - Min.X; if (width % 2 != 0) { width++; Min.X--; } width -= 2; length = Max.Z - Min.Z; if (length % 2 != 0) { length++; Min.Z--; } length -= 2; if (width <= 0 || length <= 0) { Player.SendMessage(p, "The corners of the maze need to be further apart."); return; } Player.SendMessage(p, "Generating maze... this could take a while"); //substract 2 cause we will just make the inner. the outer wall is made seperately wall = new bool[width + 1, length + 1];//+1 cause we begin at 0 so we need one object more for (int w = 0; w <= width; w++) { for (int h = 0; h <= length; h++) { wall[w, h] = true; } } rng1 = new RNGCryptoServiceProvider(); rng2 = new Random(); Stack <GridNode> stack = new Stack <GridNode>(width * length); stack.Push(new GridNode(0, 0)); wall[0, 0] = false; while (true) { GridNode P = stack.Peek(); if (TurnsPossible(P)) { GridNode P1, P2; MoveRandomDir(P, out P1, out P2); wall[P1.X, P1.Y] = false; wall[P2.X, P2.Y] = false; stack.Push(P2); //we get the next two nodes //the first is a middle node from which there shouldnt start a new corridor //the second is added to the stack. next try will be with this node //i hope this will work this time... } else { stack.Pop();//if this node is a dead and it will be removed } if (stack.Count < 1) { break; //if no nodes are free anymore we will end the generation here } } Player.SendMessage(p, "Generated maze, now drawing."); ushort minX = Min.X, minZ = Min.Z, maxX = Max.X, maxZ = Max.Z, y = Min.Y; for (ushort xx = 0; xx <= width; xx++) { for (ushort zz = 0; zz <= length; zz++) { if (wall[xx, zz]) { PlaceBlock(p, lvl, (ushort)(xx + minX + 1), y, (ushort)(zz + minZ + 1), Block.staircasefull, 0); PlaceBlock(p, lvl, (ushort)(xx + minX + 1), (ushort)(y + 1), (ushort)(zz + minZ + 1), Block.leaf, 0); PlaceBlock(p, lvl, (ushort)(xx + minX + 1), (ushort)(y + 2), (ushort)(zz + minZ + 1), Block.leaf, 0); } } } brush = new SolidBrush(Block.staircasefull, 0); QuadX(minX, y, minZ, y, maxZ, p, lvl, brush); QuadX(maxX, y, minZ, y, maxZ, p, lvl, brush); QuadZ(minZ, y, minX, y, maxX, p, lvl, brush); QuadZ(maxZ, y, minX, y, maxX, p, lvl, brush); brush = new SolidBrush(Block.leaf, 0); QuadX(minX, (ushort)(y + 1), minZ, (ushort)(y + 2), maxZ, p, lvl, brush); QuadX(maxX, (ushort)(y + 1), minZ, (ushort)(y + 2), maxZ, p, lvl, brush); QuadZ(minZ, (ushort)(y + 1), minX, (ushort)(y + 2), maxX, p, lvl, brush); QuadZ(maxZ, (ushort)(y + 1), minX, (ushort)(y + 2), maxX, p, lvl, brush); Player.SendMessage(p, "Maze painted. Build your entrance and exit yourself"); randomizer = 0; }
public Vector3[] shortestRoute(Vector3 start, Vector3 end) { Stopwatch sw = new Stopwatch(); sw.Start(); HasPath = false; Vector3[] waypoints = new Vector3[0]; GridNode startNode = grid.NodeFromWorldPoint(start); GridNode targetNode = grid.NodeFromWorldPoint(end); if (targetNode.walkable) { Heap <GridNode> openSet = new Heap <GridNode>(grid.gridSizeX * grid.gridSizeY); // Sorted so that we search for the lowest cost path each time HashSet <GridNode> closedSet = new HashSet <GridNode>(); startNode.gCost = 0; startNode.hCost = GetDistance(startNode, targetNode); openSet.Add(startNode); //while there are still qualified neighbors to check while (openSet.Count > 0) { GridNode currentNode = openSet.Pop(); //add GridNode to the heap closedSet.Add(currentNode); //if the GridNode you are looking at is the target if (currentNode == targetNode) { HasPath = true; break; } //for each immediate neighbor of the current node foreach (GridNode neighbor in grid.GetNeighbors(currentNode)) { //if that GridNode is walkable and is not in the closed set/already the best path if (neighbor.walkable && !closedSet.Contains(neighbor)) { //calculate the new cost of movement int newMovementCost = currentNode.gCost + 10;//GetDistance(currentNode, neighbor); if (newMovementCost <= neighbor.gCost || !openSet.Contains(neighbor)) { neighbor.gCost = newMovementCost; neighbor.hCost = GetDistance(neighbor, targetNode); neighbor.parent = currentNode; if (!openSet.Contains(neighbor)) { openSet.Add(neighbor); } else { openSet.Sort(neighbor); } } } } //end foreach neighbor of the currentNode } //end while openSet is not empty } //end if start and end are walkable sw.Stop(); UnityEngine.Debug.Log("Elapsed Time " + sw.ElapsedMilliseconds + "ms"); if (HasPath) { waypoints = RetracePath(startNode, targetNode); } return(waypoints); }
// Function that gets called to determine if a move a player // chooses is a valid move or not. If it is, it returns true and // updates the state of the game. public bool canMove(int player, int x, int y) { bool validMovement = false; bool validTerrain = false; bool playerNotOnNode = false; GridNode targetNode = grid[x, y]; // Check for Valid Movement if (player == (int)Players.Player1) { for (int i = 0; i < 4; i++) { validMovement = movementCheck(player1Movement, i, player1X, player1Y, targetNode); if (validMovement) { break; } } } else { for (int i = 0; i < 4; i++) { validMovement = movementCheck(player2Movement, i, player2X, player2Y, targetNode); if (validMovement) { break; } } } // Check for valid terrain if (targetNode.terrain != (int)Terrains.Mountains) { validTerrain = true; } if (targetNode.terrain == (int)Terrains.Lava) { if (player == (int)Players.Player1) { player1Health = 0; } else { player2Health = 0; } } // Check that a player is not on the targeted node playerNotOnNode = !targetNode.playerOnNode(); // If everything is valid, the tank can move to that location. // Update the state of the game if (validMovement && validTerrain && playerNotOnNode) { // Update State if (player == (int)Players.Player1) { grid[player1X, player1Y].player1OnNode = false; targetNode.player1OnNode = true; player1X = targetNode.x; player1Y = targetNode.y; } else { grid[player2X, player2Y].player2OnNode = false; targetNode.player2OnNode = true; player2X = targetNode.x; player2Y = targetNode.y; } Debug.Log("Player " + player + " moves to Position: " + targetNode.x + "," + targetNode.y + " - Terrain: " + (Terrains)targetNode.terrain); return(true); } else { Debug.Log("Invalid Move! " + " - Valid Movement: " + validMovement + " - Valid Terrain: " + validTerrain + " - Player Not On Node: " + playerNotOnNode); return(false); } }
public void CalculateStep(GridNode cur_node, GridNode tar_node, EnemyLogic me, GameObject target) { me.direction = Vector2Int.zero; ReflectIncoming(me); }
public override void useCard(Character actor) { GridNode currentNode = actor.CurrentNode; if (actor.Direction == Util.Enums.Direction.Left) { if (range == 1) { while (currentNode.Left.Type == Util.Enums.FieldType.Blue) { currentNode = currentNode.Left; } if (!(currentNode.Occupied)) { currentNode.Left.Type = Util.Enums.FieldType.Blue; } } if (range == 3) { if (!(currentNode.panelExists(Util.Enums.Direction.Up))) { currentNode = currentNode.Down; } if (!(currentNode.panelExists(Util.Enums.Direction.Down))) { currentNode = currentNode.Up; } GridNode[] stolenPanels = new GridNode[3]; while (currentNode.Left.Type == Util.Enums.FieldType.Blue && currentNode.Left.Up.Type == Util.Enums.FieldType.Blue && currentNode.Left.Down.Type == Util.Enums.FieldType.Blue) { currentNode = currentNode.Left; } stolenPanels[0] = currentNode.Left; stolenPanels[1] = currentNode.Left.Up; stolenPanels[2] = currentNode.Left.Down; foreach (GridNode node in stolenPanels) { if (!(node.Occupied)) { node.Type = Util.Enums.FieldType.Blue; } } } } if (actor.Direction == Util.Enums.Direction.Right) { if (range == 1) { while (currentNode.Right.Type == Util.Enums.FieldType.Red) { currentNode = currentNode.Right; } if (!(currentNode.Occupied)) { currentNode.Right.Type = Util.Enums.FieldType.Red; } } if (range == 3) { if (!(currentNode.panelExists(Util.Enums.Direction.Up))) { currentNode = currentNode.Down; } if (!(currentNode.panelExists(Util.Enums.Direction.Down))) { currentNode = currentNode.Up; } GridNode[] stolenPanels = new GridNode[3]; while (currentNode.Right.Type == Util.Enums.FieldType.Red && currentNode.Right.Up.Type == Util.Enums.FieldType.Red && currentNode.Right.Down.Type == Util.Enums.FieldType.Red) { currentNode = currentNode.Right; } stolenPanels[0] = currentNode.Right; stolenPanels[1] = currentNode.Right.Up; stolenPanels[2] = currentNode.Right.Down; foreach (GridNode node in stolenPanels) { if (!(node.Occupied)) { node.Type = Util.Enums.FieldType.Red; } } } } }
/// <summary> /// /// </summary> /// <param name="source"></param> /// <param name="dest"></param> /// <returns>A path from source to dest, including sturce and dest</returns> public List <Vec> Run(Vec source, Vec dest) { if (float.IsInfinity(_costFunc(dest))) { return(new List <Vec>()); } _openList.Add(source, new GridNode { Parent = null, Travelled = 0, Dist = _distFunc(source - dest) }); while (true) { if (_openList.Count == 0) { Clear(); return(null); } KeyValuePair <Vec, GridNode> current = PopOpen(); _closedList.Add(current.Key, current.Value); if (current.Key == dest) { return(TraversePath(dest)); } foreach (Vec v in _neighbors) { Vec nbr = current.Key + v; if (nbr.X < 0 || nbr.Y < 0 || nbr.X >= _size.X || nbr.Y >= _size.Y) { continue; } if (_closedList.ContainsKey(nbr)) { continue; } var cost = _costFunc(nbr); if (float.IsInfinity(cost)) { continue; } var newNode = new GridNode { Travelled = current.Value.Travelled + cost * _distFunc(v), Dist = _distFunc(nbr - dest), Parent = current.Key, }; if (_openList.ContainsKey(nbr)) { var testNode = _openList[nbr]; if (testNode.PathLength <= newNode.PathLength) { continue; } } _openList[nbr] = newNode; } } }
public void SpawnGridMesh() { int width = PathfindingGridSetup.Instance.pathfindingGrid.GetWidth(); int height = PathfindingGridSetup.Instance.pathfindingGrid.GetHeight(); int count = width * height; NativeArray <Entity> entities = new NativeArray <Entity>(count, Allocator.Temp); EntityArchetype entityArchetype = entityManager.CreateArchetype( typeof(NodeComponent), typeof(RenderMesh), typeof(Translation), typeof(Scale), typeof(LocalToWorld), typeof(Collider), typeof(NonUniformScale), ComponentType.ReadWrite <WorldRenderBounds>(), ComponentType.ChunkComponent <ChunkWorldRenderBounds>() ); entityManager.CreateEntity(entityArchetype, entities); //float offset = 3.2f; int entityCounter = 0; float cellSize = 0.32f; float3 MinBound = new float3(0, 0, 0); float3 MaxBound = new float3(50, 50, 50); Material cachMaterial = new Material(Shader.Find("Unlit/Texture")); Mesh cachmesh = quad; entityManager.SetSharedComponentData(entities[entityCounter], new RenderMesh { mesh = cachmesh, material = cachMaterial }); for (int y = 0; y < width; y++) { for (int x = 0; x < height; x++) { GridNode gridNode = (GridNode)PathfindingGridSetup.Instance.pathfindingGrid.GetGridObject(x, y); Entity entity = entities[entityCounter]; float3 myPosition = new float3(x * cellSize, y * cellSize, 1.5f); entityManager.SetComponentData(entities[entityCounter], new Translation { Value = myPosition }); if (!gridNode.IsWalkable()) { entityManager.SetComponentData(entities[entityCounter], new Collider { size = 0.32f }); entityManager.SetComponentData(entities[entityCounter], new NodeComponent { nodePosition = new int2(x, y), isWalkable = false }); } else { entityManager.SetComponentData(entities[entityCounter], new NodeComponent { nodePosition = new int2(x, y), isWalkable = true }); } entityManager.SetComponentData(entities[entityCounter], new NonUniformScale { Value = 0.32f }); //entityManager.SetComponentData(entities[entityCounter], new WorldRenderBounds { Value = MaxBound }); entityCounter++; } } entities.Dispose(); }