001/* 002 * Trident - A Multithreaded Server Alternative 003 * Copyright 2014 The TridentSDK Team 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package net.tridentsdk.server.entity.ai.pathfind; 019 020import net.tridentsdk.base.Position; 021 022import javax.annotation.concurrent.NotThreadSafe; 023 024@NotThreadSafe 025public class Node { 026 private Node parent; 027 private final int x; 028 private final int y; 029 private final int z; 030 031 private double h = -1; 032 private double g = -1; 033 private double f = -1; 034 035 public Node(Node parent, Position position) { 036 this(parent, position.x(), position.y(), position.z()); 037 } 038 039 public Node(Node parent, double x, double y, double z) { 040 this(parent, (int) x, (int) y, (int) z); 041 } 042 043 public Node(Node parent, int x, int y, int z) { 044 this.parent = parent; 045 this.x = x; 046 this.y = y; 047 this.z = z; 048 } 049 050 /** 051 * Get f value of node. 052 * 053 * @return F value 054 */ 055 public double getF() { 056 return f; 057 } 058 059 /** 060 * Get node relative to current. 061 * 062 * @param dx relative x 063 * @param dy relative y 064 * @param dz relative z 065 * @return Relative node with current as parent 066 */ 067 public Node getRelative(int dx, int dy, int dz) { 068 return new Node(this, x + dx, y + dy, z + dz); 069 } 070 071 /** 072 * Get the node x coord. 073 * 074 * @return X coord of node 075 */ 076 public int x() { 077 return x; 078 } 079 080 /** 081 * Get the node y coord 082 * 083 * @return Y coord of node 084 */ 085 public int y() { 086 return y; 087 } 088 089 /** 090 * Get the node z coord 091 * 092 * @return Z coord of node 093 */ 094 public int z() { 095 return z; 096 } 097 098 /** 099 * Set the node's parent. 100 * 101 * @param parent New parent of node 102 */ 103 public void setParent(Node parent) { 104 this.parent = parent; 105 } 106 107 /** 108 * Get the current node parent. 109 * 110 * @return Parent of node 111 */ 112 public Node parent() { 113 return parent; 114 } 115 116 /** 117 * Calculate distance cost based on euclidean distance. 118 * 119 * @param target Final tile in path 120 */ 121 public void calculateH(Node target) { 122 this.h = distance(target); 123 } 124 125 /** 126 * Calculate movement cost, we dislike jumping and moving diagonally. 127 */ 128 public void calculateG() { 129 double dx = Math.abs(x - parent.x); 130 double dy = Math.abs(y - parent.y); 131 double dz = Math.abs(z - parent.z); 132 this.g = parent.g; // Append to G value of parent 133 134 // We dislike jumping because we are lazy 135 if(dx == 1 && dy == 1 && dz == 1) { 136 g += 1.7; 137 } else if((dx == 1 && dz == 1) || dy == 1) { 138 g += 1.4; 139 } else { 140 g += 1.0; 141 } 142 } 143 144 /** 145 * Calculate F value, basically H + G. 146 */ 147 public void calculateF() { 148 this.f = h + g; 149 } 150 151 /** 152 * Calculate all movement values in one go. 153 * 154 * @param target Final tile in path 155 */ 156 public void calculateHGF(Node target) { 157 calculateH(target); 158 calculateG(); 159 calculateF(); 160 } 161 162 /** 163 * Distance squared between this node and another 164 * 165 * @param with Node to compare with 166 * @return Squared distance 167 */ 168 public double distance(Node with) { 169 int dx = with.x - x; 170 int dy = with.y - y; 171 int dz = with.z - z; 172 return dx * dx + dy * dy + dz * dz; 173 } 174 175 @Override 176 public boolean equals(Object o) { 177 if (this == o) return true; 178 if (o == null || getClass() != o.getClass()) return false; 179 180 Node node = (Node) o; 181 182 return x == node.x && y == node.y && z == node.z; 183 } 184 185 @Override 186 public int hashCode() { 187 int result = x; 188 result = 31 * result + y; 189 result = 31 * result + z; 190 return result; 191 } 192 193 @Override 194 public String toString() { 195 return "Tile{" + 196 "parent=" + parent + 197 ", x=" + x + 198 ", y=" + y + 199 ", z=" + z + 200 '}'; 201 } 202}