@@ -1,6 +1,6 @@ | |||||
[gd_resource type="Resource" load_steps=4 format=2] | [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/scenes/entities/Enemy.tscn" type="PackedScene" id=2] | ||||
[ext_resource path="res://jrpg/yarn_scripts/npc_debug.yarn" type="Resource" id=3] | [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] | [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] | [ext_resource path="res://jrpg/scenes/entities/Player.tscn" type="PackedScene" id=2] | ||||
[resource] | [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/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/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] | [sub_resource type="CapsuleShape" id=1] | ||||
radius = 0.5 | radius = 0.5 | ||||
[sub_resource type="CapsuleShape" id=2] | |||||
radius = 0.543022 | |||||
height = 0.89044 | |||||
[node name="Enemy" type="KinematicBody"] | [node name="Enemy" type="KinematicBody"] | ||||
script = ExtResource( 2 ) | 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 ) | 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="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="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="."] | [node name="CollisionShape" type="CollisionShape" parent="."] | ||||
shape = SubResource( 1 ) | shape = SubResource( 1 ) | ||||
[connection signal="body_entered" from="." to="." method="_on_Pickup_body_entered"] | |||||
[editable path="coinGold"] | [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/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] | [ext_resource path="res://jrpg/scripts/entities/player.gd" type="Script" id=4] | ||||
[sub_resource type="CapsuleShape" id=1] | [sub_resource type="CapsuleShape" id=1] | ||||
radius = 0.5 | 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 ) | script = ExtResource( 4 ) | ||||
[node name="Casual2_Female" parent="." instance=ExtResource( 1 )] | [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 | current = true | ||||
far = 329.0 | 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"] | [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 | 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 | # called every frame | ||||
func _process (delta): | func _process (delta): | ||||
# rotate along the Y axis | # rotate along the Y axis | ||||
rotate_y(rotateSpeed * delta) | rotate_y(rotateSpeed * delta) | ||||
func _on_Pickup_body_entered(body): | |||||
func on_touch(body : KinematicBody): | |||||
# is this the player? If so give them gold | # is this the player? If so give them gold | ||||
if body.name == "Player": | |||||
if body.is_in_group("Player"): | |||||
body.give_gold(goldToGive) | body.give_gold(goldToGive) | ||||
emit_signal("picked_up") | emit_signal("picked_up") | ||||
queue_free() | queue_free() |
@@ -23,6 +23,9 @@ func _process(delta): | |||||
# attack input | # attack input | ||||
if Controller.player_input_enabled and is_on_floor() and Input.is_action_just_pressed("interact"): | if Controller.player_input_enabled and is_on_floor() and Input.is_action_just_pressed("interact"): | ||||
try_interact() | try_interact() | ||||
for area in $TouchableArea.get_overlapping_areas(): | |||||
try_touch(area) | |||||
# called every physics step (60 times a second) | # called every physics step (60 times a second) | ||||
func _physics_process (delta): | func _physics_process (delta): | ||||
@@ -108,33 +111,16 @@ func die (): | |||||
# reload the scene | # reload the scene | ||||
get_tree().reload_current_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 | # called when we press the interact button | ||||
func try_interact(): | func try_interact(): | ||||
# is the ray cast colliding with an enemy? | # is the ray cast colliding with an enemy? | ||||
if interactCast.is_colliding(): | |||||
for area in $InteractorArea.get_overlapping_areas(): | |||||
# play the animation | # play the animation | ||||
anim.stop() | anim.stop() | ||||
anim.play("Idle") | 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 | export var character_data : Resource | ||||
var interaction_component : BasisInteraction | |||||
func spawn(): | func spawn(): | ||||
var inst = character_data.scene.instance() | var inst = character_data.scene.instance() | ||||
inst.name = character_data.name | inst.name = character_data.name | ||||
if character_data.yarn != null: | 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) | add_child(inst) |
@@ -71,3 +71,7 @@ func scene(args): | |||||
func _exit_tree(): | func _exit_tree(): | ||||
Controller.hud.hide() | Controller.hud.hide() | ||||
Controller.speech_panel.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", | "language": "GDScript", | ||||
"path": "res://jrpg/scripts/levels/base_level.gd" | "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", | "base": "Resource", | ||||
"class": "CharacterData", | "class": "CharacterData", | ||||
"language": "GDScript", | "language": "GDScript", | ||||
"path": "res://jrpg/scripts/entities/data/character_data.gd" | |||||
"path": "res://jrpg/scripts/data/character_data.gd" | |||||
}, { | }, { | ||||
"base": "VBoxContainer", | "base": "VBoxContainer", | ||||
"class": "ChoicesBox", | "class": "ChoicesBox", | ||||
@@ -34,6 +29,11 @@ _global_script_classes=[ { | |||||
"language": "GDScript", | "language": "GDScript", | ||||
"path": "res://jrpg/scripts/ui/test_hud.gd" | "path": "res://jrpg/scripts/ui/test_hud.gd" | ||||
}, { | }, { | ||||
"base": "Node", | |||||
"class": "NPC", | |||||
"language": "GDScript", | |||||
"path": "res://jrpg/scripts/entities/npc.gd" | |||||
}, { | |||||
"base": "KinematicBody", | "base": "KinematicBody", | ||||
"class": "Player", | "class": "Player", | ||||
"language": "GDScript", | "language": "GDScript", | ||||
@@ -42,7 +42,7 @@ _global_script_classes=[ { | |||||
"base": "Object", | "base": "Object", | ||||
"class": "PlayerInfos", | "class": "PlayerInfos", | ||||
"language": "GDScript", | "language": "GDScript", | ||||
"path": "res://jrpg/scripts/entities/model/player_infos.gd" | |||||
"path": "res://jrpg/scripts/model/player_infos.gd" | |||||
}, { | }, { | ||||
"base": "Control", | "base": "Control", | ||||
"class": "SpeechPanel", | "class": "SpeechPanel", | ||||
@@ -54,11 +54,6 @@ _global_script_classes=[ { | |||||
"language": "GDScript", | "language": "GDScript", | ||||
"path": "res://jrpg/scripts/ui/speech_text.gd" | "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", | "base": "BaseLevel", | ||||
"class": "TestLevel", | "class": "TestLevel", | ||||
"language": "GDScript", | "language": "GDScript", | ||||
@@ -86,15 +81,14 @@ _global_script_classes=[ { | |||||
} ] | } ] | ||||
_global_script_class_icons={ | _global_script_class_icons={ | ||||
"BaseLevel": "", | "BaseLevel": "", | ||||
"BasisInteraction": "", | |||||
"CharacterData": "", | "CharacterData": "", | ||||
"ChoicesBox": "", | "ChoicesBox": "", | ||||
"HUD": "", | "HUD": "", | ||||
"NPC": "", | |||||
"Player": "", | "Player": "", | ||||
"PlayerInfos": "", | "PlayerInfos": "", | ||||
"SpeechPanel": "", | "SpeechPanel": "", | ||||
"SpeechText": "", | "SpeechText": "", | ||||
"TalkInteraction": "", | |||||
"TestLevel": "", | "TestLevel": "", | ||||
"YarnImporter": "", | "YarnImporter": "", | ||||
"YarnRunner": "", | "YarnRunner": "", | ||||