2021-06-15 21:58:31 +02:00
|
|
|
extends Node2D
|
|
|
|
|
2021-06-28 21:51:09 +02:00
|
|
|
|
|
|
|
onready var Grid = get_node("Grid")
|
|
|
|
onready var GridHighlight = get_node("GridHighlight")
|
|
|
|
|
|
|
|
onready var Islands = get_node("Islands")
|
2021-06-19 23:14:01 +02:00
|
|
|
onready var EditIslandButton = get_node("UI/TopContainer/EditIslandButton")
|
2021-06-15 21:58:31 +02:00
|
|
|
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")
|
2021-07-07 22:22:07 +02:00
|
|
|
onready var WorldCoordValueLabel = get_node("UI/TopContainer/WorldCoordValue")
|
2021-07-09 18:16:21 +02:00
|
|
|
onready var TileTypeValueLabel = get_node("UI/TopContainer/TileTypeValue")
|
2021-06-17 23:03:45 +02:00
|
|
|
onready var PlayerChar = get_node("PlayerChar")
|
2021-07-09 14:17:25 +02:00
|
|
|
onready var PlayerBoat = get_node("PlayerBoat")
|
2021-06-17 23:07:57 +02:00
|
|
|
onready var FPSValueLabel = get_node("UI/TopContainer/FPSValue")
|
2021-06-15 21:58:31 +02:00
|
|
|
|
2021-06-27 12:26:44 +02:00
|
|
|
var Island = preload("Island.gd")
|
2021-06-15 21:58:31 +02:00
|
|
|
|
2021-06-17 23:03:45 +02:00
|
|
|
var hex_grid_bbox = [[0,0], [10,10]]
|
2021-06-15 21:58:31 +02:00
|
|
|
|
|
|
|
var hex_hover = Vector2.ZERO
|
|
|
|
var is_dragging = false
|
|
|
|
var drag_start = null
|
2021-06-17 23:03:45 +02:00
|
|
|
var target = Vector2()
|
2021-06-19 23:14:01 +02:00
|
|
|
var tile_data = {}
|
2021-06-28 22:34:48 +02:00
|
|
|
var current_island = null
|
2021-07-09 18:16:21 +02:00
|
|
|
var player_navigation_path = []
|
2021-07-10 14:18:47 +02:00
|
|
|
var hex_line_path = []
|
2021-06-15 21:58:31 +02:00
|
|
|
|
|
|
|
|
2021-07-10 11:24:04 +02:00
|
|
|
#
|
|
|
|
# Godot Functions
|
|
|
|
#
|
2021-06-28 21:51:09 +02:00
|
|
|
func _ready():
|
|
|
|
Grid.view_camera = WorldCamera
|
|
|
|
GridHighlight.view_camera = WorldCamera
|
2021-06-17 23:07:57 +02:00
|
|
|
|
2021-07-07 22:22:07 +02:00
|
|
|
generate()
|
2021-06-15 21:58:31 +02:00
|
|
|
|
2021-06-28 21:51:09 +02:00
|
|
|
# Set player starting position
|
|
|
|
PlayerChar.position = Globals.HexGrid.get_hex_center(Vector2(0,0))
|
2021-06-17 23:07:57 +02:00
|
|
|
|
|
|
|
|
2021-07-09 14:17:25 +02:00
|
|
|
func _process(_delta):
|
|
|
|
WorldCamera.offset = PlayerChar.position
|
|
|
|
PlayerBoat.transform.origin = PlayerChar.transform.origin
|
2021-07-09 18:16:21 +02:00
|
|
|
|
|
|
|
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]
|
2021-07-09 14:17:25 +02:00
|
|
|
|
|
|
|
|
2021-07-10 14:18:47 +02:00
|
|
|
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)
|
2021-07-10 11:24:04 +02:00
|
|
|
last_point = cur_point
|
|
|
|
|
2021-07-10 14:18:47 +02:00
|
|
|
func _draw():
|
|
|
|
draw_hex_path (player_navigation_path, "#f200f2")
|
|
|
|
draw_hex_path (hex_line_path, "#00f2f2")
|
|
|
|
|
2021-07-10 11:24:04 +02:00
|
|
|
|
|
|
|
#
|
|
|
|
# World Modification/Query
|
|
|
|
#
|
|
|
|
func clear_islands():
|
|
|
|
for island in Islands.get_children():
|
|
|
|
Islands.remove_child(island)
|
|
|
|
island.queue_free()
|
|
|
|
|
|
|
|
|
2021-07-09 18:16:21 +02:00
|
|
|
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
|
|
|
|
|
|
|
|
|
2021-07-09 14:17:25 +02:00
|
|
|
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)
|
|
|
|
|
|
|
|
|
2021-07-09 21:57:11 +02:00
|
|
|
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
|
2021-07-10 11:24:04 +02:00
|
|
|
|
2021-07-09 21:57:11 +02:00
|
|
|
|
2021-07-07 22:22:07 +02:00
|
|
|
func generate():
|
2021-07-09 22:19:23 +02:00
|
|
|
PlayerChar.transform.origin = Vector2.ZERO
|
|
|
|
PlayerChar.position = Vector2.ZERO
|
|
|
|
|
2021-07-07 22:22:07 +02:00
|
|
|
var rng = RandomNumberGenerator.new()
|
|
|
|
rng.randomize()
|
|
|
|
|
2021-07-09 14:17:25 +02:00
|
|
|
clear_islands()
|
|
|
|
|
2021-07-09 21:57:11 +02:00
|
|
|
var radius = 800
|
2021-07-09 14:17:25 +02:00
|
|
|
var num_islands = 10
|
2021-07-07 22:22:07 +02:00
|
|
|
|
|
|
|
for i in range (num_islands):
|
|
|
|
var island = Island.new()
|
2021-07-10 11:24:04 +02:00
|
|
|
var island_index = i % 4
|
2021-07-09 14:17:25 +02:00
|
|
|
var file_name = "user://pirate_game_island_" + str(island_index) + ".island"
|
2021-07-07 22:22:07 +02:00
|
|
|
island.load_island(file_name)
|
|
|
|
|
2021-07-09 14:17:25 +02:00
|
|
|
var rand_coord = Vector2(rng.randi_range(-radius, radius), rng.randi_range(-radius, radius))
|
|
|
|
island.offset_world = Globals.WorldToHexCenter(rand_coord)
|
|
|
|
|
2021-07-09 18:16:21 +02:00
|
|
|
var location_valid = check_island_location_valid(island)
|
2021-07-09 14:17:25 +02:00
|
|
|
var overlap_retry_num = 0
|
|
|
|
var overlap_retry_max = 10
|
2021-07-09 21:57:11 +02:00
|
|
|
while !location_valid and overlap_retry_num < overlap_retry_max:
|
2021-07-09 14:17:25 +02:00
|
|
|
if overlap_retry_num % 4 == 0:
|
2021-07-09 21:57:11 +02:00
|
|
|
radius = radius + 200
|
2021-07-09 14:17:25 +02:00
|
|
|
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)
|
2021-07-09 18:16:21 +02:00
|
|
|
location_valid = check_island_location_valid(island)
|
2021-07-07 22:22:07 +02:00
|
|
|
|
2021-07-09 21:57:11 +02:00
|
|
|
if !location_valid:
|
|
|
|
print ("Could not place island! steps: " + str(overlap_retry_num))
|
2021-07-07 22:22:07 +02:00
|
|
|
else:
|
2021-07-09 14:17:25 +02:00
|
|
|
print ("Placed after " + str(overlap_retry_num) + " retries.")
|
2021-07-07 22:22:07 +02:00
|
|
|
Islands.add_child(island)
|
2021-07-09 14:17:25 +02:00
|
|
|
|
|
|
|
populate_ocean_grid()
|
2021-07-10 14:18:47 +02:00
|
|
|
|
|
|
|
# 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)
|
2021-07-09 14:17:25 +02:00
|
|
|
|
2021-07-10 11:24:04 +02:00
|
|
|
#
|
|
|
|
# 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)
|
2021-07-10 14:18:47 +02:00
|
|
|
Globals.OceanGrid.add_obstacles(grid_coords, 0)
|
2021-07-10 11:24:04 +02:00
|
|
|
|
2021-07-07 22:22:07 +02:00
|
|
|
|
2021-07-09 18:16:21 +02:00
|
|
|
func update_player_navigation_target(target_world: Vector2):
|
2021-07-10 14:18:47 +02:00
|
|
|
player_navigation_path = []
|
|
|
|
|
|
|
|
var start_world = PlayerChar.transform.origin
|
|
|
|
var start_coord = Globals.WorldToHex(start_world)
|
2021-07-09 18:16:21 +02:00
|
|
|
var goal_coord = Globals.WorldToHex(target_world)
|
|
|
|
|
2021-07-10 14:18:47 +02:00
|
|
|
if get_tile_type(target_world) != null:
|
|
|
|
var direct_path = Globals.WorldLineToHexTiles(target_world, start_world)
|
|
|
|
while len(direct_path) > 0 and get_tile_type(direct_path[0]) != null:
|
|
|
|
direct_path.remove(0)
|
|
|
|
|
|
|
|
if len(direct_path) == 0:
|
|
|
|
print ("Could not find path!")
|
|
|
|
return
|
|
|
|
|
|
|
|
print ("Using ", direct_path[0], " instead of ", goal_coord, " as goal.")
|
|
|
|
goal_coord = Globals.WorldToHex(direct_path[0])
|
|
|
|
|
2021-07-09 18:16:21 +02:00
|
|
|
var path = Globals.OceanGrid.find_path(start_coord, goal_coord)
|
2021-07-09 22:19:23 +02:00
|
|
|
for target in path:
|
|
|
|
var target_world_coord = Globals.HexToWorld(target.axial_coords)
|
|
|
|
var target_type = get_tile_type(target_world_coord)
|
|
|
|
if target_type == "Sand":
|
|
|
|
break
|
|
|
|
|
|
|
|
player_navigation_path.append(target_world_coord)
|
2021-07-09 18:16:21 +02:00
|
|
|
|
|
|
|
if len(player_navigation_path) > 1:
|
|
|
|
PlayerChar.target = player_navigation_path[1]
|
|
|
|
|
|
|
|
update()
|
|
|
|
|
2021-07-07 22:22:07 +02:00
|
|
|
|
2021-07-10 11:24:04 +02:00
|
|
|
#
|
|
|
|
# Input & Events
|
|
|
|
#
|
|
|
|
func _on_generate_button_pressed():
|
|
|
|
generate()
|
|
|
|
|
|
|
|
|
2021-06-19 23:14:01 +02:00
|
|
|
func handle_game_event(event):
|
2021-06-15 21:58:31 +02:00
|
|
|
if event is InputEventMouseButton:
|
2021-06-17 23:03:45 +02:00
|
|
|
# Move main character
|
|
|
|
if event.pressed and event.button_index == BUTTON_LEFT:
|
2021-07-09 18:16:21 +02:00
|
|
|
update_player_navigation_target (Globals.HexGrid.get_hex_center(Globals.ScreenToHex(event.position, WorldCamera)))
|
2021-06-22 22:47:01 +02:00
|
|
|
|
|
|
|
return false
|
2021-06-28 21:51:09 +02:00
|
|
|
|
|
|
|
|
2021-07-10 14:18:47 +02:00
|
|
|
func update_hex_line_path(target: Vector2):
|
|
|
|
var start = PlayerChar.position
|
|
|
|
|
|
|
|
hex_line_path = Globals.WorldLineToHexTiles(start, target)
|
|
|
|
|
|
|
|
|
2021-06-19 23:14:01 +02:00
|
|
|
func _unhandled_input(event):
|
|
|
|
if event is InputEventMouseButton:
|
2021-06-27 12:26:44 +02:00
|
|
|
if handle_game_event(event):
|
2021-06-19 23:14:01 +02:00
|
|
|
return
|
|
|
|
|
2021-06-17 23:03:45 +02:00
|
|
|
# Move camera
|
2021-06-17 23:07:57 +02:00
|
|
|
if event.pressed and event.button_index == 2:
|
2021-06-15 21:58:31 +02:00
|
|
|
is_dragging = true
|
|
|
|
drag_start = (WorldCamera.offset / WorldCamera.zoom.x + event.position)
|
|
|
|
else:
|
|
|
|
is_dragging = false
|
|
|
|
|
2021-06-17 23:03:45 +02:00
|
|
|
# Zoom Camera
|
2021-06-28 21:51:09 +02:00
|
|
|
if event.pressed and event.button_index == BUTTON_WHEEL_DOWN and event.pressed and WorldCamera.zoom.y < 5.5:
|
2021-06-15 21:58:31 +02:00
|
|
|
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:
|
2021-06-28 21:51:09 +02:00
|
|
|
hex_hover = Globals.ScreenToHex(event.position, WorldCamera)
|
|
|
|
GridHighlight.pos = hex_hover
|
2021-06-22 22:47:01 +02:00
|
|
|
HexCoordValueLabel.text = str(hex_hover)
|
2021-07-09 18:16:21 +02:00
|
|
|
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"
|
2021-06-22 22:47:01 +02:00
|
|
|
|
2021-07-09 18:16:21 +02:00
|
|
|
WorldCoordValueLabel.text = str(world_coord)
|
2021-07-10 14:18:47 +02:00
|
|
|
|
|
|
|
update_hex_line_path(world_coord)
|
2021-07-07 22:22:07 +02:00
|
|
|
|
2021-06-15 21:58:31 +02:00
|
|
|
if is_dragging:
|
|
|
|
WorldCamera.offset = (drag_start - event.position) * WorldCamera.zoom.x
|
2021-06-28 21:51:09 +02:00
|
|
|
|
|
|
|
|
2021-06-15 21:58:31 +02:00
|
|
|
OffsetValueLabel.text = str(WorldCamera.offset)
|
|
|
|
ZoomValueLabel.text = str(WorldCamera.zoom)
|