diff --git a/addons/block_code/blocks/communication/add_to_group.tres b/addons/block_code/blocks/communication/add_to_group.tres index a7dcb889..d4ccb2bc 100644 --- a/addons/block_code/blocks/communication/add_to_group.tres +++ b/addons/block_code/blocks/communication/add_to_group.tres @@ -5,11 +5,13 @@ [resource] script = ExtResource("1_bcm71") name = &"add_to_group" +target_node_class = "" +description = "Add this node into the group" +category = "Communication | Groups" type = 2 variant_type = 0 display_template = "Add to group {group: STRING}" code_template = "add_to_group({group})" -description = "Add this node into the group" -category = "Communication | Groups" defaults = {} signal_name = "" +scope = "" diff --git a/addons/block_code/blocks/communication/area2d_on_entered.tres b/addons/block_code/blocks/communication/area2d_on_entered.tres new file mode 100644 index 00000000..370331e6 --- /dev/null +++ b/addons/block_code/blocks/communication/area2d_on_entered.tres @@ -0,0 +1,18 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://de4k7t7uqws1j"] + +[ext_resource type="Script" path="res://addons/block_code/code_generation/block_definition.gd" id="1_xotf5"] + +[resource] +script = ExtResource("1_xotf5") +name = &"area2d_on_entered" +target_node_class = "Area2D" +description = "" +category = "Communication | Methods" +type = 1 +variant_type = 0 +display_template = "On [body: OBJECT] entered" +code_template = "func _on_body_entered(body: Node2D): +" +defaults = {} +signal_name = "body_entered" +scope = "" diff --git a/addons/block_code/blocks/communication/area2d_on_exited.tres b/addons/block_code/blocks/communication/area2d_on_exited.tres new file mode 100644 index 00000000..3236546f --- /dev/null +++ b/addons/block_code/blocks/communication/area2d_on_exited.tres @@ -0,0 +1,18 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://b36nq4mau6lu6"] + +[ext_resource type="Script" path="res://addons/block_code/code_generation/block_definition.gd" id="1_21qth"] + +[resource] +script = ExtResource("1_21qth") +name = &"area2d_on_exited" +target_node_class = "Area2D" +description = "" +category = "Communication | Methods" +type = 1 +variant_type = 0 +display_template = "On [body: OBJECT] exited" +code_template = "func _on_body_exited(body: Node2D): +" +defaults = {} +signal_name = "body_entered" +scope = "" diff --git a/addons/block_code/blocks/communication/rigidbody2d_on_entered.tres b/addons/block_code/blocks/communication/rigidbody2d_on_entered.tres new file mode 100644 index 00000000..5be0ca5c --- /dev/null +++ b/addons/block_code/blocks/communication/rigidbody2d_on_entered.tres @@ -0,0 +1,18 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://dl1xd1jit2mlp"] + +[ext_resource type="Script" path="res://addons/block_code/code_generation/block_definition.gd" id="1_v2421"] + +[resource] +script = ExtResource("1_v2421") +name = &"rigidbody2d_on_entered" +target_node_class = "RigidBody2D" +description = "" +category = "Communication | Methods" +type = 1 +variant_type = 0 +display_template = "On [body: OBJECT] entered" +code_template = "func _on_body_entered(body: Node2D): +" +defaults = {} +signal_name = "body_entered" +scope = "" diff --git a/addons/block_code/blocks/communication/rigidbody2d_on_exited.tres b/addons/block_code/blocks/communication/rigidbody2d_on_exited.tres new file mode 100644 index 00000000..f16eb085 --- /dev/null +++ b/addons/block_code/blocks/communication/rigidbody2d_on_exited.tres @@ -0,0 +1,18 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://c15ymi1kxb570"] + +[ext_resource type="Script" path="res://addons/block_code/code_generation/block_definition.gd" id="1_sahiu"] + +[resource] +script = ExtResource("1_sahiu") +name = &"rigidbody2d_on_exited" +target_node_class = "RigidBody2D" +description = "" +category = "Communication | Methods" +type = 1 +variant_type = 0 +display_template = "On [body: OBJECT] exited" +code_template = "func _on_body_exited(body: Node2D): +" +defaults = {} +signal_name = "body_exited" +scope = "" diff --git a/addons/block_code/blocks/graphics/animationplayer_is_playing.tres b/addons/block_code/blocks/graphics/animationplayer_is_playing.tres new file mode 100644 index 00000000..1e3f6578 --- /dev/null +++ b/addons/block_code/blocks/graphics/animationplayer_is_playing.tres @@ -0,0 +1,17 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://mg4y3o0rsqd5"] + +[ext_resource type="Script" path="res://addons/block_code/code_generation/block_definition.gd" id="1_xr50b"] + +[resource] +script = ExtResource("1_xr50b") +name = &"animationplayer_is_playing" +target_node_class = "AnimationPlayer" +description = "Check if an animation is currently playing." +category = "Graphics | Animation" +type = 3 +variant_type = 1 +display_template = "Is playing" +code_template = "is_playing()" +defaults = {} +signal_name = "" +scope = "" diff --git a/addons/block_code/blocks/graphics/animationplayer_pause.tres b/addons/block_code/blocks/graphics/animationplayer_pause.tres new file mode 100644 index 00000000..15f80903 --- /dev/null +++ b/addons/block_code/blocks/graphics/animationplayer_pause.tres @@ -0,0 +1,17 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://clopo7gmje5a"] + +[ext_resource type="Script" path="res://addons/block_code/code_generation/block_definition.gd" id="1_2enqv"] + +[resource] +script = ExtResource("1_2enqv") +name = &"animationplayer_pause" +target_node_class = "AnimationPlayer" +description = "Pause the currently playing animation." +category = "Graphics | Animation" +type = 2 +variant_type = 0 +display_template = "Pause" +code_template = "pause()" +defaults = {} +signal_name = "" +scope = "" diff --git a/addons/block_code/blocks/graphics/animationplayer_play.tres b/addons/block_code/blocks/graphics/animationplayer_play.tres new file mode 100644 index 00000000..43bbce1e --- /dev/null +++ b/addons/block_code/blocks/graphics/animationplayer_play.tres @@ -0,0 +1,29 @@ +[gd_resource type="Resource" load_steps=4 format=3 uid="uid://c5e1byehtxwc0"] + +[ext_resource type="Script" path="res://addons/block_code/code_generation/block_definition.gd" id="1_emeuv"] +[ext_resource type="Script" path="res://addons/block_code/ui/block_canvas/option_data.gd" id="1_xu43h"] + +[sub_resource type="Resource" id="Resource_vnp2w"] +script = ExtResource("1_xu43h") +selected = 0 +items = ["ahead", "backwards"] + +[resource] +script = ExtResource("1_emeuv") +name = &"animationplayer_play" +target_node_class = "AnimationPlayer" +description = "Play the animation." +category = "Graphics | Animation" +type = 2 +variant_type = 0 +display_template = "Play {animation: STRING} {direction: OPTION}" +code_template = "if \"{direction}\" == \"ahead\": + play({animation}) +else: + play_backwards({animation}) +" +defaults = { +"direction": SubResource("Resource_vnp2w") +} +signal_name = "" +scope = "" diff --git a/addons/block_code/blocks/graphics/animationplayer_stop.tres b/addons/block_code/blocks/graphics/animationplayer_stop.tres new file mode 100644 index 00000000..35369a87 --- /dev/null +++ b/addons/block_code/blocks/graphics/animationplayer_stop.tres @@ -0,0 +1,17 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://b4v00oxoxbfet"] + +[ext_resource type="Script" path="res://addons/block_code/code_generation/block_definition.gd" id="1_wp8gr"] + +[resource] +script = ExtResource("1_wp8gr") +name = &"animationplayer_stop" +target_node_class = "AnimationPlayer" +description = "Stop the currently playing animation." +category = "Graphics | Animation" +type = 2 +variant_type = 0 +display_template = "Stop" +code_template = "stop()" +defaults = {} +signal_name = "" +scope = "" diff --git a/addons/block_code/blocks/input/characterbody2d_move.tres b/addons/block_code/blocks/input/characterbody2d_move.tres new file mode 100644 index 00000000..07614611 --- /dev/null +++ b/addons/block_code/blocks/input/characterbody2d_move.tres @@ -0,0 +1,31 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://cu3ru61vg6bx5"] + +[ext_resource type="Script" path="res://addons/block_code/code_generation/block_definition.gd" id="1_btxic"] + +[resource] +script = ExtResource("1_btxic") +name = &"characterbody2d_move" +target_node_class = "CharacterBody2D" +description = "" +category = "Input" +type = 2 +variant_type = 0 +display_template = "Move with keys {up: STRING} {down: STRING} {left: STRING} {right: STRING} with speed {speed: VECTOR2}" +code_template = "var dir = Vector2() +dir.x += float(Input.is_key_pressed(OS.find_keycode_from_string({right}))) +dir.x -= float(Input.is_key_pressed(OS.find_keycode_from_string({left}))) +dir.y += float(Input.is_key_pressed(OS.find_keycode_from_string({down}))) +dir.y -= float(Input.is_key_pressed(OS.find_keycode_from_string({up}))) +dir = dir.normalized() +velocity = dir*{speed} +move_and_slide() +" +defaults = { +"down": "S", +"left": "A", +"right": "D", +"speed": Vector2(100, 100), +"up": "W" +} +signal_name = "" +scope = "" diff --git a/addons/block_code/blocks/log/print.tres b/addons/block_code/blocks/log/print.tres index e6b9b89d..128c491a 100644 --- a/addons/block_code/blocks/log/print.tres +++ b/addons/block_code/blocks/log/print.tres @@ -5,6 +5,7 @@ [resource] script = ExtResource("1_0lih2") name = &"print" +target_node_class = "" description = "Print the text to output" category = "Log" type = 2 diff --git a/addons/block_code/blocks/logic/compare.tres b/addons/block_code/blocks/logic/compare.tres index 6556645b..8e124cf7 100644 --- a/addons/block_code/blocks/logic/compare.tres +++ b/addons/block_code/blocks/logic/compare.tres @@ -11,6 +11,7 @@ items = ["==", ">", "<", ">=", "<=", "!="] [resource] script = ExtResource("1_wp40r") name = &"compare" +target_node_class = "" description = "" category = "Logic | Comparison" type = 3 diff --git a/addons/block_code/blocks/math/add.tres b/addons/block_code/blocks/math/add.tres index 6ffb4155..336e1afc 100644 --- a/addons/block_code/blocks/math/add.tres +++ b/addons/block_code/blocks/math/add.tres @@ -5,6 +5,7 @@ [resource] script = ExtResource("1_rks7c") name = &"add" +target_node_class = "" description = "" category = "Math" type = 3 diff --git a/addons/block_code/blocks/math/divide.tres b/addons/block_code/blocks/math/divide.tres index 5d4dae46..0d6f00a5 100644 --- a/addons/block_code/blocks/math/divide.tres +++ b/addons/block_code/blocks/math/divide.tres @@ -5,6 +5,7 @@ [resource] script = ExtResource("1_rhh7v") name = &"divide" +target_node_class = "" description = "" category = "Math" type = 3 diff --git a/addons/block_code/blocks/math/multiply.tres b/addons/block_code/blocks/math/multiply.tres index 285c592d..1e29b3bb 100644 --- a/addons/block_code/blocks/math/multiply.tres +++ b/addons/block_code/blocks/math/multiply.tres @@ -5,6 +5,7 @@ [resource] script = ExtResource("1_c5vny") name = &"multiply" +target_node_class = "" description = "" category = "Math" type = 3 diff --git a/addons/block_code/blocks/math/pow.tres b/addons/block_code/blocks/math/pow.tres index 654d741a..a21f3eff 100644 --- a/addons/block_code/blocks/math/pow.tres +++ b/addons/block_code/blocks/math/pow.tres @@ -5,6 +5,7 @@ [resource] script = ExtResource("1_cx5g5") name = &"pow" +target_node_class = "" description = "" category = "Math" type = 3 diff --git a/addons/block_code/blocks/math/randf_range.tres b/addons/block_code/blocks/math/randf_range.tres index 641e8b34..ea47e98e 100644 --- a/addons/block_code/blocks/math/randf_range.tres +++ b/addons/block_code/blocks/math/randf_range.tres @@ -5,6 +5,7 @@ [resource] script = ExtResource("1_03jps") name = &"randf_range" +target_node_class = "" description = "Generate a random floating point number between [i]from[/i] and [i]to[/i] inclusively" category = "Math" type = 3 diff --git a/addons/block_code/blocks/math/randi_range.tres b/addons/block_code/blocks/math/randi_range.tres index 2d00f194..6636b4d4 100644 --- a/addons/block_code/blocks/math/randi_range.tres +++ b/addons/block_code/blocks/math/randi_range.tres @@ -5,6 +5,7 @@ [resource] script = ExtResource("1_hk574") name = &"randi_range" +target_node_class = "" description = "Generate a random signed 32-bits integer number between [i]from[/i] and [i]to[/i] inclusively. [i]from[/i] and [i]to[/i] can be a negative or positive number" category = "Math" type = 3 diff --git a/addons/block_code/blocks/math/subtract.tres b/addons/block_code/blocks/math/subtract.tres index a23bc765..1284f408 100644 --- a/addons/block_code/blocks/math/subtract.tres +++ b/addons/block_code/blocks/math/subtract.tres @@ -5,6 +5,7 @@ [resource] script = ExtResource("1_n0dmm") name = &"subtract" +target_node_class = "" description = "" category = "Math" type = 3 diff --git a/addons/block_code/blocks/physics/characterbody2d_move_and_slide.tres b/addons/block_code/blocks/physics/characterbody2d_move_and_slide.tres new file mode 100644 index 00000000..89448e21 --- /dev/null +++ b/addons/block_code/blocks/physics/characterbody2d_move_and_slide.tres @@ -0,0 +1,17 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://cp6ak6wea8ogh"] + +[ext_resource type="Script" path="res://addons/block_code/code_generation/block_definition.gd" id="1_e3r2r"] + +[resource] +script = ExtResource("1_e3r2r") +name = &"characterbody2d_move_and_slide" +target_node_class = "CharacterBody2D" +description = "" +category = "Physics | Velocity" +type = 2 +variant_type = 0 +display_template = "Move and slide" +code_template = "move_and_slide()" +defaults = {} +signal_name = "" +scope = "" diff --git a/addons/block_code/blocks/sounds/audiostreamplayer_play.tres b/addons/block_code/blocks/sounds/audiostreamplayer_play.tres new file mode 100644 index 00000000..1e574832 --- /dev/null +++ b/addons/block_code/blocks/sounds/audiostreamplayer_play.tres @@ -0,0 +1,17 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://bxjjml7u3rokv"] + +[ext_resource type="Script" path="res://addons/block_code/code_generation/block_definition.gd" id="1_vyl5w"] + +[resource] +script = ExtResource("1_vyl5w") +name = &"audiostreamplayer_play" +target_node_class = "AudioStreamPlayer" +description = "Play the audio stream" +category = "Sounds" +type = 2 +variant_type = 0 +display_template = "Play" +code_template = "play()" +defaults = {} +signal_name = "" +scope = "" diff --git a/addons/block_code/blocks/sounds/audiostreamplayer_stop.tres b/addons/block_code/blocks/sounds/audiostreamplayer_stop.tres new file mode 100644 index 00000000..d95f6a31 --- /dev/null +++ b/addons/block_code/blocks/sounds/audiostreamplayer_stop.tres @@ -0,0 +1,17 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://ib16grbtduab"] + +[ext_resource type="Script" path="res://addons/block_code/code_generation/block_definition.gd" id="1_db4g2"] + +[resource] +script = ExtResource("1_db4g2") +name = &"audiostreamplayer_stop" +target_node_class = "AudioStreamPlayer" +description = "Stop the audio stream" +category = "Sounds" +type = 2 +variant_type = 0 +display_template = "Stop" +code_template = "stop()" +defaults = {} +signal_name = "" +scope = "" diff --git a/addons/block_code/blocks/sounds/load_sound.tres b/addons/block_code/blocks/sounds/load_sound.tres index ddbe4fac..918ba273 100644 --- a/addons/block_code/blocks/sounds/load_sound.tres +++ b/addons/block_code/blocks/sounds/load_sound.tres @@ -5,6 +5,7 @@ [resource] script = ExtResource("1_4w4si") name = &"load_sound" +target_node_class = "" description = "Load a resource file as the audio stream" category = "Sounds" type = 2 diff --git a/addons/block_code/blocks/sounds/pause_continue_sound.tres b/addons/block_code/blocks/sounds/pause_continue_sound.tres index acac9de4..074e0352 100644 --- a/addons/block_code/blocks/sounds/pause_continue_sound.tres +++ b/addons/block_code/blocks/sounds/pause_continue_sound.tres @@ -11,6 +11,7 @@ items = ["Pause", "Continue"] [resource] script = ExtResource("1_q04gm") name = &"pause_continue_sound" +target_node_class = "" description = "Pause/Continue the audio stream" category = "Sounds" type = 2 diff --git a/addons/block_code/blocks/sounds/play_sound.tres b/addons/block_code/blocks/sounds/play_sound.tres index 128c5701..ac910d95 100644 --- a/addons/block_code/blocks/sounds/play_sound.tres +++ b/addons/block_code/blocks/sounds/play_sound.tres @@ -5,6 +5,7 @@ [resource] script = ExtResource("1_llfp1") name = &"play_sound" +target_node_class = "" description = "Play the audio stream with volume and pitch" category = "Sounds" type = 2 diff --git a/addons/block_code/blocks/sounds/stop_sound.tres b/addons/block_code/blocks/sounds/stop_sound.tres index e9c1a4a2..8233b734 100644 --- a/addons/block_code/blocks/sounds/stop_sound.tres +++ b/addons/block_code/blocks/sounds/stop_sound.tres @@ -5,6 +5,7 @@ [resource] script = ExtResource("1_rfujh") name = &"stop_sound" +target_node_class = "" description = "Stop the audio stream" category = "Sounds" type = 2 diff --git a/addons/block_code/blocks/transform/rigidbody2d_physics_position.tres b/addons/block_code/blocks/transform/rigidbody2d_physics_position.tres new file mode 100644 index 00000000..8059830d --- /dev/null +++ b/addons/block_code/blocks/transform/rigidbody2d_physics_position.tres @@ -0,0 +1,22 @@ +[gd_resource type="Resource" load_steps=2 format=3 uid="uid://ses5486g56q"] + +[ext_resource type="Script" path="res://addons/block_code/code_generation/block_definition.gd" id="1_72i54"] + +[resource] +script = ExtResource("1_72i54") +name = &"rigidbody2d_physics_position" +target_node_class = "RigidBody2D" +description = "" +category = "Transform | Position" +type = 2 +variant_type = 0 +display_template = "Set Physics Position {position: VECTOR2}" +code_template = "PhysicsServer2D.body_set_state( + get_rid(), + PhysicsServer2D.BODY_STATE_TRANSFORM, + Transform2D.IDENTITY.translated({position}) +) +" +defaults = {} +signal_name = "" +scope = "" diff --git a/addons/block_code/blocks/variables/vector2.tres b/addons/block_code/blocks/variables/vector2.tres index 0da6e806..cbdcf2eb 100644 --- a/addons/block_code/blocks/variables/vector2.tres +++ b/addons/block_code/blocks/variables/vector2.tres @@ -5,6 +5,7 @@ [resource] script = ExtResource("1_ilw3v") name = &"vector2" +target_node_class = "" description = "" category = "Variables" type = 3 diff --git a/addons/block_code/code_generation/block_definition.gd b/addons/block_code/code_generation/block_definition.gd index 1daca6e0..9f3bbb90 100644 --- a/addons/block_code/code_generation/block_definition.gd +++ b/addons/block_code/code_generation/block_definition.gd @@ -5,6 +5,11 @@ extends Resource const Types = preload("res://addons/block_code/types/types.gd") @export var name: StringName + +## The target node. Leaving this empty the block is considered a general block +## (for any node). +@export var target_node_class: String + @export_multiline var description: String @export var category: String @@ -25,6 +30,7 @@ const Types = preload("res://addons/block_code/types/types.gd") func _init( p_name: StringName = &"", + p_target_node_class = "", p_description: String = "", p_category: String = "", p_type: Types.BlockType = Types.BlockType.STATEMENT, @@ -36,6 +42,7 @@ func _init( p_scope: String = "", ): name = p_name + target_node_class = p_target_node_class description = p_description category = p_category type = p_type @@ -45,3 +52,7 @@ func _init( defaults = p_defaults signal_name = p_signal_name scope = p_scope + + +func _to_string(): + return "%s - %s" % [name, target_node_class] diff --git a/addons/block_code/code_generation/blocks_catalog.gd b/addons/block_code/code_generation/blocks_catalog.gd index 104c3df2..18ec616b 100644 --- a/addons/block_code/code_generation/blocks_catalog.gd +++ b/addons/block_code/code_generation/blocks_catalog.gd @@ -6,7 +6,210 @@ const Util = preload("res://addons/block_code/code_generation/util.gd") const _BLOCKS_PATH = "res://addons/block_code/blocks/" +const _FALLBACK_SET_FOR_TYPE = { + TYPE_BOOL: false, + TYPE_INT: 0, + TYPE_FLOAT: 0.0, + TYPE_VECTOR2: Vector2(0, 0), + TYPE_COLOR: Color.DARK_ORANGE, +} + +const _FALLBACK_CHANGE_FOR_TYPE = { + TYPE_BOOL: true, + TYPE_INT: 1, + TYPE_FLOAT: 1.0, + TYPE_VECTOR2: Vector2(1, 1), + TYPE_COLOR: Color.DARK_ORANGE, +} + +const _SETTINGS_FOR_CLASS_PROPERTY = { + "Node2D": + { + "position": + { + "category": "Transform | Position", + "default_set": Vector2(100, 100), + "default_change": Vector2(1, 1), + }, + "rotation_degrees": + { + "category": "Transform | Rotation", + "default_set": 45, + "default_change": 1, + }, + "scale": + { + "category": "Transform | Scale", + "default_set": Vector2(2, 2), + "default_change": Vector2(0.1, 0.1), + }, + }, + "CanvasItem": + { + "modulate": + { + "category": "Graphics | Modulate", + "has_change": false, + }, + "visible": + { + "category": "Graphics | Visibility", + "has_change": false, + }, + }, + "RigidBody2D": + { + "mass": {"category": "Physics | Mass"}, + "linear_velocity": {"category": "Physics | Velocity"}, + "angular_velocity": {"category": "Physics | Velocity"}, + }, + "AudioStreamPlayer": + { + "stream_paused": + { + "category": "Sounds", + "has_change": false, + }, + }, + "CharacterBody2D": + { + "velocity": {"category": "Physics | Velocity"}, + }, +} + static var _catalog: Dictionary +static var _by_class_name: Dictionary + + +static func _setup_definitions_from_files(): + var definition_files = Util.get_files_in_dir_recursive(_BLOCKS_PATH, "*.tres") + for file in definition_files: + var block_definition: BlockDefinition = load(file) + _catalog[block_definition.name] = block_definition + var target = block_definition.target_node_class + if not target: + continue + if not target in _by_class_name: + _by_class_name[target] = {} + _by_class_name[target][block_definition.name] = block_definition + + +static func _add_property_definitions(_class_name: String, property_list: Array[Dictionary], property_settings: Dictionary): + for property in property_list: + if not property.name in property_settings: + continue + var block_settings = property_settings[property.name] + var type_string: String = Types.VARIANT_TYPE_TO_STRING[property.type] + + if not _class_name in _by_class_name: + _by_class_name[_class_name] = {} + + # Setter + var block_definition: BlockDefinition = ( + BlockDefinition + . new( + &"%s_set_%s" % [_class_name, property.name], + _class_name, + "Set the %s property" % property.name, + block_settings.category, + Types.BlockType.STATEMENT, + TYPE_NIL, + "Set %s to {value: %s}" % [property.name.capitalize(), type_string], + "%s = {value}" % property.name, + {"value": block_settings.get("default_set", _FALLBACK_SET_FOR_TYPE[property.type])}, + ) + ) + _catalog[block_definition.name] = block_definition + _by_class_name[_class_name][block_definition.name] = block_definition + + # Changer + if block_settings.get("has_change", true): + block_definition = ( + BlockDefinition + . new( + &"%s_change_%s" % [_class_name, property.name], + _class_name, + "Change the %s property" % property.name, + block_settings.category, + Types.BlockType.STATEMENT, + TYPE_NIL, + "Change %s by {value: %s}" % [property.name.capitalize(), type_string], + "%s += {value}" % property.name, + {"value": block_settings.get("default_change", _FALLBACK_CHANGE_FOR_TYPE[property.type])}, + ) + ) + _catalog[block_definition.name] = block_definition + _by_class_name[_class_name][block_definition.name] = block_definition + + # Getter + block_definition = ( + BlockDefinition + . new( + &"%s_get_%s" % [_class_name, property.name], + _class_name, + "The %s property" % property.name, + block_settings.category, + Types.BlockType.VALUE, + property.type, + "%s" % property.name.capitalize(), + "%s" % property.name, + ) + ) + _catalog[block_definition.name] = block_definition + _by_class_name[_class_name][block_definition.name] = block_definition + + +static func _get_inputmap_actions() -> Array[StringName]: + var inputmap_actions: Array[StringName] + + var editor_input_actions: Dictionary = {} + var editor_input_action_deadzones: Dictionary = {} + if Engine.is_editor_hint(): + var actions := InputMap.get_actions() + for action in actions: + if action.begins_with("spatial_editor"): + var events := InputMap.action_get_events(action) + editor_input_actions[action] = events + editor_input_action_deadzones[action] = InputMap.action_get_deadzone(action) + + InputMap.load_from_project_settings() + + inputmap_actions = InputMap.get_actions() + + if Engine.is_editor_hint(): + for action in editor_input_actions.keys(): + InputMap.add_action(action, editor_input_action_deadzones[action]) + for event in editor_input_actions[action]: + InputMap.action_add_event(action, event) + + return inputmap_actions + + +static func _setup_properties_for_class(): + for _class_name in _SETTINGS_FOR_CLASS_PROPERTY: + var property_list = ClassDB.class_get_property_list(_class_name, true) + var property_settings = _SETTINGS_FOR_CLASS_PROPERTY[_class_name] + _add_property_definitions(_class_name, property_list, property_settings) + + +static func _setup_input_block(): + var inputmap_actions = _get_inputmap_actions() + + var block_definition: BlockDefinition = ( + BlockDefinition + . new( + &"is_input_actioned", + "", + "", + "Input", + Types.BlockType.VALUE, + TYPE_BOOL, + "Is action {action_name: OPTION} {action: OPTION}", + 'Input.is_action_{action}("{action_name}")', + {"action_name": OptionData.new(inputmap_actions), "action": OptionData.new(["pressed", "just_pressed", "just_released"])}, + ) + ) + _catalog[block_definition.name] = block_definition static func setup(): @@ -14,11 +217,9 @@ static func setup(): return _catalog = {} - - var definition_files = Util.get_files_in_dir_recursive(_BLOCKS_PATH, "*.tres") - for file in definition_files: - var block_definition = load(file) - _catalog[block_definition.name] = block_definition + _setup_definitions_from_files() + _setup_properties_for_class() + _setup_input_block() static func get_block(block_name: StringName): @@ -27,3 +228,28 @@ static func get_block(block_name: StringName): static func has_block(block_name: StringName): return block_name in _catalog + + +static func get_blocks_by_class(_class_name: String): + if not _class_name in _by_class_name: + return [] + var block_definitions = _by_class_name[_class_name] as Dictionary + return block_definitions.values() + + +static func add_custom_blocks( + _class_name, + block_definitions: Array[BlockDefinition] = [], + property_list: Array[Dictionary] = [], + property_settings: Dictionary = {}, +): + setup() + + if not _class_name in _by_class_name: + _by_class_name[_class_name] = {} + + for block_definition in block_definitions: + _catalog[block_definition.name] = block_definition + _by_class_name[_class_name][block_definition.name] = block_definition + + _add_property_definitions(_class_name, property_list, property_settings) diff --git a/addons/block_code/examples/pong_game/pong_game.tscn b/addons/block_code/examples/pong_game/pong_game.tscn index 6cad69bd..ec3ab35c 100644 --- a/addons/block_code/examples/pong_game/pong_game.tscn +++ b/addons/block_code/examples/pong_game/pong_game.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=122 format=3 uid="uid://tf7b8c64ecc0"] +[gd_scene load_steps=119 format=3 uid="uid://tf7b8c64ecc0"] [ext_resource type="PackedScene" uid="uid://cg8ibi18um3vg" path="res://addons/block_code/examples/pong_game/space.tscn" id="1_y56ac"] [ext_resource type="Script" path="res://addons/block_code/block_code_node/block_code.gd" id="3_6jaq8"] @@ -8,98 +8,84 @@ [ext_resource type="Script" path="res://addons/block_code/serialization/block_serialized_properties.gd" id="5_wr38c"] [ext_resource type="Script" path="res://addons/block_code/ui/block_canvas/option_data.gd" id="7_3q6bj"] [ext_resource type="Script" path="res://addons/block_code/serialization/block_script_serialization.gd" id="7_uuuue"] +[ext_resource type="Script" path="res://addons/block_code/ui/block_canvas/variable_resource.gd" id="9_lo3p1"] [ext_resource type="PackedScene" uid="uid://c7l70grmkauij" path="res://addons/block_code/examples/pong_game/ball.tscn" id="9_xrqll"] [ext_resource type="PackedScene" uid="uid://fhoapg3anjsu" path="res://addons/block_code/examples/pong_game/goal_area.tscn" id="12_nqmxu"] [ext_resource type="Script" path="res://addons/block_code/simple_nodes/simple_scoring/simple_scoring.gd" id="13_tg3yk"] -[sub_resource type="Resource" id="Resource_860cl"] +[sub_resource type="Resource" id="Resource_iegsu"] +script = ExtResource("5_wr38c") +block_class = &"EntryBlock" +serialized_props = [["scope", ""], ["param_input_strings", {}]] + +[sub_resource type="Resource" id="Resource_6fwti"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"set_prop_speed"], ["label", "StatementBlock"], ["color", Color(0.647059, 0.694118, 0.760784, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Set Speed to {value: VECTOR2}"], ["statement", "speed = {value}"], ["defaults", { -"value": "0, 0" -}], ["param_input_strings", { -"value": "0,1000" +serialized_props = [["scope", ""], ["param_input_strings", { +"value": Vector2(0, 1000) }]] -[sub_resource type="Resource" id="Resource_q65fe"] +[sub_resource type="Resource" id="Resource_bxt7h"] script = ExtResource("4_qtggh") -name = &"set_prop_speed" +name = &"SimpleCharacter_set_speed" position = Vector2(0, 0) path_child_pairs = [] -block_serialized_properties = SubResource("Resource_860cl") +block_serialized_properties = SubResource("Resource_6fwti") -[sub_resource type="Resource" id="Resource_q1vhx"] -script = ExtResource("5_wr38c") -block_class = &"EntryBlock" -serialized_props = [["color", Color(0.92549, 0.231373, 0.34902, 1)], ["scope", ""], ["param_input_strings", {}]] - -[sub_resource type="Resource" id="Resource_yiq7s"] +[sub_resource type="Resource" id="Resource_xsn6l"] script = ExtResource("4_qtggh") name = &"ready" position = Vector2(75, 175) -path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_q65fe")]] -block_serialized_properties = SubResource("Resource_q1vhx") +path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_bxt7h")]] +block_serialized_properties = SubResource("Resource_iegsu") -[sub_resource type="Resource" id="Resource_a45un"] -script = ExtResource("7_3q6bj") -selected = 0 -items = ["top-down", "platformer", "spaceship"] - -[sub_resource type="Resource" id="Resource_ldmk0"] -script = ExtResource("7_3q6bj") -selected = 0 -items = ["player_1", "player_2"] +[sub_resource type="Resource" id="Resource_41mcx"] +script = ExtResource("5_wr38c") +block_class = &"EntryBlock" +serialized_props = [["scope", ""], ["param_input_strings", {}]] -[sub_resource type="Resource" id="Resource_604n7"] +[sub_resource type="Resource" id="Resource_rwx76"] script = ExtResource("7_3q6bj") selected = 0 items = ["top-down", "platformer", "spaceship"] -[sub_resource type="Resource" id="Resource_h8b8o"] +[sub_resource type="Resource" id="Resource_ksb0o"] script = ExtResource("7_3q6bj") selected = 0 items = ["player_1", "player_2"] -[sub_resource type="Resource" id="Resource_d3xtc"] +[sub_resource type="Resource" id="Resource_82o3l"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"simplecharacter_move"], ["label", "StatementBlock"], ["color", Color(0.835294, 0.262745, 0.133333, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Move with {player: OPTION} buttons as {kind: OPTION}"], ["statement", "move_with_player_buttons(\"{player}\", \"{kind}\", delta)"], ["defaults", { -"kind": SubResource("Resource_a45un"), -"player": SubResource("Resource_ldmk0") -}], ["param_input_strings", { -"kind": SubResource("Resource_604n7"), -"player": SubResource("Resource_h8b8o") +serialized_props = [["scope", ""], ["param_input_strings", { +"kind": SubResource("Resource_rwx76"), +"player": SubResource("Resource_ksb0o") }]] -[sub_resource type="Resource" id="Resource_7x3sw"] +[sub_resource type="Resource" id="Resource_4vl0d"] script = ExtResource("4_qtggh") name = &"simplecharacter_move" position = Vector2(0, 0) path_child_pairs = [] -block_serialized_properties = SubResource("Resource_d3xtc") +block_serialized_properties = SubResource("Resource_82o3l") -[sub_resource type="Resource" id="Resource_x6ddv"] -script = ExtResource("5_wr38c") -block_class = &"EntryBlock" -serialized_props = [["block_name", &"process_block"], ["label", "EntryBlock"], ["color", Color(0.92549, 0.231373, 0.34902, 1)], ["block_type", 1], ["position", Vector2(75, 300)], ["scope", ""], ["block_format", "On Process"], ["statement", "func _process(delta):"], ["defaults", {}], ["param_input_strings", {}], ["signal_name", ""]] - -[sub_resource type="Resource" id="Resource_0m462"] +[sub_resource type="Resource" id="Resource_wntwg"] script = ExtResource("4_qtggh") -name = &"process_block" +name = &"process" position = Vector2(75, 300) -path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_7x3sw")]] -block_serialized_properties = SubResource("Resource_x6ddv") +path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_4vl0d")]] +block_serialized_properties = SubResource("Resource_41mcx") [sub_resource type="Resource" id="Resource_m2svk"] script = ExtResource("7_uuuue") script_inherits = "SimpleCharacter" -block_trees = Array[ExtResource("4_qtggh")]([SubResource("Resource_yiq7s"), SubResource("Resource_0m462")]) -variables = Array[Resource("res://addons/block_code/ui/block_canvas/variable_resource.gd")]([]) +block_trees = Array[ExtResource("4_qtggh")]([SubResource("Resource_xsn6l"), SubResource("Resource_wntwg")]) +variables = Array[ExtResource("9_lo3p1")]([]) generated_script = "extends SimpleCharacter func _ready(): - speed = Vector2(0,1000) + speed = Vector2(0, 1000) func _process(delta): move_with_player_buttons(\"player_1\", \"top-down\", delta) @@ -107,94 +93,79 @@ func _process(delta): " version = 0 -[sub_resource type="Resource" id="Resource_isc56"] +[sub_resource type="Resource" id="Resource_lhobc"] +script = ExtResource("5_wr38c") +block_class = &"EntryBlock" +serialized_props = [["scope", ""], ["param_input_strings", {}]] + +[sub_resource type="Resource" id="Resource_1ycg8"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"set_prop_speed"], ["label", "StatementBlock"], ["color", Color(0.647059, 0.694118, 0.760784, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Set Speed to {value: VECTOR2}"], ["statement", "speed = {value}"], ["defaults", { -"value": "0, 0" -}], ["param_input_strings", { -"value": "0,1000" +serialized_props = [["scope", ""], ["param_input_strings", { +"value": Vector2(0, 1000) }]] -[sub_resource type="Resource" id="Resource_ttkrd"] +[sub_resource type="Resource" id="Resource_nkjuo"] script = ExtResource("4_qtggh") -name = &"set_prop_speed" +name = &"SimpleCharacter_set_speed" position = Vector2(0, 0) path_child_pairs = [] -block_serialized_properties = SubResource("Resource_isc56") +block_serialized_properties = SubResource("Resource_1ycg8") -[sub_resource type="Resource" id="Resource_06s7w"] -script = ExtResource("5_wr38c") -block_class = &"EntryBlock" -serialized_props = [["color", Color(0.92549, 0.231373, 0.34902, 1)], ["scope", ""], ["param_input_strings", {}]] - -[sub_resource type="Resource" id="Resource_hrubs"] +[sub_resource type="Resource" id="Resource_t1m7j"] script = ExtResource("4_qtggh") name = &"ready" position = Vector2(50, 175) -path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_ttkrd")]] -block_serialized_properties = SubResource("Resource_06s7w") - -[sub_resource type="Resource" id="Resource_y2msu"] -script = ExtResource("7_3q6bj") -selected = 0 -items = ["top-down", "platformer", "spaceship"] +path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_nkjuo")]] +block_serialized_properties = SubResource("Resource_lhobc") -[sub_resource type="Resource" id="Resource_wq8lu"] -script = ExtResource("7_3q6bj") -selected = 0 -items = ["player_1", "player_2"] +[sub_resource type="Resource" id="Resource_ud032"] +script = ExtResource("5_wr38c") +block_class = &"EntryBlock" +serialized_props = [["scope", ""], ["param_input_strings", {}]] -[sub_resource type="Resource" id="Resource_cqi0p"] +[sub_resource type="Resource" id="Resource_ixcua"] script = ExtResource("7_3q6bj") selected = 0 items = ["top-down", "platformer", "spaceship"] -[sub_resource type="Resource" id="Resource_1apud"] +[sub_resource type="Resource" id="Resource_728pr"] script = ExtResource("7_3q6bj") selected = 1 items = ["player_1", "player_2"] -[sub_resource type="Resource" id="Resource_bl8w1"] +[sub_resource type="Resource" id="Resource_7aw38"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"simplecharacter_move"], ["label", "StatementBlock"], ["color", Color(0.835294, 0.262745, 0.133333, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Move with {player: OPTION} buttons as {kind: OPTION}"], ["statement", "move_with_player_buttons(\"{player}\", \"{kind}\", delta)"], ["defaults", { -"kind": SubResource("Resource_y2msu"), -"player": SubResource("Resource_wq8lu") -}], ["param_input_strings", { -"kind": SubResource("Resource_cqi0p"), -"player": SubResource("Resource_1apud") +serialized_props = [["scope", ""], ["param_input_strings", { +"kind": SubResource("Resource_ixcua"), +"player": SubResource("Resource_728pr") }]] -[sub_resource type="Resource" id="Resource_enqe8"] +[sub_resource type="Resource" id="Resource_gtejw"] script = ExtResource("4_qtggh") name = &"simplecharacter_move" position = Vector2(0, 0) path_child_pairs = [] -block_serialized_properties = SubResource("Resource_bl8w1") +block_serialized_properties = SubResource("Resource_7aw38") -[sub_resource type="Resource" id="Resource_3wgnl"] -script = ExtResource("5_wr38c") -block_class = &"EntryBlock" -serialized_props = [["block_name", &"process_block"], ["label", "EntryBlock"], ["color", Color(0.92549, 0.231373, 0.34902, 1)], ["block_type", 1], ["position", Vector2(50, 300)], ["scope", ""], ["block_format", "On Process"], ["statement", "func _process(delta):"], ["defaults", {}], ["param_input_strings", {}], ["signal_name", ""]] - -[sub_resource type="Resource" id="Resource_s8vl4"] +[sub_resource type="Resource" id="Resource_03rje"] script = ExtResource("4_qtggh") -name = &"process_block" +name = &"process" position = Vector2(50, 300) -path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_enqe8")]] -block_serialized_properties = SubResource("Resource_3wgnl") +path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_gtejw")]] +block_serialized_properties = SubResource("Resource_ud032") [sub_resource type="Resource" id="Resource_ysbi4"] script = ExtResource("7_uuuue") script_inherits = "SimpleCharacter" -block_trees = Array[ExtResource("4_qtggh")]([SubResource("Resource_hrubs"), SubResource("Resource_s8vl4")]) -variables = Array[Resource("res://addons/block_code/ui/block_canvas/variable_resource.gd")]([]) +block_trees = Array[ExtResource("4_qtggh")]([SubResource("Resource_t1m7j"), SubResource("Resource_03rje")]) +variables = Array[ExtResource("9_lo3p1")]([]) generated_script = "extends SimpleCharacter func _ready(): - speed = Vector2(0,1000) + speed = Vector2(0, 1000) func _process(delta): move_with_player_buttons(\"player_2\", \"top-down\", delta) @@ -202,319 +173,265 @@ func _process(delta): " version = 0 -[sub_resource type="Resource" id="Resource_rf047"] +[sub_resource type="Resource" id="Resource_d8f3t"] +script = ExtResource("5_wr38c") +block_class = &"EntryBlock" +serialized_props = [["scope", ""], ["param_input_strings", {}]] + +[sub_resource type="Resource" id="Resource_wtbtc"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"load_sound"], ["label", "StatementBlock"], ["color", Color(0.890196, 0.0588235, 0.752941, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Load file {file_path: STRING} as sound {name: STRING}"], ["statement", " -var __sound = AudioStreamPlayer.new() -__sound.name = {name} -__sound.set_stream(load({file_path})) -add_child(__sound) -"], ["defaults", {}], ["param_input_strings", { -"file_path": "res://addons/block_code/examples/pong_game/assets/score.ogg", -"name": "score_sound" +serialized_props = [["scope", ""], ["param_input_strings", { +"file_path": "res://addons/block_code/examples/pong_game/assets/paddle_hit.ogg", +"name": "paddle_hit" }]] -[sub_resource type="Resource" id="Resource_d34ke"] -script = ExtResource("4_qtggh") -name = &"load_sound" -position = Vector2(0, 0) -path_child_pairs = [] -block_serialized_properties = SubResource("Resource_rf047") - -[sub_resource type="Resource" id="Resource_md4i5"] +[sub_resource type="Resource" id="Resource_st0iw"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"load_sound"], ["label", "StatementBlock"], ["color", Color(0.890196, 0.0588235, 0.752941, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Load file {file_path: STRING} as sound {name: STRING}"], ["statement", " -var __sound = AudioStreamPlayer.new() -__sound.name = {name} -__sound.set_stream(load({file_path})) -add_child(__sound) -"], ["defaults", {}], ["param_input_strings", { +serialized_props = [["scope", ""], ["param_input_strings", { "file_path": "res://addons/block_code/examples/pong_game/assets/wall_hit.ogg", "name": "wall_hit" }]] -[sub_resource type="Resource" id="Resource_roxh4"] +[sub_resource type="Resource" id="Resource_jp6b8"] +script = ExtResource("5_wr38c") +block_class = &"StatementBlock" +serialized_props = [["scope", ""], ["param_input_strings", { +"file_path": "res://addons/block_code/examples/pong_game/assets/score.ogg", +"name": "score_sound" +}]] + +[sub_resource type="Resource" id="Resource_xs0e6"] script = ExtResource("4_qtggh") name = &"load_sound" position = Vector2(0, 0) -path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_d34ke")]] -block_serialized_properties = SubResource("Resource_md4i5") +path_child_pairs = [] +block_serialized_properties = SubResource("Resource_jp6b8") -[sub_resource type="Resource" id="Resource_4luvu"] -script = ExtResource("5_wr38c") -block_class = &"StatementBlock" -serialized_props = [["block_name", &"load_sound"], ["label", "StatementBlock"], ["color", Color(0.890196, 0.0588235, 0.752941, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Load file {file_path: STRING} as sound {name: STRING}"], ["statement", " -var __sound = AudioStreamPlayer.new() -__sound.name = {name} -__sound.set_stream(load({file_path})) -add_child(__sound) -"], ["defaults", {}], ["param_input_strings", { -"file_path": "res://addons/block_code/examples/pong_game/assets/paddle_hit.ogg", -"name": "paddle_hit" -}]] +[sub_resource type="Resource" id="Resource_spen4"] +script = ExtResource("4_qtggh") +name = &"load_sound" +position = Vector2(0, 0) +path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_xs0e6")]] +block_serialized_properties = SubResource("Resource_st0iw") -[sub_resource type="Resource" id="Resource_gywyt"] +[sub_resource type="Resource" id="Resource_r5331"] script = ExtResource("4_qtggh") name = &"load_sound" position = Vector2(0, 0) -path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_roxh4")]] -block_serialized_properties = SubResource("Resource_4luvu") +path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_spen4")]] +block_serialized_properties = SubResource("Resource_wtbtc") + +[sub_resource type="Resource" id="Resource_phaw7"] +script = ExtResource("4_qtggh") +name = &"ready" +position = Vector2(50, 50) +path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_r5331")]] +block_serialized_properties = SubResource("Resource_d8f3t") -[sub_resource type="Resource" id="Resource_b0aen"] +[sub_resource type="Resource" id="Resource_47jf7"] script = ExtResource("5_wr38c") block_class = &"EntryBlock" -serialized_props = [["color", Color(0.92549, 0.231373, 0.34902, 1)], ["scope", ""], ["param_input_strings", {}]] +serialized_props = [["scope", ""], ["param_input_strings", { +"method_name": "reset" +}]] -[sub_resource type="Resource" id="Resource_1h6wi"] -script = ExtResource("4_qtggh") -name = &"ready" -position = Vector2(54, 47) -path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_gywyt")]] -block_serialized_properties = SubResource("Resource_b0aen") +[sub_resource type="Resource" id="Resource_obbdk"] +script = ExtResource("5_wr38c") +block_class = &"StatementBlock" +serialized_props = [["scope", ""], ["param_input_strings", { +"position": Vector2(0, 0) +}]] -[sub_resource type="Resource" id="Resource_05cdj"] +[sub_resource type="Resource" id="Resource_qae7k"] script = ExtResource("5_wr38c") block_class = &"ParameterBlock" -serialized_props = [["block_name", &"viewport_center"], ["label", "Param"], ["color", Color(0.0117647, 0.666667, 0.454902, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Viewport Center"], ["statement", "(func (): var transform: Transform2D = get_viewport_transform(); var scale: Vector2 = transform.get_scale(); return -transform.origin / scale + get_viewport_rect().size / scale / 2).call()"], ["defaults", {}], ["variant_type", 5], ["param_input_strings", {}]] +serialized_props = [["scope", ""], ["param_input_strings", {}]] -[sub_resource type="Resource" id="Resource_kt3qw"] +[sub_resource type="Resource" id="Resource_1sea1"] script = ExtResource("4_qtggh") name = &"viewport_center" position = Vector2(0, 0) path_child_pairs = [] -block_serialized_properties = SubResource("Resource_05cdj") +block_serialized_properties = SubResource("Resource_qae7k") -[sub_resource type="Resource" id="Resource_uob83"] +[sub_resource type="Resource" id="Resource_3b4ka"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"play_sound"], ["label", "StatementBlock"], ["color", Color(0.890196, 0.0588235, 0.752941, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Play the sound {name: STRING} with Volume dB {db: FLOAT} and Pitch Scale {pitch: FLOAT}"], ["statement", " -var __sound_node = get_node({name}) -__sound_node.volume_db = {db} -__sound_node.pitch_scale = {pitch} -__sound_node.play() -"], ["defaults", { -"db": "0.0", -"pitch": "1.0" -}], ["param_input_strings", { -"db": "0.0", +serialized_props = [["scope", ""], ["param_input_strings", { +"db": 0.0, "name": "score_sound", -"pitch": "1.0" +"pitch": 1.0 }]] -[sub_resource type="Resource" id="Resource_oawyp"] +[sub_resource type="Resource" id="Resource_16pmr"] script = ExtResource("4_qtggh") name = &"play_sound" position = Vector2(0, 0) path_child_pairs = [] -block_serialized_properties = SubResource("Resource_uob83") +block_serialized_properties = SubResource("Resource_3b4ka") -[sub_resource type="Resource" id="Resource_5x1be"] -script = ExtResource("5_wr38c") -block_class = &"StatementBlock" -serialized_props = [["block_name", &"rigidbody2d_physics_position"], ["label", "StatementBlock"], ["color", Color(0.294118, 0.396078, 0.517647, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Set Physics Position {position: VECTOR2}"], ["statement", " -PhysicsServer2D.body_set_state( - get_rid(), - PhysicsServer2D.BODY_STATE_TRANSFORM, - Transform2D.IDENTITY.translated({position}) -) -"], ["defaults", {}], ["param_input_strings", { -"position": "," -}]] - -[sub_resource type="Resource" id="Resource_ftveg"] +[sub_resource type="Resource" id="Resource_ugq5m"] script = ExtResource("4_qtggh") name = &"rigidbody2d_physics_position" position = Vector2(0, 0) -path_child_pairs = [[NodePath("VBoxContainer/TopMarginContainer/MarginContainer/HBoxContainer/ParameterInput0/SnapPoint"), SubResource("Resource_kt3qw")], [NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_oawyp")]] -block_serialized_properties = SubResource("Resource_5x1be") - -[sub_resource type="Resource" id="Resource_sp3a4"] -script = ExtResource("5_wr38c") -block_class = &"EntryBlock" -serialized_props = [["block_name", &"define_method"], ["label", "EntryBlock"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 1], ["position", Vector2(50, 275)], ["scope", ""], ["block_format", "Define method {method_name: NIL}"], ["statement", "func {method_name}():"], ["defaults", {}], ["param_input_strings", { -"method_name": "reset" -}], ["signal_name", ""]] +path_child_pairs = [[NodePath("VBoxContainer/TopMarginContainer/MarginContainer/HBoxContainer/ParameterInput0/SnapPoint"), SubResource("Resource_1sea1")], [NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_16pmr")]] +block_serialized_properties = SubResource("Resource_obbdk") -[sub_resource type="Resource" id="Resource_gmlt0"] +[sub_resource type="Resource" id="Resource_ane3b"] script = ExtResource("4_qtggh") name = &"define_method" position = Vector2(50, 275) -path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_ftveg")]] -block_serialized_properties = SubResource("Resource_sp3a4") +path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_ugq5m")]] +block_serialized_properties = SubResource("Resource_47jf7") -[sub_resource type="Resource" id="Resource_r1gqk"] +[sub_resource type="Resource" id="Resource_7kl7g"] script = ExtResource("5_wr38c") -block_class = &"ParameterBlock" -serialized_props = [["block_name", &"parameter_block"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", " -func _on_body_entered(_body: Node): - var body: NodePath = _body.get_path() -"], ["block_format", "body"], ["statement", "body"], ["defaults", {}], ["variant_type", 22], ["param_input_strings", {}]] - -[sub_resource type="Resource" id="Resource_gj1nu"] -script = ExtResource("4_qtggh") -name = &"parameter_block" -position = Vector2(0, 0) -path_child_pairs = [] -block_serialized_properties = SubResource("Resource_r1gqk") +block_class = &"EntryBlock" +serialized_props = [["scope", ""], ["param_input_strings", {}]] -[sub_resource type="Resource" id="Resource_ri33r"] +[sub_resource type="Resource" id="Resource_vqtp0"] script = ExtResource("5_wr38c") block_class = &"ParameterBlock" -serialized_props = [["block_name", &"parameter_block"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", " -func _on_body_entered(_body: Node): - var body: NodePath = _body.get_path() -"], ["block_format", "body"], ["statement", "body"], ["defaults", {}], ["variant_type", 22], ["param_input_strings", {}]] +serialized_props = [["block_name", &"parameter_block"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", "func _on_body_entered(body: Node2D): +"], ["block_format", "body"], ["statement", "body"], ["defaults", {}], ["variant_type", 24], ["param_input_strings", {}]] -[sub_resource type="Resource" id="Resource_7qpii"] +[sub_resource type="Resource" id="Resource_bgppn"] script = ExtResource("4_qtggh") name = &"parameter_block" position = Vector2(0, 0) path_child_pairs = [] -block_serialized_properties = SubResource("Resource_ri33r") +block_serialized_properties = SubResource("Resource_vqtp0") + +[sub_resource type="Resource" id="Resource_dnsl7"] +script = ExtResource("5_wr38c") +block_class = &"ControlBlock" +serialized_props = [["scope", ""], ["param_input_strings_array", [{ +"condition": false +}]]] -[sub_resource type="Resource" id="Resource_s7b4y"] +[sub_resource type="Resource" id="Resource_kvrwg"] script = ExtResource("5_wr38c") block_class = &"ParameterBlock" -serialized_props = [["block_name", &"is_node_in_group"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Is {node: NODE_PATH} in group {group: STRING}"], ["statement", "get_node({node}).is_in_group({group})"], ["defaults", {}], ["variant_type", 1], ["param_input_strings", { +serialized_props = [["scope", ""], ["param_input_strings", { "group": "paddles", "node": "" }]] -[sub_resource type="Resource" id="Resource_xsgv2"] +[sub_resource type="Resource" id="Resource_et4ib"] +script = ExtResource("5_wr38c") +block_class = &"ParameterBlock" +serialized_props = [["block_name", &"parameter_block"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", "func _on_body_entered(body: Node2D): +"], ["block_format", "body"], ["statement", "body"], ["defaults", {}], ["variant_type", 24], ["param_input_strings", {}]] + +[sub_resource type="Resource" id="Resource_707bn"] +script = ExtResource("4_qtggh") +name = &"parameter_block" +position = Vector2(0, 0) +path_child_pairs = [] +block_serialized_properties = SubResource("Resource_et4ib") + +[sub_resource type="Resource" id="Resource_dj7fd"] script = ExtResource("4_qtggh") name = &"is_node_in_group" position = Vector2(0, 0) -path_child_pairs = [[NodePath("MarginContainer/HBoxContainer/ParameterInput0/SnapPoint"), SubResource("Resource_7qpii")]] -block_serialized_properties = SubResource("Resource_s7b4y") +path_child_pairs = [[NodePath("MarginContainer/HBoxContainer/ParameterInput0/SnapPoint"), SubResource("Resource_707bn")]] +block_serialized_properties = SubResource("Resource_kvrwg") -[sub_resource type="Resource" id="Resource_bh5jo"] +[sub_resource type="Resource" id="Resource_t4jty"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"play_sound"], ["label", "StatementBlock"], ["color", Color(0.890196, 0.0588235, 0.752941, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Play the sound {name: STRING} with Volume dB {db: FLOAT} and Pitch Scale {pitch: FLOAT}"], ["statement", " -var __sound_node = get_node({name}) -__sound_node.volume_db = {db} -__sound_node.pitch_scale = {pitch} -__sound_node.play() -"], ["defaults", { -"db": "0.0", -"pitch": "1.0" -}], ["param_input_strings", { -"db": "0.0", +serialized_props = [["scope", ""], ["param_input_strings", { +"db": 0.0, "name": "paddle_hit", -"pitch": "1.0" +"pitch": 1.0 }]] -[sub_resource type="Resource" id="Resource_ic2jq"] +[sub_resource type="Resource" id="Resource_2lgdm"] script = ExtResource("4_qtggh") name = &"play_sound" -position = Vector2(0, 0) +position = Vector2(20, 0) path_child_pairs = [] -block_serialized_properties = SubResource("Resource_bh5jo") +block_serialized_properties = SubResource("Resource_t4jty") -[sub_resource type="Resource" id="Resource_mgvpf"] +[sub_resource type="Resource" id="Resource_e1awu"] script = ExtResource("5_wr38c") -block_class = &"ParameterBlock" -serialized_props = [["block_name", &"parameter_block"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", " -func _on_body_entered(_body: Node): - var body: NodePath = _body.get_path() -"], ["block_format", "body"], ["statement", "body"], ["defaults", {}], ["variant_type", 22], ["param_input_strings", {}]] - -[sub_resource type="Resource" id="Resource_mbuv7"] -script = ExtResource("4_qtggh") -name = &"parameter_block" -position = Vector2(0, 0) -path_child_pairs = [] -block_serialized_properties = SubResource("Resource_mgvpf") +block_class = &"ControlBlock" +serialized_props = [["scope", ""], ["param_input_strings_array", [{ +"condition": false +}]]] -[sub_resource type="Resource" id="Resource_rc730"] +[sub_resource type="Resource" id="Resource_1en27"] script = ExtResource("5_wr38c") block_class = &"ParameterBlock" -serialized_props = [["block_name", &"is_node_in_group"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Is {node: NODE_PATH} in group {group: STRING}"], ["statement", "get_node({node}).is_in_group({group})"], ["defaults", {}], ["variant_type", 1], ["param_input_strings", { +serialized_props = [["scope", ""], ["param_input_strings", { "group": "walls", "node": "" }]] -[sub_resource type="Resource" id="Resource_fgryt"] +[sub_resource type="Resource" id="Resource_mur5c"] +script = ExtResource("5_wr38c") +block_class = &"ParameterBlock" +serialized_props = [["block_name", &"parameter_block"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", "func _on_body_entered(body: Node2D): +"], ["block_format", "body"], ["statement", "body"], ["defaults", {}], ["variant_type", 24], ["param_input_strings", {}]] + +[sub_resource type="Resource" id="Resource_wo7ob"] +script = ExtResource("4_qtggh") +name = &"parameter_block" +position = Vector2(0, 0) +path_child_pairs = [] +block_serialized_properties = SubResource("Resource_mur5c") + +[sub_resource type="Resource" id="Resource_jb4li"] script = ExtResource("4_qtggh") name = &"is_node_in_group" position = Vector2(0, 0) -path_child_pairs = [[NodePath("MarginContainer/HBoxContainer/ParameterInput0/SnapPoint"), SubResource("Resource_mbuv7")]] -block_serialized_properties = SubResource("Resource_rc730") +path_child_pairs = [[NodePath("MarginContainer/HBoxContainer/ParameterInput0/SnapPoint"), SubResource("Resource_wo7ob")]] +block_serialized_properties = SubResource("Resource_1en27") -[sub_resource type="Resource" id="Resource_71yrt"] +[sub_resource type="Resource" id="Resource_s6roe"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"play_sound"], ["label", "StatementBlock"], ["color", Color(0.890196, 0.0588235, 0.752941, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Play the sound {name: STRING} with Volume dB {db: FLOAT} and Pitch Scale {pitch: FLOAT}"], ["statement", " -var __sound_node = get_node({name}) -__sound_node.volume_db = {db} -__sound_node.pitch_scale = {pitch} -__sound_node.play() -"], ["defaults", { -"db": "0.0", -"pitch": "1.0" -}], ["param_input_strings", { -"db": "0.0", +serialized_props = [["scope", ""], ["param_input_strings", { +"db": 0.0, "name": "wall_hit", -"pitch": "1.0" +"pitch": 1.0 }]] -[sub_resource type="Resource" id="Resource_f3xwp"] +[sub_resource type="Resource" id="Resource_kd52t"] script = ExtResource("4_qtggh") name = &"play_sound" -position = Vector2(0, 0) +position = Vector2(20, 0) path_child_pairs = [] -block_serialized_properties = SubResource("Resource_71yrt") - -[sub_resource type="Resource" id="Resource_wkj8h"] -script = ExtResource("5_wr38c") -block_class = &"ControlBlock" -serialized_props = [["block_name", &"if"], ["label", "Control Block"], ["color", Color(0.270588, 0.666667, 0.94902, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_formats", ["if {condition: BOOL}"]], ["statements", ["if {condition}:"]], ["defaults", {}], ["param_input_strings_array", [{ -"condition": false -}]]] +block_serialized_properties = SubResource("Resource_s6roe") -[sub_resource type="Resource" id="Resource_qmdbv"] +[sub_resource type="Resource" id="Resource_ky5ld"] script = ExtResource("4_qtggh") name = &"if" position = Vector2(0, 0) -path_child_pairs = [[NodePath("VBoxContainer/MarginContainer/Rows/Row0/RowHBoxContainer/RowHBox/ParameterInput0/SnapPoint"), SubResource("Resource_fgryt")], [NodePath("VBoxContainer/MarginContainer/Rows/SnapContainer0/SnapPoint"), SubResource("Resource_f3xwp")]] -block_serialized_properties = SubResource("Resource_wkj8h") - -[sub_resource type="Resource" id="Resource_dwd2k"] -script = ExtResource("5_wr38c") -block_class = &"ControlBlock" -serialized_props = [["block_name", &"if"], ["label", "Control Block"], ["color", Color(0.270588, 0.666667, 0.94902, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_formats", ["if {condition: BOOL}"]], ["statements", ["if {condition}:"]], ["defaults", {}], ["param_input_strings_array", [{ -"condition": false -}]]] +path_child_pairs = [[NodePath("VBoxContainer/MarginContainer/Rows/Row0/RowHBoxContainer/RowHBox/ParameterInput0/SnapPoint"), SubResource("Resource_jb4li")], [NodePath("VBoxContainer/MarginContainer/Rows/SnapContainer0/SnapPoint"), SubResource("Resource_kd52t")]] +block_serialized_properties = SubResource("Resource_e1awu") -[sub_resource type="Resource" id="Resource_rs6a0"] +[sub_resource type="Resource" id="Resource_ef7x8"] script = ExtResource("4_qtggh") name = &"if" position = Vector2(0, 0) -path_child_pairs = [[NodePath("VBoxContainer/MarginContainer/Rows/Row0/RowHBoxContainer/RowHBox/ParameterInput0/SnapPoint"), SubResource("Resource_xsgv2")], [NodePath("VBoxContainer/MarginContainer/Rows/SnapContainer0/SnapPoint"), SubResource("Resource_ic2jq")], [NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_qmdbv")]] -block_serialized_properties = SubResource("Resource_dwd2k") +path_child_pairs = [[NodePath("VBoxContainer/MarginContainer/Rows/Row0/RowHBoxContainer/RowHBox/ParameterInput0/SnapPoint"), SubResource("Resource_dj7fd")], [NodePath("VBoxContainer/MarginContainer/Rows/SnapContainer0/SnapPoint"), SubResource("Resource_2lgdm")], [NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_ky5ld")]] +block_serialized_properties = SubResource("Resource_dnsl7") -[sub_resource type="Resource" id="Resource_7mdg3"] -script = ExtResource("5_wr38c") -block_class = &"EntryBlock" -serialized_props = [["block_name", &"rigidbody2d_on_entered"], ["label", "EntryBlock"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 1], ["position", Vector2(50, 475)], ["scope", ""], ["block_format", "On [body: NODE_PATH] entered"], ["statement", " -func _on_body_entered(_body: Node): - var body: NodePath = _body.get_path() -"], ["defaults", {}], ["param_input_strings", {}], ["signal_name", "body_entered"]] - -[sub_resource type="Resource" id="Resource_tyrtu"] +[sub_resource type="Resource" id="Resource_1bd3d"] script = ExtResource("4_qtggh") name = &"rigidbody2d_on_entered" position = Vector2(50, 475) -path_child_pairs = [[NodePath("VBoxContainer/TopMarginContainer/MarginContainer/HBoxContainer/ParameterOutput0/SnapPoint"), SubResource("Resource_gj1nu")], [NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_rs6a0")]] -block_serialized_properties = SubResource("Resource_7mdg3") +path_child_pairs = [[NodePath("VBoxContainer/TopMarginContainer/MarginContainer/HBoxContainer/ParameterOutput0/SnapPoint"), SubResource("Resource_bgppn")], [NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_ef7x8")]] +block_serialized_properties = SubResource("Resource_7kl7g") [sub_resource type="Resource" id="Resource_6m2mk"] script = ExtResource("7_uuuue") script_inherits = "RigidBody2D" -block_trees = Array[ExtResource("4_qtggh")]([SubResource("Resource_1h6wi"), SubResource("Resource_gmlt0"), SubResource("Resource_tyrtu")]) -variables = Array[Resource("res://addons/block_code/ui/block_canvas/variable_resource.gd")]([]) +block_trees = Array[ExtResource("4_qtggh")]([SubResource("Resource_phaw7"), SubResource("Resource_ane3b"), SubResource("Resource_1bd3d")]) +variables = Array[ExtResource("9_lo3p1")]([]) generated_script = "extends RigidBody2D @@ -539,23 +456,21 @@ func reset(): Transform2D.IDENTITY.translated((func (): var transform: Transform2D = get_viewport_transform(); var scale: Vector2 = transform.get_scale(); return -transform.origin / scale + get_viewport_rect().size / scale / 2).call()) ) var __sound_node_1 = get_node('score_sound') - __sound_node_1.volume_db = 0.0 - __sound_node_1.pitch_scale = 1.0 + __sound_node_1.volume_db = 0 + __sound_node_1.pitch_scale = 1 __sound_node_1.play() +func _on_body_entered(body: Node2D): -func _on_body_entered(_body: Node): - var body: NodePath = _body.get_path() - - if get_node(body).is_in_group('paddles'): + if body.is_in_group('paddles'): var __sound_node_1 = get_node('paddle_hit') - __sound_node_1.volume_db = 0.0 - __sound_node_1.pitch_scale = 1.0 + __sound_node_1.volume_db = 0 + __sound_node_1.pitch_scale = 1 __sound_node_1.play() - if get_node(body).is_in_group('walls'): + if body.is_in_group('walls'): var __sound_node_2 = get_node('wall_hit') - __sound_node_2.volume_db = 0.0 - __sound_node_2.pitch_scale = 1.0 + __sound_node_2.volume_db = 0 + __sound_node_2.pitch_scale = 1 __sound_node_2.play() func _init(): @@ -563,123 +478,114 @@ func _init(): " version = 0 -[sub_resource type="Resource" id="Resource_itmch"] +[sub_resource type="Resource" id="Resource_xxj4u"] script = ExtResource("5_wr38c") -block_class = &"ParameterBlock" -serialized_props = [["block_name", &"parameter_block"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", " -func _on_body_entered(_body: Node2D): - var body: NodePath = _body.get_path() -"], ["block_format", "body"], ["statement", "body"], ["defaults", {}], ["variant_type", 22], ["param_input_strings", {}]] - -[sub_resource type="Resource" id="Resource_3wodo"] -script = ExtResource("4_qtggh") -name = &"parameter_block" -position = Vector2(0, 0) -path_child_pairs = [] -block_serialized_properties = SubResource("Resource_itmch") +block_class = &"EntryBlock" +serialized_props = [["scope", ""], ["param_input_strings", {}]] -[sub_resource type="Resource" id="Resource_wo02o"] +[sub_resource type="Resource" id="Resource_lnfkn"] script = ExtResource("5_wr38c") block_class = &"ParameterBlock" -serialized_props = [["block_name", &"parameter_block"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", " -func _on_body_entered(_body: Node2D): - var body: NodePath = _body.get_path() -"], ["block_format", "body"], ["statement", "body"], ["defaults", {}], ["variant_type", 22], ["param_input_strings", {}]] +serialized_props = [["block_name", &"parameter_block"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", "func _on_body_entered(body: Node2D): +"], ["block_format", "body"], ["statement", "body"], ["defaults", {}], ["variant_type", 24], ["param_input_strings", {}]] -[sub_resource type="Resource" id="Resource_dcwek"] +[sub_resource type="Resource" id="Resource_r1q4l"] script = ExtResource("4_qtggh") name = &"parameter_block" position = Vector2(0, 0) path_child_pairs = [] -block_serialized_properties = SubResource("Resource_wo02o") +block_serialized_properties = SubResource("Resource_lnfkn") + +[sub_resource type="Resource" id="Resource_ft8ne"] +script = ExtResource("5_wr38c") +block_class = &"ControlBlock" +serialized_props = [["scope", ""], ["param_input_strings_array", [{ +"condition": false +}]]] -[sub_resource type="Resource" id="Resource_ma3m2"] +[sub_resource type="Resource" id="Resource_s06y5"] script = ExtResource("5_wr38c") block_class = &"ParameterBlock" -serialized_props = [["block_name", &"is_node_in_group"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Is {node: NODE_PATH} in group {group: STRING}"], ["statement", "get_node({node}).is_in_group({group})"], ["defaults", {}], ["variant_type", 1], ["param_input_strings", { +serialized_props = [["scope", ""], ["param_input_strings", { "group": "balls", "node": "" }]] -[sub_resource type="Resource" id="Resource_bny5u"] -script = ExtResource("4_qtggh") -name = &"is_node_in_group" -position = Vector2(0, 0) -path_child_pairs = [[NodePath("MarginContainer/HBoxContainer/ParameterInput0/SnapPoint"), SubResource("Resource_dcwek")]] -block_serialized_properties = SubResource("Resource_ma3m2") - -[sub_resource type="Resource" id="Resource_dkm1h"] +[sub_resource type="Resource" id="Resource_5itae"] script = ExtResource("5_wr38c") -block_class = &"StatementBlock" -serialized_props = [["block_name", &"call_group_method"], ["label", "StatementBlock"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Call method {method_name: STRING} in group {group: STRING}"], ["statement", "get_tree().call_group({group}, {method_name})"], ["defaults", {}], ["param_input_strings", { -"group": "balls", -"method_name": "reset" -}]] +block_class = &"ParameterBlock" +serialized_props = [["block_name", &"parameter_block"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", "func _on_body_entered(body: Node2D): +"], ["block_format", "body"], ["statement", "body"], ["defaults", {}], ["variant_type", 24], ["param_input_strings", {}]] -[sub_resource type="Resource" id="Resource_57tvt"] +[sub_resource type="Resource" id="Resource_ht2bw"] script = ExtResource("4_qtggh") -name = &"call_group_method" +name = &"parameter_block" position = Vector2(0, 0) path_child_pairs = [] -block_serialized_properties = SubResource("Resource_dkm1h") +block_serialized_properties = SubResource("Resource_5itae") + +[sub_resource type="Resource" id="Resource_iyvmc"] +script = ExtResource("4_qtggh") +name = &"is_node_in_group" +position = Vector2(0, 0) +path_child_pairs = [[NodePath("MarginContainer/HBoxContainer/ParameterInput0/SnapPoint"), SubResource("Resource_ht2bw")]] +block_serialized_properties = SubResource("Resource_s06y5") -[sub_resource type="Resource" id="Resource_lm5iy"] +[sub_resource type="Resource" id="Resource_eyu21"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"call_group_method"], ["label", "StatementBlock"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Call method {method_name: STRING} in group {group: STRING}"], ["statement", "get_tree().call_group({group}, {method_name})"], ["defaults", {}], ["param_input_strings", { +serialized_props = [["scope", ""], ["param_input_strings", { "group": "scoring", "method_name": "goal_left" }]] -[sub_resource type="Resource" id="Resource_26pqe"] +[sub_resource type="Resource" id="Resource_5hog4"] +script = ExtResource("5_wr38c") +block_class = &"StatementBlock" +serialized_props = [["scope", ""], ["param_input_strings", { +"group": "balls", +"method_name": "reset" +}]] + +[sub_resource type="Resource" id="Resource_x6rc5"] script = ExtResource("4_qtggh") -name = &"call_group_method" +name = &"call_method_group" position = Vector2(0, 0) -path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_57tvt")]] -block_serialized_properties = SubResource("Resource_lm5iy") +path_child_pairs = [] +block_serialized_properties = SubResource("Resource_5hog4") -[sub_resource type="Resource" id="Resource_yd7xk"] -script = ExtResource("5_wr38c") -block_class = &"ControlBlock" -serialized_props = [["block_name", &"if"], ["label", "Control Block"], ["color", Color(0.270588, 0.666667, 0.94902, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_formats", ["if {condition: BOOL}"]], ["statements", ["if {condition}:"]], ["defaults", {}], ["param_input_strings_array", [{ -"condition": false -}]]] +[sub_resource type="Resource" id="Resource_s8f8n"] +script = ExtResource("4_qtggh") +name = &"call_method_group" +position = Vector2(20, 0) +path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_x6rc5")]] +block_serialized_properties = SubResource("Resource_eyu21") -[sub_resource type="Resource" id="Resource_wva5q"] +[sub_resource type="Resource" id="Resource_fs8jx"] script = ExtResource("4_qtggh") name = &"if" position = Vector2(0, 0) -path_child_pairs = [[NodePath("VBoxContainer/MarginContainer/Rows/Row0/RowHBoxContainer/RowHBox/ParameterInput0/SnapPoint"), SubResource("Resource_bny5u")], [NodePath("VBoxContainer/MarginContainer/Rows/SnapContainer0/SnapPoint"), SubResource("Resource_26pqe")]] -block_serialized_properties = SubResource("Resource_yd7xk") - -[sub_resource type="Resource" id="Resource_fufky"] -script = ExtResource("5_wr38c") -block_class = &"EntryBlock" -serialized_props = [["block_name", &"area2d_on_entered"], ["label", "EntryBlock"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 1], ["position", Vector2(100, 50)], ["scope", ""], ["block_format", "On [body: NODE_PATH] entered"], ["statement", " -func _on_body_entered(_body: Node2D): - var body: NodePath = _body.get_path() -"], ["defaults", {}], ["param_input_strings", {}], ["signal_name", "body_entered"]] +path_child_pairs = [[NodePath("VBoxContainer/MarginContainer/Rows/Row0/RowHBoxContainer/RowHBox/ParameterInput0/SnapPoint"), SubResource("Resource_iyvmc")], [NodePath("VBoxContainer/MarginContainer/Rows/SnapContainer0/SnapPoint"), SubResource("Resource_s8f8n")]] +block_serialized_properties = SubResource("Resource_ft8ne") -[sub_resource type="Resource" id="Resource_fkj3e"] +[sub_resource type="Resource" id="Resource_m4esq"] script = ExtResource("4_qtggh") name = &"area2d_on_entered" -position = Vector2(100, 50) -path_child_pairs = [[NodePath("VBoxContainer/TopMarginContainer/MarginContainer/HBoxContainer/ParameterOutput0/SnapPoint"), SubResource("Resource_3wodo")], [NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_wva5q")]] -block_serialized_properties = SubResource("Resource_fufky") +position = Vector2(100, 350) +path_child_pairs = [[NodePath("VBoxContainer/TopMarginContainer/MarginContainer/HBoxContainer/ParameterOutput0/SnapPoint"), SubResource("Resource_r1q4l")], [NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_fs8jx")]] +block_serialized_properties = SubResource("Resource_xxj4u") [sub_resource type="Resource" id="Resource_4xylj"] script = ExtResource("7_uuuue") script_inherits = "Area2D" -block_trees = Array[ExtResource("4_qtggh")]([SubResource("Resource_fkj3e")]) -variables = Array[Resource("res://addons/block_code/ui/block_canvas/variable_resource.gd")]([]) +block_trees = Array[ExtResource("4_qtggh")]([SubResource("Resource_m4esq")]) +variables = Array[ExtResource("9_lo3p1")]([]) generated_script = "extends Area2D +func _on_body_entered(body: Node2D): -func _on_body_entered(_body: Node2D): - var body: NodePath = _body.get_path() - - if get_node(body).is_in_group('balls'): + if body.is_in_group('balls'): get_tree().call_group('scoring', 'goal_left') get_tree().call_group('balls', 'reset') @@ -688,123 +594,114 @@ func _init(): " version = 0 -[sub_resource type="Resource" id="Resource_8h48s"] +[sub_resource type="Resource" id="Resource_tfqiy"] script = ExtResource("5_wr38c") -block_class = &"ParameterBlock" -serialized_props = [["block_name", &"parameter_block"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", " -func _on_body_entered(_body: Node2D): - var body: NodePath = _body.get_path() -"], ["block_format", "body"], ["statement", "body"], ["defaults", {}], ["variant_type", 22], ["param_input_strings", {}]] - -[sub_resource type="Resource" id="Resource_0x61c"] -script = ExtResource("4_qtggh") -name = &"parameter_block" -position = Vector2(0, 0) -path_child_pairs = [] -block_serialized_properties = SubResource("Resource_8h48s") +block_class = &"EntryBlock" +serialized_props = [["scope", ""], ["param_input_strings", {}]] -[sub_resource type="Resource" id="Resource_n8f73"] +[sub_resource type="Resource" id="Resource_5i6ga"] script = ExtResource("5_wr38c") block_class = &"ParameterBlock" -serialized_props = [["block_name", &"parameter_block"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", " -func _on_body_entered(_body: Node2D): - var body: NodePath = _body.get_path() -"], ["block_format", "body"], ["statement", "body"], ["defaults", {}], ["variant_type", 22], ["param_input_strings", {}]] +serialized_props = [["block_name", &"parameter_block"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", "func _on_body_entered(body: Node2D): +"], ["block_format", "body"], ["statement", "body"], ["defaults", {}], ["variant_type", 24], ["param_input_strings", {}]] -[sub_resource type="Resource" id="Resource_tnwiy"] +[sub_resource type="Resource" id="Resource_oyktt"] script = ExtResource("4_qtggh") name = &"parameter_block" position = Vector2(0, 0) path_child_pairs = [] -block_serialized_properties = SubResource("Resource_n8f73") +block_serialized_properties = SubResource("Resource_5i6ga") + +[sub_resource type="Resource" id="Resource_pssgx"] +script = ExtResource("5_wr38c") +block_class = &"ControlBlock" +serialized_props = [["scope", ""], ["param_input_strings_array", [{ +"condition": false +}]]] -[sub_resource type="Resource" id="Resource_lurjo"] +[sub_resource type="Resource" id="Resource_2w0n0"] script = ExtResource("5_wr38c") block_class = &"ParameterBlock" -serialized_props = [["block_name", &"is_node_in_group"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Is {node: NODE_PATH} in group {group: STRING}"], ["statement", "get_node({node}).is_in_group({group})"], ["defaults", {}], ["variant_type", 1], ["param_input_strings", { +serialized_props = [["scope", ""], ["param_input_strings", { "group": "balls", "node": "" }]] -[sub_resource type="Resource" id="Resource_j6idn"] -script = ExtResource("4_qtggh") -name = &"is_node_in_group" -position = Vector2(0, 0) -path_child_pairs = [[NodePath("MarginContainer/HBoxContainer/ParameterInput0/SnapPoint"), SubResource("Resource_tnwiy")]] -block_serialized_properties = SubResource("Resource_lurjo") - -[sub_resource type="Resource" id="Resource_y2wc6"] +[sub_resource type="Resource" id="Resource_q1iue"] script = ExtResource("5_wr38c") -block_class = &"StatementBlock" -serialized_props = [["block_name", &"call_group_method"], ["label", "StatementBlock"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Call method {method_name: STRING} in group {group: STRING}"], ["statement", "get_tree().call_group({group}, {method_name})"], ["defaults", {}], ["param_input_strings", { -"group": "balls", -"method_name": "reset" -}]] +block_class = &"ParameterBlock" +serialized_props = [["block_name", &"parameter_block"], ["label", "Param"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 3], ["position", Vector2(0, 0)], ["scope", "func _on_body_entered(body: Node2D): +"], ["block_format", "body"], ["statement", "body"], ["defaults", {}], ["variant_type", 24], ["param_input_strings", {}]] -[sub_resource type="Resource" id="Resource_krykp"] +[sub_resource type="Resource" id="Resource_aaxrr"] script = ExtResource("4_qtggh") -name = &"call_group_method" +name = &"parameter_block" position = Vector2(0, 0) path_child_pairs = [] -block_serialized_properties = SubResource("Resource_y2wc6") +block_serialized_properties = SubResource("Resource_q1iue") -[sub_resource type="Resource" id="Resource_daagb"] +[sub_resource type="Resource" id="Resource_005bn"] +script = ExtResource("4_qtggh") +name = &"is_node_in_group" +position = Vector2(0, 0) +path_child_pairs = [[NodePath("MarginContainer/HBoxContainer/ParameterInput0/SnapPoint"), SubResource("Resource_aaxrr")]] +block_serialized_properties = SubResource("Resource_2w0n0") + +[sub_resource type="Resource" id="Resource_1n3fn"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"call_group_method"], ["label", "StatementBlock"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Call method {method_name: STRING} in group {group: STRING}"], ["statement", "get_tree().call_group({group}, {method_name})"], ["defaults", {}], ["param_input_strings", { +serialized_props = [["scope", ""], ["param_input_strings", { "group": "scoring", "method_name": "goal_right" }]] -[sub_resource type="Resource" id="Resource_klxbs"] +[sub_resource type="Resource" id="Resource_jr3es"] +script = ExtResource("5_wr38c") +block_class = &"StatementBlock" +serialized_props = [["scope", ""], ["param_input_strings", { +"group": "balls", +"method_name": "reset" +}]] + +[sub_resource type="Resource" id="Resource_6moia"] script = ExtResource("4_qtggh") -name = &"call_group_method" +name = &"call_method_group" position = Vector2(0, 0) -path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_krykp")]] -block_serialized_properties = SubResource("Resource_daagb") +path_child_pairs = [] +block_serialized_properties = SubResource("Resource_jr3es") -[sub_resource type="Resource" id="Resource_twkoi"] -script = ExtResource("5_wr38c") -block_class = &"ControlBlock" -serialized_props = [["block_name", &"if"], ["label", "Control Block"], ["color", Color(0.270588, 0.666667, 0.94902, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_formats", ["if {condition: BOOL}"]], ["statements", ["if {condition}:"]], ["defaults", {}], ["param_input_strings_array", [{ -"condition": false -}]]] +[sub_resource type="Resource" id="Resource_gy7s5"] +script = ExtResource("4_qtggh") +name = &"call_method_group" +position = Vector2(20, 0) +path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_6moia")]] +block_serialized_properties = SubResource("Resource_1n3fn") -[sub_resource type="Resource" id="Resource_1a3km"] +[sub_resource type="Resource" id="Resource_2ys4x"] script = ExtResource("4_qtggh") name = &"if" position = Vector2(0, 0) -path_child_pairs = [[NodePath("VBoxContainer/MarginContainer/Rows/Row0/RowHBoxContainer/RowHBox/ParameterInput0/SnapPoint"), SubResource("Resource_j6idn")], [NodePath("VBoxContainer/MarginContainer/Rows/SnapContainer0/SnapPoint"), SubResource("Resource_klxbs")]] -block_serialized_properties = SubResource("Resource_twkoi") - -[sub_resource type="Resource" id="Resource_c4had"] -script = ExtResource("5_wr38c") -block_class = &"EntryBlock" -serialized_props = [["block_name", &"area2d_on_entered"], ["label", "EntryBlock"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 1], ["position", Vector2(75, 50)], ["scope", ""], ["block_format", "On [body: NODE_PATH] entered"], ["statement", " -func _on_body_entered(_body: Node2D): - var body: NodePath = _body.get_path() -"], ["defaults", {}], ["param_input_strings", {}], ["signal_name", "body_entered"]] +path_child_pairs = [[NodePath("VBoxContainer/MarginContainer/Rows/Row0/RowHBoxContainer/RowHBox/ParameterInput0/SnapPoint"), SubResource("Resource_005bn")], [NodePath("VBoxContainer/MarginContainer/Rows/SnapContainer0/SnapPoint"), SubResource("Resource_gy7s5")]] +block_serialized_properties = SubResource("Resource_pssgx") -[sub_resource type="Resource" id="Resource_qtw4n"] +[sub_resource type="Resource" id="Resource_mi6hv"] script = ExtResource("4_qtggh") name = &"area2d_on_entered" -position = Vector2(75, 50) -path_child_pairs = [[NodePath("VBoxContainer/TopMarginContainer/MarginContainer/HBoxContainer/ParameterOutput0/SnapPoint"), SubResource("Resource_0x61c")], [NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_1a3km")]] -block_serialized_properties = SubResource("Resource_c4had") +position = Vector2(75, 350) +path_child_pairs = [[NodePath("VBoxContainer/TopMarginContainer/MarginContainer/HBoxContainer/ParameterOutput0/SnapPoint"), SubResource("Resource_oyktt")], [NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_2ys4x")]] +block_serialized_properties = SubResource("Resource_tfqiy") [sub_resource type="Resource" id="Resource_xoc8a"] script = ExtResource("7_uuuue") script_inherits = "Area2D" -block_trees = Array[ExtResource("4_qtggh")]([SubResource("Resource_qtw4n")]) -variables = Array[Resource("res://addons/block_code/ui/block_canvas/variable_resource.gd")]([]) +block_trees = Array[ExtResource("4_qtggh")]([SubResource("Resource_mi6hv")]) +variables = Array[ExtResource("9_lo3p1")]([]) generated_script = "extends Area2D +func _on_body_entered(body: Node2D): -func _on_body_entered(_body: Node2D): - var body: NodePath = _body.get_path() - - if get_node(body).is_in_group('balls'): + if body.is_in_group('balls'): get_tree().call_group('scoring', 'goal_right') get_tree().call_group('balls', 'reset') @@ -813,121 +710,121 @@ func _init(): " version = 0 -[sub_resource type="Resource" id="Resource_tqdqf"] +[sub_resource type="Resource" id="Resource_n6aol"] +script = ExtResource("5_wr38c") +block_class = &"EntryBlock" +serialized_props = [["scope", ""], ["param_input_strings", {}]] + +[sub_resource type="Resource" id="Resource_76s7d"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"add_to_group"], ["label", "StatementBlock"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Add to group {group: STRING}"], ["statement", "add_to_group({group})"], ["defaults", {}], ["param_input_strings", { -"group": "scoring" +serialized_props = [["scope", ""], ["param_input_strings", { +"score": 0 }]] -[sub_resource type="Resource" id="Resource_uxpim"] -script = ExtResource("4_qtggh") -name = &"add_to_group" -position = Vector2(0, 0) -path_child_pairs = [] -block_serialized_properties = SubResource("Resource_tqdqf") - -[sub_resource type="Resource" id="Resource_yuj6e"] +[sub_resource type="Resource" id="Resource_clf6h"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"simplescoring_set_score"], ["label", "StatementBlock"], ["color", Color(0.811765, 0.415686, 0.529412, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Set player 2 score to {score: INT}"], ["statement", "score_right = {score}"], ["defaults", {}], ["param_input_strings", { -"score": "0" +serialized_props = [["scope", ""], ["param_input_strings", { +"score": 0 }]] -[sub_resource type="Resource" id="Resource_oar78"] -script = ExtResource("4_qtggh") -name = &"simplescoring_set_score" -position = Vector2(0, 0) -path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_uxpim")]] -block_serialized_properties = SubResource("Resource_yuj6e") - -[sub_resource type="Resource" id="Resource_gkoq3"] +[sub_resource type="Resource" id="Resource_rpicc"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"simplescoring_set_score"], ["label", "StatementBlock"], ["color", Color(0.811765, 0.415686, 0.529412, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Set player 1 score to {score: INT}"], ["statement", "score_left = {score}"], ["defaults", {}], ["param_input_strings", { -"score": "0" +serialized_props = [["scope", ""], ["param_input_strings", { +"group": "scoring" }]] -[sub_resource type="Resource" id="Resource_8xxm3"] +[sub_resource type="Resource" id="Resource_hxlka"] script = ExtResource("4_qtggh") -name = &"simplescoring_set_score" +name = &"add_to_group" position = Vector2(0, 0) -path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_oar78")]] -block_serialized_properties = SubResource("Resource_gkoq3") +path_child_pairs = [] +block_serialized_properties = SubResource("Resource_rpicc") -[sub_resource type="Resource" id="Resource_g3mty"] -script = ExtResource("5_wr38c") -block_class = &"EntryBlock" -serialized_props = [["color", Color(0.92549, 0.231373, 0.34902, 1)], ["scope", ""], ["param_input_strings", {}]] +[sub_resource type="Resource" id="Resource_os82j"] +script = ExtResource("4_qtggh") +name = &"simplescoring_set_score_player_2" +position = Vector2(0, 0) +path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_hxlka")]] +block_serialized_properties = SubResource("Resource_clf6h") + +[sub_resource type="Resource" id="Resource_2cci1"] +script = ExtResource("4_qtggh") +name = &"simplescoring_set_score_player_1" +position = Vector2(0, 0) +path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_os82j")]] +block_serialized_properties = SubResource("Resource_76s7d") -[sub_resource type="Resource" id="Resource_njwj4"] +[sub_resource type="Resource" id="Resource_e0qr3"] script = ExtResource("4_qtggh") name = &"ready" -position = Vector2(54, 47) -path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_8xxm3")]] -block_serialized_properties = SubResource("Resource_g3mty") +position = Vector2(50, 25) +path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_2cci1")]] +block_serialized_properties = SubResource("Resource_n6aol") + +[sub_resource type="Resource" id="Resource_mhqvs"] +script = ExtResource("5_wr38c") +block_class = &"EntryBlock" +serialized_props = [["scope", ""], ["param_input_strings", { +"method_name": "goal_right" +}]] -[sub_resource type="Resource" id="Resource_3j7i4"] +[sub_resource type="Resource" id="Resource_nd6ab"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"simplescoring_change_score"], ["label", "StatementBlock"], ["color", Color(0.811765, 0.415686, 0.529412, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Change player 1 score by {score: INT}"], ["statement", "score_left += {score}"], ["defaults", {}], ["param_input_strings", { -"score": "1" +serialized_props = [["scope", ""], ["param_input_strings", { +"score": 1 }]] -[sub_resource type="Resource" id="Resource_ntjp0"] +[sub_resource type="Resource" id="Resource_m8e8y"] script = ExtResource("4_qtggh") -name = &"simplescoring_change_score" +name = &"simplescoring_change_score_player_1" position = Vector2(0, 0) path_child_pairs = [] -block_serialized_properties = SubResource("Resource_3j7i4") - -[sub_resource type="Resource" id="Resource_2e0ed"] -script = ExtResource("5_wr38c") -block_class = &"EntryBlock" -serialized_props = [["block_name", &"define_method"], ["label", "EntryBlock"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 1], ["position", Vector2(50, 300)], ["scope", ""], ["block_format", "Define method {method_name: NIL}"], ["statement", "func {method_name}():"], ["defaults", {}], ["param_input_strings", { -"method_name": "goal_right" -}], ["signal_name", ""]] +block_serialized_properties = SubResource("Resource_nd6ab") -[sub_resource type="Resource" id="Resource_t8g7r"] +[sub_resource type="Resource" id="Resource_kr7eg"] script = ExtResource("4_qtggh") name = &"define_method" -position = Vector2(50, 300) -path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_ntjp0")]] -block_serialized_properties = SubResource("Resource_2e0ed") +position = Vector2(50, 275) +path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_m8e8y")]] +block_serialized_properties = SubResource("Resource_mhqvs") + +[sub_resource type="Resource" id="Resource_3fbnf"] +script = ExtResource("5_wr38c") +block_class = &"EntryBlock" +serialized_props = [["scope", ""], ["param_input_strings", { +"method_name": "goal_left" +}]] -[sub_resource type="Resource" id="Resource_cxj82"] +[sub_resource type="Resource" id="Resource_7rc07"] script = ExtResource("5_wr38c") block_class = &"StatementBlock" -serialized_props = [["block_name", &"simplescoring_change_score"], ["label", "StatementBlock"], ["color", Color(0.811765, 0.415686, 0.529412, 1)], ["block_type", 2], ["position", Vector2(0, 0)], ["scope", ""], ["block_format", "Change player 2 score by {score: INT}"], ["statement", "score_right += {score}"], ["defaults", {}], ["param_input_strings", { -"score": "1" +serialized_props = [["scope", ""], ["param_input_strings", { +"score": 1 }]] -[sub_resource type="Resource" id="Resource_c17ry"] +[sub_resource type="Resource" id="Resource_7dmgm"] script = ExtResource("4_qtggh") -name = &"simplescoring_change_score" +name = &"simplescoring_change_score_player_2" position = Vector2(0, 0) path_child_pairs = [] -block_serialized_properties = SubResource("Resource_cxj82") - -[sub_resource type="Resource" id="Resource_udc68"] -script = ExtResource("5_wr38c") -block_class = &"EntryBlock" -serialized_props = [["block_name", &"define_method"], ["label", "EntryBlock"], ["color", Color(0.294118, 0.482353, 0.92549, 1)], ["block_type", 1], ["position", Vector2(50, 450)], ["scope", ""], ["block_format", "Define method {method_name: NIL}"], ["statement", "func {method_name}():"], ["defaults", {}], ["param_input_strings", { -"method_name": "goal_left" -}], ["signal_name", ""]] +block_serialized_properties = SubResource("Resource_7rc07") -[sub_resource type="Resource" id="Resource_v2aur"] +[sub_resource type="Resource" id="Resource_cnona"] script = ExtResource("4_qtggh") name = &"define_method" -position = Vector2(50, 450) -path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_c17ry")]] -block_serialized_properties = SubResource("Resource_udc68") +position = Vector2(50, 425) +path_child_pairs = [[NodePath("VBoxContainer/SnapPoint"), SubResource("Resource_7dmgm")]] +block_serialized_properties = SubResource("Resource_3fbnf") [sub_resource type="Resource" id="Resource_q418f"] script = ExtResource("7_uuuue") script_inherits = "SimpleScoring" -block_trees = Array[ExtResource("4_qtggh")]([SubResource("Resource_njwj4"), SubResource("Resource_t8g7r"), SubResource("Resource_v2aur")]) -variables = Array[Resource("res://addons/block_code/ui/block_canvas/variable_resource.gd")]([]) +block_trees = Array[ExtResource("4_qtggh")]([SubResource("Resource_e0qr3"), SubResource("Resource_kr7eg"), SubResource("Resource_cnona")]) +variables = Array[ExtResource("9_lo3p1")]([]) generated_script = "extends SimpleScoring diff --git a/addons/block_code/simple_nodes/simple_character/simple_character.gd b/addons/block_code/simple_nodes/simple_character/simple_character.gd index 3eb8fcee..dffaff35 100644 --- a/addons/block_code/simple_nodes/simple_character/simple_character.gd +++ b/addons/block_code/simple_nodes/simple_character/simple_character.gd @@ -2,7 +2,8 @@ class_name SimpleCharacter extends CharacterBody2D -const CategoryFactory = preload("res://addons/block_code/ui/picker/categories/category_factory.gd") +const BlockDefinition = preload("res://addons/block_code/code_generation/block_definition.gd") +const BlocksCatalog = preload("res://addons/block_code/code_generation/blocks_catalog.gd") const Types = preload("res://addons/block_code/types/types.gd") @export var texture: Texture2D: @@ -117,35 +118,38 @@ func move_with_player_buttons(player: String, kind: String, delta: float): move_and_slide() -static func get_custom_blocks() -> Array[Block]: - var b: Block - var block_list: Array[Block] = [] +static func setup_custom_blocks(): + var _class_name = "SimpleCharacter" + var block_list: Array[BlockDefinition] = [] # Movement - b = CategoryFactory.BLOCKS["statement_block"].instantiate() - b.block_name = "simplecharacter_move" - b.block_type = Types.BlockType.STATEMENT - b.block_format = "Move with {player: OPTION} buttons as {kind: OPTION}" + var block_definition: BlockDefinition = BlockDefinition.new() + block_definition.name = &"simplecharacter_move" + block_definition.target_node_class = _class_name + block_definition.category = "Input" + block_definition.type = Types.BlockType.STATEMENT + block_definition.display_template = "Move with {player: OPTION} buttons as {kind: OPTION}" # TODO: delta here is assumed to be the parameter name of # the _process or _physics_process method: - b.statement = 'move_with_player_buttons("{player}", "{kind}", delta)' - b.defaults = { + block_definition.code_template = 'move_with_player_buttons("{player}", "{kind}", delta)' + block_definition.defaults = { "player": OptionData.new(["player_1", "player_2"]), "kind": OptionData.new(["top-down", "platformer", "spaceship"]), } - b.category = "Input" - block_list.append(b) - - var property_blocks = ( - CategoryFactory - . property_to_blocklist( - { - "name": "speed", - "type": TYPE_VECTOR2, - "category": "Physics | Velocity", - } - ) - ) - block_list.append_array(property_blocks) - - return block_list + block_list.append(block_definition) + + var property_list: Array[Dictionary] = [ + { + "name": "speed", + "type": TYPE_VECTOR2, + }, + ] + + var property_settings = { + "speed": + { + "category": "Physics | Velocity", + }, + } + + BlocksCatalog.add_custom_blocks(_class_name, block_list, property_list, property_settings) diff --git a/addons/block_code/simple_nodes/simple_scoring/simple_scoring.gd b/addons/block_code/simple_nodes/simple_scoring/simple_scoring.gd index dcb2114a..185fcba9 100644 --- a/addons/block_code/simple_nodes/simple_scoring/simple_scoring.gd +++ b/addons/block_code/simple_nodes/simple_scoring/simple_scoring.gd @@ -2,7 +2,8 @@ class_name SimpleScoring extends CanvasLayer -const CategoryFactory = preload("res://addons/block_code/ui/picker/categories/category_factory.gd") +const BlockDefinition = preload("res://addons/block_code/code_generation/block_definition.gd") +const BlocksCatalog = preload("res://addons/block_code/code_generation/blocks_catalog.gd") const Types = preload("res://addons/block_code/types/types.gd") @export var score_left: int: @@ -95,25 +96,27 @@ func set_player_score(player: String, score: int): _score_labels[player].text = str(score) -static func get_custom_blocks() -> Array[Block]: - var b: Block - var block_list: Array[Block] = [] +static func setup_custom_blocks(): + var _class_name = "SimpleScoring" + var block_list: Array[BlockDefinition] = [] for player in _POSITIONS_FOR_PLAYER: - b = CategoryFactory.BLOCKS["statement_block"].instantiate() - b.block_name = "simplescoring_set_score" - b.block_type = Types.BlockType.STATEMENT - b.block_format = "Set player %s score to {score: INT}" % player - b.statement = "score_%s = {score}" % _POSITIONS_FOR_PLAYER[player] - b.category = "Info | Score" - block_list.append(b) - - b = CategoryFactory.BLOCKS["statement_block"].instantiate() - b.block_name = "simplescoring_change_score" - b.block_type = Types.BlockType.STATEMENT - b.block_format = "Change player %s score by {score: INT}" % player - b.statement = "score_%s += {score}" % _POSITIONS_FOR_PLAYER[player] - b.category = "Info | Score" - block_list.append(b) - - return block_list + var block_definition: BlockDefinition = BlockDefinition.new() + block_definition.name = &"simplescoring_set_score_player_%s" % player + block_definition.target_node_class = _class_name + block_definition.category = "Info | Score" + block_definition.type = Types.BlockType.STATEMENT + block_definition.display_template = "Set player %s score to {score: INT}" % player + block_definition.code_template = "score_%s = {score}" % _POSITIONS_FOR_PLAYER[player] + block_list.append(block_definition) + + block_definition = BlockDefinition.new() + block_definition.name = &"simplescoring_change_score_player_%s" % player + block_definition.target_node_class = _class_name + block_definition.category = "Info | Score" + block_definition.type = Types.BlockType.STATEMENT + block_definition.display_template = "Change player %s score by {score: INT}" % player + block_definition.code_template = "score_%s += {score}" % _POSITIONS_FOR_PLAYER[player] + block_list.append(block_definition) + + BlocksCatalog.add_custom_blocks(_class_name, block_list) diff --git a/addons/block_code/ui/block_canvas/block_canvas.gd b/addons/block_code/ui/block_canvas/block_canvas.gd index 8fe07107..ffcc4b86 100644 --- a/addons/block_code/ui/block_canvas/block_canvas.gd +++ b/addons/block_code/ui/block_canvas/block_canvas.gd @@ -154,7 +154,7 @@ func clear_canvas(): func load_tree(parent: Node, node: BlockSerialization): - var scene: Block = Util.instantiate_block(node.name) + var scene: Block = Util.instantiate_block_by_name(node.name) # TODO: Remove once the data/UI decouple is done. if scene == null: diff --git a/addons/block_code/ui/blocks/block/block.gd b/addons/block_code/ui/blocks/block/block.gd index 6d97c605..3a4e056a 100644 --- a/addons/block_code/ui/blocks/block/block.gd +++ b/addons/block_code/ui/blocks/block/block.gd @@ -138,9 +138,8 @@ func get_serialized_props() -> Array: return serialize_props(["block_name", "label", "color", "block_type", "position", "scope"]) # TODO: Remove remaining serialization: - # - Derive color from category. # - Handle scope in a different way? - return serialize_props(["color", "scope"]) + return serialize_props(["scope"]) func _to_string(): diff --git a/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd b/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd index 95073a0e..96abece8 100644 --- a/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd +++ b/addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd @@ -56,13 +56,15 @@ func set_raw_input(raw_input): _color_input.color = raw_input _update_panel_bg_color(raw_input) TYPE_VECTOR2: - var split = raw_input.split(",") - _x_line_edit.text = split[0] - _y_line_edit.text = split[1] + # Rounding because floats are doubles by default but Vector2s have single components + _x_line_edit.text = ("%.4f" % raw_input.x).rstrip("0").rstrip(".") + _y_line_edit.text = ("%.4f" % raw_input.y).rstrip("0").rstrip(".") TYPE_BOOL: _bool_input_option.select(raw_input) - _: + TYPE_NIL: _line_edit.text = raw_input + _: + _line_edit.text = "" if raw_input == null else str(raw_input) func get_raw_input(): @@ -76,9 +78,15 @@ func get_raw_input(): TYPE_COLOR: return _color_input.color TYPE_VECTOR2: - return _x_line_edit.text + "," + _y_line_edit.text + return Vector2(float(_x_line_edit.text), float(_y_line_edit.text)) TYPE_BOOL: return bool(_bool_input_option.selected) + TYPE_INT: + return null if _line_edit.text == "" else int(_line_edit.text) + TYPE_FLOAT: + return null if _line_edit.text == "" else float(_line_edit.text) + TYPE_NIL: + return _line_edit.text _: return _line_edit.text @@ -127,11 +135,16 @@ func get_string() -> String: TYPE_STRING: return "'%s'" % input.replace("\\", "\\\\").replace("'", "\\'") TYPE_VECTOR2: - return "Vector2(%s)" % input + return "Vector2%s" % str(input) TYPE_COLOR: return "Color%s" % str(input) + TYPE_OBJECT: + if input is OptionData: + var option_data := input as OptionData + return option_data.items[option_data.selected] _: return "%s" % input + return "" func _validate_and_submit_edit_text(line_edit: Node, type: Variant.Type): diff --git a/addons/block_code/ui/constants.gd b/addons/block_code/ui/constants.gd index dcb65e23..b0830952 100644 --- a/addons/block_code/ui/constants.gd +++ b/addons/block_code/ui/constants.gd @@ -11,3 +11,119 @@ const OUTLINE_WIDTH = 3.0 const MINIMUM_SNAP_DISTANCE = 80.0 const FOCUS_BORDER_COLOR = Color(225, 242, 0) + +## Properties for builtin categories. Order starts at 10 for the first +## category and then are separated by 10 to allow custom categories to +## be easily placed between builtin categories. +const BUILTIN_CATEGORIES_PROPS: Dictionary = { + "Lifecycle": + { + "color": Color("ec3b59"), + "order": 10, + }, + "Transform | Position": + { + "color": Color("4b6584"), + "order": 20, + }, + "Transform | Rotation": + { + "color": Color("4b6584"), + "order": 30, + }, + "Transform | Scale": + { + "color": Color("4b6584"), + "order": 40, + }, + "Graphics | Modulate": + { + "color": Color("03aa74"), + "order": 50, + }, + "Graphics | Visibility": + { + "color": Color("03aa74"), + "order": 60, + }, + "Graphics | Viewport": + { + "color": Color("03aa74"), + "order": 61, + }, + "Graphics | Animation": + { + "color": Color("03aa74"), + "order": 62, + }, + "Sounds": + { + "color": Color("e30fc0"), + "order": 70, + }, + "Physics | Mass": + { + "color": Color("a5b1c2"), + "order": 80, + }, + "Physics | Velocity": + { + "color": Color("a5b1c2"), + "order": 90, + }, + "Input": + { + "color": Color("d54322"), + "order": 100, + }, + "Communication | Methods": + { + "color": Color("4b7bec"), + "order": 110, + }, + "Communication | Groups": + { + "color": Color("4b7bec"), + "order": 120, + }, + "Info | Score": + { + "color": Color("cf6a87"), + "order": 130, + }, + "Loops": + { + "color": Color("20bf6b"), + "order": 140, + }, + "Logic | Conditionals": + { + "color": Color("45aaf2"), + "order": 150, + }, + "Logic | Comparison": + { + "color": Color("45aaf2"), + "order": 160, + }, + "Logic | Boolean": + { + "color": Color("45aaf2"), + "order": 170, + }, + "Variables": + { + "color": Color("ff8f08"), + "order": 180, + }, + "Math": + { + "color": Color("a55eea"), + "order": 190, + }, + "Log": + { + "color": Color("002050"), + "order": 200, + }, +} diff --git a/addons/block_code/ui/picker/categories/block_category_display.gd b/addons/block_code/ui/picker/categories/block_category_display.gd index ce85f620..b4c536e3 100644 --- a/addons/block_code/ui/picker/categories/block_category_display.gd +++ b/addons/block_code/ui/picker/categories/block_category_display.gd @@ -12,9 +12,5 @@ var category: BlockCategory func _ready(): _label.text = category.name - for _block in category.block_list: - var block: Block = _block as Block - - block.color = category.color - + for block: Block in category.block_list: _blocks.add_child(block) diff --git a/addons/block_code/ui/picker/categories/category_factory.gd b/addons/block_code/ui/picker/categories/category_factory.gd index 9ae41db1..934a333b 100644 --- a/addons/block_code/ui/picker/categories/category_factory.gd +++ b/addons/block_code/ui/picker/categories/category_factory.gd @@ -4,129 +4,7 @@ extends Object const BlockCategory = preload("res://addons/block_code/ui/picker/categories/block_category.gd") const Types = preload("res://addons/block_code/types/types.gd") const Util = preload("res://addons/block_code/ui/util.gd") - -const BLOCKS: Dictionary = { - "control_block": preload("res://addons/block_code/ui/blocks/control_block/control_block.tscn"), - "parameter_block": preload("res://addons/block_code/ui/blocks/parameter_block/parameter_block.tscn"), - "statement_block": preload("res://addons/block_code/ui/blocks/statement_block/statement_block.tscn"), - "entry_block": preload("res://addons/block_code/ui/blocks/entry_block/entry_block.tscn"), -} - -## Properties for builtin categories. Order starts at 10 for the first -## category and then are separated by 10 to allow custom categories to -## be easily placed between builtin categories. -const BUILTIN_PROPS: Dictionary = { - "Lifecycle": - { - "color": Color("ec3b59"), - "order": 10, - }, - "Transform | Position": - { - "color": Color("4b6584"), - "order": 20, - }, - "Transform | Rotation": - { - "color": Color("4b6584"), - "order": 30, - }, - "Transform | Scale": - { - "color": Color("4b6584"), - "order": 40, - }, - "Graphics | Modulate": - { - "color": Color("03aa74"), - "order": 50, - }, - "Graphics | Visibility": - { - "color": Color("03aa74"), - "order": 60, - }, - "Graphics | Viewport": - { - "color": Color("03aa74"), - "order": 61, - }, - "Graphics | Animation": - { - "color": Color("03aa74"), - "order": 62, - }, - "Sounds": - { - "color": Color("e30fc0"), - "order": 70, - }, - "Physics | Mass": - { - "color": Color("a5b1c2"), - "order": 80, - }, - "Physics | Velocity": - { - "color": Color("a5b1c2"), - "order": 90, - }, - "Input": - { - "color": Color("d54322"), - "order": 100, - }, - "Communication | Methods": - { - "color": Color("4b7bec"), - "order": 110, - }, - "Communication | Groups": - { - "color": Color("4b7bec"), - "order": 120, - }, - "Info | Score": - { - "color": Color("cf6a87"), - "order": 130, - }, - "Loops": - { - "color": Color("20bf6b"), - "order": 140, - }, - "Logic | Conditionals": - { - "color": Color("45aaf2"), - "order": 150, - }, - "Logic | Comparison": - { - "color": Color("45aaf2"), - "order": 160, - }, - "Logic | Boolean": - { - "color": Color("45aaf2"), - "order": 170, - }, - "Variables": - { - "color": Color("ff8f08"), - "order": 180, - }, - "Math": - { - "color": Color("a55eea"), - "order": 190, - }, - "Log": - { - "color": Color("002050"), - "order": 200, - }, -} +const Constants = preload("res://addons/block_code/ui/constants.gd") ## Compare block categories for sorting. Compare by order then name. @@ -148,7 +26,7 @@ static func get_categories(blocks: Array[Block], extra_categories: Array[BlockCa if cat == null: cat = extra_cat_map.get(block.category) if cat == null: - var props: Dictionary = BUILTIN_PROPS.get(block.category, {}) + var props: Dictionary = Constants.BUILTIN_CATEGORIES_PROPS.get(block.category, {}) var color: Color = props.get("color", Color.SLATE_GRAY) var order: int = props.get("order", 0) cat = BlockCategory.new(block.category, color, order) @@ -167,417 +45,66 @@ static func get_categories(blocks: Array[Block], extra_categories: Array[BlockCa static func get_general_blocks() -> Array[Block]: - var b: Block + var block: Block var block_list: Array[Block] = [] # Lifecycle for block_name in [&"ready", &"process", &"physics_process", &"queue_free"]: - b = Util.instantiate_block(block_name) - block_list.append(b) + block = Util.instantiate_block_by_name(block_name) + block_list.append(block) # Loops for block_name in [&"for", &"while", &"break", &"continue", &"await_scene_ready"]: - b = Util.instantiate_block(block_name) - block_list.append(b) + block = Util.instantiate_block_by_name(block_name) + block_list.append(block) # Logs - b = Util.instantiate_block(&"print") - block_list.append(b) + block = Util.instantiate_block_by_name(&"print") + block_list.append(block) # Communication for block_name in [&"define_method", &"call_method_group", &"call_method_node"]: - b = Util.instantiate_block(block_name) - block_list.append(b) + block = Util.instantiate_block_by_name(block_name) + block_list.append(block) for block_name in [&"add_to_group", &"add_node_to_group", &"remove_from_group", &"remove_node_from_group", &"is_in_group", &"is_node_in_group"]: - b = Util.instantiate_block(block_name) - block_list.append(b) + block = Util.instantiate_block_by_name(block_name) + block_list.append(block) # Variables - b = Util.instantiate_block(&"vector2") - block_list.append(b) + block = Util.instantiate_block_by_name(&"vector2") + block_list.append(block) # Math for block_name in [&"add", &"subtract", &"multiply", &"divide", &"pow", &"randf_range", &"randi_range", &"sin", &"cos", &"tan"]: - b = Util.instantiate_block(block_name) - block_list.append(b) + block = Util.instantiate_block_by_name(block_name) + block_list.append(block) # Logic for block_name in [&"if", &"else_if", &"else", &"compare", &"and", &"or", &"not"]: - b = Util.instantiate_block(block_name) - block_list.append(b) + block = Util.instantiate_block_by_name(block_name) + block_list.append(block) # Input - block_list.append_array(_get_input_blocks()) + block = Util.instantiate_block_by_name(&"is_input_actioned") + block_list.append(block) # Sounds for block_name in [&"load_sound", &"play_sound", &"pause_continue_sound", &"stop_sound"]: - b = Util.instantiate_block(block_name) - block_list.append(b) + block = Util.instantiate_block_by_name(block_name) + block_list.append(block) # Graphics for block_name in [&"viewport_width", &"viewport_height", &"viewport_center"]: - b = Util.instantiate_block(block_name) - block_list.append(b) - - return block_list - - -static func property_to_blocklist(property: Dictionary) -> Array[Block]: - var block_list: Array[Block] = [] - - var variant_type = property.type - - const FALLBACK_SET_FOR_TYPE = { - TYPE_BOOL: false, - TYPE_INT: "0", - TYPE_FLOAT: "0", - TYPE_VECTOR2: "0,0", - TYPE_COLOR: "DARK_ORANGE", - } - - const FALLBACK_CHANGE_FOR_TYPE = { - TYPE_BOOL: true, - TYPE_INT: "1", - TYPE_FLOAT: "1", - TYPE_VECTOR2: "1,1", - TYPE_COLOR: "DARK_ORANGE", - } - - if variant_type: - var type_string: String = Types.VARIANT_TYPE_TO_STRING[variant_type] - - var b = BLOCKS["statement_block"].instantiate() - b.block_name = "set_prop_%s" % property.name - b.block_format = "Set %s to {value: %s}" % [property.name.capitalize(), type_string] - b.statement = "%s = {value}" % property.name - var default_set = property.get("default_set", FALLBACK_SET_FOR_TYPE.get(variant_type, "")) - b.defaults = {"value": default_set} - b.category = property.category - block_list.append(b) - - if property.get("has_change", true): - b = BLOCKS["statement_block"].instantiate() - b.block_name = "change_prop_%s" % property.name - b.block_format = "Change %s by {value: %s}" % [property.name.capitalize(), type_string] - b.statement = "%s += {value}" % property.name - var default_change = property.get("default_change", FALLBACK_CHANGE_FOR_TYPE[variant_type]) - b.defaults = {"value": default_change} - b.category = property.category - block_list.append(b) - - b = BLOCKS["parameter_block"].instantiate() - b.block_name = "get_prop_%s" % property.name - b.variant_type = variant_type - b.block_format = "%s" % property.name.capitalize() - b.statement = "%s" % property.name - b.category = property.category - block_list.append(b) - - return block_list - - -static func blocks_from_property_list(property_list: Array, selected_props: Dictionary) -> Array[Block]: - var block_list: Array[Block] - - for selected_property in selected_props: - var found_prop - for prop in property_list: - if selected_property == prop.name: - found_prop = prop - found_prop.merge(selected_props[selected_property]) - break - if found_prop: - block_list.append_array(property_to_blocklist(found_prop)) - else: - push_warning("No property matching %s found in %s" % [selected_property, property_list]) + block = Util.instantiate_block_by_name(block_name) + block_list.append(block) return block_list static func get_inherited_blocks(_class_name: String) -> Array[Block]: - var blocks: Array[Block] = [] - - var current: String = _class_name - - while current != "": - blocks.append_array(get_built_in_blocks(current)) - current = ClassDB.get_parent_class(current) - - return blocks - - -static func get_built_in_blocks(_class_name: String) -> Array[Block]: - var props: Dictionary = {} - var block_list: Array[Block] = [] - - match _class_name: - "Node2D": - props = { - "position": - { - "category": "Transform | Position", - "default_set": "100,100", - "default_change": "1,1", - }, - "rotation_degrees": - { - "category": "Transform | Rotation", - "default_set": "45", - "default_change": "1", - }, - "scale": - { - "category": "Transform | Scale", - "default_set": "2,2", - "default_change": "0.1,0.1", - }, - } - - "CanvasItem": - props = { - "modulate": - { - "category": "Graphics | Modulate", - "has_change": false, - }, - "visible": - { - "category": "Graphics | Visibility", - "has_change": false, - }, - } - - "RigidBody2D": - for verb in ["entered", "exited"]: - var b = BLOCKS["entry_block"].instantiate() - b.block_name = "rigidbody2d_on_%s" % verb - b.block_format = "On [body: NODE_PATH] %s" % [verb] - # HACK: Blocks refer to nodes by path but the callback receives the node itself; - # convert to path - b.statement = ( - ( - """ - func _on_body_%s(_body: Node): - var body: NodePath = _body.get_path() - """ - . dedent() - ) - % [verb] - ) - b.signal_name = "body_%s" % [verb] - b.category = "Communication | Methods" - block_list.append(b) - - var b = BLOCKS["statement_block"].instantiate() - b.block_name = "rigidbody2d_physics_position" - b.block_format = "Set Physics Position {position: VECTOR2}" - b.statement = ( - """ - PhysicsServer2D.body_set_state( - get_rid(), - PhysicsServer2D.BODY_STATE_TRANSFORM, - Transform2D.IDENTITY.translated({position}) - ) - """ - . dedent() - ) - b.category = "Transform | Position" - block_list.append(b) - - props = { - "mass": {"category": "Physics | Mass"}, - "linear_velocity": {"category": "Physics | Velocity"}, - "angular_velocity": {"category": "Physics | Velocity"}, - } - - "AudioStreamPlayer": - var b = BLOCKS["statement_block"].instantiate() - b.block_name = "audiostreamplayer_play" - b.block_format = "Play" - b.statement = "play()" - b.tooltip_text = "Play the audio stream" - b.category = "Sounds" - block_list.append(b) - - b = BLOCKS["statement_block"].instantiate() - b.block_name = "audiostreamplayer_stop" - b.block_format = "Stop" - b.statement = "stop()" - b.tooltip_text = "Stop the audio stream" - b.category = "Sounds" - block_list.append(b) - - props = { - "stream_paused": - { - "category": "Sounds", - "has_change": false, - }, - } - - "AnimationPlayer": - var b = BLOCKS["statement_block"].instantiate() - b.block_name = "animationplayer_play" - b.block_format = "Play {animation: STRING} {direction: OPTION}" - b.statement = ( - """ - if "{direction}" == "ahead": - play({animation}) - else: - play_backwards({animation}) - """ - . dedent() - ) - b.defaults = { - "direction": OptionData.new(["ahead", "backwards"]), - } - b.tooltip_text = "Play the animation." - b.category = "Graphics | Animation" - block_list.append(b) - - b = BLOCKS["statement_block"].instantiate() - b.block_name = "animationplayer_pause" - b.block_format = "Pause" - b.statement = "pause()" - b.tooltip_text = "Pause the currently playing animation." - b.category = "Graphics | Animation" - block_list.append(b) - - b = BLOCKS["statement_block"].instantiate() - b.block_name = "animationplayer_stop" - b.block_format = "Stop" - b.statement = "stop()" - b.tooltip_text = "Stop the currently playing animation." - b.category = "Graphics | Animation" - block_list.append(b) - - b = BLOCKS["parameter_block"].instantiate() - b.block_name = "animationplayer_is_playing" - b.variant_type = TYPE_BOOL - b.block_format = "Is playing" - b.statement = "is_playing()" - b.tooltip_text = "Check if an animation is currently playing." - b.category = "Graphics | Animation" - block_list.append(b) - - "Area2D": - for verb in ["entered", "exited"]: - var b = BLOCKS["entry_block"].instantiate() - b.block_name = "area2d_on_%s" % verb - b.block_format = "On [body: NODE_PATH] %s" % [verb] - # HACK: Blocks refer to nodes by path but the callback receives the node itself; - # convert to path - b.statement = ( - ( - """ - func _on_body_%s(_body: Node2D): - var body: NodePath = _body.get_path() - """ - . dedent() - ) - % [verb] - ) - b.signal_name = "body_%s" % [verb] - b.category = "Communication | Methods" - block_list.append(b) - - "CharacterBody2D": - var b = BLOCKS["statement_block"].instantiate() - b.block_name = "characterbody2d_move" - b.block_type = Types.BlockType.STATEMENT - b.block_format = "Move with keys {up: STRING} {down: STRING} {left: STRING} {right: STRING} with speed {speed: VECTOR2}" - b.statement = ( - "var dir = Vector2()\n" - + "dir.x += float(Input.is_key_pressed(OS.find_keycode_from_string({right})))\n" - + "dir.x -= float(Input.is_key_pressed(OS.find_keycode_from_string({left})))\n" - + "dir.y += float(Input.is_key_pressed(OS.find_keycode_from_string({down})))\n" - + "dir.y -= float(Input.is_key_pressed(OS.find_keycode_from_string({up})))\n" - + "dir = dir.normalized()\n" - + "velocity = dir*{speed}\n" - + "move_and_slide()" - ) - b.defaults = { - "up": "W", - "down": "S", - "left": "A", - "right": "D", - } - b.category = "Input" - block_list.append(b) - - b = BLOCKS["statement_block"].instantiate() - b.block_name = "characterbody2d_move_and_slide" - b.block_type = Types.BlockType.STATEMENT - b.block_format = "Move and slide" - b.statement = "move_and_slide()" - b.category = "Physics | Velocity" - block_list.append(b) - - props = { - "velocity": {"category": "Physics | Velocity"}, - } - - var prop_list = ClassDB.class_get_property_list(_class_name, true) - block_list.append_array(blocks_from_property_list(prop_list, props)) - - return block_list - - -static func _get_input_blocks() -> Array[Block]: - var block_list: Array[Block] - - var editor_input_actions: Dictionary = {} - var editor_input_action_deadzones: Dictionary = {} - if Engine.is_editor_hint(): - var actions := InputMap.get_actions() - for action in actions: - if action.begins_with("spatial_editor"): - var events := InputMap.action_get_events(action) - editor_input_actions[action] = events - editor_input_action_deadzones[action] = InputMap.action_get_deadzone(action) - - InputMap.load_from_project_settings() - - var block: Block = BLOCKS["parameter_block"].instantiate() - block.block_name = "is_action" - block.variant_type = TYPE_BOOL - block.block_format = "Is action {action_name: OPTION} {action: OPTION}" - block.statement = 'Input.is_action_{action}("{action_name}")' - block.defaults = {"action_name": OptionData.new(InputMap.get_actions()), "action": OptionData.new(["pressed", "just_pressed", "just_released"])} - block.category = "Input" - block_list.append(block) - - if Engine.is_editor_hint(): - for action in editor_input_actions.keys(): - InputMap.add_action(action, editor_input_action_deadzones[action]) - for event in editor_input_actions[action]: - InputMap.action_add_event(action, event) - - return block_list + return Util.instantiate_blocks_for_class(_class_name) static func get_variable_blocks(variables: Array[VariableResource]): - var block_list: Array[Block] - - for variable in variables: - var type_string: String = Types.VARIANT_TYPE_TO_STRING[variable.var_type] - - var b = BLOCKS["parameter_block"].instantiate() - b.block_name = "get_var_%s" % variable.var_name - b.variant_type = variable.var_type - b.block_format = variable.var_name - b.statement = variable.var_name - # HACK: Color the blocks since they are outside of the normal picker system - b.color = BUILTIN_PROPS["Variables"].color - block_list.append(b) - - b = BLOCKS["statement_block"].instantiate() - b.block_name = "set_var_%s" % variable.var_name - b.block_type = Types.BlockType.STATEMENT - b.block_format = "Set %s to {value: %s}" % [variable.var_name, type_string] - b.statement = "%s = {value}" % [variable.var_name] - b.color = BUILTIN_PROPS["Variables"].color - block_list.append(b) - - return block_list + return Util.instantiate_variable_blocks(variables) diff --git a/addons/block_code/ui/picker/picker.gd b/addons/block_code/ui/picker/picker.gd index 490956e3..7d7b9648 100644 --- a/addons/block_code/ui/picker/picker.gd +++ b/addons/block_code/ui/picker/picker.gd @@ -25,22 +25,19 @@ func block_script_selected(block_script: BlockScriptSerialization): reset_picker() return - var blocks_to_add: Array[Block] = [] var categories_to_add: Array[BlockCategory] = [] - # By default, assume the class is built-in. - var parent_class: String = block_script.script_inherits for class_dict in ProjectSettings.get_global_class_list(): if class_dict.class == block_script.script_inherits: var script = load(class_dict.path) if script.has_method("get_custom_categories"): categories_to_add = script.get_custom_categories() - if script.has_method("get_custom_blocks"): - blocks_to_add = script.get_custom_blocks() - parent_class = str(script.get_instance_base_type()) + if script.has_method("setup_custom_blocks"): + script.setup_custom_blocks() break - blocks_to_add.append_array(CategoryFactory.get_inherited_blocks(parent_class)) + var blocks_to_add: Array[Block] = [] + blocks_to_add.append_array(CategoryFactory.get_inherited_blocks(block_script.script_inherits)) init_picker(blocks_to_add, categories_to_add) reload_variables(block_script.variables) diff --git a/addons/block_code/ui/util.gd b/addons/block_code/ui/util.gd index 13d602eb..5371b4e8 100644 --- a/addons/block_code/ui/util.gd +++ b/addons/block_code/ui/util.gd @@ -3,6 +3,7 @@ extends Object const BlockDefinition = preload("res://addons/block_code/code_generation/block_definition.gd") const BlocksCatalog = preload("res://addons/block_code/code_generation/blocks_catalog.gd") const Types = preload("res://addons/block_code/types/types.gd") +const Constants = preload("res://addons/block_code/ui/constants.gd") const SCENE_PER_TYPE = { Types.BlockType.ENTRY: preload("res://addons/block_code/ui/blocks/entry_block/entry_block.tscn"), @@ -12,13 +13,12 @@ const SCENE_PER_TYPE = { } -static func instantiate_block(block_name: StringName) -> Block: - BlocksCatalog.setup() - var block_definition: BlockDefinition = BlocksCatalog.get_block(block_name) - if block_definition == null: - push_error("The block %s is not in the catalog yet!" % block_name) - return +static func get_category_color(category: String) -> Color: + var category_props: Dictionary = Constants.BUILTIN_CATEGORIES_PROPS.get(category, {}) + return category_props.get("color", Color.SLATE_GRAY) + +static func instantiate_block(block_definition: BlockDefinition) -> Block: var scene = SCENE_PER_TYPE[block_definition.type] var b = scene.instantiate() b.block_name = block_definition.name @@ -36,9 +36,96 @@ static func instantiate_block(block_name: StringName) -> Block: b.defaults = block_definition.defaults b.tooltip_text = block_definition.description b.category = block_definition.category + b.color = get_category_color(block_definition.category) + return b +static func instantiate_block_by_name(block_name: StringName) -> Block: + BlocksCatalog.setup() + var block_definition: BlockDefinition = BlocksCatalog.get_block(block_name) + if block_definition == null: + push_error("The block %s is not in the catalog yet!" % block_name) + return + return instantiate_block(block_definition) + + +static func _get_builtin_parents(_class_name: String) -> Array[String]: + var parents: Array[String] = [] + var current = _class_name + + while current != "": + parents.append(current) + current = ClassDB.get_parent_class(current) + + return parents + + +static func _get_custom_parent_class_name(_custom_class_name: String) -> String: + for class_dict in ProjectSettings.get_global_class_list(): + if class_dict.class != _custom_class_name: + continue + var script = load(class_dict.path) + var builtin_class = script.get_instance_base_type() + return builtin_class + return "Node" + + +static func _get_parents(_class_name: String) -> Array[String]: + if ClassDB.class_exists(_class_name): + return _get_builtin_parents(_class_name) + var parents: Array[String] = [_class_name] + var _parent_class_name = _get_custom_parent_class_name(_class_name) + parents.append_array(_get_builtin_parents(_parent_class_name)) + return parents + + +static func instantiate_blocks_for_class(_class_name: String) -> Array[Block]: + BlocksCatalog.setup() + + var blocks: Array[Block] = [] + for subclass in _get_parents(_class_name): + for block_definition in BlocksCatalog.get_blocks_by_class(subclass): + var b = instantiate_block(block_definition) + blocks.append(b) + + return blocks + + +static func get_variable_block_definitions(variables: Array[VariableResource]) -> Array[BlockDefinition]: + var block_definitions: Array[BlockDefinition] = [] + for variable: VariableResource in variables: + var type_string: String = Types.VARIANT_TYPE_TO_STRING[variable.var_type] + + var b = BlockDefinition.new() + b.name = "get_var_%s" % variable.var_name + b.type = Types.BlockType.VALUE + b.variant_type = variable.var_type + b.display_template = variable.var_name + b.code_template = variable.var_name + block_definitions.append(b) + + b = BlockDefinition.new() + b.name = "set_var_%s" % variable.var_name + b.type = Types.BlockType.STATEMENT + b.display_template = "Set %s to {value: %s}" % [variable.var_name, type_string] + b.code_template = "%s = {value}" % [variable.var_name] + block_definitions.append(b) + + return block_definitions + + +static func instantiate_variable_blocks(variables: Array[VariableResource]) -> Array[Block]: + var blocks: Array[Block] = [] + for block_definition in get_variable_block_definitions(variables): + var b = instantiate_block(block_definition) + # HACK: Color the blocks since they are outside of the normal picker system + b.color = Constants.BUILTIN_CATEGORIES_PROPS["Variables"].color + blocks.append(b) + + return blocks + + ## Polyfill of Node.is_part_of_edited_scene(), available to GDScript in Godot 4.3+. static func node_is_part_of_edited_scene(node: Node) -> bool: if not Engine.is_editor_hint(): diff --git a/tests/test_instruction_tree.gd b/tests/test_instruction_tree.gd index 8f83a9be..81e17fab 100644 --- a/tests/test_instruction_tree.gd +++ b/tests/test_instruction_tree.gd @@ -208,9 +208,7 @@ func test_signal_script(): extends Area2D - - func _on_body_entered(_body: Node2D): - var body: NodePath = _body.get_path() + func _on_body_entered(body: Node2D): print({text})