From ec266e491a99dca8552e963afa53c7a1640ae903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Fri, 16 Aug 2024 11:14:01 -0300 Subject: [PATCH 01/17] Block definition: Add target node class Add target node class to the definition for class-specific blocks. For example, "On body entered / exited" block is specific to a node that inherits RigidBody2D. https://phabricator.endlessm.com/T35591 --- addons/block_code/blocks/communication/add_to_group.tres | 6 ++++-- addons/block_code/blocks/log/print.tres | 1 + addons/block_code/blocks/logic/compare.tres | 1 + addons/block_code/blocks/math/add.tres | 1 + addons/block_code/blocks/math/divide.tres | 1 + addons/block_code/blocks/math/multiply.tres | 1 + addons/block_code/blocks/math/pow.tres | 1 + addons/block_code/blocks/math/randf_range.tres | 1 + addons/block_code/blocks/math/randi_range.tres | 1 + addons/block_code/blocks/math/subtract.tres | 1 + addons/block_code/blocks/sounds/load_sound.tres | 1 + addons/block_code/blocks/sounds/pause_continue_sound.tres | 1 + addons/block_code/blocks/sounds/play_sound.tres | 1 + addons/block_code/blocks/sounds/stop_sound.tres | 1 + addons/block_code/blocks/variables/vector2.tres | 1 + addons/block_code/code_generation/block_definition.gd | 7 +++++++ 16 files changed, 25 insertions(+), 2 deletions(-) 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/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/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/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..defbf9aa 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 From 4349a7a3b7285bf269a2fc90c0c3730738d29424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Fri, 16 Aug 2024 11:45:31 -0300 Subject: [PATCH 02/17] Block catalog: Add getter for blocks by class As defined by the target class in the resource file. --- .../block_code/code_generation/blocks_catalog.gd | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/addons/block_code/code_generation/blocks_catalog.gd b/addons/block_code/code_generation/blocks_catalog.gd index 104c3df2..124073f5 100644 --- a/addons/block_code/code_generation/blocks_catalog.gd +++ b/addons/block_code/code_generation/blocks_catalog.gd @@ -7,6 +7,7 @@ const Util = preload("res://addons/block_code/code_generation/util.gd") const _BLOCKS_PATH = "res://addons/block_code/blocks/" static var _catalog: Dictionary +static var _by_class_name: Dictionary static func setup(): @@ -17,8 +18,14 @@ static func setup(): var definition_files = Util.get_files_in_dir_recursive(_BLOCKS_PATH, "*.tres") for file in definition_files: - var block_definition = load(file) + 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 get_block(block_name: StringName): @@ -27,3 +34,10 @@ 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() From 855c3dd84974eef8bec22aa4f00adb166b836f34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Fri, 16 Aug 2024 11:47:55 -0300 Subject: [PATCH 03/17] UI util: Instantiate all blocks by class For this, the previous instantiate_block is renamed to instantiate_block_by_name. --- .../ui/block_canvas/block_canvas.gd | 2 +- .../ui/picker/categories/category_factory.gd | 22 +++---- addons/block_code/ui/util.gd | 59 ++++++++++++++++--- 3 files changed, 65 insertions(+), 18 deletions(-) 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/picker/categories/category_factory.gd b/addons/block_code/ui/picker/categories/category_factory.gd index 9ae41db1..13dc4671 100644 --- a/addons/block_code/ui/picker/categories/category_factory.gd +++ b/addons/block_code/ui/picker/categories/category_factory.gd @@ -172,39 +172,39 @@ static func get_general_blocks() -> Array[Block]: # Lifecycle for block_name in [&"ready", &"process", &"physics_process", &"queue_free"]: - b = Util.instantiate_block(block_name) + b = Util.instantiate_block_by_name(block_name) block_list.append(b) # Loops for block_name in [&"for", &"while", &"break", &"continue", &"await_scene_ready"]: - b = Util.instantiate_block(block_name) + b = Util.instantiate_block_by_name(block_name) block_list.append(b) # Logs - b = Util.instantiate_block(&"print") + b = Util.instantiate_block_by_name(&"print") block_list.append(b) # Communication for block_name in [&"define_method", &"call_method_group", &"call_method_node"]: - b = Util.instantiate_block(block_name) + b = Util.instantiate_block_by_name(block_name) block_list.append(b) 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) + b = Util.instantiate_block_by_name(block_name) block_list.append(b) # Variables - b = Util.instantiate_block(&"vector2") + b = Util.instantiate_block_by_name(&"vector2") block_list.append(b) # Math for block_name in [&"add", &"subtract", &"multiply", &"divide", &"pow", &"randf_range", &"randi_range", &"sin", &"cos", &"tan"]: - b = Util.instantiate_block(block_name) + b = Util.instantiate_block_by_name(block_name) block_list.append(b) # Logic for block_name in [&"if", &"else_if", &"else", &"compare", &"and", &"or", &"not"]: - b = Util.instantiate_block(block_name) + b = Util.instantiate_block_by_name(block_name) block_list.append(b) # Input @@ -212,12 +212,12 @@ static func get_general_blocks() -> Array[Block]: # Sounds for block_name in [&"load_sound", &"play_sound", &"pause_continue_sound", &"stop_sound"]: - b = Util.instantiate_block(block_name) + b = Util.instantiate_block_by_name(block_name) block_list.append(b) # Graphics for block_name in [&"viewport_width", &"viewport_height", &"viewport_center"]: - b = Util.instantiate_block(block_name) + b = Util.instantiate_block_by_name(block_name) block_list.append(b) return block_list @@ -298,6 +298,8 @@ static func blocks_from_property_list(property_list: Array, selected_props: Dict static func get_inherited_blocks(_class_name: String) -> Array[Block]: var blocks: Array[Block] = [] + blocks.append_array(Util.instantiate_blocks_for_class(_class_name)) + var current: String = _class_name while current != "": diff --git a/addons/block_code/ui/util.gd b/addons/block_code/ui/util.gd index 13d602eb..d6fb72a0 100644 --- a/addons/block_code/ui/util.gd +++ b/addons/block_code/ui/util.gd @@ -12,13 +12,7 @@ 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 instantiate_block(block_definition: BlockDefinition) -> Block: var scene = SCENE_PER_TYPE[block_definition.type] var b = scene.instantiate() b.block_name = block_definition.name @@ -39,6 +33,57 @@ static func instantiate_block(block_name: StringName) -> Block: 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 + + ## 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(): From 203b1de021a8ab2afb0ca440321e51f110e047ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Fri, 16 Aug 2024 11:17:54 -0300 Subject: [PATCH 04/17] Add CharacterBody2D block definitions And remove them from the category factory. Also add a default value for speed in the characterbody2d_move block. https://phabricator.endlessm.com/T35591 --- .../blocks/input/characterbody2d_move.tres | 31 +++++++++++++++++++ .../characterbody2d_move_and_slide.tres | 17 ++++++++++ .../ui/picker/categories/category_factory.gd | 31 ------------------- 3 files changed, 48 insertions(+), 31 deletions(-) create mode 100644 addons/block_code/blocks/input/characterbody2d_move.tres create mode 100644 addons/block_code/blocks/physics/characterbody2d_move_and_slide.tres 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/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/ui/picker/categories/category_factory.gd b/addons/block_code/ui/picker/categories/category_factory.gd index 13dc4671..9549012d 100644 --- a/addons/block_code/ui/picker/categories/category_factory.gd +++ b/addons/block_code/ui/picker/categories/category_factory.gd @@ -485,37 +485,6 @@ static func get_built_in_blocks(_class_name: String) -> Array[Block]: 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"}, } From 4a1e52a70db944b911a6e483d9dcfb4fa4002e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Fri, 16 Aug 2024 14:29:51 -0300 Subject: [PATCH 05/17] Add Area2D block definitions And change the body type from NODE_PATH to OBJECT, as in previous definitions. https://phabricator.endlessm.com/T35591 --- .../communication/area2d_on_entered.tres | 18 ++++++++++++++++ .../communication/area2d_on_exited.tres | 18 ++++++++++++++++ .../ui/picker/categories/category_factory.gd | 21 ------------------- tests/test_instruction_tree.gd | 4 +--- 4 files changed, 37 insertions(+), 24 deletions(-) create mode 100644 addons/block_code/blocks/communication/area2d_on_entered.tres create mode 100644 addons/block_code/blocks/communication/area2d_on_exited.tres 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/ui/picker/categories/category_factory.gd b/addons/block_code/ui/picker/categories/category_factory.gd index 9549012d..4d7a3f3e 100644 --- a/addons/block_code/ui/picker/categories/category_factory.gd +++ b/addons/block_code/ui/picker/categories/category_factory.gd @@ -463,27 +463,6 @@ static func get_built_in_blocks(_class_name: String) -> Array[Block]: 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": props = { "velocity": {"category": "Physics | Velocity"}, 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}) From 2fbb3cb9a345a7f0c071213ede1f119983c72a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Fri, 16 Aug 2024 14:42:49 -0300 Subject: [PATCH 06/17] Add AnimationPlayer block definitions https://phabricator.endlessm.com/T35591 --- .../graphics/animationplayer_is_playing.tres | 17 +++++++ .../graphics/animationplayer_pause.tres | 17 +++++++ .../blocks/graphics/animationplayer_play.tres | 29 ++++++++++++ .../blocks/graphics/animationplayer_stop.tres | 17 +++++++ .../ui/picker/categories/category_factory.gd | 45 ------------------- 5 files changed, 80 insertions(+), 45 deletions(-) create mode 100644 addons/block_code/blocks/graphics/animationplayer_is_playing.tres create mode 100644 addons/block_code/blocks/graphics/animationplayer_pause.tres create mode 100644 addons/block_code/blocks/graphics/animationplayer_play.tres create mode 100644 addons/block_code/blocks/graphics/animationplayer_stop.tres 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/ui/picker/categories/category_factory.gd b/addons/block_code/ui/picker/categories/category_factory.gd index 4d7a3f3e..94e877d6 100644 --- a/addons/block_code/ui/picker/categories/category_factory.gd +++ b/addons/block_code/ui/picker/categories/category_factory.gd @@ -418,51 +418,6 @@ static func get_built_in_blocks(_class_name: String) -> Array[Block]: }, } - "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) - "CharacterBody2D": props = { "velocity": {"category": "Physics | Velocity"}, From 9514bbbf0f0719f34c3b65ee512460e691bc8c47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Fri, 16 Aug 2024 14:48:18 -0300 Subject: [PATCH 07/17] Add AudioStreamPlayer block definitions https://phabricator.endlessm.com/T35591 --- .../blocks/sounds/audiostreamplayer_play.tres | 17 +++++++++++++++++ .../blocks/sounds/audiostreamplayer_stop.tres | 17 +++++++++++++++++ .../ui/picker/categories/category_factory.gd | 16 ---------------- 3 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 addons/block_code/blocks/sounds/audiostreamplayer_play.tres create mode 100644 addons/block_code/blocks/sounds/audiostreamplayer_stop.tres 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/ui/picker/categories/category_factory.gd b/addons/block_code/ui/picker/categories/category_factory.gd index 94e877d6..a10afce2 100644 --- a/addons/block_code/ui/picker/categories/category_factory.gd +++ b/addons/block_code/ui/picker/categories/category_factory.gd @@ -394,22 +394,6 @@ static func get_built_in_blocks(_class_name: String) -> Array[Block]: } "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": { From 575e7c80226ddac23ccd6838c236de02c6937ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Fri, 16 Aug 2024 14:58:20 -0300 Subject: [PATCH 08/17] Add RigidBody2D block definitions https://phabricator.endlessm.com/T35591 --- .../communication/rigidbody2d_on_entered.tres | 18 ++++++++++ .../communication/rigidbody2d_on_exited.tres | 18 ++++++++++ .../rigidbody2d_physics_position.tres | 22 ++++++++++++ .../ui/picker/categories/category_factory.gd | 36 ------------------- 4 files changed, 58 insertions(+), 36 deletions(-) create mode 100644 addons/block_code/blocks/communication/rigidbody2d_on_entered.tres create mode 100644 addons/block_code/blocks/communication/rigidbody2d_on_exited.tres create mode 100644 addons/block_code/blocks/transform/rigidbody2d_physics_position.tres 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/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/ui/picker/categories/category_factory.gd b/addons/block_code/ui/picker/categories/category_factory.gd index a10afce2..7493963e 100644 --- a/addons/block_code/ui/picker/categories/category_factory.gd +++ b/addons/block_code/ui/picker/categories/category_factory.gd @@ -351,42 +351,6 @@ static func get_built_in_blocks(_class_name: String) -> Array[Block]: } "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"}, From dd1e0e9aca642dda48a741861f5e592b25b9d4ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Mon, 19 Aug 2024 17:25:03 -0300 Subject: [PATCH 09/17] Blocks catalog: Add property blocks Port the property setter/changer/getter blocks to the new block definition. These are not loaded from resource files, they are defined in code. https://phabricator.endlessm.com/T35591 --- .../code_generation/blocks_catalog.gd | 159 +++++++++++++++++- .../ui/picker/categories/category_factory.gd | 152 +---------------- 2 files changed, 154 insertions(+), 157 deletions(-) diff --git a/addons/block_code/code_generation/blocks_catalog.gd b/addons/block_code/code_generation/blocks_catalog.gd index 124073f5..c41e7a68 100644 --- a/addons/block_code/code_generation/blocks_catalog.gd +++ b/addons/block_code/code_generation/blocks_catalog.gd @@ -6,16 +6,82 @@ const Util = preload("res://addons/block_code/code_generation/util.gd") const _BLOCKS_PATH = "res://addons/block_code/blocks/" -static var _catalog: Dictionary -static var _by_class_name: Dictionary +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, +} -static func setup(): - if _catalog: - return +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 - _catalog = {} +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) @@ -28,6 +94,87 @@ static func setup(): _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 _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(): + if _catalog: + return + + _catalog = {} + _setup_definitions_from_files() + _setup_properties_for_class() + + static func get_block(block_name: StringName): return _catalog.get(block_name) diff --git a/addons/block_code/ui/picker/categories/category_factory.gd b/addons/block_code/ui/picker/categories/category_factory.gd index 7493963e..3315e6f6 100644 --- a/addons/block_code/ui/picker/categories/category_factory.gd +++ b/addons/block_code/ui/picker/categories/category_factory.gd @@ -223,158 +223,8 @@ static func get_general_blocks() -> Array[Block]: 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]) - - return block_list - - static func get_inherited_blocks(_class_name: String) -> Array[Block]: - var blocks: Array[Block] = [] - - blocks.append_array(Util.instantiate_blocks_for_class(_class_name)) - - 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": - props = { - "mass": {"category": "Physics | Mass"}, - "linear_velocity": {"category": "Physics | Velocity"}, - "angular_velocity": {"category": "Physics | Velocity"}, - } - - "AudioStreamPlayer": - props = { - "stream_paused": - { - "category": "Sounds", - "has_change": false, - }, - } - - "CharacterBody2D": - 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 + return Util.instantiate_blocks_for_class(_class_name) static func _get_input_blocks() -> Array[Block]: From 768de50eeb9fbd6899228a8093a9a0ab5ac19ac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Mon, 19 Aug 2024 17:28:48 -0300 Subject: [PATCH 10/17] Simple nodes: Port custom blocks Add a way in the blocks catalog to add custom blocks. Port SimpleScoring and SimpleCharacter to the new block definitions. Change the picker logic to instantiate these blocks. https://phabricator.endlessm.com/T35591 --- .../code_generation/blocks_catalog.gd | 18 ++++++ .../simple_character/simple_character.gd | 56 ++++++++++--------- .../simple_scoring/simple_scoring.gd | 45 ++++++++------- addons/block_code/ui/picker/picker.gd | 11 ++-- 4 files changed, 76 insertions(+), 54 deletions(-) diff --git a/addons/block_code/code_generation/blocks_catalog.gd b/addons/block_code/code_generation/blocks_catalog.gd index c41e7a68..233f5508 100644 --- a/addons/block_code/code_generation/blocks_catalog.gd +++ b/addons/block_code/code_generation/blocks_catalog.gd @@ -188,3 +188,21 @@ static func get_blocks_by_class(_class_name: String): 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/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/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) From 4c6acb1e9c18fddbf960e3f89e8f5ecf13d84a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Mon, 19 Aug 2024 17:30:56 -0300 Subject: [PATCH 11/17] Block definition: Add _to_string() method For easier debugging. --- addons/block_code/code_generation/block_definition.gd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/addons/block_code/code_generation/block_definition.gd b/addons/block_code/code_generation/block_definition.gd index defbf9aa..9f3bbb90 100644 --- a/addons/block_code/code_generation/block_definition.gd +++ b/addons/block_code/code_generation/block_definition.gd @@ -52,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] From e70ac87d94d32c18f4ace3fcc45c72d01c5349b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Tue, 20 Aug 2024 12:42:53 -0300 Subject: [PATCH 12/17] Blocks catalog: Port "is action pressed / released" block And split obtaining the inputmap action names to a inner function. https://phabricator.endlessm.com/T35591 --- .../code_generation/blocks_catalog.gd | 47 +++++++++++++++++++ .../ui/picker/categories/category_factory.gd | 36 +------------- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/addons/block_code/code_generation/blocks_catalog.gd b/addons/block_code/code_generation/blocks_catalog.gd index 233f5508..18ec616b 100644 --- a/addons/block_code/code_generation/blocks_catalog.gd +++ b/addons/block_code/code_generation/blocks_catalog.gd @@ -159,6 +159,32 @@ static func _add_property_definitions(_class_name: String, property_list: Array[ _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) @@ -166,6 +192,26 @@ static func _setup_properties_for_class(): _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(): if _catalog: return @@ -173,6 +219,7 @@ static func setup(): _catalog = {} _setup_definitions_from_files() _setup_properties_for_class() + _setup_input_block() static func get_block(block_name: StringName): diff --git a/addons/block_code/ui/picker/categories/category_factory.gd b/addons/block_code/ui/picker/categories/category_factory.gd index 3315e6f6..2f82fa62 100644 --- a/addons/block_code/ui/picker/categories/category_factory.gd +++ b/addons/block_code/ui/picker/categories/category_factory.gd @@ -208,7 +208,8 @@ static func get_general_blocks() -> Array[Block]: block_list.append(b) # Input - block_list.append_array(_get_input_blocks()) + b = Util.instantiate_block_by_name(&"is_input_actioned") + block_list.append(b) # Sounds for block_name in [&"load_sound", &"play_sound", &"pause_continue_sound", &"stop_sound"]: @@ -227,39 +228,6 @@ static func get_inherited_blocks(_class_name: String) -> Array[Block]: return Util.instantiate_blocks_for_class(_class_name) -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 - - static func get_variable_blocks(variables: Array[VariableResource]): var block_list: Array[Block] From 2a03d079caf04f2dc80717f95049016a6c0dccd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Tue, 20 Aug 2024 14:13:09 -0300 Subject: [PATCH 13/17] Dynamically add blocks for variables Using the new block definition. These are the only blocks that are not stored in the catalog. Instead, they are dynamically generated when the BlockScriptSerialization changes. Also: Move constant for the builtin category properties to the constants.gd script. Also: Finally remove the preloaded scene blocks from the category_factory.gd script. The single place where those scenes are now instantiated is the ui/util.gd script. https://phabricator.endlessm.com/T35591 --- addons/block_code/ui/constants.gd | 116 ++++++++++++++ .../ui/picker/categories/category_factory.gd | 150 +----------------- addons/block_code/ui/util.gd | 35 ++++ 3 files changed, 154 insertions(+), 147 deletions(-) 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/category_factory.gd b/addons/block_code/ui/picker/categories/category_factory.gd index 2f82fa62..358d3809 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) @@ -229,26 +107,4 @@ static func get_inherited_blocks(_class_name: String) -> Array[Block]: 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/util.gd b/addons/block_code/ui/util.gd index d6fb72a0..b6d8beb7 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"), @@ -84,6 +85,40 @@ static func instantiate_blocks_for_class(_class_name: String) -> Array[Block]: 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(): From 9a0da761cdd9961ad23c594a3c6c875a137e6cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Tue, 20 Aug 2024 16:10:01 -0300 Subject: [PATCH 14/17] Derive block color from category Stop persisting the color in the serialization. https://phabricator.endlessm.com/T35591 --- addons/block_code/ui/blocks/block/block.gd | 3 +-- .../ui/picker/categories/block_category_display.gd | 6 +----- addons/block_code/ui/util.gd | 7 +++++++ 3 files changed, 9 insertions(+), 7 deletions(-) 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/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/util.gd b/addons/block_code/ui/util.gd index b6d8beb7..5371b4e8 100644 --- a/addons/block_code/ui/util.gd +++ b/addons/block_code/ui/util.gd @@ -13,6 +13,11 @@ const SCENE_PER_TYPE = { } +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() @@ -31,6 +36,8 @@ static func instantiate_block(block_definition: BlockDefinition) -> 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 From c037bfd8647948f4d9a35539ee785abd9cf26544 Mon Sep 17 00:00:00 2001 From: Will Baumgartner Date: Tue, 20 Aug 2024 22:50:03 -0300 Subject: [PATCH 15/17] Serialize user input as Variants instead of Strings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Manuel Quiñones --- .../parameter_input/parameter_input.gd | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) 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): From 2d13c92a283142e2310691de5093309d9eecad7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Tue, 20 Aug 2024 23:24:13 -0300 Subject: [PATCH 16/17] Category factory: rename variable "b" to "block" To avoid single character names. --- .../ui/picker/categories/category_factory.gd | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/addons/block_code/ui/picker/categories/category_factory.gd b/addons/block_code/ui/picker/categories/category_factory.gd index 358d3809..934a333b 100644 --- a/addons/block_code/ui/picker/categories/category_factory.gd +++ b/addons/block_code/ui/picker/categories/category_factory.gd @@ -45,59 +45,59 @@ 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_by_name(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_by_name(block_name) - block_list.append(b) + block = Util.instantiate_block_by_name(block_name) + block_list.append(block) # Logs - b = Util.instantiate_block_by_name(&"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_by_name(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_by_name(block_name) - block_list.append(b) + block = Util.instantiate_block_by_name(block_name) + block_list.append(block) # Variables - b = Util.instantiate_block_by_name(&"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_by_name(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_by_name(block_name) - block_list.append(b) + block = Util.instantiate_block_by_name(block_name) + block_list.append(block) # Input - b = Util.instantiate_block_by_name(&"is_input_actioned") - block_list.append(b) + 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_by_name(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_by_name(block_name) - block_list.append(b) + block = Util.instantiate_block_by_name(block_name) + block_list.append(block) return block_list From 9dec121223591f2b8e17017f89f6e517ecdee954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= Date: Wed, 21 Aug 2024 10:27:30 -0300 Subject: [PATCH 17/17] Redo the Pong example --- .../examples/pong_game/pong_game.tscn | 937 ++++++++---------- 1 file changed, 417 insertions(+), 520 deletions(-) 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