extends Node2D var tiles = {} var offset_world = Vector2.ZERO var center_coord = Vector2.ZERO var center_world_coord = Vector2.ZERO var rect_local = Rect2() var rect_world = Rect2() var radius_world = 0.0 var is_active = false var landing_site_local_coord = null var landing_site_world = null var obstacles_local_coords = {} var treasure_local_coords = null var highlight_treasure = false var prerender_texture = null var render_sprite = null # Called when the node enters the scene tree for the first time. func _init(): render_sprite = Sprite.new() add_child(render_sprite) func set_tile(coord: Vector2, value: String): if HexTileDrawer.TileTypeFromString[value] == HexTileDrawer.TileType.None: if coord in tiles.keys(): tiles.erase(coord) else: tiles[coord] = value update() func set_offset_world(value: Vector2): offset_world = value rect_world.position = rect_local.position + value rect_world.size = rect_local.size func clear_island(): tiles = {} update() func generate_random_walk (length): var cur_hex_coord = Vector2(0,0) var i = length while (i >= 0): var cur_world_pos = Globals.HexToWorld(cur_hex_coord) tiles[cur_world_pos] = "Sand" var neighbours = Globals.HexGrid.get_hex_at(cur_hex_coord).get_all_adjacent() var exists = true for j in range (len(neighbours)): neighbours[j] = neighbours[j].axial_coords var rand_idx = randi() % 6 cur_hex_coord = cur_hex_coord + neighbours[rand_idx] i = i - 1 func extrude_island(): var old_tiles = tiles tiles = {} for tile in old_tiles: var hex_coord = Globals.WorldToHex(tile) tiles[tile] = "Sand" var neighbours = Globals.HexGrid.get_hex_at(hex_coord).get_all_adjacent() for cell in neighbours: var world_coord = Globals.HexToWorld(hex_coord + cell.axial_coords) tiles[world_coord] = "Sand" func mark_grass(): var old_tiles = tiles tiles = {} for tile in old_tiles: var hex_coord = Globals.WorldToHex(tile) var neighbours = Globals.HexGrid.get_hex_at(hex_coord).get_all_adjacent() var is_center_cell = true for cell in neighbours: var world_coord = Globals.HexToWorld(hex_coord + cell.axial_coords) if not world_coord in old_tiles.keys(): is_center_cell = false if is_center_cell: tiles[tile] = "Grass" else: tiles[tile] = "Sand" func generate(): var size = 62 generate_random_walk(size) extrude_island() mark_grass() calc_bbox() update() func calc_bbox(): var coord_min = Vector2.ONE * 10000 var coord_max = Vector2.ONE * -10000 var coords = tiles.keys() for coord in coords: var local_coords = (coord) if local_coords.x < coord_min.x: coord_min.x = local_coords.x if local_coords.y < coord_min.y: coord_min.y = local_coords.y if local_coords.x > coord_max.x: coord_max.x = local_coords.x if local_coords.y > coord_max.y: coord_max.y = local_coords.y var hex_half_size = Vector2 (Globals.hex_size * 0.5, Globals.hex_size * sqrt(3) * 0.25) rect_local = Rect2(coord_min - hex_half_size, coord_max - coord_min + hex_half_size * 2) center_world_coord = Globals.HexToWorld(Globals.WorldToHex(coord_min + 0.5 * (coord_max - coord_min))) center_coord = Globals.WorldToHex(center_world_coord) print ("center coord: " + str(center_coord)) radius_world = max(rect_local.size.x, rect_local.size.y) * 0.5 # brute force the bbox tiles obstacles_local_coords = {} var dx = Globals.hex_size * 0.5 var dy = Globals.hex_size * 0.5 var n_tiles_x = (rect_local.size.x + Globals.hex_size * 2) / dx var n_tiles_y = (rect_local.size.y + Globals.hex_size * 2) / dy for r in range (n_tiles_y): for c in range (n_tiles_x): var point_hex_local = Globals.WorldToHexCenter(Vector2(rect_local.position.x+ c * dx, rect_local.position.y + r * dy) - Vector2.ONE * Globals.hex_size * 0.5) if not obstacles_local_coords.has(point_hex_local) and not tiles.has(point_hex_local): obstacles_local_coords[point_hex_local] = "#bb44aa" func save_island(path: String): var island_save_data = File.new() island_save_data.open(path, File.WRITE) island_save_data.store_line (to_json(tiles)) island_save_data.close() func load_island(path: String): var island_save_data = File.new() if !island_save_data.file_exists(path): clear_island() return island_save_data.open(path, File.READ) var data = parse_json(island_save_data.get_line()) island_save_data.close() var data_keys = data.keys() tiles = {} var coord_regex = RegEx.new() coord_regex.compile("\\((?-?\\d+(.?\\d+)?), (?-?\\d+(.?\\d+)?)\\)") var reg_test_result = coord_regex.search("(0, 0)") assert(reg_test_result) reg_test_result = coord_regex.search("(123.124, 552.0)") assert(reg_test_result) for k in data_keys: var coords = Vector2.ZERO var regresult = coord_regex.search(k) if regresult: # print(regresult.get_string("tile_x"), " - ", regresult.get_string("tile_y")) coords = Vector2(float(regresult.get_string("tile_x")), float(regresult.get_string("tile_y"))) tiles[coords] = data[k] name = path calc_bbox() update() func check_overlap(other): var rect_world = calc_rect_world() var rect_world_other = other.calc_rect_world() return rect_world.intersects(rect_world_other) func get_tile_by_world_coord(world_coord: Vector2): var local_coord = get_local_coord_by_world_coord(world_coord) if local_coord in tiles.keys(): return tiles[local_coord] return null func is_point_on_treasure_site(world_coord: Vector2): var local_coord = get_local_coord_by_world_coord(world_coord) return treasure_local_coords != null and local_coord == treasure_local_coords func is_point_on_landing_site(world_coord: Vector2): return (Globals.WorldToHex(world_coord) - Globals.WorldToHex(landing_site_world)).length_squared() < 1 func get_local_coord_by_world_coord(world_coord: Vector2): return Globals.WorldToHexCenter(world_coord - offset_world) func calc_rect_world(): var rect_world = Rect2(rect_local) rect_world.position = transform.origin + rect_world.position + offset_world return rect_world func draw_bsphere(): var transform = get_transform() draw_set_transform(transform.origin + offset_world, transform.get_rotation(), transform.get_scale()) draw_circle(center_world_coord, radius_world, Color("#80000033")) draw_circle(center_world_coord, 10, Color.red) func _draw(): var transform = get_transform() for coord in tiles.keys(): draw_set_transform (coord + offset_world, 0, Vector2.ONE) draw_polygon(HexTileDrawer.HexPoints, HexTileDrawer.get_tile_color(tiles[coord])) if highlight_treasure and treasure_local_coords: draw_set_transform (treasure_local_coords + offset_world, 0, Vector2.ONE) draw_polygon(HexTileDrawer.HexPoints, HexTileDrawer.create_color_array("#922")) if Globals.draw_island_bbox: # draw_set_transform(transform.origin, transform.get_rotation(), transform.get_scale()) draw_rect(rect_world, Color.red, false)