206 lines
5.9 KiB
GDScript
206 lines
5.9 KiB
GDScript
extends CanvasLayer
|
||
|
||
@warning_ignore("unused_signal")
|
||
signal exit(arg)
|
||
|
||
|
||
@onready var animation_player: AnimationPlayer = %AnimationPlayer
|
||
@onready var slot_bowl: Marker2D = %DropSlotBowl
|
||
@onready var drawers: Array[HoverLightClickArea] = [
|
||
%Drawer1, %Drawer2, %Drawer3, %Drawer4, %Drawer5, %Drawer6, %"Hover蟋蟀", %"Hover粉末"
|
||
]
|
||
@onready var draggables: Array[DraggableRigid] = [
|
||
%DraggableRigid1,
|
||
%DraggableRigid2,
|
||
%DraggableRigid3,
|
||
%DraggableRigid4,
|
||
%DraggableRigid5,
|
||
%DraggableRigid6,
|
||
%DraggableRigid7,
|
||
%DraggableRigid8
|
||
]
|
||
|
||
@onready var sfx_picked = $SfxPicked as Sfx
|
||
@onready var sfx_invalid_drop = $SfxInvalidDrop as Sfx
|
||
@onready var sfx_dropped = $SfxDropped as Sfx
|
||
@onready var sfx_ready_to_grind = $SfxReadyToGrind as Sfx
|
||
@onready var sfx_ingredients_ready = $SfxIngredientsReady as Sfx
|
||
@onready var sfx_toggle_grinder = $SfxToggleGrinder as Sfx
|
||
@onready var sfx_grinding = $SfxGrinding as Sfx
|
||
@onready var sfx_packing = $SfxPacking as Sfx
|
||
|
||
@onready var inspect_content = %"InspectContent" as Control
|
||
@onready var hover_spec = %"Hover药方" as HoverLightClickArea
|
||
@onready var hover_grinder = %"Hover石臼棒" as HoverLightClickArea
|
||
@onready var hover_finished_powder = %"Hover完成的药粉" as HoverLightClickArea
|
||
|
||
|
||
const correct_ingredients = [0, 3, 5, 6, 7] # 生姜,竹叶,甘蔗, 蟋蟀, 粉末
|
||
var picked_ingredients: Array[int] = []
|
||
var holding_ingredient := -1
|
||
var all_picked = false
|
||
|
||
|
||
func _ready() -> void:
|
||
layer = GlobalConfig.CANVAS_LAYER_LITTLE_GAME
|
||
for i in drawers.size():
|
||
toggle_draggable_visible(i, false)
|
||
var drawer = drawers[i]
|
||
drawer.interacted.connect(_on_drawer_interacted.bind(i))
|
||
var drag = draggables[i]
|
||
drag.picked.connect(_on_picked.bind(i))
|
||
drag.dropped.connect(_on_dropped.bind(i))
|
||
hover_spec.interacted.connect(_on_spec_interacted)
|
||
|
||
|
||
func _on_spec_interacted() -> void:
|
||
hover_spec.hide()
|
||
inspect_content.show()
|
||
$"Sfx药方".play()
|
||
|
||
|
||
func toggle_draggable_freeze(freezing := true):
|
||
for d in draggables:
|
||
d.freezing = freezing
|
||
|
||
|
||
func toggle_draggable_visible(id: int, display := true):
|
||
var draggable = draggables[id]
|
||
draggable.visible = display
|
||
draggable.freeze = not display
|
||
|
||
|
||
var has_notified_put_to_bowl = false
|
||
|
||
|
||
func _on_drawer_interacted(id: int):
|
||
if picked_ingredients.has(id) or holding_ingredient > 0:
|
||
$SfxPickFailed.play()
|
||
drawers[id].invalid_blink()
|
||
SceneManager.pop_center_notification("ui_center_notify_c03药车不能再取药材")
|
||
else:
|
||
if not has_notified_put_to_bowl:
|
||
SceneManager.pop_center_notification("ui_center_notify_c03碗口放入药材")
|
||
has_notified_put_to_bowl = true
|
||
holding_ingredient = id
|
||
toggle_draggable_visible(id, true)
|
||
draggables[id].force_hold()
|
||
sfx_picked.play()
|
||
|
||
|
||
func _on_picked(_node: DraggableRigid, id: int):
|
||
$SfxPicked.play()
|
||
if holding_ingredient > 0 and holding_ingredient != id:
|
||
printerr(
|
||
"DraggableRigid _on_picked: holding_ingredient=",
|
||
holding_ingredient,
|
||
" but picked id=",
|
||
id
|
||
)
|
||
picked_ingredients.erase(id)
|
||
holding_ingredient = id
|
||
|
||
|
||
func _on_dropped(node: DraggableRigid, id: int):
|
||
var dropping_position = node.global_position
|
||
var dropped = false
|
||
if dropping_position.x < 210:
|
||
dropped = true
|
||
picked_ingredients.append(id)
|
||
if GlobalConfig.DEBUG:
|
||
print("picked_ingredients updated:", picked_ingredients)
|
||
else:
|
||
# 判断是否对应到 slots 在 limit_squared 范围内
|
||
var drawer = drawers[id]
|
||
if drawer.is_focused():
|
||
holding_ingredient = -1
|
||
dropped = true
|
||
toggle_draggable_visible(id, false)
|
||
else:
|
||
for d in drawers:
|
||
if d.is_focused():
|
||
d.invalid_blink()
|
||
if dropped:
|
||
holding_ingredient = -1
|
||
# If all items are placed
|
||
all_picked = picked_ingredients.size() == correct_ingredients.size()
|
||
# 检查配方
|
||
for ingredient in correct_ingredients:
|
||
if not ingredient in picked_ingredients:
|
||
all_picked = false
|
||
break
|
||
# 配方 match
|
||
if all_picked:
|
||
print(picked_ingredients)
|
||
# 全部插入,stage 进入下一阶段
|
||
sfx_ingredients_ready.play()
|
||
_setup_on_ready_to_grind()
|
||
else:
|
||
sfx_dropped.play()
|
||
else:
|
||
SceneManager.pop_center_notification("ui_center_notify_c03放到碗中或原处")
|
||
node.invalid_shake()
|
||
node.force_hold()
|
||
sfx_invalid_drop.play()
|
||
|
||
|
||
func _freezing_drawers() -> void:
|
||
# 禁用 drawer
|
||
for d in drawers:
|
||
d.freezing = true
|
||
|
||
|
||
func _setup_on_ready_to_grind() -> void:
|
||
toggle_draggable_freeze(true)
|
||
_freezing_drawers()
|
||
_process_grinding()
|
||
var p = get_parent() as Closeup2D
|
||
if p:
|
||
p.hold_cancel_before_exit()
|
||
|
||
|
||
func _process_grinding() -> void:
|
||
hover_spec.freezing = true
|
||
hover_spec.show()
|
||
inspect_content.hide()
|
||
SceneManager.pop_center_notification("ui_center_notify_c03准备研磨")
|
||
sfx_ready_to_grind.play()
|
||
hover_grinder.freezing = false
|
||
await hover_grinder.interacted
|
||
hover_grinder.freezing = true
|
||
animation_player.play("intro_grinding")
|
||
sfx_toggle_grinder.play()
|
||
await animation_player.animation_finished
|
||
hover_finished_powder.freezing = false
|
||
hover_finished_powder.interacted.connect(_on_finished_powder_interacted, CONNECT_ONE_SHOT)
|
||
|
||
|
||
func _on_finished_powder_interacted() -> void:
|
||
var packing_paper = $"洞中药纸"
|
||
sfx_packing.play()
|
||
var tween = create_tween()
|
||
tween.tween_property(packing_paper, "modulate:a", 0.0, 1.0)
|
||
tween = create_tween()
|
||
tween.tween_interval(0.5)
|
||
tween.tween_property(hover_finished_powder, "modulate:a", 0.0, 0.5)
|
||
tween.tween_callback(SceneManager.enable_prop_item.bind("prop_药包"))
|
||
tween.tween_callback(exit.emit.bind(true))
|
||
|
||
|
||
func ingredients_fading_out() -> void:
|
||
var tween = create_tween()
|
||
tween.tween_interval(0.01)
|
||
for i in drawers.size():
|
||
tween.parallel().tween_property(draggables[i], "modulate:a", 0.0, 3.0)
|
||
for i in drawers.size():
|
||
tween.tween_callback(draggables[i].queue_free)
|
||
|
||
|
||
func _unhandled_input(event: InputEvent) -> void:
|
||
if event.is_action_pressed("cancel") and inspect_content.visible:
|
||
get_viewport().set_input_as_handled()
|
||
hover_spec.show()
|
||
inspect_content.get_node("ContentInspector").setup_display(false)
|
||
inspect_content.hide()
|
||
$"Sfx药方".play()
|