| @@ -1,6 +1,6 @@ | |||
| [gd_resource type="Resource" load_steps=4 format=2] | |||
| [ext_resource path="res://jrpg/scripts/entities/data/character_data.gd" type="Script" id=1] | |||
| [ext_resource path="res://jrpg/scripts/data/character_data.gd" type="Script" id=1] | |||
| [ext_resource path="res://jrpg/scenes/entities/Enemy.tscn" type="PackedScene" id=2] | |||
| [ext_resource path="res://jrpg/yarn_scripts/npc_debug.yarn" type="Resource" id=3] | |||
| @@ -1,6 +1,6 @@ | |||
| [gd_resource type="Resource" load_steps=3 format=2] | |||
| [ext_resource path="res://jrpg/scripts/entities/data/character_data.gd" type="Script" id=1] | |||
| [ext_resource path="res://jrpg/scripts/data/character_data.gd" type="Script" id=1] | |||
| [ext_resource path="res://jrpg/scenes/entities/Player.tscn" type="PackedScene" id=2] | |||
| [resource] | |||
| @@ -1,11 +1,16 @@ | |||
| [gd_scene load_steps=4 format=2] | |||
| [gd_scene load_steps=6 format=2] | |||
| [ext_resource path="res://jrpg/models/chars/Zombie_Male.glb" type="PackedScene" id=1] | |||
| [ext_resource path="res://jrpg/scripts/entities/npc.gd" type="Script" id=2] | |||
| [ext_resource path="res://jrpg/scripts/entities/utils/trigger_relay.gd" type="Script" id=3] | |||
| [sub_resource type="CapsuleShape" id=1] | |||
| radius = 0.5 | |||
| [sub_resource type="CapsuleShape" id=2] | |||
| radius = 0.543022 | |||
| height = 0.89044 | |||
| [node name="Enemy" type="KinematicBody"] | |||
| script = ExtResource( 2 ) | |||
| @@ -17,4 +22,12 @@ shape = SubResource( 1 ) | |||
| transform = Transform( 0.65, 0, 0, 0, 0.65, 0, 0, 0, 0.65, 0, 0, 0 ) | |||
| [node name="Timer" type="Timer" parent="."] | |||
| [node name="InteractableArea" type="Area" parent="."] | |||
| script = ExtResource( 3 ) | |||
| [node name="CollisionShape" type="CollisionShape" parent="InteractableArea"] | |||
| 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"] | |||
| @@ -21,6 +21,5 @@ material/1 = ExtResource( 4 ) | |||
| [node name="CollisionShape" type="CollisionShape" parent="."] | |||
| shape = SubResource( 1 ) | |||
| [connection signal="body_entered" from="." to="." method="_on_Pickup_body_entered"] | |||
| [editable path="coinGold"] | |||
| @@ -1,13 +1,21 @@ | |||
| [gd_scene load_steps=5 format=2] | |||
| [gd_scene load_steps=7 format=2] | |||
| [ext_resource path="res://jrpg/models/chars/Casual2_Female.glb" type="PackedScene" id=1] | |||
| [ext_resource path="res://jrpg/scripts/entities/camera/camera_orbit.gd" type="Script" id=3] | |||
| [ext_resource path="res://jrpg/scripts/camera/camera_orbit.gd" type="Script" id=3] | |||
| [ext_resource path="res://jrpg/scripts/entities/player.gd" type="Script" id=4] | |||
| [sub_resource type="CapsuleShape" id=1] | |||
| radius = 0.5 | |||
| [node name="Player" type="KinematicBody"] | |||
| [sub_resource type="CapsuleShape" id=2] | |||
| radius = 0.628143 | |||
| height = 0.985831 | |||
| [sub_resource type="SphereShape" id=3] | |||
| [node name="Player" type="KinematicBody" groups=[ | |||
| "Player", | |||
| ]] | |||
| script = ExtResource( 4 ) | |||
| [node name="Casual2_Female" parent="." instance=ExtResource( 1 )] | |||
| @@ -26,9 +34,16 @@ transform = Transform( -1, 0, -3.25841e-07, 0, 1, 0, 3.25841e-07, 0, -1, -1, 1, | |||
| current = true | |||
| far = 329.0 | |||
| [node name="InteractRayCast" type="RayCast" parent="."] | |||
| transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.3, 1, 0.2 ) | |||
| enabled = true | |||
| cast_to = Vector3( 0, 0, 1.7 ) | |||
| [node name="TouchableArea" type="Area" parent="."] | |||
| [node name="CollisionShape" type="CollisionShape" parent="TouchableArea"] | |||
| transform = Transform( 1, 0, 0, 0, -1.62921e-07, 1, 0, -1, -1.62921e-07, 0, 1.12047, 0 ) | |||
| shape = SubResource( 2 ) | |||
| [node name="InteractorArea" type="Area" parent="."] | |||
| [node name="CollisionShape" type="CollisionShape" parent="InteractorArea"] | |||
| transform = Transform( 1, 0, 0, 0, -1.62921e-07, 1, 0, -1, -1.62921e-07, 0, 1.12047, 0.99678 ) | |||
| shape = SubResource( 3 ) | |||
| [editable path="Casual2_Female"] | |||
| @@ -0,0 +1,101 @@ | |||
| [gd_scene load_steps=10 format=2] | |||
| [ext_resource path="res://jrpg/scripts/entities/switch.gd" type="Script" id=1] | |||
| [ext_resource path="res://jrpg/scripts/entities/utils/trigger_relay.gd" type="Script" id=2] | |||
| [sub_resource type="BoxShape" id=1] | |||
| extents = Vector3( 0.25, 0.25, 0.25 ) | |||
| [sub_resource type="CubeMesh" id=2] | |||
| size = Vector3( 0.5, 0.2, 0.5 ) | |||
| [sub_resource type="CubeMesh" id=3] | |||
| size = Vector3( 0.2, 0.159, 0.287 ) | |||
| [sub_resource type="SpatialMaterial" id=4] | |||
| albedo_color = Color( 1, 0, 0, 1 ) | |||
| [sub_resource type="Animation" id=5] | |||
| tracks/0/type = "value" | |||
| tracks/0/path = NodePath("Model/MeshInstance2:material/0:albedo_color") | |||
| tracks/0/interp = 1 | |||
| tracks/0/loop_wrap = true | |||
| tracks/0/imported = false | |||
| tracks/0/enabled = true | |||
| tracks/0/keys = { | |||
| "times": PoolRealArray( 1 ), | |||
| "transitions": PoolRealArray( 1 ), | |||
| "update": 0, | |||
| "values": [ Color( 1, 0, 0, 1 ) ] | |||
| } | |||
| tracks/1/type = "value" | |||
| tracks/1/path = NodePath("Model/MeshInstance2:rotation_degrees") | |||
| tracks/1/interp = 1 | |||
| tracks/1/loop_wrap = true | |||
| tracks/1/imported = false | |||
| tracks/1/enabled = true | |||
| tracks/1/keys = { | |||
| "times": PoolRealArray( 1 ), | |||
| "transitions": PoolRealArray( 1 ), | |||
| "update": 0, | |||
| "values": [ Vector3( -22, 0, 0 ) ] | |||
| } | |||
| [sub_resource type="Animation" id=6] | |||
| tracks/0/type = "value" | |||
| tracks/0/path = NodePath("Model/MeshInstance2:material/0:albedo_color") | |||
| tracks/0/interp = 1 | |||
| tracks/0/loop_wrap = true | |||
| tracks/0/imported = false | |||
| tracks/0/enabled = true | |||
| tracks/0/keys = { | |||
| "times": PoolRealArray( 1 ), | |||
| "transitions": PoolRealArray( 1 ), | |||
| "update": 0, | |||
| "values": [ Color( 0, 1, 0.505882, 1 ) ] | |||
| } | |||
| tracks/1/type = "value" | |||
| tracks/1/path = NodePath("Model/MeshInstance2:rotation_degrees") | |||
| tracks/1/interp = 1 | |||
| tracks/1/loop_wrap = true | |||
| tracks/1/imported = false | |||
| tracks/1/enabled = true | |||
| tracks/1/keys = { | |||
| "times": PoolRealArray( 1 ), | |||
| "transitions": PoolRealArray( 1 ), | |||
| "update": 0, | |||
| "values": [ Vector3( 22, 0, 0 ) ] | |||
| } | |||
| [sub_resource type="SphereShape" id=7] | |||
| radius = 0.5 | |||
| [node name="Switch" type="KinematicBody"] | |||
| script = ExtResource( 1 ) | |||
| [node name="CollisionShape" type="CollisionShape" parent="."] | |||
| transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.15, 0 ) | |||
| shape = SubResource( 1 ) | |||
| [node name="Model" type="Spatial" parent="."] | |||
| [node name="MeshInstance" type="MeshInstance" parent="Model"] | |||
| mesh = SubResource( 2 ) | |||
| material/0 = null | |||
| [node name="MeshInstance2" type="MeshInstance" parent="Model"] | |||
| transform = Transform( 1, 0, 0, 0, 0.927184, 0.374607, 0, -0.374607, 0.927184, 0, 0.0918144, 0 ) | |||
| mesh = SubResource( 3 ) | |||
| material/0 = SubResource( 4 ) | |||
| [node name="AnimationPlayer" type="AnimationPlayer" parent="."] | |||
| anims/Off = SubResource( 5 ) | |||
| anims/On = SubResource( 6 ) | |||
| [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.35, 0 ) | |||
| shape = SubResource( 7 ) | |||
| [connection signal="on_interact" from="InteractableArea" to="." method="on_interact"] | |||
| @@ -0,0 +1,13 @@ | |||
| extends Area | |||
| export var yarnScript : Resource | |||
| var enabled := false | |||
| func enable(): | |||
| enabled = true | |||
| func on_touch(body): | |||
| if enabled: | |||
| EventDispatcher.emit_signal("trigger_script", yarnScript) | |||
| enabled = false | |||
| @@ -1,16 +0,0 @@ | |||
| extends Node | |||
| class_name BasisInteraction | |||
| export var auto_connect_on_ready := true | |||
| func _ready(): | |||
| init() | |||
| if auto_connect_on_ready: | |||
| get_parent().connect("on_interact", self, "on_interact") | |||
| func init(): | |||
| pass | |||
| func on_interact(): | |||
| print("interact") | |||
| @@ -1,8 +0,0 @@ | |||
| extends BasisInteraction | |||
| class_name TalkInteraction | |||
| var yarn_script : Resource | |||
| func on_interact(): | |||
| EventDispatcher.emit_signal("trigger_script", yarn_script) | |||
| @@ -1,88 +0,0 @@ | |||
| extends KinematicBody | |||
| # stats | |||
| var curHp : int = 3 | |||
| var maxHp : int = 3 | |||
| # attacking | |||
| var damage : int = 1 | |||
| var attackDist : float = 1.5 | |||
| var attackRate : float = 1.0 | |||
| # physics | |||
| var moveSpeed : float = 2.5 | |||
| var gravity : float = 15.0 | |||
| # vectors | |||
| var vel : Vector3 = Vector3() | |||
| # components | |||
| onready var timer = get_node("Timer") | |||
| export var player_path : NodePath | |||
| onready var player = get_node(player_path) | |||
| onready var anim = get_node("Zombie_Male/AnimationPlayer") | |||
| func _ready (): | |||
| # set the timer wait time | |||
| timer.wait_time = attackRate | |||
| timer.start() | |||
| # called every "attackRate" seconds | |||
| func _on_Timer_timeout (): | |||
| # if we're within the attack distance - attack the player | |||
| if translation.distance_to(player.translation) <= attackDist: | |||
| anim.play("Punch") | |||
| player.take_damage(damage) | |||
| # called 60 times a second | |||
| func _physics_process (delta): | |||
| # get the distance from us to the player | |||
| var dist = translation.distance_to(player.translation) | |||
| # if we're outside of the attack distance, chase after the player | |||
| if dist > attackDist: | |||
| # calculate the direction between us and the player | |||
| var dir = (player.translation - translation).normalized() | |||
| vel.x = dir.x | |||
| vel.z = dir.z | |||
| # gravity | |||
| vel.y -= gravity * delta | |||
| # TODO better | |||
| look_at(player.translation, Vector3.UP) | |||
| rotation_degrees.x = 0 | |||
| rotation_degrees.y = rotation_degrees.y + 180 | |||
| rotation_degrees.z = 0 | |||
| # move towards the player | |||
| vel = move_and_slide(vel, Vector3.UP) | |||
| if is_on_floor(): | |||
| if anim.current_animation != "Punch" and anim.current_animation != "RecieveHit": | |||
| if vel.length_squared() > 0: | |||
| anim.play("Walk") | |||
| else: | |||
| anim.play("Idle") | |||
| else: | |||
| anim.play("RecieveHit") | |||
| # called when the player deals damage to us | |||
| func take_damage (damageToTake): | |||
| curHp -= damageToTake | |||
| anim.play("RecieveHit") | |||
| # if our health reaches 0 - die | |||
| if curHp <= 0: | |||
| die() | |||
| # called when our health reaches 0 | |||
| func die (): | |||
| # destroy the node | |||
| queue_free() | |||
| @@ -1,4 +1,8 @@ | |||
| extends Node | |||
| signal on_interact | |||
| signal on_attack | |||
| class_name NPC | |||
| var yarn_script : Resource | |||
| func on_interact(): | |||
| EventDispatcher.emit_signal("trigger_script", yarn_script) | |||
| @@ -7,13 +7,12 @@ var rotateSpeed : float = 5.0 | |||
| # called every frame | |||
| func _process (delta): | |||
| # rotate along the Y axis | |||
| rotate_y(rotateSpeed * delta) | |||
| func _on_Pickup_body_entered(body): | |||
| func on_touch(body : KinematicBody): | |||
| # is this the player? If so give them gold | |||
| if body.name == "Player": | |||
| if body.is_in_group("Player"): | |||
| body.give_gold(goldToGive) | |||
| emit_signal("picked_up") | |||
| queue_free() | |||
| @@ -23,6 +23,9 @@ func _process(delta): | |||
| # attack input | |||
| if Controller.player_input_enabled and is_on_floor() and Input.is_action_just_pressed("interact"): | |||
| try_interact() | |||
| for area in $TouchableArea.get_overlapping_areas(): | |||
| try_touch(area) | |||
| # called every physics step (60 times a second) | |||
| func _physics_process (delta): | |||
| @@ -108,33 +111,16 @@ func die (): | |||
| # reload the scene | |||
| get_tree().reload_current_scene() | |||
| ## called when we press the attack button | |||
| #func try_attack(): | |||
| # # if we're not ready to attack, return | |||
| # if OS.get_ticks_msec() - lastAttackTime < attackRate * 1000: | |||
| # return | |||
| # | |||
| # # set the last attack time to now | |||
| # lastAttackTime = OS.get_ticks_msec() | |||
| # | |||
| # # play the animation | |||
| # anim.stop() | |||
| # anim.play("Punch") | |||
| # | |||
| # # is the ray cast colliding with an enemy? | |||
| # if attackCast.is_colliding(): | |||
| # if attackCast.get_collider().has_method("take_damage"): | |||
| # attackCast.get_collider().take_damage(damage) | |||
| # if attackCast.get_collider().has_signal("on_interact"): | |||
| # attackCast.get_collider().emit_signal("on_interact") | |||
| func try_touch(area): | |||
| if area.has_method("on_touch"): | |||
| area.on_touch(self) | |||
| # called when we press the interact button | |||
| func try_interact(): | |||
| # is the ray cast colliding with an enemy? | |||
| if interactCast.is_colliding(): | |||
| for area in $InteractorArea.get_overlapping_areas(): | |||
| # play the animation | |||
| anim.stop() | |||
| anim.play("Idle") | |||
| if interactCast.get_collider().has_signal("on_interact"): | |||
| interactCast.get_collider().emit_signal("on_interact") | |||
| if area.has_method("on_interact"): | |||
| area.on_interact() | |||
| @@ -0,0 +1,23 @@ | |||
| extends KinematicBody | |||
| signal switch | |||
| export var initial_state := false | |||
| var activated := false | |||
| func _ready(): | |||
| activated = initial_state | |||
| update_view() | |||
| emit_signal("switch", activated) | |||
| func on_interact(): | |||
| activated = !activated | |||
| update_view() | |||
| emit_signal("switch", activated) | |||
| func update_view(): | |||
| if activated: | |||
| $AnimationPlayer.play("On") | |||
| else: | |||
| $AnimationPlayer.play("Off") | |||
| @@ -0,0 +1,6 @@ | |||
| extends Node | |||
| signal on_interact() | |||
| func on_interact(): | |||
| emit_signal("on_interact") | |||
| @@ -1,9 +0,0 @@ | |||
| extends Area | |||
| export var yarnScript : Resource | |||
| func enable(): | |||
| self.connect("body_entered", self, "_on_TriggerArea_body_entered") | |||
| func _on_TriggerArea_body_entered(body): | |||
| EventDispatcher.emit_signal("trigger_script", yarnScript) | |||
| @@ -2,14 +2,9 @@ extends Node | |||
| export var character_data : Resource | |||
| var interaction_component : BasisInteraction | |||
| func spawn(): | |||
| var inst = character_data.scene.instance() | |||
| inst.name = character_data.name | |||
| if character_data.yarn != null: | |||
| interaction_component = TalkInteraction.new() | |||
| interaction_component.name = character_data.yarn.resource_name | |||
| interaction_component.yarn_script = character_data.yarn | |||
| inst.add_child(interaction_component) | |||
| inst.yarn_script = character_data.yarn | |||
| add_child(inst) | |||
| @@ -71,3 +71,7 @@ func scene(args): | |||
| func _exit_tree(): | |||
| Controller.hud.hide() | |||
| Controller.speech_panel.hide() | |||
| func _on_Switch_switch(activated): | |||
| $DirectionalLight.light_energy = activated if 1 else 0 | |||
| @@ -14,15 +14,10 @@ _global_script_classes=[ { | |||
| "language": "GDScript", | |||
| "path": "res://jrpg/scripts/levels/base_level.gd" | |||
| }, { | |||
| "base": "Node", | |||
| "class": "BasisInteraction", | |||
| "language": "GDScript", | |||
| "path": "res://jrpg/scripts/entities/components/interactions/basis_interaction.gd" | |||
| }, { | |||
| "base": "Resource", | |||
| "class": "CharacterData", | |||
| "language": "GDScript", | |||
| "path": "res://jrpg/scripts/entities/data/character_data.gd" | |||
| "path": "res://jrpg/scripts/data/character_data.gd" | |||
| }, { | |||
| "base": "VBoxContainer", | |||
| "class": "ChoicesBox", | |||
| @@ -34,6 +29,11 @@ _global_script_classes=[ { | |||
| "language": "GDScript", | |||
| "path": "res://jrpg/scripts/ui/test_hud.gd" | |||
| }, { | |||
| "base": "Node", | |||
| "class": "NPC", | |||
| "language": "GDScript", | |||
| "path": "res://jrpg/scripts/entities/npc.gd" | |||
| }, { | |||
| "base": "KinematicBody", | |||
| "class": "Player", | |||
| "language": "GDScript", | |||
| @@ -42,7 +42,7 @@ _global_script_classes=[ { | |||
| "base": "Object", | |||
| "class": "PlayerInfos", | |||
| "language": "GDScript", | |||
| "path": "res://jrpg/scripts/entities/model/player_infos.gd" | |||
| "path": "res://jrpg/scripts/model/player_infos.gd" | |||
| }, { | |||
| "base": "Control", | |||
| "class": "SpeechPanel", | |||
| @@ -54,11 +54,6 @@ _global_script_classes=[ { | |||
| "language": "GDScript", | |||
| "path": "res://jrpg/scripts/ui/speech_text.gd" | |||
| }, { | |||
| "base": "BasisInteraction", | |||
| "class": "TalkInteraction", | |||
| "language": "GDScript", | |||
| "path": "res://jrpg/scripts/entities/components/interactions/talk_interaction.gd" | |||
| }, { | |||
| "base": "BaseLevel", | |||
| "class": "TestLevel", | |||
| "language": "GDScript", | |||
| @@ -86,15 +81,14 @@ _global_script_classes=[ { | |||
| } ] | |||
| _global_script_class_icons={ | |||
| "BaseLevel": "", | |||
| "BasisInteraction": "", | |||
| "CharacterData": "", | |||
| "ChoicesBox": "", | |||
| "HUD": "", | |||
| "NPC": "", | |||
| "Player": "", | |||
| "PlayerInfos": "", | |||
| "SpeechPanel": "", | |||
| "SpeechText": "", | |||
| "TalkInteraction": "", | |||
| "TestLevel": "", | |||
| "YarnImporter": "", | |||
| "YarnRunner": "", | |||