diff --git a/Sources/armory/logicnode/AnimationControllerNode.hx b/Sources/armory/logicnode/AnimationControllerNode.hx index 46c2a96..a80f2ae 100644 --- a/Sources/armory/logicnode/AnimationControllerNode.hx +++ b/Sources/armory/logicnode/AnimationControllerNode.hx @@ -9,7 +9,6 @@ class AnimationControllerNode extends LogicNode { } override function run() { - trace("start"); var animated:Object = inputs[1].get(); var idle:String = inputs[2].get(); diff --git a/Sources/armory/logicnode/TimerNode.hx b/Sources/armory/logicnode/TimerNode.hx new file mode 100644 index 0000000..3f52209 --- /dev/null +++ b/Sources/armory/logicnode/TimerNode.hx @@ -0,0 +1,112 @@ +package armory.logicnode; + +class TimerNode extends LogicNode { + + var currentDuration:Float = 0.0; + var duration:Float = 0.0; + + var repetitions:Int = 0; + var totalRepetitions:Int = 0; + + var running:Bool = false; + + var pause:Bool = false; + var paused:Bool = false; + + var stop:Bool = false; + + public function new(tree:LogicTree) { + super(tree); + } + + override function run() { + pause = inputs[1].get(); + stop = inputs[2].get(); + if(!running && !(stop || pause || paused)) { + duration = inputs[3].get(); + currentDuration = duration; + repetitions = inputs[4].get(); + totalRepetitions = repetitions; + running = true; + tree.notifyOnUpdate(update); + } + if(!running && !(stop || pause) && paused) { + paused = false; + running = true; + } + } + + override function get(from:Int):Dynamic { + if(from == 2) { + return running; + } else { + if(from == 3) { + return paused; + } else { + if(from == 4) { + return currentDuration; + } else { + if(from == 5) { + if(repetitions < 0) { + return 0; + } else { + return (totalRepetitions - repetitions + 1 - currentDuration/duration)/(totalRepetitions+1); + } + } else { + return totalRepetitions - repetitions; + } + } + } + } + } + + function update() { + pause = inputs[1].get(); + stop = inputs[2].get(); + + if(running && !(stop || pause)) { + currentDuration -= iron.system.Time.delta; + if(currentDuration <= 0) { + runOutputs(0); + if(repetitions == 0) { + runOutputs(1); + tree.removeUpdate(update); + running = false; + currentDuration = 0.0; + duration = 0.0; + repetitions = 0; + totalRepetitions = 0; + paused = false; + } + if(repetitions > 0) { + repetitions -= 1; + currentDuration = duration; + } + if(repetitions < 0) { + currentDuration = duration; + } + } + } + + if(running && pause) { + running = false; + if(!stop && pause) + paused = true; + } + + if(paused && !pause) { + running = true; + paused = false; + } + + if(stop) { + running = false; + currentDuration = 0.0; + duration = 0.0; + repetitions = 0; + totalRepetitions = 0; + paused = false; + tree.removeUpdate(update); + } + } +} diff --git a/blender.py b/blender.py index 50521c4..765286b 100644 --- a/blender.py +++ b/blender.py @@ -143,8 +143,8 @@ def init(self, context): self.inputs.new('NodeSocketBool', 'Additional Modifier (e.g. sniper)') self.inputs.new('NodeSocketFloat', 'Modifier') self.inputs[-1].default_value = 0.25 - self.inputs.new('NodeSocketBool', 'Invert Vertical') self.inputs.new('NodeSocketBool', 'Invert Horizontal') + self.inputs.new('NodeSocketBool', 'Invert Vertical') self.inputs.new('NodeSocketFloat', 'Horizontal Axis Movement') self.inputs.new('NodeSocketFloat', 'Horiontal Speed') @@ -201,6 +201,28 @@ def draw_buttons(self, context, layout): op4 = row2.operator('arm.node_remove_input', text='', icon='X', emboss=True) op4.node_index = str(id(self)) +class TimerNode(Node, ArmLogicTreeNode): + '''TimerNode''' + bl_idname = 'LNTimerNode' + bl_label = 'Timer Node' + bl_icon = 'GAME' + + def init(self, context): + self.outputs.new('ArmNodeSocketAction', 'Out') + self.outputs.new('ArmNodeSocketAction', 'Done') + self.outputs.new('NodeSocketBool', 'Running') + self.outputs.new('NodeSocketBool', 'Paused') + self.outputs.new('NodeSocketFloat', 'Seconds left') + self.outputs.new('NodeSocketFloat', 'Progress (in %)') + self.outputs.new('NodeSocketInt', 'Repetitions done') + + self.inputs.new('ArmNodeSocketAction', 'Start') + self.inputs.new('NodeSocketBool', 'Pause') + self.inputs.new('NodeSocketBool', 'Stop') + + self.inputs.new('NodeSocketFloat', 'Seconds') + self.inputs.new('NodeSocketInt', 'Repetitions (0 for oneshot, negative for unlimited)') + def register(): # Add custom nodes # TODO: separate into single .py file per logic node, similar to the main Armory repository @@ -212,6 +234,7 @@ def register(): add_node(PlayerController, category='Action') add_node(CameraController, category='Action') add_node(AnimationControllerNode, category='Animation') + add_node(TimerNode, category='Logic') # Register newly added nodes arm.nodes_logic.register_nodes()