This commit is contained in:
Rendo 2026-01-30 11:39:09 +05:00
commit 2f2ac7c540
20 changed files with 218 additions and 30 deletions

View file

@ -0,0 +1,9 @@
[gd_resource type="Resource" script_class="Draggable" format=3 uid="uid://kg34c4105ssp"]
[ext_resource type="Script" uid="uid://b3i73cilpra74" path="res://src/resources/draggable.gd" id="1_bi20d"]
[ext_resource type="PackedScene" uid="uid://c1mddt0n064ub" path="res://scenes/burner.tscn" id="1_welab"]
[resource]
script = ExtResource("1_bi20d")
scene_to_spawn = ExtResource("1_welab")
metadata/_custom_type_script = "uid://b3i73cilpra74"

View file

@ -0,0 +1,6 @@
[gd_resource type="StandardMaterial3D" format=3 uid="uid://b2h6brwubdafv"]
[resource]
albedo_color = Color(0.5689727, 0.56897277, 0.5689727, 1)
metallic = 1.0
roughness = 0.59

BIN
assets/models/SPIRTOVKA.glb Normal file

Binary file not shown.

View file

@ -0,0 +1,55 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://3bg8whyxun5k"
path="res://.godot/imported/SPIRTOVKA.glb-4fab95e39d53ad866889e6b7e1f9b04f.scn"
[deps]
source_file="res://assets/models/SPIRTOVKA.glb"
dest_files=["res://.godot/imported/SPIRTOVKA.glb-4fab95e39d53ad866889e6b7e1f9b04f.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={
"materials": {
"mat_cap": {
"use_external/enabled": true,
"use_external/fallback_path": "res://assets/materials/mat_metal.tres",
"use_external/path": "uid://b2h6brwubdafv"
},
"mat_glass": {
"use_external/enabled": true,
"use_external/fallback_path": "res://assets/materials/mat_glass.tres",
"use_external/path": "uid://64m17act0kwu"
}
}
}
gltf/naming_version=2
gltf/embedded_image_handling=1

View file

@ -1,4 +1,4 @@
[gd_resource type="Resource" script_class="Reaction" load_steps=11 format=3 uid="uid://norc8wahican"]
[gd_resource type="Resource" script_class="Reaction" format=3 uid="uid://norc8wahican"]
[ext_resource type="Resource" uid="uid://dr65qbkum4emy" path="res://assets/substances/CH3COONa.tres" id="2_8tq4d"]
[ext_resource type="Script" uid="uid://dwks86y6383p4" path="res://src/resources/reaction.gd" id="2_fmr2g"]
@ -35,4 +35,5 @@ metadata/_custom_type_script = "uid://bb8o8l6u6fiai"
script = ExtResource("2_fmr2g")
input_substances = Array[ExtResource("2_mw1oh")]([SubResource("Resource_ad7jh"), SubResource("Resource_ohxs7")])
output_substances = Array[ExtResource("2_mw1oh")]([SubResource("Resource_6x1ca"), SubResource("Resource_h3tvm")])
reaction_temperature = 30.0
metadata/_custom_type_script = "uid://dwks86y6383p4"

40
scenes/burner.tscn Normal file
View file

@ -0,0 +1,40 @@
[gd_scene format=3 uid="uid://c1mddt0n064ub"]
[ext_resource type="Script" uid="uid://bjnv2g1ni0525" path="res://src/drag/draggable_object.gd" id="1_v8cqm"]
[ext_resource type="PackedScene" uid="uid://3bg8whyxun5k" path="res://assets/models/SPIRTOVKA.glb" id="2_83yjx"]
[ext_resource type="Script" uid="uid://d3v8045s7423j" path="res://src/button_gens/burner_button.gd" id="3_tuoyb"]
[ext_resource type="Script" uid="uid://iv0p3iafoogu" path="res://src/burn_area.gd" id="4_s4s5n"]
[sub_resource type="CylinderShape3D" id="CylinderShape3D_83yjx"]
height = 0.42895508
radius = 0.2241211
[sub_resource type="CylinderShape3D" id="CylinderShape3D_tuoyb"]
height = 0.31713867
radius = 0.103515625
[node name="Burner" type="Area3D" unique_id=822962276 node_paths=PackedStringArray("button_generator")]
script = ExtResource("1_v8cqm")
button_generator = NodePath("ButtonGen")
[node name="SPIRTOVKA" parent="." unique_id=410340270 instance=ExtResource("2_83yjx")]
transform = Transform3D(0.2, 0, 0, 0, 0.2, 0, 0, 0, 0.2, 0, 0, 0)
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=578010566]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.2145507, 0)
shape = SubResource("CylinderShape3D_83yjx")
[node name="ButtonGen" type="Node" parent="." unique_id=739595415]
script = ExtResource("3_tuoyb")
[node name="BurnArea" type="Area3D" parent="." unique_id=1510885909]
collision_mask = 5
script = ExtResource("4_s4s5n")
power = 1.0
[node name="CollisionShape3D" type="CollisionShape3D" parent="BurnArea" unique_id=2023114437]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.49743652, 0)
shape = SubResource("CylinderShape3D_tuoyb")
[connection signal="area_entered" from="BurnArea" to="BurnArea" method="_on_area_entered"]
[connection signal="area_exited" from="BurnArea" to="BurnArea" method="_on_area_exited"]

View file

@ -1,10 +1,10 @@
[gd_scene load_steps=2 format=3 uid="uid://c2vxq6kqhris0"]
[gd_scene format=3 uid="uid://c2vxq6kqhris0"]
[ext_resource type="Script" uid="uid://crjao0jjv5yqs" path="res://src/drag/draggable_camera.gd" id="1_v4apc"]
[node name="Camera3D" type="Camera3D"]
[node name="Camera3D" type="Camera3D" unique_id=982578725]
transform = Transform3D(1, 0, 0, 0, 0.86602545, 0.5, 0, -0.5, 0.8660253, 0, 0, 0)
script = ExtResource("1_v4apc")
[node name="DragRaycast" type="RayCast3D" parent="."]
[node name="DragRaycast" type="RayCast3D" parent="." unique_id=125477051]
target_position = Vector3(0, 0, -10)

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=15 format=4 uid="uid://bjxjcx2qu16q5"]
[gd_scene format=4 uid="uid://bjxjcx2qu16q5"]
[ext_resource type="Script" uid="uid://bjnv2g1ni0525" path="res://src/drag/draggable_object.gd" id="1_0xufn"]
[ext_resource type="Material" uid="uid://64m17act0kwu" path="res://assets/materials/mat_glass.tres" id="2_dbm1u"]
@ -68,22 +68,22 @@ bottom_radius = 0.772
radial_segments = 16
rings = 0
[node name="Flask" type="Area3D" node_paths=PackedStringArray("interactible") groups=["flask"]]
[node name="Flask" type="Area3D" unique_id=516093165 node_paths=PackedStringArray("interactible") groups=["flask"]]
collision_layer = 5
script = ExtResource("1_0xufn")
interactible = NodePath("Interactible")
mask = PackedStringArray("flask")
[node name="DragArea" type="CollisionShape3D" parent="."]
[node name="DragArea" type="CollisionShape3D" parent="." unique_id=1005865273]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
shape = SubResource("CapsuleShape3D_vcwhe")
[node name="Flash" type="MeshInstance3D" parent="."]
[node name="Flash" type="MeshInstance3D" parent="." unique_id=829971384]
transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0.1, 0)
mesh = SubResource("ArrayMesh_nvewc")
skeleton = NodePath("")
[node name="FillLiquid" type="MeshInstance3D" parent="Flash"]
[node name="FillLiquid" type="MeshInstance3D" parent="Flash" unique_id=439339804]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3.8061247, 0)
visible = false
material_override = SubResource("StandardMaterial3D_ailwx")
@ -91,7 +91,7 @@ mesh = SubResource("CylinderMesh_h7awq")
skeleton = NodePath("")
script = ExtResource("3_0xufn")
[node name="FillSolid" type="MeshInstance3D" parent="Flash"]
[node name="FillSolid" type="MeshInstance3D" parent="Flash" unique_id=390551675]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.8061155, 0)
visible = false
material_override = SubResource("StandardMaterial3D_kkw7a")
@ -100,13 +100,13 @@ skeleton = NodePath("")
script = ExtResource("3_0xufn")
display_type = 1
[node name="Inventory" type="Node" parent="."]
[node name="Inventory" type="Node" parent="." unique_id=1748297338]
unique_name_in_owner = true
script = ExtResource("7_h7awq")
open_on_top = true
metadata/_custom_type_script = "uid://82ettbegollp"
[node name="Interactible" type="ConfirmationDialog" parent="."]
[node name="Interactible" type="ConfirmationDialog" parent="." unique_id=1877318778]
oversampling_override = 1.0
title = "Перелить вещество в колбе?"
position = Vector2i(0, 36)
@ -115,24 +115,24 @@ ok_button_text = "Перелить"
cancel_button_text = "Нет"
script = ExtResource("4_dbm1u")
[node name="HBoxContainer" type="HBoxContainer" parent="Interactible"]
[node name="HBoxContainer" type="HBoxContainer" parent="Interactible" unique_id=1430463296]
offset_left = 8.0
offset_top = 8.0
offset_right = 293.0
offset_bottom = 51.0
[node name="Label" type="Label" parent="Interactible/HBoxContainer"]
[node name="Label" type="Label" parent="Interactible/HBoxContainer" unique_id=578568523]
layout_mode = 2
text = "000%"
[node name="HSlider" type="HSlider" parent="Interactible/HBoxContainer"]
[node name="HSlider" type="HSlider" parent="Interactible/HBoxContainer" unique_id=1518009939]
layout_mode = 2
size_flags_horizontal = 3
max_value = 1.0
step = 0.01
value = 1.0
[node name="Interaction" type="Node" parent="Interactible"]
[node name="Interaction" type="Node" parent="Interactible" unique_id=703093826]
script = ExtResource("5_pmegg")
[connection signal="inventory_changed" from="Inventory" to="Flash/FillLiquid" method="update_material_unfiltered"]

View file

@ -1,13 +1,15 @@
[gd_scene load_steps=7 format=3 uid="uid://dfxlr4svnsdyx"]
[gd_scene format=3 uid="uid://dfxlr4svnsdyx"]
[ext_resource type="Script" uid="uid://cqdtgvrotvjhb" path="res://src/ui/logger.gd" id="1_8dubc"]
[ext_resource type="Script" uid="uid://457xdl1tsmde" path="res://src/ui/control_buttons_holder.gd" id="1_ktti3"]
[ext_resource type="PackedScene" uid="uid://bcj0mesdlfsfj" path="res://scenes/popup_container.tscn" id="1_nt7q6"]
[ext_resource type="Script" uid="uid://c5pv2idedy1oy" path="res://src/ui/reagents_gen.gd" id="2_x4jx1"]
[ext_resource type="PackedScene" uid="uid://vhn8h4mhb6nh" path="res://scenes/drag_and_drop.tscn" id="3_yev5y"]
[ext_resource type="Resource" uid="uid://cay05wpketmny" path="res://assets/draggables/flask.tres" id="4_gdt2y"]
[ext_resource type="Resource" uid="uid://6vpr6n7yruie" path="res://assets/draggables/spoon.tres" id="5_wm3ai"]
[ext_resource type="Resource" uid="uid://kg34c4105ssp" path="res://assets/draggables/burner.tres" id="6_p7vwb"]
[node name="UserInterface" type="Control"]
[node name="UserInterface" type="Control" unique_id=1780432093]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@ -17,7 +19,7 @@ grow_vertical = 2
mouse_filter = 2
metadata/_edit_lock_ = true
[node name="HSplitContainer" type="HSplitContainer" parent="."]
[node name="HSplitContainer" type="HSplitContainer" parent="." unique_id=1503058072]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@ -25,7 +27,7 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="TabBar" type="TabBar" parent="HSplitContainer"]
[node name="TabBar" type="TabBar" parent="HSplitContainer" unique_id=723713577]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 0
@ -37,27 +39,28 @@ tab_1/title = "Вопросы для самопроверки"
tab_2/title = "Отчёт"
tab_3/title = "Очистить"
[node name="InspectorPanel" type="PanelContainer" parent="HSplitContainer"]
[node name="InspectorPanel" type="PanelContainer" parent="HSplitContainer" unique_id=918152974]
layout_mode = 2
size_flags_horizontal = 3
[node name="ScrollContainer" type="ScrollContainer" parent="HSplitContainer/InspectorPanel"]
[node name="ScrollContainer" type="ScrollContainer" parent="HSplitContainer/InspectorPanel" unique_id=1904486129]
layout_mode = 2
horizontal_scroll_mode = 0
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/InspectorPanel/ScrollContainer"]
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/InspectorPanel/ScrollContainer" unique_id=1723824494]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
script = ExtResource("1_ktti3")
[node name="Logger" type="TextEdit" parent="HSplitContainer/InspectorPanel/ScrollContainer/VBoxContainer"]
[node name="Logger" type="TextEdit" parent="HSplitContainer/InspectorPanel/ScrollContainer/VBoxContainer" unique_id=1997720811]
layout_mode = 2
size_flags_vertical = 3
editable = false
wrap_mode = 1
script = ExtResource("1_8dubc")
[node name="Reagents" parent="." instance=ExtResource("1_nt7q6")]
[node name="Reagents" parent="." unique_id=1303212589 instance=ExtResource("1_nt7q6")]
layout_mode = 1
anchors_preset = -1
anchor_left = -0.14756945
@ -81,10 +84,10 @@ offset_top = 197.44484
offset_right = 173.02982
offset_bottom = 48.876526
[node name="Generator" type="Node" parent="Reagents"]
[node name="Generator" type="Node" parent="Reagents" unique_id=670239833]
script = ExtResource("2_x4jx1")
[node name="Intruments" parent="." instance=ExtResource("1_nt7q6")]
[node name="Intruments" parent="." unique_id=1127354373 instance=ExtResource("1_nt7q6")]
layout_mode = 1
anchors_preset = -1
anchor_left = -0.14756945
@ -96,12 +99,17 @@ metadata/_edit_use_anchors_ = true
[node name="ScrollContainer" parent="Intruments" index="0"]
offset_right = -20.904999
[node name="Flask" parent="Intruments/ScrollContainer/VBoxContainer" index="0" instance=ExtResource("3_yev5y")]
[node name="Flask" parent="Intruments/ScrollContainer/VBoxContainer" index="0" unique_id=852024836 instance=ExtResource("3_yev5y")]
layout_mode = 2
text = "Пробирка"
draggable = ExtResource("4_gdt2y")
[node name="Spoon" parent="Intruments/ScrollContainer/VBoxContainer" index="1" instance=ExtResource("3_yev5y")]
[node name="Burner" parent="Intruments/ScrollContainer/VBoxContainer" index="1" unique_id=1243872558 instance=ExtResource("3_yev5y")]
layout_mode = 2
text = "Спиртовка"
draggable = ExtResource("6_p7vwb")
[node name="Spoon" parent="Intruments/ScrollContainer/VBoxContainer" index="2" unique_id=1377215067 instance=ExtResource("3_yev5y")]
layout_mode = 2
text = "Ложка"
draggable = ExtResource("5_wm3ai")

20
src/burn_area.gd Normal file
View file

@ -0,0 +1,20 @@
extends Area3D
@export var enabled: bool = false
@export_range(0,10,0.01,"or_greater","suffix:градус/с") var power: float = 0.1
var flasks: Array[DraggableObject] = []
func _process(delta: float) -> void:
if enabled:
for flask in flasks:
flask.get_node("Inventory").mean_temperature += delta * power
func _on_area_entered(area: Area3D) -> void:
if area.is_in_group("flask"):
flasks.append(area)
func _on_area_exited(area: Area3D) -> void:
if area.is_in_group("flask"):
flasks.erase(area)

1
src/burn_area.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://iv0p3iafoogu

View file

@ -0,0 +1,13 @@
extends ButtonGenerator
func get_buttons() -> Control:
var burn_button: Button = Button.new()
burn_button.text = "Потушить спиртовку" if $"../BurnArea".enabled else "Зажечь спиртовку"
burn_button.pressed.connect(toggle_burner)
return burn_button
func toggle_burner() -> void:
$"../BurnArea".enabled = not $"../BurnArea".enabled
GuiSignalBus.add_buttons.emit(get_buttons())

View file

@ -0,0 +1 @@
uid://d3v8045s7423j

View file

@ -11,12 +11,16 @@ var dragged: bool = false:
if dragged != value:
if value:
drag_started.emit()
GuiSignalBus.clear_buttons.emit()
get_viewport().get_camera_3d().start_interaction_seeking(self)
if button_generator:
GuiSignalBus.add_buttons.emit(button_generator.get_buttons())
else:
drag_ended.emit()
dragged = value
@export var interactible: Interactible
@export var button_generator: ButtonGenerator
@export var mask: PackedStringArray
var contacted_draggables: Array[DraggableObject]

7
src/drag/gui_buttons.gd Normal file
View file

@ -0,0 +1,7 @@
@abstract
extends Node
class_name ButtonGenerator
@abstract
func get_buttons() -> Control

View file

@ -0,0 +1 @@
uid://dvpg3dt8qke2w

View file

@ -4,6 +4,8 @@ extends Node
signal interaction_confirmed(data: Dictionary)
signal log_pushed(log_data: String)
signal clear_buttons
signal add_buttons(buttons: Control)
func push(log_data: String):
log_pushed.emit(log_data)

View file

@ -9,7 +9,8 @@ var mean_temperature: float:
set(new_temperature):
mean_temperature = new_temperature
temperature_changed.emit(new_temperature)
update_temperature()
if new_temperature != 0:
update_temperature()
var total_amount: float:
set(value):

View file

@ -0,0 +1,18 @@
extends Control
var current_inspected: Control
func _ready() -> void:
GuiSignalBus.add_buttons.connect(add_buttons)
GuiSignalBus.clear_buttons.connect(clear_buttons)
func clear_buttons() -> void:
if current_inspected:
current_inspected.queue_free()
func add_buttons(buttons: Control) -> void:
clear_buttons()
current_inspected = buttons
add_child(buttons)

View file

@ -0,0 +1 @@
uid://457xdl1tsmde