diff --git a/jrpg/scenes/TestLVL.tscn b/jrpg/scenes/TestLVL.tscn index e3870f9..025da9e 100644 --- a/jrpg/scenes/TestLVL.tscn +++ b/jrpg/scenes/TestLVL.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=32 format=2] +[gd_scene load_steps=33 format=2] [ext_resource path="res://jrpg/scripts/levels/spawner.gd" type="Script" id=1] [ext_resource path="res://jrpg/yarn_scripts/test_start.yarn" type="Resource" id=2] @@ -17,6 +17,7 @@ [ext_resource path="res://jrpg/scripts/misc/test_level.gd" type="Script" id=15] [ext_resource path="res://jrpg/models/nature/river/water.tres" type="Material" id=16] [ext_resource path="res://jrpg/scenes/entities/Switch.tscn" type="PackedScene" id=17] +[ext_resource path="res://jrpg/scenes/entities/Crate.tscn" type="PackedScene" id=18] [sub_resource type="PlaneMesh" id=1] size = Vector2( 600, 600 ) @@ -418,4 +419,7 @@ shape = SubResource( 14 ) [node name="Switch" parent="." instance=ExtResource( 17 )] transform = Transform( 1, 0, 0, 0, 0.0600904, 0.998193, 0, -0.998193, 0.0600904, 7.74067, -0.485543, -28.5048 ) + +[node name="Crate" parent="." instance=ExtResource( 18 )] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 8.32558, -1.44783, 0 ) [connection signal="switch" from="Switch" to="." method="_on_Switch_switch"] diff --git a/jrpg/scenes/entities/Crate.tscn b/jrpg/scenes/entities/Crate.tscn new file mode 100644 index 0000000..47eee39 --- /dev/null +++ b/jrpg/scenes/entities/Crate.tscn @@ -0,0 +1,32 @@ +[gd_scene load_steps=6 format=2] + +[ext_resource path="res://jrpg/scripts/entities/crate.gd" type="Script" id=1] +[ext_resource path="res://jrpg/scripts/entities/utils/trigger_relay.gd" type="Script" id=2] + +[sub_resource type="CubeMesh" id=1] +size = Vector3( 1.5, 1.5, 1.5 ) + +[sub_resource type="BoxShape" id=2] +extents = Vector3( 0.75, 0.75, 0.75 ) + +[sub_resource type="BoxShape" id=3] +extents = Vector3( 0.75, 0.75, 0.75 ) + +[node name="Crate" type="KinematicBody"] +script = ExtResource( 1 ) + +[node name="MeshInstance" type="MeshInstance" parent="."] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.75, 0 ) +mesh = SubResource( 1 ) +material/0 = null + +[node name="CollisionShape" type="CollisionShape" parent="."] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.75, 0 ) +shape = SubResource( 2 ) + +[node name="InteractableArea" type="Area" parent="."] +script = ExtResource( 2 ) + +[node name="CollisionShape" type="CollisionShape" parent="InteractableArea"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.75, 0 ) +shape = SubResource( 3 ) diff --git a/jrpg/scenes/entities/Enemy.tscn b/jrpg/scenes/entities/Enemy.tscn index d631022..dbe2afb 100644 --- a/jrpg/scenes/entities/Enemy.tscn +++ b/jrpg/scenes/entities/Enemy.tscn @@ -30,4 +30,3 @@ script = ExtResource( 3 ) transform = Transform( 1, 0, 0, 0, -1.62921e-07, 1, 0, -1, -1.62921e-07, 0, 1, 0 ) shape = SubResource( 2 ) [connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"] -[connection signal="on_interact" from="InteractableArea" to="." method="on_interact"] diff --git a/jrpg/scenes/entities/Switch.tscn b/jrpg/scenes/entities/Switch.tscn index cf2c3ee..ea6507a 100644 --- a/jrpg/scenes/entities/Switch.tscn +++ b/jrpg/scenes/entities/Switch.tscn @@ -98,4 +98,3 @@ script = ExtResource( 2 ) [node name="CollisionShape" type="CollisionShape" parent="InteractableArea"] transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.35, 0 ) shape = SubResource( 7 ) -[connection signal="on_interact" from="InteractableArea" to="." method="on_interact"] diff --git a/jrpg/scripts/entities/crate.gd b/jrpg/scripts/entities/crate.gd new file mode 100644 index 0000000..2005003 --- /dev/null +++ b/jrpg/scripts/entities/crate.gd @@ -0,0 +1,8 @@ +extends KinematicBody + +func on_interact_pressed(interactor): + interactor.start_pushing(self) + +func on_interact_released(interactor): + interactor.stop_pushing(self) + diff --git a/jrpg/scripts/entities/npc.gd b/jrpg/scripts/entities/npc.gd index cebabf5..857d53b 100644 --- a/jrpg/scripts/entities/npc.gd +++ b/jrpg/scripts/entities/npc.gd @@ -4,5 +4,5 @@ class_name NPC var yarn_script : Resource -func on_interact(): +func on_interact_pressed(interactor): EventDispatcher.emit_signal("trigger_script", yarn_script) diff --git a/jrpg/scripts/entities/pickup.gd b/jrpg/scripts/entities/pickup.gd index e78af96..77cdf8f 100644 --- a/jrpg/scripts/entities/pickup.gd +++ b/jrpg/scripts/entities/pickup.gd @@ -10,9 +10,9 @@ func _process (delta): # rotate along the Y axis rotate_y(rotateSpeed * delta) -func on_touch(body : KinematicBody): +func on_touch(interactor : KinematicBody): # is this the player? If so give them gold - if body.is_in_group("Player"): - body.give_gold(goldToGive) + if interactor.is_in_group("Player"): + interactor.give_gold(goldToGive) emit_signal("picked_up") queue_free() diff --git a/jrpg/scripts/entities/player.gd b/jrpg/scripts/entities/player.gd index edb73ba..3ded966 100644 --- a/jrpg/scripts/entities/player.gd +++ b/jrpg/scripts/entities/player.gd @@ -19,10 +19,19 @@ onready var camera = get_node("CameraOrbit") onready var interactCast = get_node("InteractRayCast") onready var anim = get_node("Casual2_Female/AnimationPlayer") +# internal + +var interactables := [] +var pushed_object + func _process(delta): # attack input - if Controller.player_input_enabled and is_on_floor() and Input.is_action_just_pressed("interact"): - try_interact() + if Controller.player_input_enabled and is_on_floor(): + if Input.is_action_just_pressed("interact"): + try_interact_pressed() + + if Input.is_action_just_released("interact"): + try_interact_released() for area in $TouchableArea.get_overlapping_areas(): try_touch(area) @@ -62,7 +71,7 @@ func _physics_process (delta): vel.z = dir.z * walkSpeed # jump input - if Input.is_action_pressed("jump") and is_on_floor(): + if can_jump(): vel.y = jumpForce else: vel.x = 0 @@ -80,8 +89,14 @@ func _physics_process (delta): else: anim.play("RecieveHit") - # move along the current velocity var previous_vel = vel + # move pushed object first if there is one + if pushed_object: + var object_vel = pushed_object.move_and_slide(vel, Vector3.UP, true, 1, deg2rad(30)) + vel.x = object_vel.x + vel.z = object_vel.z + + # move along the current velocity vel = move_and_slide(vel, Vector3.UP, true, 4, deg2rad(30)) "debug for water" @@ -116,11 +131,33 @@ func try_touch(area): area.on_touch(self) # called when we press the interact button -func try_interact(): - # is the ray cast colliding with an enemy? +func try_interact_pressed(): + # play the animation + anim.stop() + anim.play("Idle") + for area in $InteractorArea.get_overlapping_areas(): - # play the animation - anim.stop() - anim.play("Idle") - if area.has_method("on_interact"): - area.on_interact() + if area.has_method("on_interact_pressed"): + interactables.push_back(area) + area.on_interact_pressed(self) + +# called when we release the interact button +func try_interact_released(): + # play the animation + anim.stop() + anim.play("Idle") + + for interactable in interactables: + if interactable.has_method("on_interact_released"): + interactable.on_interact_released(self) + + interactables.clear() + +func start_pushing(body): + pushed_object = body + +func stop_pushing(body): + pushed_object = null + +func can_jump(): + return pushed_object == null and Input.is_action_pressed("jump") and is_on_floor() diff --git a/jrpg/scripts/entities/switch.gd b/jrpg/scripts/entities/switch.gd index e54f50d..1eb4607 100644 --- a/jrpg/scripts/entities/switch.gd +++ b/jrpg/scripts/entities/switch.gd @@ -11,7 +11,7 @@ func _ready(): update_view() emit_signal("switch", activated) -func on_interact(): +func on_interact_pressed(interactor): activated = !activated update_view() emit_signal("switch", activated) diff --git a/jrpg/scripts/entities/utils/trigger_relay.gd b/jrpg/scripts/entities/utils/trigger_relay.gd index ffd7934..7c45846 100644 --- a/jrpg/scripts/entities/utils/trigger_relay.gd +++ b/jrpg/scripts/entities/utils/trigger_relay.gd @@ -1,6 +1,20 @@ extends Node -signal on_interact() +export var target_path : NodePath = ".." -func on_interact(): - emit_signal("on_interact") +signal on_interact_pressed +signal on_interact_released + +func _ready(): + if target_path: + var target_node = get_node(target_path) + if target_node != null and target_node.has_method("on_interact_pressed"): + self.connect("on_interact_pressed", target_node, "on_interact_pressed") + if target_node != null and target_node.has_method("on_interact_released"): + self.connect("on_interact_released", target_node, "on_interact_released") + +func on_interact_pressed(interactor): + emit_signal("on_interact_pressed", interactor) + +func on_interact_released(interactor): + emit_signal("on_interact_released", interactor)