extends Node2D onready var Grid = get_node("Grid") onready var GridHighlight = get_node("GridHighlight") onready var Islands = get_node("Islands") onready var EditIslandButton = get_node("UI/TopContainer/EditIslandButton") onready var WorldCamera = get_node("Camera") onready var OffsetValueLabel = get_node("UI/TopContainer/OffsetValue") onready var ZoomValueLabel = get_node("UI/TopContainer/ZoomValue") onready var HexCoordValueLabel = get_node("UI/TopContainer/HexCoordValue") onready var WorldCoordValueLabel = get_node("UI/TopContainer/WorldCoordValue") onready var TileTypeValueLabel = get_node("UI/TopContainer/TileTypeValue") onready var PlayerChar = get_node("PlayerChar") onready var PlayerBoat = get_node("PlayerBoat") onready var FPSValueLabel = get_node("UI/TopContainer/FPSValue") var Island = preload("Island.gd") var hex_grid_bbox = [[0,0], [10,10]] var hex_hover = Vector2.ZERO var is_dragging = false var drag_start = null var target = Vector2() var tile_data = {} var current_island = null var player_navigation_path = [] var hex_line_path = [] # # Godot Functions # func _ready(): Grid.view_camera = WorldCamera GridHighlight.view_camera = WorldCamera generate() # Set player starting position PlayerChar.position = Globals.HexGrid.get_hex_center(Vector2(0,0)) func _process(_delta): WorldCamera.offset = PlayerChar.position PlayerBoat.transform.origin = PlayerChar.transform.origin if len(player_navigation_path) > 1: var player_coord = Globals.WorldToHexCenter(PlayerChar.transform.origin) if (player_coord - player_navigation_path[0]).length_squared() < 0.1: player_navigation_path.remove(0) if len(player_navigation_path) > 0: PlayerChar.target = player_navigation_path[0] update_current_island() if current_island: PlayerBoat.visible = false else: PlayerBoat.visible = true func draw_hex_path (path: Array, color: Color): var path_len = len(path) if path_len > 0: var last_point = path[0] draw_circle(last_point, 5, color) for i in range (1, path_len): var cur_point = path[i] draw_line (last_point, cur_point, color) draw_circle(cur_point, 5, color) last_point = cur_point func _draw(): draw_hex_path (hex_line_path, "#00f2f2") draw_hex_path (player_navigation_path, "#f200f2") # # World Modification/Query # func clear_islands(): for island in Islands.get_children(): Islands.remove_child(island) island.queue_free() func get_tile_type(world_coord: Vector2): for island in Islands.get_children(): var tile = island.get_tile_by_world_coord(world_coord) if tile != null: return tile return null func add_island_at(file_name, offset_world: Vector2): var island = Island.new() island.load_island(file_name) island.offset_world = offset_world Islands.add_child(island) func check_island_location_valid(new_island): var grid_origin_world_coord = Globals.HexToWorld(Vector2(0,0)) if new_island.get_tile_by_world_coord(grid_origin_world_coord) != null: return false var islands = Islands.get_children() for island in islands: if island.check_overlap(new_island): return false return true func generate(): PlayerChar.transform.origin = Vector2.ZERO PlayerChar.position = Vector2.ZERO var rng = RandomNumberGenerator.new() rng.randomize() clear_islands() var radius = 800 var num_islands = 10 for i in range (num_islands): var island = Island.new() var island_index = i % 4 var file_name = "user://pirate_game_island_" + str(island_index) + ".island" island.load_island(file_name) var rand_coord = Vector2(rng.randi_range(-radius, radius), rng.randi_range(-radius, radius)) island.offset_world = Globals.WorldToHexCenter(rand_coord) var location_valid = check_island_location_valid(island) var overlap_retry_num = 0 var overlap_retry_max = 10 while !location_valid and overlap_retry_num < overlap_retry_max: if overlap_retry_num % 4 == 0: radius = radius + 200 overlap_retry_num = overlap_retry_num + 1 rand_coord = Vector2(rng.randi_range(-radius, radius), rng.randi_range(-radius, radius)) island.offset_world = Globals.WorldToHexCenter(rand_coord) location_valid = check_island_location_valid(island) if !location_valid: print ("Could not place island! steps: " + str(overlap_retry_num)) else: print ("Placed after " + str(overlap_retry_num) + " retries.") Islands.add_child(island) populate_ocean_grid() # var island = Islands.get_children()[0] # var player_pos = island.center_world_coord + island.offset_world # PlayerChar.position = player_pos # PlayerChar.target = player_pos # PlayerChar.update() # print (player_pos) # # Navigation # func populate_ocean_grid(): var obstacles = Globals.OceanGrid.get_obstacles() Globals.OceanGrid.remove_obstacles(obstacles.keys()) Globals.OceanGrid.set_bounds(Vector2.ONE * -500, Vector2.ONE * 500) for island in Islands.get_children(): for tile in island.tiles.keys(): var grid_coords = Globals.WorldToHex(tile + island.offset_world) Globals.OceanGrid.add_obstacles(grid_coords, 15) func update_current_island(): var islands = Islands.get_children() var last_current_island = current_island current_island = null for island in islands: if island.get_tile_by_world_coord(PlayerChar.position) != null: current_island = island break if last_current_island != current_island: if last_current_island != null: last_current_island.is_active = false last_current_island.update() if current_island != null: current_island.is_active = true current_island.update() func update_player_navigation_target(target_world: Vector2): player_navigation_path = [] var start_world = PlayerChar.transform.origin var start_coord = Globals.WorldToHex(start_world) var goal_coord = Globals.WorldToHex(target_world) if get_tile_type(target_world) != null: var direct_path = Globals.WorldLineToHexTiles(target_world, start_world) var last_removed = null while len(direct_path) > 0 and get_tile_type(direct_path[0]) != null: last_removed = direct_path[0] direct_path.remove(0) if len(direct_path) == 0: print ("Could not find path!") return print ("Using ", Globals.WorldToHex(direct_path[0]), " instead of ", goal_coord, " as goal.") goal_coord = Globals.WorldToHex(last_removed) var path = Globals.OceanGrid.find_path(start_coord, goal_coord) for target in path.slice(1,-1): var target_world_coord = Globals.HexToWorld(target.axial_coords) var target_type = get_tile_type(target_world_coord) player_navigation_path.append(target_world_coord) if target_type == "Sand": break if len(player_navigation_path) > 0: PlayerChar.target = player_navigation_path[0] update() # # Input & Events # func _on_generate_button_pressed(): generate() func handle_game_event(event): if event is InputEventMouseButton: # Move main character if event.pressed and event.button_index == BUTTON_LEFT: update_player_navigation_target (Globals.HexGrid.get_hex_center(Globals.ScreenToHex(event.position, WorldCamera))) return false func update_hex_line_path(target: Vector2): var start = PlayerChar.position hex_line_path = Globals.WorldLineToHexTiles(start, target) func _unhandled_input(event): if event is InputEventMouseButton: if handle_game_event(event): return # Move camera if event.pressed and event.button_index == 2: is_dragging = true drag_start = (WorldCamera.offset / WorldCamera.zoom.x + event.position) else: is_dragging = false # Zoom Camera if event.pressed and event.button_index == BUTTON_WHEEL_DOWN and event.pressed and WorldCamera.zoom.y < 5.5: WorldCamera.zoom = WorldCamera.zoom * 1.0 / 0.8 elif event.button_index == BUTTON_WHEEL_UP and event.pressed: WorldCamera.zoom = WorldCamera.zoom * 0.8 if 'position' in event: hex_hover = Globals.ScreenToHex(event.position, WorldCamera) GridHighlight.pos = hex_hover HexCoordValueLabel.text = str(hex_hover) var world_coord = Globals.ScreenToWorld(event.position, WorldCamera) var tile_type = get_tile_type(world_coord) if tile_type != null: TileTypeValueLabel.text = tile_type else: TileTypeValueLabel.text = "None" WorldCoordValueLabel.text = str(world_coord) update_hex_line_path(world_coord) if is_dragging: WorldCamera.offset = (drag_start - event.position) * WorldCamera.zoom.x OffsetValueLabel.text = str(WorldCamera.offset) ZoomValueLabel.text = str(WorldCamera.zoom)