From a575b8a47dcb2945f611cb54643aac69a133c9b8 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Mon, 12 May 2025 21:00:13 -0500 Subject: [PATCH] Almost fixed entities --- scenes/Entities/Rosa.tscn | 14 ++++- scenes/Entities/TestNPC.tscn | 12 +++- scenes/Maps/TestMap/TestMap.tscn | 3 +- scripts/Entity/BasicNPCEntity.gd | 15 +++++ scripts/Entity/Component/EntityDirection.gd | 31 ++++++---- .../Entity/Component/EntityInteractable.gd | 9 ++- scripts/Entity/Component/EntityInteractor.gd | 59 ++++++++++++++++++- scripts/Entity/Rosa.gd | 26 -------- scripts/Event/Entity/EventEntityTurn.gd | 2 +- scripts/Event/Event.gd | 9 ++- scripts/Event/EventConversation.gd | 47 ++++++++------- scripts/Event/EventPause.gd | 8 +-- scripts/Singleton/Pause.gd | 2 +- 13 files changed, 158 insertions(+), 79 deletions(-) diff --git a/scenes/Entities/Rosa.tscn b/scenes/Entities/Rosa.tscn index e3da052..01436e5 100644 --- a/scenes/Entities/Rosa.tscn +++ b/scenes/Entities/Rosa.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=11 format=3 uid="uid://yhtpoum3eek7"] +[gd_scene load_steps=12 format=3 uid="uid://yhtpoum3eek7"] [ext_resource type="Script" uid="uid://ixwikdguyhf0" path="res://scripts/Entity/Rosa.gd" id="1_r5ufg"] [ext_resource type="Script" uid="uid://dtjjqp2atjyhr" path="res://scripts/Entity/Entity.gd" id="1_rvn3n"] @@ -7,6 +7,7 @@ [ext_resource type="Shader" uid="uid://7h2axb2tsh17" path="res://shaders/NPC Shader.gdshader" id="3_j5vis"] [ext_resource type="Script" uid="uid://c5nfs0m6ua4eb" path="res://scripts/Entity/Component/EntityMovement.gd" id="4_7s3uq"] [ext_resource type="Texture2D" uid="uid://cofrgefp8e617" path="res://textures/human.png" id="4_rvn3n"] +[ext_resource type="Script" uid="uid://dfh2rh8idx267" path="res://scripts/Entity/Component/EntityInteractor.gd" id="5_ug24t"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_ls7r8"] radius = 0.437175 @@ -32,10 +33,11 @@ metadata/_custom_type_script = "uid://ixwikdguyhf0" script = ExtResource("1_rvn3n") metadata/_custom_type_script = "uid://dtjjqp2atjyhr" -[node name="EntityDirection" type="Node" parent="Entity" node_paths=PackedStringArray("meshInstance")] +[node name="EntityDirection" type="Node" parent="Entity" node_paths=PackedStringArray("meshInstance", "characterBody")] script = ExtResource("2_vcxxc") meshInstance = NodePath("../../MeshInstance3D") direction = 2 +characterBody = NodePath("../..") metadata/_custom_type_script = "uid://cjfcpi7sxentf" [node name="EntityMoving" type="Node" parent="Entity" node_paths=PackedStringArray("characterBody", "entity", "entityDirection")] @@ -45,6 +47,14 @@ entity = NodePath("..") entityDirection = NodePath("../EntityDirection") movementType = 0 +[node name="EntityInteractor" type="Node" parent="Entity" node_paths=PackedStringArray("entityDirection", "characterBody", "entity")] +script = ExtResource("5_ug24t") +interactorType = 0 +entityDirection = NodePath("../EntityDirection") +characterBody = NodePath("../..") +entity = NodePath("..") +metadata/_custom_type_script = "uid://dfh2rh8idx267" + [node name="Rosa Camera" type="Camera3D" parent="." node_paths=PackedStringArray("follow")] transform = Transform3D(1, 0, 0, 0, 0.130388, 0.991463, 0, -0.991463, 0.130388, 0, 3.14994, 0.404846) current = true diff --git a/scenes/Entities/TestNPC.tscn b/scenes/Entities/TestNPC.tscn index 95a4d4b..341ccbe 100644 --- a/scenes/Entities/TestNPC.tscn +++ b/scenes/Entities/TestNPC.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=10 format=3 uid="uid://dr4b2pmsknuhc"] +[gd_scene load_steps=11 format=3 uid="uid://dr4b2pmsknuhc"] [ext_resource type="Script" uid="uid://d23qg1ovkbxst" path="res://scripts/Entity/BasicNPCEntity.gd" id="1_1muh7"] [ext_resource type="Shader" uid="uid://7h2axb2tsh17" path="res://shaders/NPC Shader.gdshader" id="1_xgcv1"] @@ -6,6 +6,7 @@ [ext_resource type="Script" uid="uid://cjfcpi7sxentf" path="res://scripts/Entity/Component/EntityDirection.gd" id="3_gyi1p"] [ext_resource type="Script" uid="uid://c5nfs0m6ua4eb" path="res://scripts/Entity/Component/EntityMovement.gd" id="4_3wesq"] [ext_resource type="Texture2D" uid="uid://cofrgefp8e617" path="res://textures/human.png" id="4_vo0ku"] +[ext_resource type="Script" uid="uid://03dqknw7v4mr" path="res://scripts/Entity/Component/EntityInteractable.gd" id="5_gyi1p"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_dw1sy"] radius = 0.420979 @@ -31,9 +32,10 @@ metadata/_custom_type_script = "uid://d23qg1ovkbxst" script = ExtResource("2_ehu3x") metadata/_custom_type_script = "uid://dtjjqp2atjyhr" -[node name="EntityDirection" type="Node" parent="Entity" node_paths=PackedStringArray("meshInstance")] +[node name="EntityDirection" type="Node" parent="Entity" node_paths=PackedStringArray("meshInstance", "characterBody")] script = ExtResource("3_gyi1p") meshInstance = NodePath("../../MeshInstance3D") +characterBody = NodePath("../..") metadata/_custom_type_script = "uid://cjfcpi7sxentf" [node name="EntityMoving" type="Node" parent="Entity" node_paths=PackedStringArray("characterBody", "entity", "entityDirection")] @@ -43,6 +45,12 @@ entity = NodePath("..") entityDirection = NodePath("../EntityDirection") movementType = 2 +[node name="EntityInteractable" type="Node" parent="Entity" node_paths=PackedStringArray("entityDirection", "entity")] +script = ExtResource("5_gyi1p") +entityDirection = NodePath("../EntityDirection") +entity = NodePath("..") +metadata/_custom_type_script = "uid://03dqknw7v4mr" + [node name="CollisionShape3D" type="CollisionShape3D" parent="."] shape = SubResource("CapsuleShape3D_dw1sy") diff --git a/scenes/Maps/TestMap/TestMap.tscn b/scenes/Maps/TestMap/TestMap.tscn index 3aac610..c3e359f 100644 --- a/scenes/Maps/TestMap/TestMap.tscn +++ b/scenes/Maps/TestMap/TestMap.tscn @@ -32,8 +32,9 @@ environment = SubResource("Environment_nyivo") [node name="Rosa" parent="." instance=ExtResource("1_7b7hx")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.19857, 0.684572, 0.968477) -[node name="Green" parent="." instance=ExtResource("2_cg1ph")] +[node name="Green" parent="." node_paths=PackedStringArray("interactEvent") instance=ExtResource("2_cg1ph")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.68747, 0.459578, -0.399262) +interactEvent = NodePath("../Events/TestConversation") [node name="OmniLight3D" type="OmniLight3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7.20244, 3.80554) diff --git a/scripts/Entity/BasicNPCEntity.gd b/scripts/Entity/BasicNPCEntity.gd index 5450f31..265c995 100644 --- a/scripts/Entity/BasicNPCEntity.gd +++ b/scripts/Entity/BasicNPCEntity.gd @@ -1 +1,16 @@ class_name BasicNPCEntity extends CharacterBody3D + +@export var interactEvent:Event = null + +func _ready() -> void: + $Entity/EntityInteractable.onInteract.connect( + self.onEntityInteract + ) + +func onEntityInteract( + interactor:EntityInteractor, + interactee:EntityInteractable +) -> void: + if interactEvent == null || interactEvent.started: + return + interactEvent.onEntityInteract(interactor, $Entity/EntityInteractable) diff --git a/scripts/Entity/Component/EntityDirection.gd b/scripts/Entity/Component/EntityDirection.gd index c8fe075..d02fcef 100644 --- a/scripts/Entity/Component/EntityDirection.gd +++ b/scripts/Entity/Component/EntityDirection.gd @@ -18,6 +18,8 @@ enum Direction { direction = newDirection; _updateMaterial(); +@export var characterBody:CharacterBody3D = null + func _ready() -> void: _updateMaterial(); @@ -63,16 +65,19 @@ func updateDirectionFromMovement(movement:Vector2) -> void: elif (movement.y < 0): direction = Direction.NORTH; -# func getDirectionToFace(position:Vector3) -> Direction: -# var diff = position - self.position; -# if abs(diff.x) > abs(diff.z): -# if diff.x > 0: -# return Direction.EAST; -# else: -# return Direction.WEST; -# else: -# if diff.z > 0: -# return Direction.SOUTH; -# else: -# return Direction.NORTH; -# return Direction.SOUTH; +func getDirectionToFace(position:Vector3) -> Direction: + if !characterBody: + return Direction.SOUTH; + + var diff = position - characterBody.position; + if abs(diff.x) > abs(diff.z): + if diff.x > 0: + return Direction.EAST; + else: + return Direction.WEST; + else: + if diff.z > 0: + return Direction.SOUTH; + else: + return Direction.NORTH; + return Direction.SOUTH; diff --git a/scripts/Entity/Component/EntityInteractable.gd b/scripts/Entity/Component/EntityInteractable.gd index 4619529..e9426b7 100644 --- a/scripts/Entity/Component/EntityInteractable.gd +++ b/scripts/Entity/Component/EntityInteractable.gd @@ -1,3 +1,10 @@ class_name EntityInteractable extends Node -signal entityOnInteract(entity:EntityInteractor); \ No newline at end of file +@export var entityDirection:EntityDirection = null +@export var entity:Entity = null +@export var characterBody:CharacterBody3D = null; + +signal onInteract(interactor:EntityInteractor, interactable:EntityInteractable) + +func interact(interactor:EntityInteractor) -> void: + onInteract.emit(interactor, self) \ No newline at end of file diff --git a/scripts/Entity/Component/EntityInteractor.gd b/scripts/Entity/Component/EntityInteractor.gd index 04ef3ce..b353654 100644 --- a/scripts/Entity/Component/EntityInteractor.gd +++ b/scripts/Entity/Component/EntityInteractor.gd @@ -1,4 +1,59 @@ class_name EntityInteractor extends Node -func tryInteract() -> EntityInteractable: - return null \ No newline at end of file +enum InteractorType { + PLAYER_INPUT, + UNDECIDED +} + +@export var interactorType:InteractorType = InteractorType.UNDECIDED; +@export var entityDirection:EntityDirection = null; +@export var characterBody:CharacterBody3D = null; +@export var interactRange = 0.7; +@export var entity:Entity = null +@export_flags_3d_physics() var interactLayers = 2; + +func interactWith(interactable:EntityInteractable) -> void: + interactable.interact(self) + pass + +func getRaycastInteractable() -> EntityInteractable: + if !entityDirection or !characterBody: + return null + + var rayDirection = entityDirection.getDirectionVector() + var query = PhysicsRayQueryParameters3D.create( + characterBody.position, + characterBody.position + (rayDirection * interactRange) + ) + query.collide_with_bodies = true; + query.collide_with_areas = true; + query.collision_mask = interactLayers; + query.exclude = [ characterBody ]; + + var result = characterBody.get_world_3d().direct_space_state.intersect_ray(query) + if !result or !result.collider: + return null + + var coll:Node3D = result.collider; + var interactable:EntityInteractable = coll.find_child("EntityInteractable") + return interactable + +func _process(delta: float) -> void: + match interactorType: + InteractorType.PLAYER_INPUT: + _processPlayerInput() + InteractorType.UNDECIDED: + _processUndecided() + _: + assert(false, "Invalid interactor type") + +func _processPlayerInput() -> void: + if !Input.is_action_just_pressed("interact"): + return + + var interactable:EntityInteractable = getRaycastInteractable() + if interactable: + self.interactWith(interactable) + +func _processUndecided() -> void: + pass \ No newline at end of file diff --git a/scripts/Entity/Rosa.gd b/scripts/Entity/Rosa.gd index 642b063..2937dde 100644 --- a/scripts/Entity/Rosa.gd +++ b/scripts/Entity/Rosa.gd @@ -1,27 +1 @@ class_name Rosa extends CharacterBody3D - - - -# var interactRange = 0.7; - -# func updateOverworldLogic(delta) -> void: -# # Check if interact button is pressed -# if(Input.is_action_just_pressed("interact")): -# var rayDirection = getDirectionVector(); -# # cast ray - -# var query = PhysicsRayQueryParameters3D.create( -# position, -# position + (rayDirection * interactRange) -# ) -# query.collide_with_areas = true -# query.exclude = [self] - -# var result = get_world_3d().direct_space_state.intersect_ray(query) -# if result and result.collider: -# var collider = result.collider -# if(collider.has_method("interact")): -# collider.interact(self) - -# if Input.is_action_just_pressed("pause"): -# PAUSE.playerPauseToggle(); diff --git a/scripts/Event/Entity/EventEntityTurn.gd b/scripts/Event/Entity/EventEntityTurn.gd index 430260d..e27ee33 100644 --- a/scripts/Event/Entity/EventEntityTurn.gd +++ b/scripts/Event/Entity/EventEntityTurn.gd @@ -1,6 +1,6 @@ class_name EventEntityTurn extends "res://scripts/Event/Event.gd" -@export var entity:Entity = null +@export var entity:EntityDirection = null @export var direction:EntityDirection.Direction = EntityDirection.Direction.SOUTH func start(): diff --git a/scripts/Event/Event.gd b/scripts/Event/Event.gd index ae5397b..442400f 100644 --- a/scripts/Event/Event.gd +++ b/scripts/Event/Event.gd @@ -2,11 +2,10 @@ class_name Event extends Node const Entity = preload("res://scripts/Entity/Entity.gd"); - var started:bool = false; var ended:bool = false; -var interactor:Entity = null -var interactee:Entity = null +var interactor:EntityInteractor = null +var interactee:EntityInteractable = null # Godot Methods func _init() -> void: @@ -43,8 +42,8 @@ func reset() -> void: interactee = null func onEntityInteract( - interactor:Entity, - interactee:Entity + interactor:EntityInteractor, + interactee:EntityInteractable ) -> void: self.reset() self.interactor = interactor diff --git a/scripts/Event/EventConversation.gd b/scripts/Event/EventConversation.gd index 31d49e6..f92d3c6 100644 --- a/scripts/Event/EventConversation.gd +++ b/scripts/Event/EventConversation.gd @@ -12,34 +12,39 @@ class_name EventConversation extends "res://scripts/Event/Flow/EventGroup.gd" func start() -> void: # Turn events - if interactee != null && interactor != null: - if pauseInteractee && turnInteractee: + if interactee && interactor: + if turnInteractee && interactee.entityDirection && interactor.characterBody: var turn = EventEntityTurn.new() - turn.entity = interactee - turn.direction = interactee.getDirectionToFace(interactor.position) + turn.entity = interactee.entityDirection + turn.direction = turn.entity.getDirectionToFace(interactor.characterBody.position) addExtraEvent(turn, 0) - if pauseInteractor && turnInteractor: + if turnInteractor && interactor.entityDirection && interactee.characterBody: var turn = EventEntityTurn.new() - turn.entity = interactor - turn.direction = interactor.getDirectionToFace(interactee.position) + turn.entity = interactor.entityDirection + turn.direction = turn.entity.getDirectionToFace(interactee.characterBody.position) addExtraEvent(turn, 0) # Create start pause event - var startPause = EventPause.new() - startPause.pauseType = startPauseType - startPause.entities = entities - startPause.includeInteractee = pauseInteractee - startPause.includeInteractor = pauseInteractor - addExtraEvent(startPause, 0) + if (pauseInteractee && interactee.entity) || (pauseInteractor && interactor.entity): + var startPause = EventPause.new() + startPause.pauseType = startPauseType + startPause.entities = entities + if pauseInteractee && interactee.entity: + startPause.includeInteractee = pauseInteractee + if pauseInteractor && interactor.entity: + startPause.includeInteractor = pauseInteractor + addExtraEvent(startPause, 0) - # Create end pause event. - var endPause = EventPause.new() - endPause.pauseType = endPauseType - endPause.entities = entities - endPause.includeInteractee = pauseInteractee - endPause.includeInteractor = pauseInteractor - addExtraEvent(endPause, -1) + # Create end pause event. + var endPause = EventPause.new() + endPause.pauseType = endPauseType + endPause.entities = entities + if pauseInteractee && interactee.entity: + endPause.includeInteractee = pauseInteractee + if pauseInteractor && interactor.entity: + endPause.includeInteractor = pauseInteractor + addExtraEvent(endPause, -1) # Pass off to event group - super.start() \ No newline at end of file + super.start() diff --git a/scripts/Event/EventPause.gd b/scripts/Event/EventPause.gd index 09e5132..0089308 100644 --- a/scripts/Event/EventPause.gd +++ b/scripts/Event/EventPause.gd @@ -9,8 +9,8 @@ const PauseSystem = preload("res://scripts/Singleton/Pause.gd") func start() -> void: var ents:Array[Entity] = entities - if interactor != null and includeInteractor: - ents.append(interactor) - if interactee != null and includeInteractee: - ents.append(interactee) + if interactor && includeInteractor && interactor.entity: + ents.append(interactor.entity) + if interactee && includeInteractee && interactee.entity: + ents.append(interactee.entity) PAUSE.pause(pauseType, ents) diff --git a/scripts/Singleton/Pause.gd b/scripts/Singleton/Pause.gd index 5256978..ee831ff 100644 --- a/scripts/Singleton/Pause.gd +++ b/scripts/Singleton/Pause.gd @@ -12,7 +12,7 @@ enum PauseType { }; var pauseType:PauseType = PauseType.NOT_PAUSED; -var entities:Array = []; +var entities:Array[Entity] = []; var playerPaused:bool = false; func getPauseState() -> PauseType: