diff --git a/.gitignore b/.gitignore index ec9bd70..5b22aae 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,7 @@ export_credentials.cfg # Mono-specific ignores .mono/ data_*/ -mono_crash.*.json \ No newline at end of file +mono_crash.*.json + +# Project specific ignores +out/ diff --git a/bat_dropoff.gd b/bat_dropoff.gd new file mode 100644 index 0000000..2e329ce --- /dev/null +++ b/bat_dropoff.gd @@ -0,0 +1,4 @@ +class_name BatDropoff +extends Sprite2D + +@onready var dropoff_area: Area2D = $Area2D diff --git a/bat_extraction_bat.gd b/bat_extraction_bat.gd new file mode 100644 index 0000000..31c8e06 --- /dev/null +++ b/bat_extraction_bat.gd @@ -0,0 +1,36 @@ +class_name BatExtractionBat +extends Sprite2D + + +@export var speed: float = 0.2 + +@onready var grab_area: Area2D = $BatArea + +var path_follow: PathFollow2D +var is_grabbed = false +var is_dropped = false +var pliers: Pliers + +func _ready(): + path_follow = get_parent() as PathFollow2D + pliers = get_tree().get_first_node_in_group("grabber") as Pliers + +func _physics_process(delta): + if is_dropped: return + + if is_grabbed: + global_position = pliers.grab_area.global_position + else: + path_follow.progress_ratio += delta * speed + + +func grab_bat(): + is_grabbed = true + grab_area.set_deferred("monitoring", false) + grab_area.set_deferred("monitorable", false) + path_follow.progress_ratio = 0.0 + position = Vector2.ZERO + top_level = true + +func drop_bat(): + is_dropped = true diff --git a/cut_sequence.gd b/cut_sequence.gd index f5cb364..341e555 100644 --- a/cut_sequence.gd +++ b/cut_sequence.gd @@ -4,6 +4,8 @@ extends Node2D signal sequence_failed signal sequence_succeeded +@export var is_skipped = false + var cut_sequence_points: Array[CutSequencePoint] = [] func _ready(): _build_sequence() @@ -23,12 +25,12 @@ func _trigger_point_cut(point: CutSequencePoint): if cut_indices.is_empty(): is_cut_valid = cut_index == 0 or cut_index == cut_sequence_points.size() - 1 if not is_cut_valid: - print("Failed cut: Expected %i or %i as first point, but got %i." % [0, cut_sequence_points.size() - 1, cut_index]) + print("Failed cut: Expected %s or %s as first point, but got %s." % [0, cut_sequence_points.size() - 1, cut_index]) else: var direction = -1 if cut_indices[0] == 0 else 1 is_cut_valid = cut_index + direction == cut_indices[-1] # Expect the next index if not is_cut_valid: - print("Failed cut: Expected %i as next point, but got %i." % [cut_indices[-1] - direction, cut_index]) + print("Failed cut: Expected %s as next point, but got %s." % [cut_indices[-1] - direction, cut_index]) if not is_cut_valid: _fail_sequence() diff --git a/export_presets.cfg b/export_presets.cfg new file mode 100644 index 0000000..0bbdf55 --- /dev/null +++ b/export_presets.cfg @@ -0,0 +1,289 @@ +[preset.0] + +name="necra_prototype_macOS" +platform="macOS" +runnable=true +advanced_options=false +dedicated_server=false +custom_features="" +export_filter="all_resources" +include_filter="" +exclude_filter="" +export_path="out/necra_prototype_macOS.zip" +encryption_include_filters="" +encryption_exclude_filters="" +encrypt_pck=false +encrypt_directory=false +script_export_mode=2 + +[preset.0.options] + +export/distribution_type=1 +binary_format/architecture="universal" +custom_template/debug="" +custom_template/release="" +debug/export_console_wrapper=1 +application/icon="" +application/icon_interpolation=4 +application/bundle_identifier="dev.antonio-da.necra-prototype" +application/signature="" +application/app_category="Games" +application/short_version="" +application/version="" +application/copyright="" +application/copyright_localized={} +application/min_macos_version="10.12" +application/export_angle=0 +display/high_res=true +application/additional_plist_content="" +xcode/platform_build="14C18" +xcode/sdk_version="13.1" +xcode/sdk_build="22C55" +xcode/sdk_name="macosx13.1" +xcode/xcode_version="1420" +xcode/xcode_build="14C18" +codesign/codesign=1 +codesign/installer_identity="" +codesign/apple_team_id="" +codesign/identity="" +codesign/entitlements/custom_file="" +codesign/entitlements/allow_jit_code_execution=false +codesign/entitlements/allow_unsigned_executable_memory=false +codesign/entitlements/allow_dyld_environment_variables=false +codesign/entitlements/disable_library_validation=false +codesign/entitlements/audio_input=false +codesign/entitlements/camera=false +codesign/entitlements/location=false +codesign/entitlements/address_book=false +codesign/entitlements/calendars=false +codesign/entitlements/photos_library=false +codesign/entitlements/apple_events=false +codesign/entitlements/debugging=false +codesign/entitlements/app_sandbox/enabled=false +codesign/entitlements/app_sandbox/network_server=false +codesign/entitlements/app_sandbox/network_client=false +codesign/entitlements/app_sandbox/device_usb=false +codesign/entitlements/app_sandbox/device_bluetooth=false +codesign/entitlements/app_sandbox/files_downloads=0 +codesign/entitlements/app_sandbox/files_pictures=0 +codesign/entitlements/app_sandbox/files_music=0 +codesign/entitlements/app_sandbox/files_movies=0 +codesign/entitlements/app_sandbox/files_user_selected=0 +codesign/entitlements/app_sandbox/helper_executables=[] +codesign/custom_options=PackedStringArray() +notarization/notarization=0 +privacy/microphone_usage_description="" +privacy/microphone_usage_description_localized={} +privacy/camera_usage_description="" +privacy/camera_usage_description_localized={} +privacy/location_usage_description="" +privacy/location_usage_description_localized={} +privacy/address_book_usage_description="" +privacy/address_book_usage_description_localized={} +privacy/calendar_usage_description="" +privacy/calendar_usage_description_localized={} +privacy/photos_library_usage_description="" +privacy/photos_library_usage_description_localized={} +privacy/desktop_folder_usage_description="" +privacy/desktop_folder_usage_description_localized={} +privacy/documents_folder_usage_description="" +privacy/documents_folder_usage_description_localized={} +privacy/downloads_folder_usage_description="" +privacy/downloads_folder_usage_description_localized={} +privacy/network_volumes_usage_description="" +privacy/network_volumes_usage_description_localized={} +privacy/removable_volumes_usage_description="" +privacy/removable_volumes_usage_description_localized={} +privacy/tracking_enabled=false +privacy/tracking_domains=PackedStringArray() +privacy/collected_data/name/collected=false +privacy/collected_data/name/linked_to_user=false +privacy/collected_data/name/used_for_tracking=false +privacy/collected_data/name/collection_purposes=0 +privacy/collected_data/email_address/collected=false +privacy/collected_data/email_address/linked_to_user=false +privacy/collected_data/email_address/used_for_tracking=false +privacy/collected_data/email_address/collection_purposes=0 +privacy/collected_data/phone_number/collected=false +privacy/collected_data/phone_number/linked_to_user=false +privacy/collected_data/phone_number/used_for_tracking=false +privacy/collected_data/phone_number/collection_purposes=0 +privacy/collected_data/physical_address/collected=false +privacy/collected_data/physical_address/linked_to_user=false +privacy/collected_data/physical_address/used_for_tracking=false +privacy/collected_data/physical_address/collection_purposes=0 +privacy/collected_data/other_contact_info/collected=false +privacy/collected_data/other_contact_info/linked_to_user=false +privacy/collected_data/other_contact_info/used_for_tracking=false +privacy/collected_data/other_contact_info/collection_purposes=0 +privacy/collected_data/health/collected=false +privacy/collected_data/health/linked_to_user=false +privacy/collected_data/health/used_for_tracking=false +privacy/collected_data/health/collection_purposes=0 +privacy/collected_data/fitness/collected=false +privacy/collected_data/fitness/linked_to_user=false +privacy/collected_data/fitness/used_for_tracking=false +privacy/collected_data/fitness/collection_purposes=0 +privacy/collected_data/payment_info/collected=false +privacy/collected_data/payment_info/linked_to_user=false +privacy/collected_data/payment_info/used_for_tracking=false +privacy/collected_data/payment_info/collection_purposes=0 +privacy/collected_data/credit_info/collected=false +privacy/collected_data/credit_info/linked_to_user=false +privacy/collected_data/credit_info/used_for_tracking=false +privacy/collected_data/credit_info/collection_purposes=0 +privacy/collected_data/other_financial_info/collected=false +privacy/collected_data/other_financial_info/linked_to_user=false +privacy/collected_data/other_financial_info/used_for_tracking=false +privacy/collected_data/other_financial_info/collection_purposes=0 +privacy/collected_data/precise_location/collected=false +privacy/collected_data/precise_location/linked_to_user=false +privacy/collected_data/precise_location/used_for_tracking=false +privacy/collected_data/precise_location/collection_purposes=0 +privacy/collected_data/coarse_location/collected=false +privacy/collected_data/coarse_location/linked_to_user=false +privacy/collected_data/coarse_location/used_for_tracking=false +privacy/collected_data/coarse_location/collection_purposes=0 +privacy/collected_data/sensitive_info/collected=false +privacy/collected_data/sensitive_info/linked_to_user=false +privacy/collected_data/sensitive_info/used_for_tracking=false +privacy/collected_data/sensitive_info/collection_purposes=0 +privacy/collected_data/contacts/collected=false +privacy/collected_data/contacts/linked_to_user=false +privacy/collected_data/contacts/used_for_tracking=false +privacy/collected_data/contacts/collection_purposes=0 +privacy/collected_data/emails_or_text_messages/collected=false +privacy/collected_data/emails_or_text_messages/linked_to_user=false +privacy/collected_data/emails_or_text_messages/used_for_tracking=false +privacy/collected_data/emails_or_text_messages/collection_purposes=0 +privacy/collected_data/photos_or_videos/collected=false +privacy/collected_data/photos_or_videos/linked_to_user=false +privacy/collected_data/photos_or_videos/used_for_tracking=false +privacy/collected_data/photos_or_videos/collection_purposes=0 +privacy/collected_data/audio_data/collected=false +privacy/collected_data/audio_data/linked_to_user=false +privacy/collected_data/audio_data/used_for_tracking=false +privacy/collected_data/audio_data/collection_purposes=0 +privacy/collected_data/gameplay_content/collected=false +privacy/collected_data/gameplay_content/linked_to_user=false +privacy/collected_data/gameplay_content/used_for_tracking=false +privacy/collected_data/gameplay_content/collection_purposes=0 +privacy/collected_data/customer_support/collected=false +privacy/collected_data/customer_support/linked_to_user=false +privacy/collected_data/customer_support/used_for_tracking=false +privacy/collected_data/customer_support/collection_purposes=0 +privacy/collected_data/other_user_content/collected=false +privacy/collected_data/other_user_content/linked_to_user=false +privacy/collected_data/other_user_content/used_for_tracking=false +privacy/collected_data/other_user_content/collection_purposes=0 +privacy/collected_data/browsing_history/collected=false +privacy/collected_data/browsing_history/linked_to_user=false +privacy/collected_data/browsing_history/used_for_tracking=false +privacy/collected_data/browsing_history/collection_purposes=0 +privacy/collected_data/search_hhistory/collected=false +privacy/collected_data/search_hhistory/linked_to_user=false +privacy/collected_data/search_hhistory/used_for_tracking=false +privacy/collected_data/search_hhistory/collection_purposes=0 +privacy/collected_data/user_id/collected=false +privacy/collected_data/user_id/linked_to_user=false +privacy/collected_data/user_id/used_for_tracking=false +privacy/collected_data/user_id/collection_purposes=0 +privacy/collected_data/device_id/collected=false +privacy/collected_data/device_id/linked_to_user=false +privacy/collected_data/device_id/used_for_tracking=false +privacy/collected_data/device_id/collection_purposes=0 +privacy/collected_data/purchase_history/collected=false +privacy/collected_data/purchase_history/linked_to_user=false +privacy/collected_data/purchase_history/used_for_tracking=false +privacy/collected_data/purchase_history/collection_purposes=0 +privacy/collected_data/product_interaction/collected=false +privacy/collected_data/product_interaction/linked_to_user=false +privacy/collected_data/product_interaction/used_for_tracking=false +privacy/collected_data/product_interaction/collection_purposes=0 +privacy/collected_data/advertising_data/collected=false +privacy/collected_data/advertising_data/linked_to_user=false +privacy/collected_data/advertising_data/used_for_tracking=false +privacy/collected_data/advertising_data/collection_purposes=0 +privacy/collected_data/other_usage_data/collected=false +privacy/collected_data/other_usage_data/linked_to_user=false +privacy/collected_data/other_usage_data/used_for_tracking=false +privacy/collected_data/other_usage_data/collection_purposes=0 +privacy/collected_data/crash_data/collected=false +privacy/collected_data/crash_data/linked_to_user=false +privacy/collected_data/crash_data/used_for_tracking=false +privacy/collected_data/crash_data/collection_purposes=0 +privacy/collected_data/performance_data/collected=false +privacy/collected_data/performance_data/linked_to_user=false +privacy/collected_data/performance_data/used_for_tracking=false +privacy/collected_data/performance_data/collection_purposes=0 +privacy/collected_data/other_diagnostic_data/collected=false +privacy/collected_data/other_diagnostic_data/linked_to_user=false +privacy/collected_data/other_diagnostic_data/used_for_tracking=false +privacy/collected_data/other_diagnostic_data/collection_purposes=0 +privacy/collected_data/environment_scanning/collected=false +privacy/collected_data/environment_scanning/linked_to_user=false +privacy/collected_data/environment_scanning/used_for_tracking=false +privacy/collected_data/environment_scanning/collection_purposes=0 +privacy/collected_data/hands/collected=false +privacy/collected_data/hands/linked_to_user=false +privacy/collected_data/hands/used_for_tracking=false +privacy/collected_data/hands/collection_purposes=0 +privacy/collected_data/head/collected=false +privacy/collected_data/head/linked_to_user=false +privacy/collected_data/head/used_for_tracking=false +privacy/collected_data/head/collection_purposes=0 +privacy/collected_data/other_data_types/collected=false +privacy/collected_data/other_data_types/linked_to_user=false +privacy/collected_data/other_data_types/used_for_tracking=false +privacy/collected_data/other_data_types/collection_purposes=0 +ssh_remote_deploy/enabled=false +ssh_remote_deploy/host="user@host_ip" +ssh_remote_deploy/port="22" +ssh_remote_deploy/extra_args_ssh="" +ssh_remote_deploy/extra_args_scp="" +ssh_remote_deploy/run_script="#!/usr/bin/env bash +unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\" +open \"{temp_dir}/{exe_name}.app\" --args {cmd_args}" +ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash +kill $(pgrep -x -f \"{temp_dir}/{exe_name}.app/Contents/MacOS/{exe_name} {cmd_args}\") +rm -rf \"{temp_dir}\"" + +[preset.1] + +name="necra_prototype_linux" +platform="Linux" +runnable=true +advanced_options=false +dedicated_server=false +custom_features="" +export_filter="all_resources" +include_filter="" +exclude_filter="" +export_path="out/necra_prototype_linux.zip" +encryption_include_filters="" +encryption_exclude_filters="" +encrypt_pck=false +encrypt_directory=false +script_export_mode=2 + +[preset.1.options] + +custom_template/debug="" +custom_template/release="" +debug/export_console_wrapper=1 +binary_format/embed_pck=false +texture_format/s3tc_bptc=true +texture_format/etc2_astc=false +binary_format/architecture="x86_64" +ssh_remote_deploy/enabled=false +ssh_remote_deploy/host="user@host_ip" +ssh_remote_deploy/port="22" +ssh_remote_deploy/extra_args_ssh="" +ssh_remote_deploy/extra_args_scp="" +ssh_remote_deploy/run_script="#!/usr/bin/env bash +export DISPLAY=:0 +unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\" +\"{temp_dir}/{exe_name}\" {cmd_args}" +ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash +kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\") +rm -rf \"{temp_dir}\"" diff --git a/feedback_canvas_modulate.gd b/feedback_canvas_modulate.gd index 86e0f06..bd4bfa0 100644 --- a/feedback_canvas_modulate.gd +++ b/feedback_canvas_modulate.gd @@ -12,3 +12,8 @@ func show_hurt_feedback(): tween.tween_property(self, "color", Color(1.0,0,0, .2), .1) tween.tween_property(self, "color", default_color, .3) tween.tween_callback(func(): is_tweening = false) + +func fade_to_black() -> Tween: + var tween: Tween = create_tween() + tween.tween_property(self, "color", Color.BLACK, 3.0) + return tween diff --git a/grab_step.gd b/grab_step.gd new file mode 100644 index 0000000..168b06e --- /dev/null +++ b/grab_step.gd @@ -0,0 +1,41 @@ +class_name GrabStep +extends Node2D + +signal step_succeeded +signal step_failed + + +@export var is_skipped = false +@export_node_path("BatExtractionBat") var grabbing_target_path: NodePath + + +@onready var feedback_canvas_modulate: FeedbackCanvasModulate = %FeedbackCanvasModulate + + +var grabbing_target: BatExtractionBat +var pliers: Pliers + +func _ready(): + grabbing_target = get_node(grabbing_target_path) as BatExtractionBat + pliers = get_tree().get_first_node_in_group("grabber") as Pliers + pliers.pliers_used.connect(_on_pliers_used) + +func _on_pliers_used(top_area: Area2D): + if not grabbing_target.is_grabbed and top_area == grabbing_target.grab_area: + _target_grabbed() + elif grabbing_target.is_grabbed and top_area == (%BatDropoff as BatDropoff).dropoff_area: + _target_dropped() + else: + _hurt() + + +func _target_grabbed(): + grabbing_target.grab_bat() + +func _target_dropped(): + grabbing_target.drop_bat() + step_succeeded.emit() + +func _hurt(): + feedback_canvas_modulate.show_hurt_feedback() + %PatienceBar.value = clampi(%PatienceBar.value - 10, 0, 100) diff --git a/operation.gd b/operation.gd index 1da4cba..1e499a0 100644 --- a/operation.gd +++ b/operation.gd @@ -8,13 +8,26 @@ func _ready(): var children = get_children() for child in children: if child is Node2D: + if "is_skipped" in child and child.is_skipped: + _disable_node2d(child) + continue + steps.push_back(child) if child is CutSequence: child.sequence_succeeded.connect(_on_cut_sequence_succeeded.bind(child)) child.sequence_failed.connect(_on_cut_sequence_failed.bind(child)) _disable_node2d(child) - + elif child is GrabStep: + child.step_succeeded.connect(_on_grab_step_succeeded.bind(child)) + _disable_node2d(child) + active_step = steps[0] + if active_step is GrabStep: + _disable_node2d(%TestBody1) + _enable_node2d(%BatExtraction) + else: + _disable_node2d(%BatExtraction) + _enable_node2d(%TestBody1) _enable_node2d(active_step) @@ -22,8 +35,8 @@ func _on_cut_sequence_succeeded(cut_sequence: CutSequence): _disable_node2d(active_step) var next_index = steps.find(cut_sequence) + 1 if next_index == 4: - _enable_node2d(%TestBody2) - _disable_node2d(%BatExtraction) + _enable_node2d(%BatExtraction) + _disable_node2d(%TestBody1) active_step = steps[next_index] _enable_node2d(active_step) @@ -32,6 +45,11 @@ func _on_cut_sequence_succeeded(cut_sequence: CutSequence): func _on_cut_sequence_failed(cut_sequence: CutSequence): pass +func _on_grab_step_succeeded(grab_step: GrabStep): + await (%FeedbackCanvasModulate as FeedbackCanvasModulate).fade_to_black().finished + get_tree().reload_current_scene() + + func _enable_node2d(node: Node2D): node.set_deferred("visible", true) node.set_deferred("process_mode", Node.PROCESS_MODE_INHERIT) diff --git a/pickup_area.gd b/pickup_area.gd new file mode 100644 index 0000000..4406de0 --- /dev/null +++ b/pickup_area.gd @@ -0,0 +1,50 @@ +class_name PickupArea +extends Area2D + +signal picked_up() +signal dropped() + + +@onready var dropoff_area: Area2D = %UtilsDropoff.get_node("Area2D") + + +var is_clickable = false +var is_picked_up = false +var is_dropable = false +var parent: Node2D + +func _ready(): + mouse_entered.connect(func(): is_clickable = true) + mouse_exited.connect(func(): is_clickable = false) + parent = get_parent() as Node2D + +func _input(event): + if event is InputEventMouseButton and event.is_pressed(): + if is_picked_up and is_dropable: + _drop() + elif not is_picked_up and is_clickable: + _pickup() + if is_picked_up and event is InputEventMouseMotion: + parent.global_position = event.global_position + +func _exit_tree(): + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + +func _on_dropoff_area_entered(area): + if area == dropoff_area: + is_dropable = true + +func _on_dropoff_area_exited(area): + if area == dropoff_area: + is_dropable = false + + +func _pickup(): + is_picked_up = true + Input.mouse_mode = Input.MOUSE_MODE_HIDDEN + picked_up.emit() + +func _drop(): + is_picked_up = false + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + dropped.emit() diff --git a/pickup_area.tscn b/pickup_area.tscn new file mode 100644 index 0000000..6ffe2b6 --- /dev/null +++ b/pickup_area.tscn @@ -0,0 +1,11 @@ +[gd_scene load_steps=2 format=3 uid="uid://c3of67m4ic212"] + +[ext_resource type="Script" path="res://pickup_area.gd" id="1_6qsiy"] + +[node name="PickupArea" type="Area2D"] +collision_layer = 2 +collision_mask = 2 +script = ExtResource("1_6qsiy") + +[connection signal="area_entered" from="." to="." method="_on_dropoff_area_entered"] +[connection signal="area_exited" from="." to="." method="_on_dropoff_area_exited"] diff --git a/pliers.gd b/pliers.gd new file mode 100644 index 0000000..762b08e --- /dev/null +++ b/pliers.gd @@ -0,0 +1,18 @@ +class_name Pliers +extends Sprite2D + +signal pliers_used(top_area: Area2D) + +@onready var pickup_area: PickupArea = $PickupArea +@onready var grab_area: Area2D = $GrabArea + + + +func _input(event): + if event is InputEventMouseButton and pickup_area.is_picked_up and event.is_pressed(): + var areas = grab_area.get_overlapping_areas() + print("Before sorting:", areas) + if not areas.is_empty(): + areas.sort_custom(func(a: Area2D, b: Area2D): return a.priority > b.priority) + print("After sorting:", areas) + pliers_used.emit(areas[0]) diff --git a/pliers.png b/pliers.png new file mode 100644 index 0000000..23b8446 Binary files /dev/null and b/pliers.png differ diff --git a/pliers.png.import b/pliers.png.import new file mode 100644 index 0000000..42f26bc --- /dev/null +++ b/pliers.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ccy71gl4qatjy" +path="res://.godot/imported/pliers.png-851b2339f2c5c7c6c30da64e0b329620.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://pliers.png" +dest_files=["res://.godot/imported/pliers.png-851b2339f2c5c7c6c30da64e0b329620.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/project.godot b/project.godot index 474fddd..e517fa9 100644 --- a/project.godot +++ b/project.godot @@ -24,8 +24,10 @@ window/stretch/mode="viewport" 2d_physics/layer_1="Operation" 2d_physics/layer_2="Pickup" 2d_physics/layer_3="Body" +2d_physics/layer_4="Pliers" [rendering] renderer/rendering_method="gl_compatibility" renderer/rendering_method.mobile="gl_compatibility" +textures/vram_compression/import_etc2_astc=true diff --git a/prototype_dark_cut.tscn b/prototype_dark_cut.tscn index 0390f01..41af886 100644 --- a/prototype_dark_cut.tscn +++ b/prototype_dark_cut.tscn @@ -1,19 +1,26 @@ -[gd_scene load_steps=19 format=3 uid="uid://be0rqt7sk1da0"] +[gd_scene load_steps=29 format=3 uid="uid://be0rqt7sk1da0"] [ext_resource type="Texture2D" uid="uid://bicjfwpoa3pma" path="res://test_table.png" id="1_7i8d4"] [ext_resource type="Script" path="res://prototype_dark_cut.gd" id="1_vl0qk"] [ext_resource type="Texture2D" uid="uid://bp10w3bh1gn14" path="res://test_body_1.png" id="2_atjyl"] [ext_resource type="Texture2D" uid="uid://cg3dg7iqif56d" path="res://test_scalpel.png" id="3_a4jra"] +[ext_resource type="Script" path="res://bat_dropoff.gd" id="4_2wsdd"] [ext_resource type="Script" path="res://test_scalpel.gd" id="4_5ba3g"] +[ext_resource type="Texture2D" uid="uid://ccy71gl4qatjy" path="res://pliers.png" id="4_aj8rk"] [ext_resource type="Texture2D" uid="uid://bkjxp2r3pobmc" path="res://bat_extraction_open_chest.png" id="5_c2dn1"] +[ext_resource type="Script" path="res://pliers.gd" id="5_ewpkr"] [ext_resource type="Texture2D" uid="uid://ciy24ri5lusqs" path="res://bat_extraction_bat.png" id="6_yfdwj"] [ext_resource type="Texture2D" uid="uid://dwjmlaw1vxgxo" path="res://bat_extraction_body.png" id="7_7hv63"] [ext_resource type="Script" path="res://operation.gd" id="7_mteqj"] +[ext_resource type="PackedScene" uid="uid://c3of67m4ic212" path="res://pickup_area.tscn" id="7_uhavf"] [ext_resource type="Texture2D" uid="uid://n8x3g2swx0x2" path="res://bat_extraction_open_chest_flaps.png" id="8_1vja2"] +[ext_resource type="Shape2D" uid="uid://bo77ihhtxfueg" path="res://scalpel_pickup_area_collision_shape.tres" id="8_mvvp0"] [ext_resource type="Script" path="res://feedback_canvas_modulate.gd" id="9_4ghh6"] [ext_resource type="Texture2D" uid="uid://ljl3y4633ted" path="res://bat_extraction_bones.png" id="9_7uu43"] [ext_resource type="Script" path="res://cut_sequence.gd" id="10_gcaa6"] [ext_resource type="PackedScene" uid="uid://x5powiwrfash" path="res://cut_sequence_point.tscn" id="11_hcsao"] +[ext_resource type="Script" path="res://bat_extraction_bat.gd" id="13_um5dt"] +[ext_resource type="Script" path="res://grab_step.gd" id="18_d00rj"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pgu75"] bg_color = Color(0.417457, 0, 0.105249, 1) @@ -21,13 +28,26 @@ bg_color = Color(0.417457, 0, 0.105249, 1) [sub_resource type="RectangleShape2D" id="RectangleShape2D_m114t"] size = Vector2(325.047, 551.953) -[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_jndi4"] -radius = 14.3435 -height = 142.904 +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_1a0oe"] +radius = 7.10071 +height = 206.493 + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_f4g1u"] +radius = 7.10071 +height = 193.839 + +[sub_resource type="CircleShape2D" id="CircleShape2D_8w656"] +radius = 8.24621 [sub_resource type="CircleShape2D" id="CircleShape2D_qmwrh"] radius = 5.65684 +[sub_resource type="Curve2D" id="Curve2D_wv8oy"] +_data = { +"points": PackedVector2Array(0, 0, 0, 0, -44, -62, 0, 0, 0, 0, 19, -64, 0, 0, 0, 0, -46, -35, 0, 0, 0, 0, 29, -24, 0, 0, 0, 0, 28, 6, 0, 0, 0, 0, -52, 12, 0, 0, 0, 0, -66, -50, 0, 0, 0, 0, -44, -62) +} +point_count = 8 + [node name="PrototypeDarkCut" type="Node"] script = ExtResource("1_vl0qk") @@ -68,19 +88,89 @@ unique_name_in_owner = true script = ExtResource("9_4ghh6") [node name="UtilsDropoff" type="Sprite2D" parent="."] +unique_name_in_owner = true position = Vector2(1020.25, 43) scale = Vector2(0.761429, 0.14494) texture = ExtResource("1_7i8d4") [node name="Area2D" type="Area2D" parent="UtilsDropoff"] +collision_layer = 2 +collision_mask = 2 [node name="CollisionShape2D" type="CollisionShape2D" parent="UtilsDropoff/Area2D"] shape = SubResource("RectangleShape2D_m114t") +[node name="BatDropoff" type="Sprite2D" parent="."] +unique_name_in_owner = true +position = Vector2(895, 222) +scale = Vector2(0.317262, -0.14494) +texture = ExtResource("1_7i8d4") +script = ExtResource("4_2wsdd") + +[node name="Area2D" type="Area2D" parent="BatDropoff"] +collision_layer = 8 +collision_mask = 8 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="BatDropoff/Area2D"] +shape = SubResource("RectangleShape2D_m114t") + [node name="TestTable" type="Sprite2D" parent="."] position = Vector2(613, 358) texture = ExtResource("1_7i8d4") +[node name="Pliers" type="Sprite2D" parent="." groups=["grabber"]] +z_index = 10 +position = Vector2(1026, 45) +scale = Vector2(0.5, 0.5) +texture = ExtResource("4_aj8rk") +script = ExtResource("5_ewpkr") + +[node name="PickupArea" parent="Pliers" instance=ExtResource("7_uhavf")] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Pliers/PickupArea"] +position = Vector2(2, 18) +rotation = 1.00484 +shape = SubResource("CapsuleShape2D_1a0oe") + +[node name="CollisionShape2D2" type="CollisionShape2D" parent="Pliers/PickupArea"] +position = Vector2(-30, -2) +rotation = 0.363771 +shape = SubResource("CapsuleShape2D_f4g1u") + +[node name="GrabArea" type="Area2D" parent="Pliers"] +position = Vector2(-74, 78) +collision_layer = 8 +collision_mask = 8 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Pliers/GrabArea"] +shape = SubResource("CircleShape2D_8w656") +debug_color = Color(0.879882, 0.304191, 0.394852, 0.42) + +[node name="TestScalpel" type="Sprite2D" parent="." groups=["cutter"]] +z_index = 10 +position = Vector2(949, 41) +rotation = -2.0542 +scale = Vector2(0.5, 0.5) +texture = ExtResource("3_a4jra") +script = ExtResource("4_5ba3g") + +[node name="PickupArea" parent="TestScalpel" instance=ExtResource("7_uhavf")] + +[node name="CollisionShape2D2" type="CollisionShape2D" parent="TestScalpel/PickupArea"] +shape = ExtResource("8_mvvp0") + +[node name="CutArea" type="Area2D" parent="TestScalpel"] +collision_layer = 5 +collision_mask = 5 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="TestScalpel/CutArea"] +position = Vector2(9.33812, -65.1214) +shape = SubResource("CircleShape2D_qmwrh") +debug_color = Color(0.879882, 0.304191, 0.394852, 0.42) + +[node name="CutHurtTimer" type="Timer" parent="TestScalpel"] +unique_name_in_owner = true + [node name="TestBody1" type="Sprite2D" parent="."] unique_name_in_owner = true position = Vector2(620, 399) @@ -100,9 +190,52 @@ position = Vector2(620, 399) [node name="BatExtractionOpenChest" type="Sprite2D" parent="BatExtraction"] texture = ExtResource("5_c2dn1") -[node name="BatExtractionBat" type="Sprite2D" parent="BatExtraction"] -position = Vector2(-43, -24) +[node name="OpenChestHurtArea" type="Area2D" parent="BatExtraction/BatExtractionOpenChest"] +collision_layer = 8 +collision_mask = 8 +priority = 2 + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BatExtraction/BatExtractionOpenChest/OpenChestHurtArea"] +polygon = PackedVector2Array(35.5, -87.4, 33, -86.3, 33, -85.1, 25.3, -80, 23.4, -80, 22.7, -76.9, 28.5, -74, 31.8, -74, 37.8, -80, 39.3, -80, 40.4, -82.5) + +[node name="CollisionPolygon2D2" type="CollisionPolygon2D" parent="BatExtraction/BatExtractionOpenChest/OpenChestHurtArea"] +polygon = PackedVector2Array(48.9, -81.3, 46, -80.5, 46, -79, 34, -70, 7.89999, -69, 2.5, -69, 0.5, -62, -2.2, -62, 1, -55.6, 1, -53.4, 21.8, -49, 38.7, -49, 44.7, -54, 46.5, -54, 51.5, -72, 52.2, -72, 53.3, -74) + +[node name="CollisionPolygon2D3" type="CollisionPolygon2D" parent="BatExtraction/BatExtractionOpenChest/OpenChestHurtArea"] +polygon = PackedVector2Array(22.5, -80.4, 20, -79.3, 20, -78.3, 18, -77.2, 18, -73, 26.3, -73, 27.4, -75.5) + +[node name="CollisionPolygon2D4" type="CollisionPolygon2D" parent="BatExtraction/BatExtractionOpenChest/OpenChestHurtArea"] +polygon = PackedVector2Array(-64.7, -78.4, -67, -77.3, -67, -75.4, -71, -66.4, -71, -57.8, -61, -52.8, -61, -51.4, -51.2, -49, -38.7, -49, -17.7, -56, -14.5, -56, -17, -67.4, -17, -70.1, -36.1, -69, -43.7, -69, -55.7, -73, -58.3, -73) + +[node name="CollisionPolygon2D5" type="CollisionPolygon2D" parent="BatExtraction/BatExtractionOpenChest/OpenChestHurtArea"] +polygon = PackedVector2Array(-24, -53.4, -24, -50, -28, -47, -40, -45.8, -69.9, -48, -72.4, -48, -74.4, -42, -76, -42, -76, -24.6, -66.4, 0, -65.5, 0, -60, 22, -60, 25.9, -38.6, 18, -35.5, 18, -11.7, 4.5, -10.3, 5, -7.7, 5, 2.3, 13, 4.10001, 13, 17.2, 25, 19.8, 25, 23, 21.8, 23, 19.2, 16, 11.2, 16, 9.10001, 6.8, 1, 4.89999, 1, -12.1, -19, -13, -45.1, -13, -47.2) + +[node name="CollisionPolygon2D6" type="CollisionPolygon2D" parent="BatExtraction/BatExtractionOpenChest/OpenChestHurtArea"] +polygon = PackedVector2Array(2, -48.6, 2, -46.3, 0, -45.2, 0, -36.7, 13, -30.8, 13, -29.4, 23, -27.4, 23, -25.6, 43.3, -29, 46.5, -29, 44, -40.4, 44, -43, 22.1, -43) + +[node name="CollisionPolygon2D7" type="CollisionPolygon2D" parent="BatExtraction/BatExtractionOpenChest/OpenChestHurtArea"] +polygon = PackedVector2Array(8.2, -26.3, 6, -25.2, 6, -24.3, 4, -23.2, 4, -19.8, 13.5, -15, 16.5, -10.6, 16, -8.2, 16, -6.39999, 11, -4.39999, 11, -0.899994, 37, 16.1, 37, 17.5, 39.8, 18.3, 44.1, 12, 46, 12, 46, 0, 47.3, 0, 45, -18.2, 45, -21, 15.6, -21) + +[node name="Path2D" type="Path2D" parent="BatExtraction"] +curve = SubResource("Curve2D_wv8oy") + +[node name="PathFollow2D" type="PathFollow2D" parent="BatExtraction/Path2D"] +position = Vector2(-44, -62) +rotation = -0.0317354 +rotates = false + +[node name="BatExtractionBat" type="Sprite2D" parent="BatExtraction/Path2D/PathFollow2D"] texture = ExtResource("6_yfdwj") +script = ExtResource("13_um5dt") +speed = 0.1 + +[node name="BatArea" type="Area2D" parent="BatExtraction/Path2D/PathFollow2D/BatExtractionBat"] +collision_layer = 8 +collision_mask = 8 +priority = 3 + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BatExtraction/Path2D/PathFollow2D/BatExtractionBat/BatArea"] +polygon = PackedVector2Array(-9, -13, -22.4, -13, -24, -12.2, -24, -9.6, -18, 3.3, -18, 5, -8, 12.9, 5, 13, 23.7, -3, 25, -3, 25, -6.9, 18.8, -13, 13, -13, 3, -3.9, 3, -3, -1.1, -3, -9, -11.8) [node name="BatExtractionBody" type="Sprite2D" parent="BatExtraction"] texture = ExtResource("7_7hv63") @@ -110,34 +243,27 @@ texture = ExtResource("7_7hv63") [node name="BatExtractionOpenChestFlaps" type="Sprite2D" parent="BatExtraction"] texture = ExtResource("8_1vja2") +[node name="OpenChestFlapsHurtArea" type="Area2D" parent="BatExtraction/BatExtractionOpenChestFlaps"] +collision_layer = 8 +collision_mask = 8 +priority = 4 + +[node name="CollisionPolygon2D2" type="CollisionPolygon2D" parent="BatExtraction/BatExtractionOpenChestFlaps/OpenChestFlapsHurtArea"] +polygon = PackedVector2Array(-88, -97, -88, -95.4, -89.4, -94, -90.6, -94, -93, -89.2, -93, -87.4, -99.5, -79, -100.8, -79, -102.8, -71, -103.9, -71, -105, -63.1, -105, -43.8, -103, -39.8, -103, -33, -103.9, -28, -104.9, -28, -105.9, -11, -107.1, -11, -106, 8.10001, -106, 16.3, -100, 24.3, -100, 26.6, -98, 27.6, -98, 28.8, -85, 31.8, -85, 33, -75.7, 33, -68.7, 28, -60.5, 28, -58.5, 25, -56.4, 25, -58.4, 21, -59.1, 21, -62, 4.8, -62, 0.800003, -64.4, -4, -65, -4, -65, -7.2, -66.4, -10, -67.2, -10, -72.3, -26, -73, -26, -73, -39.8, -69.2, -55, -67.9, -55, -69, -66.1, -69, -68.6, -68.6, -69, -67, -69, -67, -71, -66.2, -71, -64, -81.9, -64, -83.4, -70, -89.4, -70, -91, -72.6, -91, -74, -92.4, -74, -93.6, -78, -95.6, -78, -97) + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BatExtraction/BatExtractionOpenChestFlaps/OpenChestFlapsHurtArea"] +polygon = PackedVector2Array(66, -103.6, 66, -101.6, 62.8, -100, 60.6, -100, 51.6, -90, 50, -90, 50, -74.2, 48.3, -70, 47, -70, 47, -67, 46.2, -67, 43.2, -51, 41.9, -51, 43, -38.9, 43, -30.6, 45.6, -28, 49, -28, 49, -27, 47.4, -27, 46.4, -25, 45.3, -25, 44.8, -23.8, 47, -21.6, 47, -19.4, 45.6, -18, 44.1, -18, 43, -2, 43, 9.79999, 41.4, 13, 40, 13, 40, 16.6, 42, 17.6, 42, 19.6, 41.6, 20, 40.3, 20, 39.1, 23.4, 38.2, 23, 36.7, 23, 32.7, 26, 31.4, 26, 30.8, 27.1, 33.5, 31, 37.4, 31, 39.8, 28.5, 40.8, 29, 44.6, 29, 45.6, 27, 52.3, 27, 55.3, 25, 57.6, 25, 58.6, 23, 60.5, 23, 65.5, 17, 66.9, 17, 68, 9.10001, 68, 6.29999, 70.5, 3, 71.7, 3, 73.7, -2, 74.7, -2, 76, -5.8, 76, -11.8, 78.6, -17, 79.7, -17, 82.8, -27, 83.8, -27, 86, -36.9, 86, -53.2, 81.6, -62, 80.8, -62, 78, -71.3, 78, -89.3, 72, -97.4, 72, -100.6) + [node name="BatExtractionBones" type="Sprite2D" parent="BatExtraction"] texture = ExtResource("9_7uu43") -[node name="TestScalpel" type="Sprite2D" parent="." groups=["cutter"]] -position = Vector2(949, 41) -rotation = -2.0542 -scale = Vector2(0.5, 0.5) -texture = ExtResource("3_a4jra") -script = ExtResource("4_5ba3g") +[node name="BonesHurtArea" type="Area2D" parent="BatExtraction/BatExtractionBones"] +collision_layer = 8 +collision_mask = 8 +priority = 4 -[node name="PickupArea" type="Area2D" parent="TestScalpel"] -collision_layer = 2 -collision_mask = 2 - -[node name="CollisionShape2D" type="CollisionShape2D" parent="TestScalpel/PickupArea"] -shape = SubResource("CapsuleShape2D_jndi4") - -[node name="CutArea" type="Area2D" parent="TestScalpel"] -collision_layer = 5 -collision_mask = 5 - -[node name="CollisionShape2D" type="CollisionShape2D" parent="TestScalpel/CutArea"] -position = Vector2(9.33812, -65.1214) -shape = SubResource("CircleShape2D_qmwrh") -debug_color = Color(0.879882, 0.304191, 0.394852, 0.42) - -[node name="CutHurtTimer" type="Timer" parent="TestScalpel"] -unique_name_in_owner = true +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BatExtraction/BatExtractionBones/BonesHurtArea"] +polygon = PackedVector2Array(39, -86, 39, -84.3, 21, -75.2, -2, -75, -2, -74, -14.8, -74, -16, -76.5, -16, -79.8, -32.4, -74, -34.6, -74, -62.7, -84, -64.8, -84, -68, -80.8, -68, -78.2, -61, -71.2, -61, -69.3, -38, -65.3, -38, -63.6, -19, -67, -19, -59.5, -41, -53.5, -50.9, -54, -55.4, -54, -63.4, -59, -68.1, -59, -71.1, -54, -74.2, -54, -72, -49.6, -72, -45.8, -68, -43.8, -68, -42, -54, -42, -54, -40.9, -37.9, -42, -29.4, -42, -20, -48.7, -17.1, -44, -16, -24.9, -16, -16.2, 20, 21.8, 20, 23.2, 22.1, 24.3, 25.1, 22.3, 27.9, 27, 36.6, 27, 45, 21, 45, 16.9, 22.6, 2, 19.8, 2, 14.3, -3.5, 21, -6.8, 21, -13.1, 5.60001, -22.8, 15, -18.8, 15, -17, 23, -17, 23, -15.9, 40.1, -17, 45.5, -17, 48, -25.7, 48, -28.8, 37.1, -30, 25.3, -30, 4, -39.3, 4, -43.5, 21.8, -39, 42.4, -39, 46, -49.7, 46, -52.8, 42.8, -56, 40.2, -56, 37.2, -53, 22.1, -53, 3, -58.5, 3, -59.5, 5.7, -65.1, 30.1, -66, 36.8, -66, 49.8, -79, 51.3, -79, 52.4, -81.5, 50, -83.9, 50, -86) [node name="Operation" type="Node" parent="."] script = ExtResource("7_mteqj") @@ -208,11 +334,11 @@ position = Vector2(647, 353) [node name="CutSequencePoint4" parent="Operation/CutSequence4" instance=ExtResource("11_hcsao")] position = Vector2(665, 355) -[node name="GrabBat" type="Node2D" parent="Operation"] +[node name="BatGrabStep" type="Node2D" parent="Operation"] +script = ExtResource("18_d00rj") +grabbing_target_path = NodePath("../../BatExtraction/Path2D/PathFollow2D/BatExtractionBat") [connection signal="value_changed" from="UI/HBoxContainer/PatienceBar" to="." method="_on_patience_bar_value_changed"] -[connection signal="area_entered" from="UtilsDropoff/Area2D" to="TestScalpel" method="_on_dropoff_area_entered"] -[connection signal="area_exited" from="UtilsDropoff/Area2D" to="TestScalpel" method="_on_dropoff_area_exited"] +[connection signal="timeout" from="TestScalpel/CutHurtTimer" to="TestScalpel" method="_on_cut_hurt_timer_timeout"] [connection signal="area_entered" from="TestBody1/Area2D" to="TestScalpel" method="_on_body_area_entered"] [connection signal="area_exited" from="TestBody1/Area2D" to="TestScalpel" method="_on_body_area_exited"] -[connection signal="timeout" from="TestScalpel/CutHurtTimer" to="TestScalpel" method="_on_cut_hurt_timer_timeout"] diff --git a/scalpel_pickup_area_collision_shape.tres b/scalpel_pickup_area_collision_shape.tres new file mode 100644 index 0000000..1aa1d8f --- /dev/null +++ b/scalpel_pickup_area_collision_shape.tres @@ -0,0 +1,5 @@ +[gd_resource type="CapsuleShape2D" format=3 uid="uid://bo77ihhtxfueg"] + +[resource] +radius = 14.3435 +height = 142.904 diff --git a/test_scalpel.gd b/test_scalpel.gd index b7e162b..a8fb2d3 100644 --- a/test_scalpel.gd +++ b/test_scalpel.gd @@ -4,44 +4,20 @@ extends Sprite2D signal cut_started signal cut_ended -var is_clickable = false -var is_picked_up = false -var is_dropable = false var is_cutting_possible = false var is_cutting = false -@onready var pickup_area: Area2D = $PickupArea +@onready var pickup_area: PickupArea = $PickupArea @onready var cut_area: Area2D = $CutArea @onready var feedback_canvas_modulate: FeedbackCanvasModulate = %FeedbackCanvasModulate -func _ready(): - pickup_area.connect("mouse_entered", func(): is_clickable = true) - pickup_area.connect("mouse_exited", func(): is_clickable = false) func _input(event: InputEvent): - if event is InputEventMouseButton and event.is_pressed(): - if is_picked_up: - if is_dropable: - _drop_scalpel() - elif is_cutting_possible: - start_cutting() - elif is_clickable: - _pickup_scalpel() - if event is InputEventMouseButton and event.is_released(): - if is_cutting: + if event is InputEventMouseButton: + if event.is_pressed() and is_cutting_possible: + start_cutting() + elif event.is_released() and is_cutting: stop_cutting() - if is_picked_up and event is InputEventMouseMotion: - global_position = event.global_position - - -func _on_dropoff_area_entered(area): - if area != pickup_area: return - is_dropable = true - - -func _on_dropoff_area_exited(area): - if area != pickup_area: return - is_dropable = false func _on_body_area_entered(area): @@ -54,16 +30,6 @@ func _on_body_area_exited(area): is_cutting_possible = false stop_cutting() -func _pickup_scalpel(): - is_picked_up = true - Input.mouse_mode = Input.MOUSE_MODE_HIDDEN - -func _drop_scalpel(): - is_picked_up = false - Input.mouse_mode = Input.MOUSE_MODE_VISIBLE - -func _exit_tree(): - Input.mouse_mode = Input.MOUSE_MODE_VISIBLE var _scalpel_degrees_default: float const SCALPEL_ROTATION_CUTTING = -90.0