Finish dark cut prototype

This commit is contained in:
Antonio Dell'Annunziata 2025-02-28 15:43:23 +01:00
parent 01cc6dab02
commit 36c4a19f6b
No known key found for this signature in database
GPG key ID: 8D2BB16641F06E94
17 changed files with 689 additions and 79 deletions

5
.gitignore vendored
View file

@ -12,4 +12,7 @@ export_credentials.cfg
# Mono-specific ignores
.mono/
data_*/
mono_crash.*.json
mono_crash.*.json
# Project specific ignores
out/

4
bat_dropoff.gd Normal file
View file

@ -0,0 +1,4 @@
class_name BatDropoff
extends Sprite2D
@onready var dropoff_area: Area2D = $Area2D

36
bat_extraction_bat.gd Normal file
View file

@ -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

View file

@ -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()

289
export_presets.cfg Normal file
View file

@ -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}\""

View file

@ -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

41
grab_step.gd Normal file
View file

@ -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)

View file

@ -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)

50
pickup_area.gd Normal file
View file

@ -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()

11
pickup_area.tscn Normal file
View file

@ -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"]

18
pliers.gd Normal file
View file

@ -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])

BIN
pliers.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

34
pliers.png.import Normal file
View file

@ -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

View file

@ -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

View file

@ -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"]

View file

@ -0,0 +1,5 @@
[gd_resource type="CapsuleShape2D" format=3 uid="uid://bo77ihhtxfueg"]
[resource]
radius = 14.3435
height = 142.904

View file

@ -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