Files
dauphincraft/scripts/Main.gd

117 lines
3.8 KiB
GDScript

extends Node3D
@onready var world: Node3D = $World/ChunkManager
@onready var dolphin: CharacterBody3D = $Dolphin
@onready var hud: CanvasLayer = $Dolphin/HUD
@onready var plankton_follower: Node3D = $PlanktonFollower
var inventory: Inventory = Inventory.new()
var _inventory_ui: CanvasLayer = null
var _pause_menu: Control = null
var _last_chunk_update_pos: Vector3 = Vector3(99999, 99999, 99999)
func _ready() -> void:
dolphin.block_break_requested.connect(_on_block_break)
dolphin.block_place_requested.connect(_on_block_place)
dolphin.echolocation_triggered.connect(_on_echolocation)
if dolphin.has_signal("hotbar_scroll"):
dolphin.hotbar_scroll.connect(inventory.scroll_hotbar)
if is_instance_valid(hud) and hud.has_method("connect_to_dolphin"):
hud.connect_to_dolphin(dolphin)
# Load and attach InventoryUI
var ui_scene: PackedScene = load("res://scenes/InventoryUI.tscn")
if ui_scene != null:
_inventory_ui = ui_scene.instantiate() as CanvasLayer
add_child(_inventory_ui)
_inventory_ui.setup(inventory)
else:
push_error("Main: could not load InventoryUI.tscn")
# Load and attach PauseMenu
var pause_scene: PackedScene = preload("res://scenes/PauseMenu.tscn")
_pause_menu = pause_scene.instantiate() as Control
add_child(_pause_menu)
_pause_menu.hide()
AudioManager.play_ambient_loop("underwater_ambient")
AudioManager.play_music("underwater_theme")
AudioManager.play_whale_call_random()
world.world_seed = 12345
# Starting inventory
inventory.add_item(2, 10) # 10 SAND
inventory.add_item(6, 5) # 5 KELP
inventory.add_item(8, 2) # 2 ICE
# Add dolphin to player group (for mob detection)
dolphin.add_to_group("player")
# Spawner de mobs
var MobSpawnerScene: PackedScene = load("res://scenes/mobs/MobSpawner.tscn")
var mob_spawner: Node3D = MobSpawnerScene.instantiate()
add_child(mob_spawner)
mob_spawner.player = mob_spawner.get_path_to(dolphin)
func _process(_delta: float) -> void:
# Throttle chunk updates: only when dolphin moved > 4m
if dolphin.global_position.distance_to(_last_chunk_update_pos) > 4.0:
world.update_player_position(dolphin.global_position)
_last_chunk_update_pos = dolphin.global_position
plankton_follower.global_position = dolphin.global_position
func _unhandled_input(event: InputEvent) -> void:
if not event.is_action_pressed("escape"):
return
# Priority: close inventory first if open
if _inventory_ui != null and _inventory_ui.get("_is_open"):
_inventory_ui.call("_toggle_inventory")
get_viewport().set_input_as_handled()
return
# Toggle pause menu
if is_instance_valid(_pause_menu):
if _pause_menu.visible:
_pause_menu.hide_pause()
else:
_pause_menu.show_pause()
get_viewport().set_input_as_handled()
func _on_block_break(hit_position: Vector3, _normal: Vector3) -> void:
var broken_id: int = world.break_block(hit_position)
if broken_id > 0:
inventory.add_item(broken_id, 1)
AudioManager.play_bubble_sfx(hit_position)
func _on_block_place(hit_position: Vector3, normal: Vector3) -> void:
var selected: Variant = inventory.get_selected_item()
if selected == null:
return
if not ItemDatabase.is_placeable(selected["item_id"]):
return
var place_pos := hit_position + normal * 0.5
var block_coord := Vector3(floor(place_pos.x), floor(place_pos.y), floor(place_pos.z))
var block_center := block_coord + Vector3(0.5, 0.5, 0.5)
# Refuse if bloc overlaps player AABB (CapsuleShape3D r=0.4 h=2.0)
var dolphin_pos: Vector3 = dolphin.global_position
var dist := block_center - dolphin_pos
if abs(dist.x) < 1.0 and abs(dist.y) < 1.8 and abs(dist.z) < 1.0:
return # too close to player, silent refuse
if world.place_block(place_pos, selected["item_id"]):
inventory.remove_item_from_slot(inventory.selected_hotbar, 1)
func _on_echolocation(position: Vector3, _radius: float) -> void:
AudioManager.play_bubble_sfx(position)