@icon("res://components/Cursor/mouse-pointer-2.svg") extends Base @onready var mouse_control = $"MouseControl" @onready var sprite_2d: Sprite2D = $MouseControl/Sprite2D @onready var audio_stream_player: AudioStreamPlayer = $AudioStreamPlayer @onready var audio_stream_player_2: AudioStreamPlayer = $AudioStreamPlayer2 @onready var audio_stream_player_3: AudioStreamPlayer = $AudioStreamPlayer3 const CURSOR_UI = preload("res://components/Cursor/hover-1.png") const CURSOR_HOLD = preload("res://components/Cursor/grab-1.png") const CURSOR = preload("res://components/Cursor/normal-1.png") const CREATURE = preload("res://src/Creature.tscn") var rotation_tween var cursor_tween var hovered_objects = 0 var holding = false var grabbed_creature var signal_object var original_window var original_position var timer = 0 var hover_timer = 0 func _ready() -> void: Persister.data_persisted.connect(_on_data_persisted) Triggerer.listen("grab_creature", _on_grab_creature) Triggerer.listen("hovered", _on_hovered) for child in get_parent().get_children(): if child.is_in_group("mouse_signals"): signal_object = child func _on_hovered(_data): hover_timer = 0.125 func _on_grab_creature(data): grabbed_creature = CREATURE.instantiate() grabbed_creature.key = data.creature grabbed_creature.held = true grabbed_creature.tiles = data.tiles grabbed_creature.tiled = data.tiled mouse_control.add_child(grabbed_creature) grabbed_creature.position = Vector2(0, 0) holding = true original_window = data.old_window original_position = data.old_position if get_window().get_window_id() == 0: audio_stream_player_3.play() func let_go(): if holding and grabbed_creature: if get_window().get_window_id() == 0 and not Persister.get_value("hovered"): var new_creature = CREATURE.instantiate() new_creature.key = grabbed_creature.key new_creature.position = original_position original_window.add_child(new_creature) audio_stream_player_2.play() if get_window().get_window_id() == 0: Persister.persist_data("grabbing", false) if signal_object and signal_object.mouse_in_window: if get_window().name == "CreatureWindow": var new_creature = CREATURE.instantiate() new_creature.key = grabbed_creature.key new_creature.global_position = grabbed_creature.global_position get_window().add_child(new_creature) audio_stream_player_2.play() if grabbed_creature.tiled: original_window.remove_tiles(grabbed_creature.tiles) else: if not get_window().attempt_place(grabbed_creature.key, mouse_control.position, grabbed_creature.tiles): var new_creature = CREATURE.instantiate() new_creature.key = grabbed_creature.key new_creature.position = original_position new_creature.tiles = grabbed_creature.tiles new_creature.tiled = grabbed_creature.tiled original_window.add_child(new_creature) audio_stream_player.play() else: audio_stream_player_2.play() if grabbed_creature.tiled: original_window.remove_tiles(grabbed_creature.tiles) grabbed_creature.queue_free() grabbed_creature = null holding = false func _on_release(): let_go() Triggerer.trigger("released") var overlapping_areas = mouse_control.get_overlapping_areas() overlapping_areas.sort_custom(func(a, b): return a.z_index > b.z_index ) for area in overlapping_areas: if area.has_method("_on_released"): var current_node = area var hidden = false while current_node: if "modulate" in current_node: if current_node.modulate.a < 1: hidden = true break current_node = current_node.get_parent() if hidden: continue if not area._on_released(): break func _on_click(): var overlapping_areas = mouse_control.get_overlapping_areas() overlapping_areas.sort_custom(func(a, b): return a.z_index > b.z_index ) for area in overlapping_areas: if area.has_method("_on_clicked"): var current_node = area var hidden = false while current_node: if "modulate" in current_node: if current_node.modulate.a < 1: hidden = true break if "visible" in current_node: if not current_node.visible: hidden = true break current_node = current_node.get_parent() if hidden: continue if not area._on_clicked(): break func _process(delta): if Input.is_action_just_released("left_click"): _on_release() if Input.is_action_just_pressed("left_click"): _on_click() #Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN) mouse_control.position = mouse_control.get_global_mouse_position() if timer > 0: timer -= delta if timer <= 0: let_go() if hover_timer > 0: hover_timer -= delta timer = 0 if not Input.is_action_pressed("left_click"): sprite_2d.rotation = move_toward(sprite_2d.rotation, 0, delta) sprite_2d.scale = sprite_2d.scale.move_toward(Vector2.ONE, delta) else: sprite_2d.scale = sprite_2d.scale.move_toward(Vector2.ONE * 0.9, delta * 2) sprite_2d.rotation = move_toward(sprite_2d.rotation, -0.1, delta * 2) func _on_mouse_control_area_entered(area): if area.has_method("_on_hovered"): var current_node = area var hidden = false while current_node: if "visible" in current_node: if not current_node.visible: hidden = true break current_node = current_node.get_parent() if not hidden: area._on_hovered() hovered_objects += 1 _update_cursor() func _on_mouse_control_area_exited(area): if area.has_method("_on_unhovered"): var current_node = area var hidden = false while current_node: if "visible" in current_node: if not current_node.visible: hidden = true break current_node = current_node.get_parent() if not hidden: area._on_unhovered() hovered_objects -= 1 _update_cursor() func _update_cursor(): if holding: sprite_2d.texture = CURSOR_HOLD if hovered_objects: sprite_2d.texture = CURSOR_UI else: sprite_2d.texture = CURSOR