├── .gitignore ├── HexGrid.cpp ├── HexGrid.h ├── README.md ├── SCsub ├── config.py ├── register_types.cpp └── register_types.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | 3 | -------------------------------------------------------------------------------- /HexGrid.cpp: -------------------------------------------------------------------------------- 1 | #include "HexGrid.h" 2 | #define _USE_MATH_DEFINES 3 | #include 4 | #include 5 | using std::abs; 6 | using std::max; 7 | 8 | 9 | HexGrid::HexGrid(){ 10 | rows = 10; 11 | cols = 10; 12 | size = Vector2(10,10); 13 | origin = Vector2(0,0); 14 | grid_layout = "flat"; 15 | setUpConstants(); 16 | } 17 | 18 | void HexGrid::setUpConstants(){ 19 | 20 | //hex directions 21 | //I'm such a noob I have no clue how to simply create the array. =( 22 | hex_directions.push_back(Vector3(1,0,-1)); 23 | hex_directions.push_back(Vector3(1,-1,0)); 24 | hex_directions.push_back(Vector3(0,-1,1)); 25 | hex_directions.push_back(Vector3(-1,0,1)); 26 | hex_directions.push_back(Vector3(-1,1,0)); 27 | hex_directions.push_back(Vector3(0,1,-1)); 28 | 29 | layout_pointy["f0"] = sqrt(3.0); 30 | layout_pointy["f1"] = sqrt(3.0) / 2.0; 31 | layout_pointy["f2"] = 0.0; 32 | layout_pointy["f3"] = 3.0 / 2.0; 33 | layout_pointy["b0"] = sqrt(3.0) / 3.0; 34 | layout_pointy["b1"] = -1.0 / 3.0; 35 | layout_pointy["b2"] = 0.0; 36 | layout_pointy["b3"] = 2.0 / 3.0; 37 | layout_pointy["start_angle"] = 0.5; 38 | 39 | layout_flat["f0"] = 3.0 / 2.0; 40 | layout_flat["f1"] = 0.0; 41 | layout_flat["f2"] = sqrt(3.0) / 2.0; 42 | layout_flat["f3"] = sqrt(3.0); 43 | layout_flat["b0"] = 2.0 / 3.0; 44 | layout_flat["b1"] = 0.0; 45 | layout_flat["b2"] = -1.0 / 3.0; 46 | layout_flat["b3"] = sqrt(3.0) / 3.0; 47 | layout_flat["start_angle"] = 0.0; 48 | 49 | setupLayout(); 50 | 51 | } 52 | 53 | void HexGrid::setupLayout(){ 54 | if (grid_layout == "flat"){ 55 | orient["f0"] = layout_flat["f0"]; 56 | orient["f1"] = layout_flat["f1"]; 57 | orient["f2"] = layout_flat["f2"]; 58 | orient["f3"] = layout_flat["f3"]; 59 | orient["b0"] = layout_flat["b0"]; 60 | orient["b1"] = layout_flat["b1"]; 61 | orient["b2"] = layout_flat["b2"]; 62 | orient["b3"] = layout_flat["b3"]; 63 | orient["start_angle"] = layout_flat["start_angle"]; 64 | } else { 65 | orient["f0"] = layout_pointy["f0"]; 66 | orient["f1"] = layout_pointy["f1"]; 67 | orient["f2"] = layout_pointy["f2"]; 68 | orient["f3"] = layout_pointy["f3"]; 69 | orient["b0"] = layout_pointy["b0"]; 70 | orient["b1"] = layout_pointy["b1"]; 71 | orient["b2"] = layout_pointy["b2"]; 72 | orient["b3"] = layout_pointy["b3"]; 73 | orient["start_angle"] = layout_pointy["start_angle"]; 74 | } 75 | createMap(); 76 | } 77 | 78 | //Random things not really related to the calculation of Hex 79 | void HexGrid::set_rows(int r){ 80 | rows = r; 81 | } 82 | 83 | void HexGrid::set_cols(int c){ 84 | cols = c; 85 | } 86 | 87 | void HexGrid::set_rows_and_cols(int r, int c){ 88 | set_cols(c); 89 | set_rows(r); 90 | } 91 | 92 | void HexGrid::set_hex_size(Vector2 size_){ 93 | size = size_; 94 | } 95 | 96 | void HexGrid::set_origin(Vector2 origin_){ 97 | origin = origin_; 98 | } 99 | 100 | void HexGrid::set_layout(String layout){ 101 | grid_layout = layout; 102 | setupLayout(); 103 | } 104 | 105 | Vector2 HexGrid::point(double x, double y){ 106 | return Vector2(x,y); 107 | } 108 | 109 | Vector3 HexGrid::hex(int q, int r, int s) 110 | { 111 | return Vector3(q,r,s); 112 | } 113 | 114 | Vector3 HexGrid::fractionalHex(double q, double r,double s){ 115 | return Vector3(q,r,s); 116 | } 117 | 118 | Vector2 HexGrid::offsetCoord(int r, int c){ 119 | return Vector2(r,c); 120 | } 121 | 122 | Vector3 HexGrid::hex_add(Vector3 a, Vector3 b) 123 | { 124 | return Vector3(a.x + b.x, a.y + b.y, a.z + b.z); 125 | } 126 | 127 | Vector3 HexGrid::hex_subtract(Vector3 a, Vector3 b) 128 | { 129 | return Vector3(a.x - b.x, a.y - b.y, a.z - b.z); 130 | } 131 | 132 | Vector3 HexGrid::hex_scale(Vector3 a, int k) 133 | { 134 | return Vector3(a.x * k, a.y * k, a.z * k); 135 | } 136 | 137 | Vector3 HexGrid::hex_direction(int direction) 138 | { 139 | return hex_directions[direction]; 140 | } 141 | 142 | Vector3 HexGrid::hex_neighbor(Vector3 hex, int direction) 143 | { 144 | return hex_add(hex, hex_direction(direction)); 145 | } 146 | 147 | Array HexGrid::hex_neighbors(Vector3 hex) 148 | { 149 | Array results; 150 | for (int i = 0; i < 6; i++) 151 | { 152 | results.push_back(hex_neighbor(hex,i)); 153 | } 154 | return results; 155 | } 156 | 157 | 158 | int HexGrid::hex_length(Vector3 hex) 159 | { 160 | return int((abs(hex.x) + abs(hex.y) + abs(hex.z)) / 2); 161 | } 162 | 163 | int HexGrid::hex_distance(Vector3 a, Vector3 b) 164 | { 165 | return hex_length(hex_subtract(a, b)); 166 | } 167 | 168 | Vector3 HexGrid::hex_round(Vector3 h) 169 | { 170 | int q = int(round(h.x)); 171 | int r = int(round(h.y)); 172 | int s = int(round(h.z)); 173 | double q_diff = abs(q - h.x); 174 | double r_diff = abs(r - h.y); 175 | double s_diff = abs(s - h.z); 176 | if (q_diff > r_diff && q_diff > s_diff) 177 | { 178 | q = -r - s; 179 | } 180 | else 181 | if (r_diff > s_diff) 182 | { 183 | r = -q - s; 184 | } 185 | else 186 | { 187 | s = -q - r; 188 | } 189 | return Vector3(q, r, s); 190 | } 191 | 192 | Vector3 HexGrid::hex_lerp(Vector3 a, Vector3 b, double t) 193 | { 194 | return Vector3(a.x * (1 - t) + b.x * t, a.y * (1 - t) + b.y * t, a.z * (1 - t) + b.z * t); 195 | } 196 | 197 | Array HexGrid::hex_linedraw(Vector3 a, Vector3 b) 198 | { 199 | int N = hex_distance(a, b); 200 | Vector3 a_nudge = fractionalHex(a.x + 0.000001, a.y + 0.000001, a.z - 0.000002); 201 | Vector3 b_nudge = fractionalHex(b.x + 0.000001, b.y + 0.000001, b.z - 0.000002); 202 | Array results; 203 | double step = 1.0 / max(N, 1); 204 | for (int i = 0; i <= N; i++) 205 | { 206 | results.push_back(hex_round(hex_lerp(a_nudge, b_nudge, step * i))); 207 | } 208 | return results; 209 | } 210 | 211 | Vector2 HexGrid::hex_to_point(Vector3 h) 212 | { 213 | double x = (double(orient["f0"]) * h.x + double(orient["f1"]) * h.y) * size.x; 214 | double y = (double(orient["f2"]) * h.x + double(orient["f3"]) * h.y) * size.y; 215 | 216 | return Vector2(x + origin.x, y + origin.y); 217 | } 218 | 219 | Vector3 HexGrid::point_to_hex(Vector2 p) 220 | { 221 | Vector2 pt = Vector2((p.x - origin.x) / size.x, (p.y - origin.y) / size.y); 222 | double q = double(orient["b0"]) * pt.x + double(orient["b1"]) * pt.y; 223 | double r = double(orient["b2"]) * pt.x + double(orient["b3"]) * pt.y; 224 | 225 | return hex_round(Vector3(q, r, -q - r)); 226 | } 227 | 228 | Vector2 HexGrid::hex_corner_offset(int corner) 229 | { 230 | double angle = 2.0 * M_PI * (corner + double(orient["start_angle"])) / 6; 231 | return Vector2(size.x * cos(angle), size.y * sin(angle)); 232 | } 233 | 234 | Array HexGrid::hex_corners(Vector3 h) 235 | { 236 | Array corners; 237 | Vector2 center = hex_to_point(h); 238 | for (int i = 1; i < 7; i++) 239 | { 240 | Vector2 offset = hex_corner_offset(i); 241 | corners.push_back(Vector2(center.x + offset.x, center.y + offset.y)); 242 | } 243 | return corners; 244 | } 245 | 246 | Array HexGrid::hex_edges(Vector3 hex){ 247 | Array edges; 248 | Array corners = hex_corners(hex); 249 | for (int i = 0; i < 6; i++){ 250 | int l = i+1; 251 | if(l == 6){ 252 | l = 0; 253 | } 254 | Array edge; 255 | edge.push_back(corners[l]); 256 | edge.push_back(corners[i]); 257 | edges.push_back(edge); 258 | } 259 | return edges; 260 | } 261 | 262 | //This makes a ring 263 | Array HexGrid::hexes_at_distance(Vector3 hex,int dist) 264 | { 265 | Array results; 266 | Vector3 pHex = hex_add(hex,hex_scale(hex_direction(4), dist)); 267 | for (int i = 0; i < 6; i++) 268 | { 269 | for (int j = 0; j < dist; j++){ 270 | results.push_back(pHex); 271 | pHex = hex_neighbor(pHex,i); 272 | } 273 | } 274 | return results; 275 | } 276 | 277 | Array HexGrid::hexes_within_distance(Vector3 hex,int dist) 278 | { 279 | Array results; 280 | results.push_back(hex); 281 | for (int i = 1; i < dist; i++){ 282 | Array subR = hexes_at_distance(hex,i); 283 | for (int j = 0; j < subR.size(); j++){ 284 | results.push_back(subR[j]); 285 | } 286 | } 287 | return results; 288 | } 289 | 290 | bool HexGrid::los_clear_to(Vector3 start, Vector3 finish,Array obstacles){ 291 | bool clear = true; 292 | Array line; 293 | line.push_back(hex_to_point(start)); 294 | line.push_back(hex_to_point(finish)); 295 | 296 | //This offcenters it just enough to not go through the point GHETTO i know but it sorta works enough 297 | Vector2 line0 = line[0]; 298 | line0.y = line0.y+0.005; 299 | 300 | for(int i = 0; i < obstacles.size(); i++){ 301 | if(line.size() == 2 && obstacles.size() > i){ 302 | if(line_intersect_hex(obstacles[i],line0,line[1])){ 303 | clear = false; 304 | } 305 | } 306 | } 307 | return clear; 308 | } 309 | 310 | Array HexGrid::los_within_range(Vector3 hex,int dist, Array obstacles, Array checkList){ 311 | Array outList; 312 | if(checkList.size() == 0){ 313 | checkList = hexes_within_distance(hex, dist); 314 | } 315 | for(int i = 0; i < checkList.size(); i++){ 316 | if(los_clear_to(checkList[i], hex,obstacles)){ 317 | outList.push_back(checkList[i]); 318 | } 319 | } 320 | return outList; 321 | } 322 | 323 | bool HexGrid::lines_intersect(Vector2 l1Start,Vector2 l1End, Vector2 l2Start, Vector2 l2End){ 324 | bool results = false; 325 | 326 | double line1StartX = l1Start.x; 327 | double line1StartY = l1Start.y; 328 | double line1EndX = l1End.x; 329 | double line1EndY = l1End.y; 330 | 331 | double line2StartX = l2Start.x; 332 | double line2StartY = l2Start.y; 333 | double line2EndX = l2End.x; 334 | double line2EndY = l2End.y; 335 | double denominator = ((line2EndY - line2StartY) * (line1EndX - line1StartX)) - ((line2EndX - line2StartX) * (line1EndY - line1StartY)); 336 | 337 | if(denominator == 0){ 338 | return results; 339 | } 340 | 341 | double a = line1StartY - line2StartY; 342 | double b = line1StartX - line2StartX; 343 | double numerator1 = ((line2EndX - line2StartX) * a) - ((line2EndY - line2StartY) * b); 344 | double numerator2 = ((line1EndX - line1StartX) * a) - ((line1EndY - line1StartY) * b); 345 | a = numerator1 / denominator; 346 | b = numerator2 / denominator; 347 | 348 | if(a > 0 && a < 1 && b > 0 && b < 1){ 349 | results = true; 350 | } 351 | return results; 352 | } 353 | 354 | bool HexGrid::line_intersect_hex(Vector3 hex,Vector2 lStart, Vector2 lEnd){ 355 | bool crosses = false; 356 | Array edges = hex_edges(hex); 357 | for (int i = 0; i < edges.size(); i++){ 358 | if (edges.size() > i){ 359 | Array edge = edges[i]; 360 | if (lines_intersect(lStart,lEnd,edge[0],edge[1])){ 361 | crosses = true; 362 | } 363 | } 364 | } 365 | return crosses; 366 | } 367 | 368 | void HexGrid::createMap(){ 369 | if(grid_layout == "pointy"){ 370 | makePointyMap(); 371 | } else { 372 | makeFlatMap(); 373 | } 374 | } 375 | 376 | void HexGrid::makePointyMap(){ 377 | hex_map.clear(); 378 | for(int r = 0; r= 0){ 428 | if(hexList.find(neighs[_i]) > -1){ 429 | hEdges.remove(_i); 430 | } 431 | _i--; 432 | } 433 | for(int e = 0; e < hEdges.size(); e++){ 434 | lines.append(hEdges[e]); 435 | } 436 | } 437 | return lines; 438 | } 439 | 440 | Array HexGrid::astar_get_path_to(Vector3 startHex, Vector3 endHex, Array obstacles, int dist){ 441 | int lowInd = 0; 442 | Dictionary currentNode; 443 | Dictionary curr; 444 | Dictionary neighbor; 445 | Dictionary nei; 446 | Array neighbors; 447 | Array openList; 448 | Array closedList; 449 | Array ret; 450 | // int n; 451 | int gScore; 452 | bool gScoreIsBest; 453 | bool isClosed; 454 | bool isObstacle; 455 | bool visited; 456 | bool nFound; 457 | 458 | Dictionary tN; 459 | Dictionary lTN; 460 | 461 | for(int i = 0; i < astar_grid.size(); i++){ 462 | _astar_reset_Nhex(i,obstacles); 463 | } 464 | 465 | for(int i = 0; i < astar_grid.size(); i++){ 466 | Dictionary agi = astar_grid[i]; 467 | if(agi["id"] == startHex){ 468 | openList.push_back(agi["id"]); 469 | } 470 | } 471 | 472 | int its = 0; 473 | while(openList.size() > 0){ 474 | its +=1; 475 | 476 | //TODO maybe the low index changes is causing a problem 477 | lowInd = 0; 478 | for(int i = 0; i < openList.size(); i++){ 479 | tN = _astar_get_grid_item_from_id(openList[i]); 480 | lTN = _astar_get_grid_item_from_id(openList[lowInd]); 481 | 482 | if(tN["f"] < lTN["f"]){ 483 | lowInd = i; 484 | } 485 | } 486 | lTN = _astar_get_grid_item_from_id(openList[lowInd]); 487 | 488 | currentNode = lTN; 489 | 490 | 491 | if(currentNode["id"] == endHex){ 492 | 493 | while(curr["hasParent"]){ 494 | 495 | ret.push_back("I am going to loos it"); 496 | return ret; 497 | 498 | ret.push_back(curr); 499 | curr = _astar_get_grid_item_from_id(currentNode["parent"]); 500 | // return ret; 501 | } 502 | 503 | //i may need to invert the path here 504 | ret.push_back("Im returning it at line 482"); 505 | return ret; 506 | } 507 | 508 | openList.remove(lowInd); 509 | ret.push_back(openList.size()); 510 | if(its > 50){ 511 | ret.push_back("it is greater than 50"); 512 | return ret; 513 | } 514 | 515 | currentNode["closed"] = true; 516 | neighbors = currentNode["neighbors"]; 517 | 518 | nFound = false; 519 | for(int i = 0; i < neighbors.size(); i++){ 520 | 521 | neighbor = _astar_get_grid_item_from_id(neighbors[i]); 522 | if(neighbor["found"]){ 523 | nFound = true; 524 | } 525 | 526 | if(nFound == true){ 527 | isClosed = neighbor["closed"]; 528 | isObstacle = neighbor["isObstacle"]; 529 | visited = neighbor["visited"]; 530 | 531 | if(neighbor.size() >=1 && isClosed == false && isObstacle == false ){ 532 | gScore = int(currentNode["g"]) + 1; 533 | gScoreIsBest = false; 534 | if(visited == false){ 535 | gScoreIsBest = true; 536 | neighbor["h"] = hex_distance(neighbor["id"], endHex); 537 | neighbor["visited"] = true; 538 | 539 | openList.push_back(neighbor["id"]); 540 | 541 | } else if(gScore < int(neighbor["g"])){ 542 | gScoreIsBest = true; 543 | } 544 | 545 | if(gScoreIsBest){ 546 | 547 | neighbor["parent"] = currentNode["id"]; 548 | neighbor["hasParent"] = true; 549 | neighbor["g"] = gScore; 550 | neighbor["f"] = double(neighbor["g"])+double(neighbor["h"]); 551 | 552 | } 553 | } 554 | } 555 | } 556 | } 557 | //ret.push_back(endHex); 558 | //ret.push_back(startHex); 559 | // ret.push_back(its); 560 | return ret; 561 | 562 | } 563 | 564 | //the ranglist is a list of all the tiles or the possible tiles to get to 565 | Array HexGrid::astar_grid_setup(Array obstacles, Array rangeList){ 566 | astar_grid.clear(); 567 | if(rangeList.size() == 0){ 568 | rangeList == hex_map; 569 | } 570 | for (int i=0; i < rangeList.size(); i++){ 571 | Dictionary nHex = _astar_gridify_hex(rangeList[i]); 572 | for(int o = 0; o < obstacles.size(); o++){ 573 | if (obstacles[o] == nHex){ 574 | nHex["isObstacle"] = true; 575 | } 576 | } 577 | astar_grid.push_back(nHex); 578 | } 579 | return astar_grid; 580 | } 581 | 582 | void HexGrid::_astar_reset_Nhex(int index,Array obstacles){ 583 | //this is probably wrong ... I should be using pointers or something 584 | Dictionary i = astar_grid[index]; 585 | i["f"] = 0; 586 | i["g"] = 0; 587 | i["h"] = 0; 588 | i["debug"] = ""; 589 | i["parent"] = false; 590 | i["hasParent"] = false; 591 | i["closed"] = false; 592 | i["visited"] = false; 593 | i["found"] = true; 594 | 595 | for(int o = 0; o < obstacles.size(); o++){ 596 | if (obstacles[o] == i["id"]){ 597 | i["isObstacle"] = true; 598 | } 599 | } 600 | astar_grid[index] = i; 601 | } 602 | 603 | Dictionary HexGrid::_astar_get_grid_item_from_id(Vector3 hex){ 604 | Dictionary t; 605 | for(int i = 0; i < astar_grid.size(); i++){ 606 | t = astar_grid[i]; 607 | if(t["id"] == hex){ 608 | return t; 609 | } 610 | } 611 | t["found"] = false; 612 | return t; 613 | } 614 | 615 | Dictionary HexGrid::_astar_gridify_hex(Vector3 hex){ 616 | Dictionary nHex; 617 | //this is ghetto but I cannot seem to use normal ways for converting numbers to strings so I'm just going to use the vector for the id until I figure it out 618 | nHex["id"] = hex; 619 | if(hex_map.find(hex) > -1){ 620 | nHex["neighbors"] = hex_neighbors(hex);//engine._neighbors(hGrid.map[hex]) 621 | nHex["q"] = hex.x; 622 | nHex["r"] = hex.y; 623 | nHex["s"] = hex.z; 624 | nHex["f"] = 0; 625 | nHex["g"] = 0; 626 | nHex["h"] = 0; 627 | // nHex.debug = "" 628 | nHex["parent"] = false; 629 | nHex["hasParent"] = false; 630 | nHex["isObstacle"] = false; 631 | nHex["closed"] = false; 632 | nHex["visited"] = false; 633 | nHex["found"] = true; 634 | } 635 | return nHex; 636 | } 637 | 638 | void HexGrid::_bind_methods() { 639 | ClassDB::bind_method("set_rows",&HexGrid::set_rows); 640 | ClassDB::bind_method("set_cols",&HexGrid::set_cols); 641 | ClassDB::bind_method("set_layout",&HexGrid::set_layout); 642 | 643 | ClassDB::bind_method("hex",&HexGrid::hex); 644 | ClassDB::bind_method("point",&HexGrid::point); 645 | ClassDB::bind_method("hex_add",&HexGrid::hex_add); 646 | ClassDB::bind_method("hex_subtract",&HexGrid::hex_subtract); 647 | ClassDB::bind_method("hex_scale",&HexGrid::hex_scale); 648 | ClassDB::bind_method("hex_distance",&HexGrid::hex_distance); 649 | ClassDB::bind_method("hex_neighbor",&HexGrid::hex_neighbor); 650 | ClassDB::bind_method("hex_neighbors",&HexGrid::hex_neighbors); 651 | ClassDB::bind_method("hex_round",&HexGrid::hex_round); 652 | ClassDB::bind_method("hex_linedraw",&HexGrid::hex_linedraw); 653 | ClassDB::bind_method("set_hex_size",&HexGrid::set_hex_size); 654 | ClassDB::bind_method("set_origin",&HexGrid::set_origin); 655 | 656 | ClassDB::bind_method("hex_to_point",&HexGrid::hex_to_point); 657 | ClassDB::bind_method("point_to_hex",&HexGrid::point_to_hex); 658 | ClassDB::bind_method("hex_corners",&HexGrid::hex_corners); 659 | ClassDB::bind_method("hex_edges",&HexGrid::hex_edges); 660 | 661 | ClassDB::bind_method("get_map",&HexGrid::get_map); 662 | 663 | ClassDB::bind_method("line_intersect_hex",&HexGrid::line_intersect_hex); 664 | ClassDB::bind_method("lines_intersect",&HexGrid::lines_intersect); 665 | ClassDB::bind_method("los_clear_to",&HexGrid::los_clear_to); 666 | //los_within_range 667 | ClassDB::bind_method("los_within_range",&HexGrid::los_within_range); 668 | 669 | ClassDB::bind_method("hexes_at_distance",&HexGrid::hexes_at_distance); 670 | ClassDB::bind_method("hexes_within_distance",&HexGrid::hexes_within_distance); 671 | ClassDB::bind_method("hexes_outlined",&HexGrid::hexes_outlined); 672 | 673 | // ClassDB::bind_method("astar_get_path_to",&HexGrid::astar_get_path_to); 674 | // ClassDB::bind_method("astar_grid_setup",&HexGrid::astar_grid_setup); 675 | } 676 | -------------------------------------------------------------------------------- /HexGrid.h: -------------------------------------------------------------------------------- 1 | #ifndef HEXGRID_H 2 | #define HEXGRID_H 3 | #include "scene/main/node.h" 4 | 5 | class HexGrid : public Node { 6 | GDCLASS(HexGrid,Node); 7 | int cols; 8 | int rows; 9 | Vector2 size; 10 | Vector2 origin; 11 | Dictionary orient; 12 | Array hex_directions; 13 | String grid_layout; 14 | Dictionary _grid_layout; 15 | 16 | Array astar_grid; 17 | Array hex_map; 18 | 19 | //these may be a waste 20 | Dictionary layout_pointy;//orientations 21 | Dictionary layout_flat;//orientaions 22 | 23 | protected: 24 | void setUpConstants(); 25 | static void _bind_methods(); 26 | 27 | public: 28 | void setupLayout(); 29 | void createMap(); 30 | void makeFlatMap(); 31 | void makePointyMap(); 32 | 33 | Vector3 hex(int q, int r, int s); 34 | Vector3 fractionalHex(double q, double r, double s); 35 | Vector2 point(double x, double y); 36 | Vector2 offsetCoord(int r, int c); 37 | Vector3 hex_add(Vector3 a, Vector3 b); 38 | Vector3 hex_subtract(Vector3 a, Vector3 b); 39 | Vector3 hex_scale(Vector3 a, int k); 40 | Vector3 hex_direction(int direction); 41 | Vector3 hex_neighbor(Vector3 hex, int direction); 42 | Array hex_neighbors(Vector3 hex); 43 | int hex_length(Vector3 hex); 44 | int hex_distance(Vector3 a, Vector3 b); 45 | Vector3 hex_round(Vector3 h); 46 | Vector3 hex_lerp(Vector3 a, Vector3 b, double t); 47 | Array hex_linedraw(Vector3 a, Vector3 b); 48 | Vector2 hex_to_point(Vector3 h); 49 | Vector3 point_to_hex(Vector2 p); 50 | Vector2 hex_corner_offset(int corner); 51 | Array hex_corners(Vector3 h); 52 | Array hex_edges(Vector3 hex); 53 | 54 | Array hexes_at_distance(Vector3 hex,int dist); 55 | Array hexes_within_distance(Vector3 hex,int dist); 56 | 57 | Array hexes_outlined(Array hexList); 58 | 59 | bool line_intersect_hex(Vector3 hex,Vector2 lStart, Vector2 lEnd); 60 | bool lines_intersect(Vector2 l1Start,Vector2 l1End, Vector2 l2Start, Vector2 l2End); 61 | bool los_clear_to(Vector3 start, Vector3 finish,Array obstacles); 62 | Array los_within_range(Vector3 hex,int dist, Array obstacles, Array checkList); 63 | 64 | void set_hex_size(Vector2 size_); 65 | void set_origin(Vector2 origin_); 66 | Array get_map(); 67 | 68 | void set_layout(String layout); 69 | void set_rows(int r); 70 | void set_cols(int c); 71 | void set_rows_and_cols(int c, int r); 72 | int get_values(); 73 | 74 | Array astar_get_path_to(Vector3 startHex, Vector3 endHex, Array obstacles, int dist); 75 | Array astar_grid_setup(Array obstacles, Array rangeList); 76 | void _astar_reset_Nhex(int index, Array obstacles); 77 | Dictionary _astar_gridify_hex(Vector3 hex); 78 | Dictionary _astar_get_grid_item_from_id(Vector3 hex); 79 | HexGrid(); 80 | }; 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HexModule 2 | a module for hex grids in c++ for Godot Game Engine. 3 | -------------------------------------------------------------------------------- /SCsub: -------------------------------------------------------------------------------- 1 | # SCsub 2 | Import('env') 3 | 4 | env.add_source_files(env.modules_sources,"*.cpp") 5 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | def can_build(platform): 2 | return True 3 | 4 | def configure(env): 5 | pass 6 | -------------------------------------------------------------------------------- /register_types.cpp: -------------------------------------------------------------------------------- 1 | #include "register_types.h" 2 | #include "class_db.h" 3 | #include "HexGrid.h" 4 | 5 | void register_hex_types() { 6 | 7 | ClassDB::register_class(); 8 | // ObjectTypeDB::register_type(); 9 | } 10 | 11 | void unregister_hex_types() { 12 | //nothing to do here 13 | } 14 | -------------------------------------------------------------------------------- /register_types.h: -------------------------------------------------------------------------------- 1 | void register_hex_types(); 2 | void unregister_hex_types(); 3 | /* yes, the word in the middle must be the same as the module folder name */ 4 | --------------------------------------------------------------------------------