From db7fb0c6d5859ab597dd433375546bf52c6f6de2 Mon Sep 17 00:00:00 2001 From: QuantumCoderQC Date: Sun, 3 Mar 2024 13:59:51 +0100 Subject: [PATCH 1/6] New select output node --- Sources/armory/logicnode/SelectOutputNode.hx | 20 ++++++++++ .../arm/logicnode/logic/LN_select_output.py | 40 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 Sources/armory/logicnode/SelectOutputNode.hx create mode 100644 blender/arm/logicnode/logic/LN_select_output.py diff --git a/Sources/armory/logicnode/SelectOutputNode.hx b/Sources/armory/logicnode/SelectOutputNode.hx new file mode 100644 index 0000000000..a9c8dcc925 --- /dev/null +++ b/Sources/armory/logicnode/SelectOutputNode.hx @@ -0,0 +1,20 @@ +package armory.logicnode; + +class SelectOutputNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function run(from: Int) { + //Get index to run + var outIndex: Int = inputs[1].get(); + // Check if output index found + if(outIndex > (outputs.length - 2) || outIndex < 0) + { + runOutput(0); + return; + } + runOutput(outIndex + 1); + } +} diff --git a/blender/arm/logicnode/logic/LN_select_output.py b/blender/arm/logicnode/logic/LN_select_output.py new file mode 100644 index 0000000000..adcbc8c791 --- /dev/null +++ b/blender/arm/logicnode/logic/LN_select_output.py @@ -0,0 +1,40 @@ +from arm.logicnode.arm_nodes import * + +class SelectOutputNode(ArmLogicTreeNode): + """Selects one of multiple outputs depending on the index + + @input In: Action input. + + @input Index: Output index to run. + + @output Default: Run if output index not present. + """ + + bl_idname = 'LNSelectOutputNode' + bl_label = 'Select output' + arm_version = 1 + min_outputs = 2 + + def __init__(self): + super(SelectOutputNode, self).__init__() + array_nodes[self.get_id_str()] = self + + def arm_init(self, context): + self.add_input('ArmNodeSocketAction', 'In') + self.add_input('ArmIntSocket', 'Index') + + self.add_output('ArmNodeSocketAction', 'Default') + self.add_output('ArmNodeSocketAction', 'Index 0') + + def draw_buttons(self, context, layout): + row = layout.row(align=True) + op = row.operator('arm.node_add_output', text='New', icon='PLUS', emboss=True) + op.node_index = self.get_id_str() + op.socket_type = 'ArmNodeSocketAction' + op.name_format = 'Index {0}' + op.index_name_offset = -1 + column = row.column(align=True) + op = column.operator('arm.node_remove_output', text='', icon='X', emboss=True) + op.node_index = self.get_id_str() + if len(self.outputs) == self.min_outputs: + column.enabled = False From 7da68371e06c3c7e76b73424c9361114980d9fb3 Mon Sep 17 00:00:00 2001 From: QuantumCoderQC Date: Sun, 3 Mar 2024 14:00:11 +0100 Subject: [PATCH 2/6] document set map value node --- blender/arm/logicnode/map/LN_set_map_value.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/blender/arm/logicnode/map/LN_set_map_value.py b/blender/arm/logicnode/map/LN_set_map_value.py index 081f1c5318..8bbd4dc1e8 100644 --- a/blender/arm/logicnode/map/LN_set_map_value.py +++ b/blender/arm/logicnode/map/LN_set_map_value.py @@ -2,7 +2,17 @@ class SetMapValueNode(ArmLogicTreeNode): - """Set Map Value""" + """Set Map Value + + @input In: Set the map. + + @input Map: Map to set values. + + @input Key: Key to be set. + + @input Value: Value for the key. + """ + bl_idname = 'LNSetMapValueNode' bl_label = 'Set Map Value' arm_version = 1 From 64e85049338a2bf7cb6d9ffabcc4a3e3c153511d Mon Sep 17 00:00:00 2001 From: QuantumCoderQC Date: Sun, 3 Mar 2024 14:00:39 +0100 Subject: [PATCH 3/6] New set Map From Array Node --- .../armory/logicnode/SetMapFromArrayNode.hx | 25 ++++++++++++++++++ .../logicnode/map/LN_set_map_from_array.py | 26 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 Sources/armory/logicnode/SetMapFromArrayNode.hx create mode 100644 blender/arm/logicnode/map/LN_set_map_from_array.py diff --git a/Sources/armory/logicnode/SetMapFromArrayNode.hx b/Sources/armory/logicnode/SetMapFromArrayNode.hx new file mode 100644 index 0000000000..a54e91d1ee --- /dev/null +++ b/Sources/armory/logicnode/SetMapFromArrayNode.hx @@ -0,0 +1,25 @@ +package armory.logicnode; + + +class SetMapFromArrayNode extends LogicNode { + + public function new(tree:LogicTree) { + super(tree); + } + + override function run(from:Int) { + var map: Map = inputs[1].get(); + if (map == null) return; + + var keys: Array = inputs[2].get(); + var values: Array = inputs[3].get(); + + assert(Error, keys.length == values.length, "Number of keys and values should be equal"); + + for(i in 0...keys.length) { + map[keys[i]] = values[i]; + } + runOutput(0); + } + +} diff --git a/blender/arm/logicnode/map/LN_set_map_from_array.py b/blender/arm/logicnode/map/LN_set_map_from_array.py new file mode 100644 index 0000000000..0bac0e888e --- /dev/null +++ b/blender/arm/logicnode/map/LN_set_map_from_array.py @@ -0,0 +1,26 @@ +from arm.logicnode.arm_nodes import * + + +class SetMapFromArrayNode(ArmLogicTreeNode): + """Set Map From Arrays + + @input In: Set the map. + + @input Map: Map to set values. + + @input Key: Array of keys to be set. + + @input Value: Array of corresponding values for the keys. + """ + + bl_idname = 'LNSetMapFromArrayNode' + bl_label = 'Set Map From Array' + arm_version = 1 + + def init(self, context): + self.add_input('ArmNodeSocketAction', 'In') + self.add_input('ArmDynamicSocket', 'Map') + self.add_input('ArmNodeSocketArray', 'Keys') + self.add_input('ArmNodeSocketArray', 'Values') + + self.add_output('ArmNodeSocketAction', 'Out') From 6d9957f6a0a3304ad88ef400b2ca5aacdf4b00c2 Mon Sep 17 00:00:00 2001 From: QuantumCoderQC Date: Sun, 3 Mar 2024 14:01:17 +0100 Subject: [PATCH 4/6] New String Map Node --- Sources/armory/logicnode/StringMapNode.hx | 24 ++++++++++ blender/arm/logicnode/map/LN_string_map.py | 55 ++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 Sources/armory/logicnode/StringMapNode.hx create mode 100644 blender/arm/logicnode/map/LN_string_map.py diff --git a/Sources/armory/logicnode/StringMapNode.hx b/Sources/armory/logicnode/StringMapNode.hx new file mode 100644 index 0000000000..433bfb3d78 --- /dev/null +++ b/Sources/armory/logicnode/StringMapNode.hx @@ -0,0 +1,24 @@ +package armory.logicnode; + + +class StringMapNode extends LogicNode { + + public var property0: Int; + public var map: Map = []; + public function new(tree:LogicTree) { + super(tree); + } + + override function run(from: Int) { + map.clear(); + for(i in 0...property0) { + map.set(inputs[i * 2 + 1].get(), inputs[i * 2 + 2].get()); + } + runOutput(0); + } + + override function get(from: Int):Dynamic { + return map; + } + +} diff --git a/blender/arm/logicnode/map/LN_string_map.py b/blender/arm/logicnode/map/LN_string_map.py new file mode 100644 index 0000000000..1175f5de83 --- /dev/null +++ b/blender/arm/logicnode/map/LN_string_map.py @@ -0,0 +1,55 @@ +from arm.logicnode.arm_nodes import * + +class StringMapNode(ArmLogicTreeNode): + """Create String Map + + @input In: Create a map using given keys and values. + + @input Key: Key. + + @input Value: Value. + + @output Out: Run after map is created. + + @output Map: The created map. + """ + + bl_idname = 'LNStringMapNode' + bl_label = 'String Map' + arm_version = 1 + + min_inputs = 1 + property0: HaxeIntProperty('property0', name='Number of keys', default=0) + + def __init__(self): + super(StringMapNode, self).__init__() + self.register_id() + + def arm_init(self, context): + self.add_input('ArmNodeSocketAction', 'In') + self.add_output('ArmNodeSocketAction', 'Out') + self.add_output('ArmDynamicSocket', 'Map') + + def add_sockets(self): + self.add_input('ArmStringSocket', f'Key [{self.property0}]') + self.add_input('ArmStringSocket', f'Value [{self.property0}]') + self.property0 += 1 + + def remove_sockets(self): + if self.property0 > 0: + self.inputs.remove(self.inputs.values()[-1]) + self.inputs.remove(self.inputs.values()[-1]) + self.property0 -= 1 + + def draw_buttons(self, context, layout): + row = layout.row(align=True) + + op = row.operator('arm.node_call_func', text='New', icon='PLUS', emboss=True) + op.node_index = self.get_id_str() + op.callback_name = 'add_sockets' + column = row.column(align=True) + op = column.operator('arm.node_call_func', text='', icon='X', emboss=True) + op.node_index = self.get_id_str() + op.callback_name = 'remove_sockets' + if len(self.inputs) == self.min_inputs: + column.enabled = False From 6eaf09180983a5f93677d1b515d7c71a10b8a721 Mon Sep 17 00:00:00 2001 From: QuantumCoderQC Date: Thu, 7 Mar 2024 21:31:07 +0100 Subject: [PATCH 5/6] fix documentation --- blender/arm/logicnode/logic/LN_select_output.py | 2 +- blender/arm/logicnode/map/LN_set_map_from_array.py | 2 +- blender/arm/logicnode/map/LN_set_map_value.py | 2 +- blender/arm/logicnode/map/LN_string_map.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/blender/arm/logicnode/logic/LN_select_output.py b/blender/arm/logicnode/logic/LN_select_output.py index adcbc8c791..9d05f4a9bc 100644 --- a/blender/arm/logicnode/logic/LN_select_output.py +++ b/blender/arm/logicnode/logic/LN_select_output.py @@ -1,7 +1,7 @@ from arm.logicnode.arm_nodes import * class SelectOutputNode(ArmLogicTreeNode): - """Selects one of multiple outputs depending on the index + """Selects one of multiple outputs depending on the index. @input In: Action input. diff --git a/blender/arm/logicnode/map/LN_set_map_from_array.py b/blender/arm/logicnode/map/LN_set_map_from_array.py index 0bac0e888e..af11aaf2b3 100644 --- a/blender/arm/logicnode/map/LN_set_map_from_array.py +++ b/blender/arm/logicnode/map/LN_set_map_from_array.py @@ -2,7 +2,7 @@ class SetMapFromArrayNode(ArmLogicTreeNode): - """Set Map From Arrays + """Set Map From Arrays. @input In: Set the map. diff --git a/blender/arm/logicnode/map/LN_set_map_value.py b/blender/arm/logicnode/map/LN_set_map_value.py index 8bbd4dc1e8..45e14bae80 100644 --- a/blender/arm/logicnode/map/LN_set_map_value.py +++ b/blender/arm/logicnode/map/LN_set_map_value.py @@ -2,7 +2,7 @@ class SetMapValueNode(ArmLogicTreeNode): - """Set Map Value + """Set Map Value. @input In: Set the map. diff --git a/blender/arm/logicnode/map/LN_string_map.py b/blender/arm/logicnode/map/LN_string_map.py index 1175f5de83..57ce1db331 100644 --- a/blender/arm/logicnode/map/LN_string_map.py +++ b/blender/arm/logicnode/map/LN_string_map.py @@ -1,7 +1,7 @@ from arm.logicnode.arm_nodes import * class StringMapNode(ArmLogicTreeNode): - """Create String Map + """Create String Map. @input In: Create a map using given keys and values. From d0db8c22e4d6052e0d356cebd45c763ca9ffd8d6 Mon Sep 17 00:00:00 2001 From: QuantumCoderQC Date: Thu, 7 Mar 2024 23:44:07 +0100 Subject: [PATCH 6/6] Implement JSON nodes --- Sources/armory/logicnode/JsonStringifyNode.hx | 14 ++++++++++++++ Sources/armory/logicnode/ParseJsonNode.hx | 13 +++++++++++++ blender/arm/logicnode/map/LN_json_parse.py | 18 ++++++++++++++++++ blender/arm/logicnode/map/LN_json_stringify.py | 18 ++++++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 Sources/armory/logicnode/JsonStringifyNode.hx create mode 100644 Sources/armory/logicnode/ParseJsonNode.hx create mode 100644 blender/arm/logicnode/map/LN_json_parse.py create mode 100644 blender/arm/logicnode/map/LN_json_stringify.py diff --git a/Sources/armory/logicnode/JsonStringifyNode.hx b/Sources/armory/logicnode/JsonStringifyNode.hx new file mode 100644 index 0000000000..cd54413558 --- /dev/null +++ b/Sources/armory/logicnode/JsonStringifyNode.hx @@ -0,0 +1,14 @@ +package armory.logicnode; +import haxe.Json; + +class JsonStringifyNode extends LogicNode { + + public function new(tree:LogicTree) { + super(tree); + } + + override function get(from: Int):Dynamic { + return Json.stringify(inputs[0].get()); + } + +} diff --git a/Sources/armory/logicnode/ParseJsonNode.hx b/Sources/armory/logicnode/ParseJsonNode.hx new file mode 100644 index 0000000000..01d30779c9 --- /dev/null +++ b/Sources/armory/logicnode/ParseJsonNode.hx @@ -0,0 +1,13 @@ +package armory.logicnode; +import haxe.Json; + +class ParseJsonNode extends LogicNode { + + public function new(tree:LogicTree) { + super(tree); + } + + override function get(from: Int):Dynamic { + return Json.parse(inputs[0].get()); + } +} diff --git a/blender/arm/logicnode/map/LN_json_parse.py b/blender/arm/logicnode/map/LN_json_parse.py new file mode 100644 index 0000000000..4bbd826d62 --- /dev/null +++ b/blender/arm/logicnode/map/LN_json_parse.py @@ -0,0 +1,18 @@ +from arm.logicnode.arm_nodes import * + + +class ParseJsonNode(ArmLogicTreeNode): + """Parse a JSON String to Haxe object. + + @input JSON: JSON string. + + @output Value: Parsed value. + """ + + bl_idname = 'LNParseJsonNode' + bl_label = 'Parse JSON' + arm_version = 1 + + def init(self, context): + self.add_input('ArmStringSocket', 'JSON') + self.add_output('ArmDynamicSocket', 'Value') diff --git a/blender/arm/logicnode/map/LN_json_stringify.py b/blender/arm/logicnode/map/LN_json_stringify.py new file mode 100644 index 0000000000..670964fe8c --- /dev/null +++ b/blender/arm/logicnode/map/LN_json_stringify.py @@ -0,0 +1,18 @@ +from arm.logicnode.arm_nodes import * + + +class JsonStringifyNode(ArmLogicTreeNode): + """Convert a Haxe object to JSON String. + + @input Value: Value to convert. + + @output String: JSON String. + """ + + bl_idname = 'LNJsonStringifyNode' + bl_label = 'JSON Stringify' + arm_version = 1 + + def init(self, context): + self.add_input('ArmDynamicSocket', 'Value') + self.add_output('ArmStringSocket', 'JSON') \ No newline at end of file