From f46588004499b0cc928019885418bbf8d9e9b19a Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Fri, 9 May 2025 22:33:51 -0500 Subject: [PATCH] Rewrote entity system --- project.godot | 5 + scenes/Entities/Rosa.tscn | 34 +++- scenes/Entities/TestNPC.tscn | 26 ++- scenes/Maps/TestMap/TestMap.tscn | 9 +- scenes/Maps/TestMap/TestMapGround.tscn | 2 + scenes/UI/VNTextbox.tscn | 2 +- scripts/Entity/BasicNPCEntity.gd | 35 +--- scripts/Entity/Component/EntityDirection.gd | 78 +++++++++ .../Entity/Component/EntityDirection.gd.uid | 1 + scripts/Entity/Component/EntityMovement.gd | 77 +++++++++ .../Entity/Component/EntityMovement.gd.uid | 1 + scripts/Entity/Component/EntityMoving.gd.uid | 1 + scripts/Entity/Entity.gd | 88 ++++++++++ scripts/Entity/Entity.gd.uid | 1 + scripts/Entity/MovingEntity.gd.uid | 1 + scripts/Entity/OverworldEntity.gd | 160 ------------------ scripts/Entity/Rosa.gd | 27 +++ .../{RosaController.gd.uid => Rosa.gd.uid} | 0 scripts/Entity/RosaCamera.gd | 2 +- scripts/Entity/RosaController.gd | 57 ------- scripts/Event/Entity/EventEntityTurn.gd | 6 +- scripts/Event/Event.gd | 10 +- scripts/Event/EventConversation.gd | 2 +- scripts/Event/EventPause.gd | 4 +- scripts/Quest/Quest.gd | 5 +- scripts/Quest/QuestObjective.gd | 12 +- scripts/Sign.gd.uid | 1 + scripts/Singleton/Quest.gd | 7 +- scripts/UI/QuestMenu.gd | 2 +- 29 files changed, 372 insertions(+), 284 deletions(-) create mode 100644 scripts/Entity/Component/EntityDirection.gd create mode 100644 scripts/Entity/Component/EntityDirection.gd.uid create mode 100644 scripts/Entity/Component/EntityMovement.gd create mode 100644 scripts/Entity/Component/EntityMovement.gd.uid create mode 100644 scripts/Entity/Component/EntityMoving.gd.uid create mode 100644 scripts/Entity/Entity.gd create mode 100644 scripts/Entity/Entity.gd.uid create mode 100644 scripts/Entity/MovingEntity.gd.uid delete mode 100644 scripts/Entity/OverworldEntity.gd create mode 100644 scripts/Entity/Rosa.gd rename scripts/Entity/{RosaController.gd.uid => Rosa.gd.uid} (100%) delete mode 100644 scripts/Entity/RosaController.gd create mode 100644 scripts/Sign.gd.uid diff --git a/project.godot b/project.godot index 813bff6..2182e6a 100644 --- a/project.godot +++ b/project.godot @@ -106,6 +106,11 @@ run={ ] } +[layer_names] + +3d_physics/layer_2="Overworld Entities" +3d_physics/layer_9="Overworld Solid" + [rendering] textures/canvas_textures/default_texture_filter=0 diff --git a/scenes/Entities/Rosa.tscn b/scenes/Entities/Rosa.tscn index c00bac5..e3da052 100644 --- a/scenes/Entities/Rosa.tscn +++ b/scenes/Entities/Rosa.tscn @@ -1,8 +1,11 @@ -[gd_scene load_steps=8 format=3 uid="uid://yhtpoum3eek7"] +[gd_scene load_steps=11 format=3 uid="uid://yhtpoum3eek7"] -[ext_resource type="Script" uid="uid://ixwikdguyhf0" path="res://scripts/Entity/RosaController.gd" id="1_3g383"] +[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"] [ext_resource type="Script" uid="uid://jd50n00bo05y" path="res://scripts/Entity/RosaCamera.gd" id="2_tr66j"] +[ext_resource type="Script" uid="uid://cjfcpi7sxentf" path="res://scripts/Entity/Component/EntityDirection.gd" id="2_vcxxc"] [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"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_ls7r8"] @@ -17,13 +20,34 @@ shader = ExtResource("3_j5vis") shader_parameter/npcTexture = ExtResource("4_rvn3n") shader_parameter/color = Color(1, 1, 1, 1) shader_parameter/frame = 0 -shader_parameter/direction = 1 +shader_parameter/direction = 2 [node name="Rosa" type="CharacterBody3D"] -script = ExtResource("1_3g383") +collision_layer = 2 +collision_mask = 258 +script = ExtResource("1_r5ufg") +metadata/_custom_type_script = "uid://ixwikdguyhf0" + +[node name="Entity" type="Node" parent="."] +script = ExtResource("1_rvn3n") +metadata/_custom_type_script = "uid://dtjjqp2atjyhr" + +[node name="EntityDirection" type="Node" parent="Entity" node_paths=PackedStringArray("meshInstance")] +script = ExtResource("2_vcxxc") +meshInstance = NodePath("../../MeshInstance3D") +direction = 2 +metadata/_custom_type_script = "uid://cjfcpi7sxentf" + +[node name="EntityMoving" type="Node" parent="Entity" node_paths=PackedStringArray("characterBody", "entity", "entityDirection")] +script = ExtResource("4_7s3uq") +characterBody = NodePath("../..") +entity = NodePath("..") +entityDirection = NodePath("../EntityDirection") +movementType = 0 [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 fov = 30.0 script = ExtResource("2_tr66j") follow = NodePath("..") @@ -32,6 +56,6 @@ follow = NodePath("..") shape = SubResource("CapsuleShape3D_ls7r8") [node name="MeshInstance3D" type="MeshInstance3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 0.173648, 0.984808, 0, -0.984808, 0.173648, 0.00989294, 0, 0) +transform = Transform3D(1, 0, 0, 0, 0.173648, 0.984808, 0, -0.984808, 0.173648, 0, 0, 0) mesh = SubResource("QuadMesh_dyaax") surface_material_override/0 = SubResource("ShaderMaterial_fegux") diff --git a/scenes/Entities/TestNPC.tscn b/scenes/Entities/TestNPC.tscn index d7fe00d..95a4d4b 100644 --- a/scenes/Entities/TestNPC.tscn +++ b/scenes/Entities/TestNPC.tscn @@ -1,7 +1,10 @@ -[gd_scene load_steps=7 format=3 uid="uid://dr4b2pmsknuhc"] +[gd_scene load_steps=10 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"] +[ext_resource type="Script" uid="uid://dtjjqp2atjyhr" path="res://scripts/Entity/Entity.gd" id="2_ehu3x"] +[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"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_dw1sy"] @@ -16,10 +19,29 @@ shader = ExtResource("1_xgcv1") shader_parameter/npcTexture = ExtResource("4_vo0ku") shader_parameter/color = Color(0, 0.563816, 0, 1) shader_parameter/frame = 0 -shader_parameter/direction = 1 +shader_parameter/direction = 0 [node name="TestNpc" type="CharacterBody3D"] +collision_layer = 2 +collision_mask = 258 script = ExtResource("1_1muh7") +metadata/_custom_type_script = "uid://d23qg1ovkbxst" + +[node name="Entity" type="Node" parent="."] +script = ExtResource("2_ehu3x") +metadata/_custom_type_script = "uid://dtjjqp2atjyhr" + +[node name="EntityDirection" type="Node" parent="Entity" node_paths=PackedStringArray("meshInstance")] +script = ExtResource("3_gyi1p") +meshInstance = NodePath("../../MeshInstance3D") +metadata/_custom_type_script = "uid://cjfcpi7sxentf" + +[node name="EntityMoving" type="Node" parent="Entity" node_paths=PackedStringArray("characterBody", "entity", "entityDirection")] +script = ExtResource("4_3wesq") +characterBody = NodePath("../..") +entity = NodePath("..") +entityDirection = NodePath("../EntityDirection") +movementType = 2 [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 15214e1..3aac610 100644 --- a/scenes/Maps/TestMap/TestMap.tscn +++ b/scenes/Maps/TestMap/TestMap.tscn @@ -32,11 +32,8 @@ 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="." node_paths=PackedStringArray("interactEvent") instance=ExtResource("2_cg1ph")] +[node name="Green" parent="." 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") -moveType = 1 -direction = 1 [node name="OmniLight3D" type="OmniLight3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7.20244, 3.80554) @@ -52,9 +49,13 @@ metadata/_edit_lock_ = true [node name="Building2" parent="Map" instance=ExtResource("4_brp0k")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.13514, 2.62692, -0.0984068) +collision_layer = 256 +collision_mask = 2 [node name="Building" parent="Map" instance=ExtResource("4_brp0k")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.92766, 2.37929, -4.38178) +collision_layer = 256 +collision_mask = 2 [node name="Events" type="Node" parent="."] diff --git a/scenes/Maps/TestMap/TestMapGround.tscn b/scenes/Maps/TestMap/TestMapGround.tscn index 8eda50a..3821439 100644 --- a/scenes/Maps/TestMap/TestMapGround.tscn +++ b/scenes/Maps/TestMap/TestMapGround.tscn @@ -17,6 +17,8 @@ shader_parameter/tileset = ExtResource("2_3bnhs") size = Vector3(50, 0.1, 50) [node name="Ground" type="StaticBody3D"] +collision_layer = 256 +collision_mask = 2 metadata/_edit_lock_ = true [node name="MeshInstance3D" type="MeshInstance3D" parent="."] diff --git a/scenes/UI/VNTextbox.tscn b/scenes/UI/VNTextbox.tscn index dcfa7de..6a379f1 100644 --- a/scenes/UI/VNTextbox.tscn +++ b/scenes/UI/VNTextbox.tscn @@ -8,7 +8,7 @@ anchors_preset = 12 anchor_top = 1.0 anchor_right = 1.0 anchor_bottom = 1.0 -offset_top = -60.0 +offset_top = -50.0 grow_horizontal = 2 grow_vertical = 0 theme = ExtResource("1_wx4lp") diff --git a/scripts/Entity/BasicNPCEntity.gd b/scripts/Entity/BasicNPCEntity.gd index 49af713..5450f31 100644 --- a/scripts/Entity/BasicNPCEntity.gd +++ b/scripts/Entity/BasicNPCEntity.gd @@ -1,34 +1 @@ -class_name BasicNPCEntity extends "res://scripts/Entity/OverworldEntity.gd" -const Event = preload("res://scripts/Event/Event.gd"); - -enum BasicNPCMoveType { - STILL, - RANDOM_LOOK -}; - -@export var interactEvent:Event; - -@export var moveType:BasicNPCMoveType = BasicNPCMoveType.STILL; - -@export var randomLookMinTime:float = 1.5; -@export var randomLookMaxTime:float = 4.0; -var randomLookTimer:float = 0.0; - -func interact(interactor:OverworldEntity) -> void: - if interactEvent == null: - push_error("BasicNPCEntity: interactType EVENT but no event set"); - return - interactEvent.onEntityInteract(interactor, self); - -func updateMovement(delta:float) -> void: - if moveType == BasicNPCMoveType.STILL: - return - - if moveType == BasicNPCMoveType.RANDOM_LOOK: - randomLookTimer -= delta; - if randomLookTimer <= 0: - randomLookTimer = randf_range(randomLookMinTime, randomLookMaxTime); - self.direction = randi_range(0, 3); - return - - pass +class_name BasicNPCEntity extends CharacterBody3D diff --git a/scripts/Entity/Component/EntityDirection.gd b/scripts/Entity/Component/EntityDirection.gd new file mode 100644 index 0000000..c8fe075 --- /dev/null +++ b/scripts/Entity/Component/EntityDirection.gd @@ -0,0 +1,78 @@ +@tool +class_name EntityDirection extends Node + +enum Direction { + SOUTH, + WEST, + NORTH, + EAST, +} + +@export var meshInstance:MeshInstance3D = null: + set(newInstance): + meshInstance = newInstance; + _updateMaterial(); + +@export var direction = Direction.SOUTH: + set(newDirection): + direction = newDirection; + _updateMaterial(); + +func _ready() -> void: + _updateMaterial(); + +func _updateMaterial() -> void: + if !meshInstance: + return + + for i in range(meshInstance.get_surface_override_material_count()): + var material:ShaderMaterial = meshInstance.get_surface_override_material(i) + if !material: + continue + material.set_shader_parameter("direction", direction) + +func getDirectionVector() -> Vector3: + match direction: + Direction.NORTH: + return Vector3(0, 0, -1); + Direction.SOUTH: + return Vector3(0, 0, 1); + Direction.WEST: + return Vector3(-1, 0, 0); + Direction.EAST: + return Vector3(1, 0, 0); + _: + assert(false, "Invalid direction"); + return Vector3(0, 0, 0); + +func updateDirectionFromMovement(movement:Vector2) -> void: + if movement.x >= abs(movement.y) and( + movement.y == 0 or + (movement.y > 0 and direction != Direction.SOUTH) or + (movement.y < 0 and direction != Direction.NORTH) + ): + direction = Direction.EAST; + elif (movement.x <= -abs(movement.y) and ( + movement.y == 0 or + (movement.y > 0 and direction != Direction.SOUTH) or + (movement.y < 0 and direction != Direction.NORTH) + )): + direction = Direction.WEST; + elif (movement.y > 0): + direction = Direction.SOUTH; + 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; diff --git a/scripts/Entity/Component/EntityDirection.gd.uid b/scripts/Entity/Component/EntityDirection.gd.uid new file mode 100644 index 0000000..de4bfc5 --- /dev/null +++ b/scripts/Entity/Component/EntityDirection.gd.uid @@ -0,0 +1 @@ +uid://cjfcpi7sxentf diff --git a/scripts/Entity/Component/EntityMovement.gd b/scripts/Entity/Component/EntityMovement.gd new file mode 100644 index 0000000..34cae79 --- /dev/null +++ b/scripts/Entity/Component/EntityMovement.gd @@ -0,0 +1,77 @@ +class_name EntityMovement extends Node + +enum MovementType { + PLAYER_INPUT, + STILL, + NPC_RANDOM_LOOK +}; + +@export var characterBody:CharacterBody3D = null; +@export var entity:Entity = null; +@export var entityDirection:EntityDirection = null; + +@export var speed:float = 200; +@export var runSpeed:float = 400; +@export var friction:float = 8.5; +@export var gravity:float = 30; + +@export var movementType:MovementType = MovementType.STILL; + +@export var randomLookMinTime:float = 1.5; +@export var randomLookMaxTime:float = 4.0; +var randomLookTimer:float = 0.0; + +func _physics_process(delta:float) -> void: + if !entity || entity.isPaused() || !characterBody: + return; + + # Update movement + _updateVelocity(delta) + + # Gravity and friction + if !characterBody.is_on_floor(): + characterBody.velocity.y -= gravity * delta; + else: + characterBody.velocity += -(characterBody.velocity * friction * delta); + # if velocity.length() != 0: + # _updateTileData(); + + # Update character controller. + characterBody.move_and_slide(); + +func _updateVelocity(delta:float): + match movementType: + MovementType.PLAYER_INPUT: + _updatePlayerInput(delta); + MovementType.STILL: + _updateStill(delta); + MovementType.NPC_RANDOM_LOOK: + _updateNPCRandomLook(delta); + +func _updatePlayerInput(delta:float) -> void: + var dir:Vector2 = Input.get_vector("left", "right", "up", "down"); + + var moveSpeed:float; + if Input.is_action_pressed("run"): + moveSpeed = runSpeed; + else: + moveSpeed = speed; + + if dir.x != 0 or dir.y != 0: + characterBody.velocity.x = dir.x * moveSpeed * delta; + characterBody.velocity.z = dir.y * moveSpeed * delta; + + if entityDirection: + entityDirection.updateDirectionFromMovement(dir); + +func _updateStill(delta:float): + pass + +func _updateNPCRandomLook(delta:float): + if !entityDirection: + return + randomLookTimer -= delta; + + if randomLookTimer <= 0: + randomLookTimer = randf_range(randomLookMinTime, randomLookMaxTime); + entityDirection.direction = randi_range(0, 3); diff --git a/scripts/Entity/Component/EntityMovement.gd.uid b/scripts/Entity/Component/EntityMovement.gd.uid new file mode 100644 index 0000000..ab0a58c --- /dev/null +++ b/scripts/Entity/Component/EntityMovement.gd.uid @@ -0,0 +1 @@ +uid://c5nfs0m6ua4eb diff --git a/scripts/Entity/Component/EntityMoving.gd.uid b/scripts/Entity/Component/EntityMoving.gd.uid new file mode 100644 index 0000000..12508f0 --- /dev/null +++ b/scripts/Entity/Component/EntityMoving.gd.uid @@ -0,0 +1 @@ +uid://dp6itsmbl0ucn diff --git a/scripts/Entity/Entity.gd b/scripts/Entity/Entity.gd new file mode 100644 index 0000000..d5dd433 --- /dev/null +++ b/scripts/Entity/Entity.gd @@ -0,0 +1,88 @@ +class_name Entity extends Node + +# var meshInstance:MeshInstance3D; +# var underFootTile:int = -1; +# var underFootPosition:Vector3; +# var material:ShaderMaterial; + +# func updateMaterial() -> bool: +# if !meshInstance: +# return false +# if !material: +# return false +# return true + +# # Virtual Methods +# func updateMovement(delta) -> void: +# pass + +# func updateOverworldLogic(delta) -> void: +# pass + +func isPaused() -> bool: + var ps = PAUSE.getPauseState(); + match ps: + PauseSystem.PauseType.NOT_PAUSED: + return false; + PauseSystem.PauseType.FULLY_PAUSED: + return true; + PauseSystem.PauseType.ENTITY_PAUSED: + if PAUSE.entities.find(self) != -1: + return true; + return false; + PauseSystem.PauseType.CUTSCENE_PAUSED: + if PAUSE.entities.find(self) != -1: + return false; + return true; + _: + assert(false, "Invalid pause state"); + + return false; + +# Private methods +# func _updateTileData() -> void: +# # ray cast down +# var offset = Vector3(0, 0, 0.426); +# var query = PhysicsRayQueryParameters3D.create( +# position + offset, +# position + Vector3(0, -1, 0) + offset +# ) +# query.collide_with_areas = true +# query.exclude = [self] + +# var result = get_world_3d().direct_space_state.intersect_ray(query) +# if !result or !result.collider: +# return; + +# var collider = result.collider; +# var colliderMesh = collider.get_node("../"); +# if !colliderMesh or !(colliderMesh is ArrayMesh) or !colliderMesh.mesh or colliderMesh.mesh.get_surface_count() == 0: +# return; + +# # Get the face index (triangle) +# var arrays = colliderMesh.mesh.surface_get_arrays(0); +# var indiceIdx = result.face_index * 3; + +# # Get each indice of the triangle +# var index0 = arrays[Mesh.ARRAY_INDEX][indiceIdx+0]; +# var index1 = arrays[Mesh.ARRAY_INDEX][indiceIdx+1]; +# var index2 = arrays[Mesh.ARRAY_INDEX][indiceIdx+2]; + +# # Get each uv of each indice +# var uv0:Vector2 = arrays[Mesh.ARRAY_TEX_UV][index0]; +# var uv1:Vector2 = arrays[Mesh.ARRAY_TEX_UV][index1]; +# var uv2:Vector2 = arrays[Mesh.ARRAY_TEX_UV][index2]; + +# # Determine the lowest texture coordinate +# var min = Vector2(min(uv0.x, uv1.x, uv2.x), min(uv0.y, uv1.y, uv2.y)); + +# # Convert to column/row +# var w = 256; +# var h = w; +# var tw = 48; +# var th = tw; +# var column = int(roundf(min.x * w)) / tw; +# var row = int(roundf(min.y * h)) / th; +# var columns = 768 / tw; +# underFootPosition = result.position; +# underFootTile = column % columns + row * columns; diff --git a/scripts/Entity/Entity.gd.uid b/scripts/Entity/Entity.gd.uid new file mode 100644 index 0000000..f416ee6 --- /dev/null +++ b/scripts/Entity/Entity.gd.uid @@ -0,0 +1 @@ +uid://dtjjqp2atjyhr diff --git a/scripts/Entity/MovingEntity.gd.uid b/scripts/Entity/MovingEntity.gd.uid new file mode 100644 index 0000000..c0b10cc --- /dev/null +++ b/scripts/Entity/MovingEntity.gd.uid @@ -0,0 +1 @@ +uid://bcei5b2x3gu8y diff --git a/scripts/Entity/OverworldEntity.gd b/scripts/Entity/OverworldEntity.gd deleted file mode 100644 index f202060..0000000 --- a/scripts/Entity/OverworldEntity.gd +++ /dev/null @@ -1,160 +0,0 @@ -class_name OverworldEntity extends CharacterBody3D - -enum Direction { - SOUTH, - WEST, - NORTH, - EAST, -} - -var speed:float = 200; -var runSpeed:float = 400; -var friction:float = 8.5; -var gravity:float = 30; - -@export var direction = Direction.SOUTH: - set(newDirection): - direction = newDirection; - _updateMaterial(); - -var meshInstance:MeshInstance3D; -var underFootTile:int = -1; -var underFootPosition:Vector3; - -func _updateMaterial(): - if !meshInstance: - return - var material:ShaderMaterial = meshInstance.get_surface_override_material(0) - if !material: - return - material.set_shader_parameter("direction", direction) - -func getDirectionVector() -> Vector3: - match direction: - Direction.NORTH: - return Vector3(0, 0, -1); - Direction.SOUTH: - return Vector3(0, 0, 1); - Direction.WEST: - return Vector3(-1, 0, 0); - Direction.EAST: - return Vector3(1, 0, 0); - return Vector3(0, 0, 0); - -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; - -# Virtual Methods -func updateMovement(delta) -> void: - pass - -func updateOverworldLogic(delta) -> void: - pass - -func isPaused() -> bool: - var ps = PAUSE.getPauseState(); - - if ps == PauseSystem.PauseType.NOT_PAUSED: - return false; - elif ps == PauseSystem.PauseType.FULLY_PAUSED: - return true; - elif ps == PauseSystem.PauseType.ENTITY_PAUSED: - if PAUSE.entities.find(self) != -1: - return true; - return false - elif ps == PauseSystem.PauseType.CUTSCENE_PAUSED: - if PAUSE.entities.find(self) != -1: - return false; - return true; - return false; - -# Private methods -func _updateTileData() -> void: - # ray cast down - var offset = Vector3(0, 0, 0.426); - var query = PhysicsRayQueryParameters3D.create( - position + offset, - position + Vector3(0, -1, 0) + offset - ) - query.collide_with_areas = true - query.exclude = [self] - - var result = get_world_3d().direct_space_state.intersect_ray(query) - if !result or !result.collider: - return; - - var collider = result.collider; - var colliderMesh = collider.get_node("../"); - if !colliderMesh or !(colliderMesh is ArrayMesh) or !colliderMesh.mesh or colliderMesh.mesh.get_surface_count() == 0: - return; - - # Get the face index (triangle) - var arrays = colliderMesh.mesh.surface_get_arrays(0); - var indiceIdx = result.face_index * 3; - - # Get each indice of the triangle - var index0 = arrays[Mesh.ARRAY_INDEX][indiceIdx+0]; - var index1 = arrays[Mesh.ARRAY_INDEX][indiceIdx+1]; - var index2 = arrays[Mesh.ARRAY_INDEX][indiceIdx+2]; - - # Get each uv of each indice - var uv0:Vector2 = arrays[Mesh.ARRAY_TEX_UV][index0]; - var uv1:Vector2 = arrays[Mesh.ARRAY_TEX_UV][index1]; - var uv2:Vector2 = arrays[Mesh.ARRAY_TEX_UV][index2]; - - # Determine the lowest texture coordinate - var min = Vector2(min(uv0.x, uv1.x, uv2.x), min(uv0.y, uv1.y, uv2.y)); - - # Convert to column/row - var w = 256; - var h = w; - var tw = 48; - var th = tw; - var column = int(roundf(min.x * w)) / tw; - var row = int(roundf(min.y * h)) / th; - var columns = 768 / tw; - underFootPosition = result.position; - underFootTile = column % columns + row * columns; - -# Events -func _ready() -> void: - meshInstance = get_node("MeshInstance3D") - _updateTileData(); - _updateMaterial(); - pass - -func _process(delta:float) -> void: - if isPaused(): - return; - - # Update logic - updateOverworldLogic(delta) - -func _physics_process(delta: float) -> void: - if isPaused(): - return; - - # Update movement - updateMovement(delta); - - # Gravity and friction - if !is_on_floor(): - velocity.y -= gravity * delta; - else: - velocity += -(velocity * friction * delta); - if velocity.length() != 0: - _updateTileData(); - - # Update character controller. - move_and_slide(); diff --git a/scripts/Entity/Rosa.gd b/scripts/Entity/Rosa.gd new file mode 100644 index 0000000..642b063 --- /dev/null +++ b/scripts/Entity/Rosa.gd @@ -0,0 +1,27 @@ +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/Entity/RosaController.gd.uid b/scripts/Entity/Rosa.gd.uid similarity index 100% rename from scripts/Entity/RosaController.gd.uid rename to scripts/Entity/Rosa.gd.uid diff --git a/scripts/Entity/RosaCamera.gd b/scripts/Entity/RosaCamera.gd index 190ab84..10980ef 100644 --- a/scripts/Entity/RosaCamera.gd +++ b/scripts/Entity/RosaCamera.gd @@ -1,7 +1,7 @@ extends Camera3D @export var pixelScale:float = 1.0; -@export var follow:Node; +@export var follow:Node3D; const WORLD_UNITS:float = 32.0; diff --git a/scripts/Entity/RosaController.gd b/scripts/Entity/RosaController.gd deleted file mode 100644 index f2c4922..0000000 --- a/scripts/Entity/RosaController.gd +++ /dev/null @@ -1,57 +0,0 @@ -class_name RosaController extends "res://scripts/Entity/OverworldEntity.gd" - -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(); - -func updateMovement(delta) -> void: - # User movement - var dir:Vector2 = Input.get_vector("left", "right", "up", "down"); - - var moveSpeed:float; - if Input.is_action_pressed("run"): - moveSpeed = runSpeed; - else: - moveSpeed = speed; - - if(dir.x != 0 or dir.y != 0): - velocity.x = dir.x * moveSpeed * delta; - velocity.z = dir.y * moveSpeed * delta; - - # Update direction - if(dir.x >= abs(dir.y) and( - dir.y == 0 or - (dir.y > 0 and direction != Direction.SOUTH) or - (dir.y < 0 and direction != Direction.NORTH) - )): - direction = Direction.EAST; - elif (dir.x <= -abs(dir.y) and ( - dir.y == 0 or - (dir.y > 0 and direction != Direction.SOUTH) or - (dir.y < 0 and direction != Direction.NORTH) - )): - direction = Direction.WEST; - elif (dir.y > 0): - direction = Direction.SOUTH; - elif (dir.y < 0): - direction = Direction.NORTH; diff --git a/scripts/Event/Entity/EventEntityTurn.gd b/scripts/Event/Entity/EventEntityTurn.gd index 744688a..430260d 100644 --- a/scripts/Event/Entity/EventEntityTurn.gd +++ b/scripts/Event/Entity/EventEntityTurn.gd @@ -1,9 +1,9 @@ class_name EventEntityTurn extends "res://scripts/Event/Event.gd" -@export var entity:OverworldEntity = null -@export var direction:OverworldEntity.Direction = OverworldEntity.Direction.SOUTH +@export var entity:Entity = null +@export var direction:EntityDirection.Direction = EntityDirection.Direction.SOUTH func start(): if entity == null: return - entity.direction = direction \ No newline at end of file + entity.direction = direction diff --git a/scripts/Event/Event.gd b/scripts/Event/Event.gd index c6df206..ae5397b 100644 --- a/scripts/Event/Event.gd +++ b/scripts/Event/Event.gd @@ -1,12 +1,12 @@ class_name Event extends Node -const OverworldEntity = preload("res://scripts/Entity/OverworldEntity.gd"); +const Entity = preload("res://scripts/Entity/Entity.gd"); var started:bool = false; var ended:bool = false; -var interactor:OverworldEntity = null -var interactee:OverworldEntity = null +var interactor:Entity = null +var interactee:Entity = null # Godot Methods func _init() -> void: @@ -43,8 +43,8 @@ func reset() -> void: interactee = null func onEntityInteract( - interactor:OverworldEntity, - interactee:OverworldEntity + interactor:Entity, + interactee:Entity ) -> void: self.reset() self.interactor = interactor diff --git a/scripts/Event/EventConversation.gd b/scripts/Event/EventConversation.gd index c22910a..31d49e6 100644 --- a/scripts/Event/EventConversation.gd +++ b/scripts/Event/EventConversation.gd @@ -3,7 +3,7 @@ class_name EventConversation extends "res://scripts/Event/Flow/EventGroup.gd" @export var startPauseType:PauseSystem.PauseType = PauseSystem.PauseType.ENTITY_PAUSED @export var endPauseType:PauseSystem.PauseType = PauseSystem.PauseType.NOT_PAUSED -@export var entities:Array[OverworldEntity] = [] +@export var entities:Array[Entity] = [] @export var pauseInteractee:bool = true @export var pauseInteractor:bool = true diff --git a/scripts/Event/EventPause.gd b/scripts/Event/EventPause.gd index 168c25f..09e5132 100644 --- a/scripts/Event/EventPause.gd +++ b/scripts/Event/EventPause.gd @@ -3,12 +3,12 @@ class_name EventPause extends "res://scripts/Event/Event.gd" const PauseSystem = preload("res://scripts/Singleton/Pause.gd") @export var pauseType:PauseSystem.PauseType = PauseSystem.PauseType.ENTITY_PAUSED -@export var entities:Array[OverworldEntity] = [] +@export var entities:Array[Entity] = [] @export var includeInteractee:bool = true @export var includeInteractor:bool = true func start() -> void: - var ents:Array[OverworldEntity] = entities + var ents:Array[Entity] = entities if interactor != null and includeInteractor: ents.append(interactor) if interactee != null and includeInteractee: diff --git a/scripts/Quest/Quest.gd b/scripts/Quest/Quest.gd index 9057b0b..c58b17a 100644 --- a/scripts/Quest/Quest.gd +++ b/scripts/Quest/Quest.gd @@ -13,12 +13,13 @@ func _ready() -> void: for child in get_children(): if child is QuestObjective: objectives.append(child) + child.onQuestReady(self) func start() -> void: questStarted = true questComplete = false - QUEST.questStarted.emit(questKey) - QUEST.questUpdated.emit(questKey) + QUEST.questStarted.emit(self) + QUEST.questUpdated.emit(self) func isCompleted() -> bool: return questComplete diff --git a/scripts/Quest/QuestObjective.gd b/scripts/Quest/QuestObjective.gd index 2384fe6..0efbec2 100644 --- a/scripts/Quest/QuestObjective.gd +++ b/scripts/Quest/QuestObjective.gd @@ -1,7 +1,13 @@ class_name QuestObjective extends Node -# enum Type { -# } +enum Type { + Item, +} @export var objectiveName:String = "Some objective" -# @export var objectiveType:Type = Type.Item \ No newline at end of file +@export var objectiveType:Type = Type.Item + +var quest:Quest + +func onQuestReady(quest:Quest) -> void: + self.quest = quest \ No newline at end of file diff --git a/scripts/Sign.gd.uid b/scripts/Sign.gd.uid new file mode 100644 index 0000000..ed987e7 --- /dev/null +++ b/scripts/Sign.gd.uid @@ -0,0 +1 @@ +uid://cctqgee7dumwg diff --git a/scripts/Singleton/Quest.gd b/scripts/Singleton/Quest.gd index 948d397..5656045 100644 --- a/scripts/Singleton/Quest.gd +++ b/scripts/Singleton/Quest.gd @@ -6,9 +6,10 @@ enum QuestKey { var quests:Dictionary[int, Quest] -signal questStarted(questKey:QuestKey) -signal questUpdated(questKey:QuestKey) -signal questCompleted(questKey:QuestKey) +signal questStarted(quest:Quest) +signal questUpdated(quest:Quest) +signal questCompleted(quest:Quest) +# signal questObjectiveCompleted(quest:Quest, objective:QuestObjective) func _ready() -> void: _updateQuests() diff --git a/scripts/UI/QuestMenu.gd b/scripts/UI/QuestMenu.gd index 834f1b3..cd02ad0 100644 --- a/scripts/UI/QuestMenu.gd +++ b/scripts/UI/QuestMenu.gd @@ -100,7 +100,7 @@ func _onQuestSelected(index:int) -> void: func _onQuestObjectiveSelected(index:int) -> void: setQuestObjective(index) -func _onQuestUpdated(questKey:QuestSystem.QuestKey) -> void: +func _onQuestUpdated(_q:Quest) -> void: _updateQuestList() func _onCloseClicked() -> void: