beta-1.0
This commit is contained in:
33
Scripts/Characters/Chicken/npc_chicken.gd
Normal file
33
Scripts/Characters/Chicken/npc_chicken.gd
Normal file
@@ -0,0 +1,33 @@
|
||||
extends CharacterBody2D
|
||||
|
||||
enum States {
|
||||
IDLE,
|
||||
PECKING
|
||||
}
|
||||
|
||||
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D
|
||||
|
||||
var current_state := States.IDLE
|
||||
var pecking_sched := randf_range(8.0, 25.0)
|
||||
var pecking_timer := 0.0
|
||||
|
||||
func _ready() -> void:
|
||||
_print_sched()
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if current_state == States.IDLE:
|
||||
pecking_timer += delta
|
||||
if pecking_timer >= pecking_sched:
|
||||
current_state = States.PECKING
|
||||
animated_sprite_2d.play("pecking")
|
||||
await animated_sprite_2d.animation_finished
|
||||
animated_sprite_2d.play("idle")
|
||||
pecking_sched = randf_range(8.0, 25.0)
|
||||
pecking_timer = 0
|
||||
current_state = States.IDLE
|
||||
_print_sched()
|
||||
|
||||
|
||||
func _print_sched() -> void:
|
||||
print("%s Pecking Schedule: %f" % [name, pecking_sched])
|
||||
1
Scripts/Characters/Chicken/npc_chicken.gd.uid
Normal file
1
Scripts/Characters/Chicken/npc_chicken.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c5pt6iroi01si
|
||||
@@ -0,0 +1,10 @@
|
||||
extends Node
|
||||
|
||||
@export var state_machine: PlayerStateMachine
|
||||
|
||||
# Public Methods
|
||||
func OnMovementInput(_movement_vector: Vector2) -> void:
|
||||
var current_state := state_machine.GetCurrentStateEnum()
|
||||
if current_state == PlayerStateMachine.States.IDLE:
|
||||
var idle_state := state_machine.current_state as PlayerIdleState
|
||||
idle_state.QueueMovement()
|
||||
@@ -0,0 +1 @@
|
||||
uid://ctoxjn2rvtjs6
|
||||
33
Scripts/Characters/Player/States/base_state.gd
Normal file
33
Scripts/Characters/Player/States/base_state.gd
Normal file
@@ -0,0 +1,33 @@
|
||||
class_name BaseState
|
||||
extends Node
|
||||
|
||||
@export var state_machine: PlayerStateMachine
|
||||
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
push_error("Unimplemented Method: BaseState.GetName")
|
||||
return PlayerStateMachine.States.IDLE
|
||||
|
||||
|
||||
func GetAnimationBaseName() -> String:
|
||||
var state: String = PlayerStateMachine.States.keys()[GetStateEnum()]
|
||||
return state.to_lower()
|
||||
|
||||
|
||||
func Enter(_extra_parameters: Dictionary) -> void:
|
||||
pass
|
||||
|
||||
|
||||
func Exit() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func Update(_delta: float) -> void:
|
||||
pass
|
||||
|
||||
|
||||
func IsActive() -> bool:
|
||||
return state_machine.GetCurrentStateEnum() == GetStateEnum()
|
||||
|
||||
|
||||
func IsStateActionable() -> bool:
|
||||
return true
|
||||
1
Scripts/Characters/Player/States/base_state.gd.uid
Normal file
1
Scripts/Characters/Player/States/base_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cb57l5vpq5bee
|
||||
29
Scripts/Characters/Player/States/cutscene_state.gd
Normal file
29
Scripts/Characters/Player/States/cutscene_state.gd
Normal file
@@ -0,0 +1,29 @@
|
||||
extends BaseState
|
||||
class_name PlayerCutsceneState
|
||||
|
||||
@onready var interact_scanner: InteractScanner = $"../../../Marker2D/InteractScanner"
|
||||
|
||||
# Public Methods
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
return PlayerStateMachine.States.CUTSCENE
|
||||
|
||||
|
||||
func GetAnimationBaseName() -> String:
|
||||
return "idle"
|
||||
|
||||
|
||||
func Enter(_extra_parameters: Dictionary) -> void:
|
||||
print("Cutscene Started")
|
||||
interact_scanner.disable_interactions = true
|
||||
|
||||
|
||||
func Exit() -> void:
|
||||
interact_scanner.disable_interactions = false
|
||||
|
||||
|
||||
func OnCutsceneEnded() -> void:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.IDLE)
|
||||
|
||||
|
||||
func IsStateActionable() -> bool:
|
||||
return false
|
||||
1
Scripts/Characters/Player/States/cutscene_state.gd.uid
Normal file
1
Scripts/Characters/Player/States/cutscene_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bnontuqj3cnom
|
||||
37
Scripts/Characters/Player/States/drawing_bow_state.gd
Normal file
37
Scripts/Characters/Player/States/drawing_bow_state.gd
Normal file
@@ -0,0 +1,37 @@
|
||||
extends BaseState
|
||||
|
||||
signal PlayerBeganDrawingBow
|
||||
|
||||
@export var strafing_speed := 35
|
||||
@export var movement_componenent: MovementComponent
|
||||
@export var body: CharacterBody2D
|
||||
|
||||
var used_item_action: String
|
||||
var animation_finished := false
|
||||
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
return PlayerStateMachine.States.DRAWING_BOW
|
||||
|
||||
|
||||
func Enter(extra_parameters: Dictionary) -> void:
|
||||
animation_finished = false
|
||||
used_item_action = extra_parameters.action_name
|
||||
PlayerBeganDrawingBow.emit()
|
||||
|
||||
|
||||
func Update(_delta: float) -> void:
|
||||
if !animation_finished:
|
||||
return
|
||||
|
||||
if !Input.is_action_pressed(used_item_action):
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.FIRING_ARROW)
|
||||
return
|
||||
|
||||
var movement_vector := movement_componenent.movement_vector
|
||||
if movement_vector != Vector2.ZERO:
|
||||
body.velocity = movement_vector * strafing_speed
|
||||
body.move_and_slide()
|
||||
|
||||
|
||||
func OnDrawingBowAnimationFinished() -> void:
|
||||
animation_finished = true
|
||||
@@ -0,0 +1 @@
|
||||
uid://bnp1vowmu15lg
|
||||
30
Scripts/Characters/Player/States/firing_arrow_state.gd
Normal file
30
Scripts/Characters/Player/States/firing_arrow_state.gd
Normal file
@@ -0,0 +1,30 @@
|
||||
extends BaseState
|
||||
|
||||
signal PlayerBeganFiringArrow
|
||||
signal PlayerFiredArrow(spawn_position: Vector2, direction: Vector2)
|
||||
|
||||
@export var direction_component: FacingDirectionComponent
|
||||
@export var arrow_spawn_marker: Marker2D
|
||||
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
return PlayerStateMachine.States.FIRING_ARROW
|
||||
|
||||
|
||||
func Enter(_extra_parameters: Dictionary) -> void:
|
||||
PlayerBeganFiringArrow.emit()
|
||||
|
||||
var position := arrow_spawn_marker.global_position
|
||||
var direction := Vector2.ZERO
|
||||
if direction_component.current_direction == Enums.Directions.LEFT:
|
||||
direction = Vector2.LEFT
|
||||
elif direction_component.current_direction == Enums.Directions.RIGHT:
|
||||
direction = Vector2.RIGHT
|
||||
elif direction_component.current_direction == Enums.Directions.UP:
|
||||
direction = Vector2.UP
|
||||
elif direction_component.current_direction == Enums.Directions.DOWN:
|
||||
direction = Vector2.DOWN
|
||||
PlayerFiredArrow.emit(position, direction)
|
||||
|
||||
|
||||
func OnFiringArrowAnimationFinished() -> void:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.IDLE)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cd2ewadcm8oi5
|
||||
47
Scripts/Characters/Player/States/idle_state.gd
Normal file
47
Scripts/Characters/Player/States/idle_state.gd
Normal file
@@ -0,0 +1,47 @@
|
||||
extends BaseState
|
||||
class_name PlayerIdleState
|
||||
|
||||
@export var movement_component: MovementComponent
|
||||
|
||||
signal PlayerBecameIdle
|
||||
|
||||
var _sit_queued := false
|
||||
var _sit_queue_pos: Vector2
|
||||
var _sit_queue_dir: Enums.Directions
|
||||
|
||||
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
return PlayerStateMachine.States.IDLE
|
||||
|
||||
|
||||
func Enter(_extra_parameters: Dictionary) -> void:
|
||||
PlayerBecameIdle.emit()
|
||||
|
||||
|
||||
func Update(_delta: float) -> void:
|
||||
var item_a := Input.is_action_just_pressed("use_item_a")
|
||||
|
||||
if item_a:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.USING_ITEM_A, {})
|
||||
return
|
||||
|
||||
if _sit_queued:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.SITTING, {"pos": _sit_queue_pos, "dir": _sit_queue_dir})
|
||||
_sit_queued = false
|
||||
return
|
||||
|
||||
if movement_component.movement_vector != Vector2.ZERO:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.WALKING)
|
||||
|
||||
|
||||
func OnSitOnFurnitureTriggered(sitting_position: Vector2, sitting_direction: Enums.Directions) -> void:
|
||||
if state_machine.GetCurrentStateEnum() != GetStateEnum():
|
||||
return
|
||||
|
||||
_sit_queued = true
|
||||
_sit_queue_pos = sitting_position
|
||||
_sit_queue_dir = sitting_direction
|
||||
|
||||
|
||||
func OnCutsceneStarted() -> void:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.CUTSCENE)
|
||||
1
Scripts/Characters/Player/States/idle_state.gd.uid
Normal file
1
Scripts/Characters/Player/States/idle_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dkmc1t43gomdb
|
||||
25
Scripts/Characters/Player/States/sitting_state.gd
Normal file
25
Scripts/Characters/Player/States/sitting_state.gd
Normal file
@@ -0,0 +1,25 @@
|
||||
extends BaseState
|
||||
|
||||
@onready var player: PlayerCharacter = $"../../.."
|
||||
@onready var facing_direction_component: FacingDirectionComponent = $"../../../Components/FacingDirectionComponent"
|
||||
|
||||
func GetAnimationBaseName() -> String:
|
||||
return "idle"
|
||||
|
||||
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
return PlayerStateMachine.States.SITTING
|
||||
|
||||
|
||||
func Enter(extra_parameters: Dictionary) -> void:
|
||||
var pos := extra_parameters["pos"] as Vector2
|
||||
var dir := extra_parameters["dir"] as Enums.Directions
|
||||
|
||||
player.position = pos
|
||||
facing_direction_component.SetDirectionManually(dir)
|
||||
|
||||
|
||||
func Update(_delta: float) -> void:
|
||||
if Input.is_action_just_pressed("player_interact"):
|
||||
player.position = Vector2(player.position.x, player.position.y + 16)
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.IDLE)
|
||||
1
Scripts/Characters/Player/States/sitting_state.gd.uid
Normal file
1
Scripts/Characters/Player/States/sitting_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bx1a35al4yiej
|
||||
15
Scripts/Characters/Player/States/using_item_a_state.gd
Normal file
15
Scripts/Characters/Player/States/using_item_a_state.gd
Normal file
@@ -0,0 +1,15 @@
|
||||
extends BaseState
|
||||
|
||||
@export var body: CharacterBody2D
|
||||
@export var direction_component: FacingDirectionComponent
|
||||
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
return PlayerStateMachine.States.USING_ITEM_A
|
||||
|
||||
|
||||
func GetAnimationBaseName() -> String:
|
||||
return "idle"
|
||||
|
||||
|
||||
func Update(_delta: float) -> void:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.DRAWING_BOW, { "action_name": "use_item_a" })
|
||||
@@ -0,0 +1 @@
|
||||
uid://ckn7gmtc23b8l
|
||||
22
Scripts/Characters/Player/States/walking_state.gd
Normal file
22
Scripts/Characters/Player/States/walking_state.gd
Normal file
@@ -0,0 +1,22 @@
|
||||
extends BaseState
|
||||
|
||||
@export var walking_speed := 100
|
||||
|
||||
@export var movement_component: MovementComponent
|
||||
@export var direction_component: FacingDirectionComponent
|
||||
@export var body: CharacterBody2D
|
||||
|
||||
func GetStateEnum() -> PlayerStateMachine.States:
|
||||
return PlayerStateMachine.States.WALKING
|
||||
|
||||
|
||||
func Update(_delta: float) -> void:
|
||||
if movement_component.movement_vector == Vector2.ZERO:
|
||||
state_machine.QueueStateChange(PlayerStateMachine.States.IDLE)
|
||||
return
|
||||
|
||||
var movement_vector := movement_component.movement_vector
|
||||
body.velocity = movement_vector * walking_speed
|
||||
body.move_and_slide()
|
||||
|
||||
direction_component.ChangeDirectionUsingMovementVector(movement_vector)
|
||||
1
Scripts/Characters/Player/States/walking_state.gd.uid
Normal file
1
Scripts/Characters/Player/States/walking_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bwmmah30t3m0u
|
||||
@@ -1,7 +1,11 @@
|
||||
extends Area2D
|
||||
class_name InteractScanner
|
||||
|
||||
signal InteractionActionTriggered()
|
||||
|
||||
@export var parent: Node2D
|
||||
@export var direction_component: FacingDirectionComponent
|
||||
@export var disable_interactions := false
|
||||
|
||||
# Public Methods
|
||||
func OnDirectionChanged() -> void:
|
||||
@@ -14,3 +18,11 @@ func OnDirectionChanged() -> void:
|
||||
parent.rotation = deg_to_rad(180)
|
||||
else:
|
||||
parent.rotation = deg_to_rad(0)
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if disable_interactions:
|
||||
return
|
||||
if Input.is_action_just_pressed("player_interact"):
|
||||
InputManager.IgnoreAction("player_interact")
|
||||
InteractionActionTriggered.emit()
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
extends Node
|
||||
class_name MovementComponent
|
||||
|
||||
signal MovementPerformed(movement_vector: Vector2)
|
||||
|
||||
# Constant Exports
|
||||
@export var SPEED := 100.0
|
||||
signal MovementInput(movement_vector: Vector2)
|
||||
|
||||
# Dynamic Exports
|
||||
@export var body: CharacterBody2D
|
||||
|
||||
var movement_vector: Vector2
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
var direction_vector := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
|
||||
|
||||
if direction_vector:
|
||||
var movement_vector := direction_vector * SPEED
|
||||
body.velocity = movement_vector
|
||||
body.move_and_slide()
|
||||
|
||||
MovementPerformed.emit(movement_vector)
|
||||
movement_vector = direction_vector
|
||||
MovementInput.emit(movement_vector)
|
||||
else:
|
||||
movement_vector = Vector2.ZERO
|
||||
|
||||
@@ -1,12 +1,56 @@
|
||||
extends CharacterBody2D
|
||||
class_name PlayerCharacter
|
||||
|
||||
signal InteractScannerAreaEntered(area: Area2D)
|
||||
signal InteractScannerAreaExited(area: Area2D)
|
||||
|
||||
signal InteractScannerBodyEntered(body: Node2D)
|
||||
signal InteractScannerBodyExited(body: Node2D)
|
||||
|
||||
signal InteractionActionTriggered()
|
||||
|
||||
signal ArrowFired(fire_position: Vector2, direction: Vector2)
|
||||
signal SitOnFurnitureTriggered(sitting_position: Vector2, sitting_direction: Enums.Directions)
|
||||
|
||||
signal CutsceneStarted()
|
||||
signal CutsceneEnded()
|
||||
|
||||
@onready var state_machine: PlayerStateMachine = $StateMachine
|
||||
|
||||
# Public Methods
|
||||
func OnSitOnFurnitureTriggered(sitting_position: Vector2, sitting_direction: Enums.Directions):
|
||||
SitOnFurnitureTriggered.emit(sitting_position, sitting_direction)
|
||||
|
||||
|
||||
func OnCutsceneStarted() -> void:
|
||||
CutsceneStarted.emit()
|
||||
|
||||
|
||||
func OnCutsceneEnded() -> void:
|
||||
CutsceneEnded.emit()
|
||||
|
||||
|
||||
# Private Methods
|
||||
func _on_interact_scanner_area_entered(area: Area2D) -> void:
|
||||
InteractScannerAreaEntered.emit(area)
|
||||
|
||||
|
||||
func _on_interact_scanner_area_exited(area: Area2D) -> void:
|
||||
InteractScannerAreaExited.emit(area)
|
||||
|
||||
|
||||
func _on_interact_scanner_body_entered(body: Node2D) -> void:
|
||||
InteractScannerBodyEntered.emit(body)
|
||||
|
||||
|
||||
func _on_interact_scanner_body_exited(body: Node2D) -> void:
|
||||
InteractScannerBodyExited.emit(body)
|
||||
|
||||
|
||||
func _on_interaction_action_triggered() -> void:
|
||||
if state_machine.current_state.IsStateActionable():
|
||||
InteractionActionTriggered.emit()
|
||||
|
||||
|
||||
func _on_using_item_a_state_arrow_fired(fire_position: Vector2, direction: Vector2) -> void:
|
||||
ArrowFired.emit(fire_position, direction)
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
extends Node2D
|
||||
|
||||
signal DrawingBowAnimationFinished
|
||||
signal FiringArrowAnimationFinished
|
||||
|
||||
@export var state_machine: PlayerStateMachine
|
||||
@export var direction_component: FacingDirectionComponent
|
||||
|
||||
@onready var full: AnimatedSprite2D = $Full
|
||||
@onready var base: AnimatedSprite2D = $Base
|
||||
@onready var hair: AnimatedSprite2D = $Hair
|
||||
@onready var pants: AnimatedSprite2D = $Pants
|
||||
@@ -15,7 +19,7 @@ var is_flipped := false
|
||||
|
||||
# Public Methods
|
||||
func UpdateSprite() -> void:
|
||||
var current_state := state_machine.GetCurrentState()
|
||||
var current_state := state_machine.current_state
|
||||
var current_direction := direction_component.GetCurrentDirection()
|
||||
var animation := _build_animation_name(current_state, current_direction)
|
||||
var should_flip := _should_flip_horizontal()
|
||||
@@ -31,18 +35,26 @@ func UpdateSprite() -> void:
|
||||
part.play()
|
||||
part.flip_h = should_flip
|
||||
|
||||
|
||||
func OnAnimationFinished() -> void:
|
||||
if current_animation.begins_with("drawing-bow-"):
|
||||
DrawingBowAnimationFinished.emit()
|
||||
elif current_animation.begins_with("firing-arrow-"):
|
||||
FiringArrowAnimationFinished.emit()
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
all_parts = [
|
||||
base, hair, pants, hands, shoes
|
||||
full, #base, hair, pants, hands, shoes
|
||||
]
|
||||
|
||||
UpdateSprite()
|
||||
|
||||
|
||||
func _build_animation_name(state: PlayerStateMachine.States, direction: Enums.Directions) -> String:
|
||||
func _build_animation_name(state: BaseState, direction: Enums.Directions) -> String:
|
||||
# e.g. "idle-down", "walking-up"
|
||||
var state_str = PlayerStateMachine.States.keys()[state].to_lower()
|
||||
var state_str = state.GetAnimationBaseName().replace("_", "-")
|
||||
var direction_str = _direction_to_animation_state(direction)
|
||||
return "%s-%s" % [state_str, direction_str]
|
||||
|
||||
|
||||
@@ -2,18 +2,54 @@ extends Node
|
||||
class_name PlayerStateMachine
|
||||
|
||||
enum States {
|
||||
IDLE, WALKING
|
||||
UNSET, IDLE, WALKING, USING_ITEM_A, DRAWING_BOW, FIRING_ARROW,
|
||||
SITTING, CUTSCENE
|
||||
}
|
||||
|
||||
@export var states_container: Node
|
||||
@export var current_state: BaseState
|
||||
|
||||
var state_dict := {}
|
||||
var queued_state: PlayerStateMachine.States = PlayerStateMachine.States.UNSET
|
||||
var queued_parameters: Dictionary = {}
|
||||
|
||||
# Public Methods
|
||||
func GetCurrentState() -> States:
|
||||
return States.IDLE
|
||||
func GetCurrentStateEnum() -> States:
|
||||
return current_state.GetStateEnum()
|
||||
|
||||
|
||||
func QueueStateChange(to_state_enum: PlayerStateMachine.States, extra_parameters: Dictionary = {}) -> void:
|
||||
queued_state = to_state_enum
|
||||
queued_parameters = extra_parameters
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
pass # Replace with function body.
|
||||
var children := states_container.get_children()
|
||||
for child in children:
|
||||
if child is not BaseState:
|
||||
continue
|
||||
var state := child as BaseState
|
||||
state_dict[state.GetStateEnum()] = state
|
||||
|
||||
if current_state:
|
||||
current_state.Enter({})
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(_delta: float) -> void:
|
||||
pass
|
||||
func _process(delta: float) -> void:
|
||||
if current_state:
|
||||
current_state.Update(delta)
|
||||
|
||||
if queued_state != PlayerStateMachine.States.UNSET:
|
||||
_swap_state()
|
||||
|
||||
|
||||
func _swap_state() -> void:
|
||||
if current_state:
|
||||
current_state.Exit()
|
||||
|
||||
current_state = state_dict[queued_state] as BaseState
|
||||
current_state.Enter(queued_parameters)
|
||||
queued_state = PlayerStateMachine.States.UNSET
|
||||
queued_parameters = {}
|
||||
|
||||
@@ -17,6 +17,12 @@ func ChangeDirectionUsingMovementVector(movement_vector: Vector2) -> void:
|
||||
DirectionChanged.emit()
|
||||
|
||||
|
||||
func SetDirectionManually(direction: Enums.Directions) -> void:
|
||||
if current_direction != direction:
|
||||
current_direction = direction
|
||||
DirectionChanged.emit()
|
||||
|
||||
|
||||
# Private Methods
|
||||
func _get_direction_from_mov_vec(mov_vec: Vector2) -> Enums.Directions:
|
||||
if mov_vec.x < 0: return Enums.Directions.LEFT
|
||||
|
||||
24
Scripts/Entity Spawners/arrow_spawner.gd
Normal file
24
Scripts/Entity Spawners/arrow_spawner.gd
Normal file
@@ -0,0 +1,24 @@
|
||||
extends Node
|
||||
|
||||
@export var arrow_parent: Node2D
|
||||
|
||||
const wooden_arrow_scene: PackedScene = preload("uid://b2wq5m01b68rx")
|
||||
|
||||
# Public Methods
|
||||
func OnArrowFired(fire_position: Vector2, direction: Vector2) -> void:
|
||||
var wooden_arrow := wooden_arrow_scene.instantiate() as BaseProjectile
|
||||
wooden_arrow.SetProjectileStartAndDirection(fire_position, direction)
|
||||
|
||||
if arrow_parent == null:
|
||||
return
|
||||
arrow_parent.add_child(wooden_arrow)
|
||||
|
||||
|
||||
# Private Methods
|
||||
func _ready() -> void:
|
||||
var players := get_tree().get_nodes_in_group("Player Group")
|
||||
if players == null or players.is_empty() or players[0] is not PlayerCharacter:
|
||||
return
|
||||
|
||||
var player := players[0] as PlayerCharacter
|
||||
player.ArrowFired.connect(OnArrowFired)
|
||||
1
Scripts/Entity Spawners/arrow_spawner.gd.uid
Normal file
1
Scripts/Entity Spawners/arrow_spawner.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dvgd5ejerauqm
|
||||
53
Scripts/Managers/group_utils.gd
Normal file
53
Scripts/Managers/group_utils.gd
Normal file
@@ -0,0 +1,53 @@
|
||||
extends Node
|
||||
|
||||
func GetAllTreasureChests() -> Array[BaseChest]:
|
||||
var nodes := get_tree().get_nodes_in_group("Treasure Chest Group")
|
||||
var arr: Array[BaseChest] = []
|
||||
|
||||
for node in nodes:
|
||||
if node is BaseChest:
|
||||
arr.append(node as BaseChest)
|
||||
|
||||
return arr
|
||||
|
||||
|
||||
func GetAllInteractiveLoadingZones() -> Array[InteractiveLoadingZone]:
|
||||
var nodes := get_tree().get_nodes_in_group("Interactive Loading Zone Group")
|
||||
var arr: Array[InteractiveLoadingZone] = []
|
||||
|
||||
for node in nodes:
|
||||
if node is InteractiveLoadingZone:
|
||||
arr.append(node)
|
||||
|
||||
return arr
|
||||
|
||||
|
||||
func GetAllLoadingZoneTransporters() -> Array[LoadingZoneTransporter]:
|
||||
var nodes := get_tree().get_nodes_in_group("Loading Zone Transporter Group")
|
||||
var arr: Array[LoadingZoneTransporter] = []
|
||||
|
||||
for node in nodes:
|
||||
if node is LoadingZoneTransporter:
|
||||
arr.append(node)
|
||||
|
||||
return arr
|
||||
|
||||
|
||||
func GetAllDialogueTriggers() -> Array[DialogueTrigger]:
|
||||
var nodes := get_tree().get_nodes_in_group("Dialog Trigger Group")
|
||||
|
||||
var arr: Array[DialogueTrigger] = []
|
||||
|
||||
for node in nodes:
|
||||
if node is DialogueTrigger:
|
||||
arr.append(node)
|
||||
|
||||
return arr
|
||||
|
||||
|
||||
func GetPlayer() -> PlayerCharacter:
|
||||
var nodes := get_tree().get_nodes_in_group("Player Group")
|
||||
if nodes.is_empty():
|
||||
return null
|
||||
|
||||
return nodes[0] as PlayerCharacter
|
||||
1
Scripts/Managers/group_utils.gd.uid
Normal file
1
Scripts/Managers/group_utils.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bk7o4drbfh24p
|
||||
16
Scripts/Managers/input_manager.gd
Normal file
16
Scripts/Managers/input_manager.gd
Normal file
@@ -0,0 +1,16 @@
|
||||
extends Node
|
||||
|
||||
var _actions_to_ignore: Array[StringName] = []
|
||||
|
||||
# Public Methods
|
||||
func IgnoreAction(action_name: StringName) -> void:
|
||||
_actions_to_ignore.append(action_name)
|
||||
|
||||
|
||||
func ShouldIgnoreAction(action_name: StringName) -> bool:
|
||||
return _actions_to_ignore.has(action_name)
|
||||
|
||||
|
||||
# Private Methods
|
||||
func _process(_delta: float) -> void:
|
||||
_actions_to_ignore = []
|
||||
1
Scripts/Managers/input_manager.gd.uid
Normal file
1
Scripts/Managers/input_manager.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dnbg1dpjcq6vk
|
||||
25
Scripts/Managers/map_loader.gd
Normal file
25
Scripts/Managers/map_loader.gd
Normal file
@@ -0,0 +1,25 @@
|
||||
extends Node
|
||||
|
||||
const HOME_01 = preload("uid://laxewy7irxno")
|
||||
const PATH_TO_DUNGEON_01 = preload("uid://b07m0k40dh042")
|
||||
const SHOP = preload("uid://bwt0ijoq4qmhn")
|
||||
|
||||
@onready var mapping := {
|
||||
Enums.MapIds.SHOP_01: SHOP,
|
||||
Enums.MapIds.PATH_TO_FOREST_DUNGEON_01: PATH_TO_DUNGEON_01,
|
||||
Enums.MapIds.PATH_TO_FOREST_HOME_01: HOME_01
|
||||
}
|
||||
|
||||
var _spawn_marker: String
|
||||
|
||||
# Public Methods
|
||||
func GetMap(map_id: Enums.MapIds) -> PackedScene:
|
||||
return mapping[map_id]
|
||||
|
||||
|
||||
func SetSpawnMarker(marker_name: String) -> void:
|
||||
_spawn_marker = marker_name
|
||||
|
||||
|
||||
func GetSpawnMarker() -> String:
|
||||
return _spawn_marker
|
||||
1
Scripts/Managers/map_loader.gd.uid
Normal file
1
Scripts/Managers/map_loader.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c4jogxtdi3m13
|
||||
58
Scripts/Maps/Connectors/bench_interaction_connector.gd
Normal file
58
Scripts/Maps/Connectors/bench_interaction_connector.gd
Normal file
@@ -0,0 +1,58 @@
|
||||
extends Node
|
||||
|
||||
signal SitOnBenchTriggered(position: Vector2, sitting_direction: Enums.Directions)
|
||||
|
||||
@export var player: CharacterBody2D
|
||||
|
||||
var benches_in_range: Array[WoodenBench] = []
|
||||
|
||||
# Public Methods
|
||||
func OnPlayerInteractScannerAreaEntered(area: Area2D) -> void:
|
||||
var parent := area.get_parent()
|
||||
if parent == null or parent is not WoodenBench or benches_in_range.has(parent):
|
||||
return
|
||||
benches_in_range.append(parent)
|
||||
|
||||
|
||||
func OnPlayerInteractScannerAreaExited(area: Area2D) -> void:
|
||||
var parent = area.get_parent()
|
||||
if parent == null or parent is not WoodenBench or !benches_in_range.has(parent):
|
||||
return
|
||||
benches_in_range.erase(parent)
|
||||
|
||||
|
||||
func OnPlayerInteractionActionTriggered() -> void:
|
||||
if benches_in_range.is_empty():
|
||||
return
|
||||
|
||||
var bench := benches_in_range[0]
|
||||
var sitting_spots_container := bench.get_node("Sitting Spots") as Node2D
|
||||
var sitting_spot_markers := sitting_spots_container.get_children()
|
||||
|
||||
var closest_marker: Marker2D
|
||||
var distance_to_player := 9999.0
|
||||
for node in sitting_spot_markers:
|
||||
var marker := node as Marker2D
|
||||
var distance := marker.global_position.distance_to(player.global_position)
|
||||
if distance < distance_to_player:
|
||||
closest_marker = marker
|
||||
distance_to_player = distance
|
||||
|
||||
if !closest_marker:
|
||||
return
|
||||
|
||||
SitOnBenchTriggered.emit(closest_marker.global_position, Enums.Directions.DOWN)
|
||||
|
||||
|
||||
# Private Methods
|
||||
func _ready() -> void:
|
||||
var all_players := get_tree().get_nodes_in_group("Player Group")
|
||||
if all_players == null or all_players.is_empty():
|
||||
return
|
||||
|
||||
for player_node in all_players:
|
||||
var player := player_node as PlayerCharacter
|
||||
|
||||
player.InteractScannerAreaEntered.connect(OnPlayerInteractScannerAreaEntered)
|
||||
player.InteractScannerAreaExited.connect(OnPlayerInteractScannerAreaExited)
|
||||
player.InteractionActionTriggered.connect(OnPlayerInteractionActionTriggered)
|
||||
@@ -0,0 +1 @@
|
||||
uid://c5yjcjk51l4bd
|
||||
26
Scripts/Maps/Connectors/camera_limit_connector.gd
Normal file
26
Scripts/Maps/Connectors/camera_limit_connector.gd
Normal file
@@ -0,0 +1,26 @@
|
||||
extends Area2D
|
||||
|
||||
@export var camera_to_limit: Camera2D
|
||||
@export var auto_limit := true
|
||||
|
||||
func _ready() -> void:
|
||||
if camera_to_limit == null or !auto_limit or get_child_count() == 0:
|
||||
return
|
||||
|
||||
var collision_shape: CollisionShape2D = get_children()[0]
|
||||
if collision_shape.shape is not RectangleShape2D:
|
||||
return
|
||||
|
||||
var limits := _get_normalized_limits(collision_shape)
|
||||
camera_to_limit.limit_left = limits.position.x
|
||||
camera_to_limit.limit_top = limits.position.y
|
||||
camera_to_limit.limit_right = limits.end.x
|
||||
camera_to_limit.limit_bottom = limits.end.y
|
||||
|
||||
|
||||
func _get_normalized_limits(collision_shape: CollisionShape2D) -> Rect2i:
|
||||
var rectangle_shape := collision_shape.shape as RectangleShape2D
|
||||
var rect_position := collision_shape.position
|
||||
var size := rectangle_shape.size
|
||||
var begin := rect_position - size / 2
|
||||
return Rect2(begin.x, begin.y, size.x, size.y)
|
||||
1
Scripts/Maps/Connectors/camera_limit_connector.gd.uid
Normal file
1
Scripts/Maps/Connectors/camera_limit_connector.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://kfupww4frb1r
|
||||
53
Scripts/Maps/Connectors/chest_interaction_connector.gd
Normal file
53
Scripts/Maps/Connectors/chest_interaction_connector.gd
Normal file
@@ -0,0 +1,53 @@
|
||||
extends Node
|
||||
|
||||
# Drop-in that automatically connects signals from player to chest objects
|
||||
signal ChestInteractedWith(chest: BaseChest)
|
||||
signal OpeningOfOpenedChestAttempted
|
||||
|
||||
@export var auto_connect_all_chests := true
|
||||
|
||||
var chests_in_range: Array[BaseChest] = []
|
||||
|
||||
# Public Methods
|
||||
func OnPlayerInteractScannerAreaEntered(area: Area2D) -> void:
|
||||
var chest = area.get_parent()
|
||||
if chest == null or chest is not BaseChest:
|
||||
return
|
||||
if chests_in_range.has(chest):
|
||||
return
|
||||
chests_in_range.append(chest)
|
||||
|
||||
|
||||
func OnPlayerInteractScannerAreaExited(area: Area2D) -> void:
|
||||
var chest = area.get_parent()
|
||||
if chest == null or chest is not BaseChest:
|
||||
return
|
||||
if !chests_in_range.has(chest):
|
||||
return
|
||||
chests_in_range.erase(chest)
|
||||
|
||||
|
||||
func OnPlayerInteractionActionTriggered() -> void:
|
||||
if chests_in_range.is_empty():
|
||||
return
|
||||
|
||||
var chest := chests_in_range[0]
|
||||
if !chest.is_open:
|
||||
chest.Open()
|
||||
else:
|
||||
chest.OpenAlreadyOpened()
|
||||
OpeningOfOpenedChestAttempted.emit()
|
||||
|
||||
|
||||
# Private Methods
|
||||
func _ready() -> void:
|
||||
var all_players := get_tree().get_nodes_in_group("Player Group")
|
||||
if all_players == null or all_players.is_empty():
|
||||
return
|
||||
|
||||
for player_node in all_players:
|
||||
var player := player_node as PlayerCharacter
|
||||
|
||||
player.InteractScannerAreaEntered.connect(OnPlayerInteractScannerAreaEntered)
|
||||
player.InteractScannerAreaExited.connect(OnPlayerInteractScannerAreaExited)
|
||||
player.InteractionActionTriggered.connect(OnPlayerInteractionActionTriggered)
|
||||
@@ -0,0 +1 @@
|
||||
uid://dw76slp457s1v
|
||||
12
Scripts/Maps/Connectors/collision_loading_zone_connector.gd
Normal file
12
Scripts/Maps/Connectors/collision_loading_zone_connector.gd
Normal file
@@ -0,0 +1,12 @@
|
||||
extends Node
|
||||
|
||||
@export var player: PlayerCharacter
|
||||
|
||||
# Public Methods
|
||||
func OnPlayerAreaEntered(area: Area2D) -> void:
|
||||
pass
|
||||
|
||||
|
||||
# Private Methods
|
||||
func _ready() -> void:
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
uid://dbscr0b7k3rtp
|
||||
@@ -0,0 +1,39 @@
|
||||
extends Node
|
||||
|
||||
var _zones_in_range: Array[InteractiveLoadingZone] = []
|
||||
|
||||
# Public Methods
|
||||
func OnPlayerInteractScannerAreaEntered(area: Area2D) -> void:
|
||||
if area is not InteractiveLoadingZone or _zones_in_range.has(area):
|
||||
return
|
||||
|
||||
_zones_in_range.append(area)
|
||||
|
||||
|
||||
func OnPlayerInteractScannerAreaExited(area: Area2D) -> void:
|
||||
if area is not InteractiveLoadingZone or !_zones_in_range.has(area):
|
||||
return
|
||||
|
||||
_zones_in_range.erase(area)
|
||||
|
||||
|
||||
func OnPlayerInteractionActionTriggered() -> void:
|
||||
if _zones_in_range.is_empty():
|
||||
return
|
||||
|
||||
var zone := _zones_in_range[0]
|
||||
zone.Activate()
|
||||
|
||||
|
||||
# Private Methods
|
||||
func _ready() -> void:
|
||||
var all_players := get_tree().get_nodes_in_group("Player Group")
|
||||
if all_players == null or all_players.is_empty():
|
||||
return
|
||||
|
||||
for player_node in all_players:
|
||||
var player := player_node as PlayerCharacter
|
||||
|
||||
player.InteractScannerAreaEntered.connect(OnPlayerInteractScannerAreaEntered)
|
||||
player.InteractScannerAreaExited.connect(OnPlayerInteractScannerAreaExited)
|
||||
player.InteractionActionTriggered.connect(OnPlayerInteractionActionTriggered)
|
||||
@@ -0,0 +1 @@
|
||||
uid://d3hhbegfxdnqq
|
||||
16
Scripts/Maps/Connectors/spawn_marker_connector.gd
Normal file
16
Scripts/Maps/Connectors/spawn_marker_connector.gd
Normal file
@@ -0,0 +1,16 @@
|
||||
extends Node
|
||||
|
||||
@export var player: CharacterBody2D
|
||||
@export var markers: Node2D
|
||||
|
||||
# Public Methods
|
||||
func _ready() -> void:
|
||||
var marker_name := MapLoader.GetSpawnMarker()
|
||||
if !marker_name:
|
||||
return
|
||||
|
||||
for child in markers.get_children():
|
||||
if child.name == marker_name:
|
||||
var marker := child as Marker2D
|
||||
var position := marker.global_position
|
||||
player.position = position
|
||||
1
Scripts/Maps/Connectors/spawn_marker_connector.gd.uid
Normal file
1
Scripts/Maps/Connectors/spawn_marker_connector.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dkcsftcdqtmg
|
||||
12
Scripts/Objects/Chests/Bases/chest_base.gd
Normal file
12
Scripts/Objects/Chests/Bases/chest_base.gd
Normal file
@@ -0,0 +1,12 @@
|
||||
extends StaticBody2D
|
||||
class_name BaseChest
|
||||
|
||||
@export var is_open := false
|
||||
|
||||
# Public Methods
|
||||
func Open() -> void:
|
||||
is_open = true
|
||||
|
||||
|
||||
func OpenAlreadyOpened() -> void:
|
||||
pass
|
||||
1
Scripts/Objects/Chests/Bases/chest_base.gd.uid
Normal file
1
Scripts/Objects/Chests/Bases/chest_base.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://0fsmtp1umvmp
|
||||
4
Scripts/Objects/Chests/Bases/item_chest.gd
Normal file
4
Scripts/Objects/Chests/Bases/item_chest.gd
Normal file
@@ -0,0 +1,4 @@
|
||||
extends BaseChest
|
||||
class_name BaseItemChest
|
||||
|
||||
@export var item_id: Enums.Items
|
||||
1
Scripts/Objects/Chests/Bases/item_chest.gd.uid
Normal file
1
Scripts/Objects/Chests/Bases/item_chest.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dbuc0f87m24xf
|
||||
31
Scripts/Objects/Chests/item_chest_01.gd
Normal file
31
Scripts/Objects/Chests/item_chest_01.gd
Normal file
@@ -0,0 +1,31 @@
|
||||
extends BaseItemChest
|
||||
|
||||
@onready var chest_01_sprite: AnimatedSprite2D = $"Sprite"
|
||||
|
||||
@export var is_locked := false
|
||||
@export var locked_message_dialogue_trigger: DialogueTrigger
|
||||
@export var already_opened_message_dialogue_trigger: DialogueTrigger
|
||||
|
||||
# Public Methods
|
||||
func Open() -> void:
|
||||
if is_locked:
|
||||
if locked_message_dialogue_trigger:
|
||||
locked_message_dialogue_trigger.Trigger()
|
||||
return
|
||||
|
||||
super.Open()
|
||||
chest_01_sprite.play("opening")
|
||||
|
||||
var item_name: String = Enums.Items.keys()[item_id]
|
||||
print(item_name)
|
||||
|
||||
|
||||
func OpenAlreadyOpened() -> void:
|
||||
if already_opened_message_dialogue_trigger:
|
||||
already_opened_message_dialogue_trigger.Trigger()
|
||||
|
||||
|
||||
# Private Methods
|
||||
func _ready() -> void:
|
||||
if is_open:
|
||||
chest_01_sprite.play("opened")
|
||||
1
Scripts/Objects/Chests/item_chest_01.gd.uid
Normal file
1
Scripts/Objects/Chests/item_chest_01.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bvq13h8uyx572
|
||||
2
Scripts/Objects/Decorative/Outdoor/wooden_bench.gd
Normal file
2
Scripts/Objects/Decorative/Outdoor/wooden_bench.gd
Normal file
@@ -0,0 +1,2 @@
|
||||
extends StaticBody2D
|
||||
class_name WoodenBench
|
||||
1
Scripts/Objects/Decorative/Outdoor/wooden_bench.gd.uid
Normal file
1
Scripts/Objects/Decorative/Outdoor/wooden_bench.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c6n652dy18xbm
|
||||
10
Scripts/Objects/Dialogue/dialogue_trigger.gd
Normal file
10
Scripts/Objects/Dialogue/dialogue_trigger.gd
Normal file
@@ -0,0 +1,10 @@
|
||||
extends Area2D
|
||||
class_name DialogueTrigger
|
||||
|
||||
signal DialogueTriggered(dialogue_name: String)
|
||||
|
||||
@export var dialogue_name: String
|
||||
|
||||
# Public Methods
|
||||
func Trigger() -> void:
|
||||
DialogueTriggered.emit(dialogue_name)
|
||||
1
Scripts/Objects/Dialogue/dialogue_trigger.gd.uid
Normal file
1
Scripts/Objects/Dialogue/dialogue_trigger.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cfsfx0sahh5t7
|
||||
17
Scripts/Objects/Gates/Spike Gate/spike_gate.gd
Normal file
17
Scripts/Objects/Gates/Spike Gate/spike_gate.gd
Normal file
@@ -0,0 +1,17 @@
|
||||
extends StaticBody2D
|
||||
|
||||
@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
|
||||
@onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D
|
||||
|
||||
var is_open := false
|
||||
|
||||
func OpenGate() -> void:
|
||||
if is_open:
|
||||
return
|
||||
is_open = true
|
||||
|
||||
sprite.play("opening")
|
||||
await sprite.animation_finished
|
||||
|
||||
collision_shape_2d.set_deferred("disabled", true)
|
||||
sprite.play("open")
|
||||
1
Scripts/Objects/Gates/Spike Gate/spike_gate.gd.uid
Normal file
1
Scripts/Objects/Gates/Spike Gate/spike_gate.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://8erg53skow38
|
||||
11
Scripts/Objects/Loading Zone/collision_loading_zone.gd
Normal file
11
Scripts/Objects/Loading Zone/collision_loading_zone.gd
Normal file
@@ -0,0 +1,11 @@
|
||||
extends Area2D
|
||||
class_name CollisionLoadingZone
|
||||
|
||||
@export var loading_zone_transporter: LoadingZoneTransporter
|
||||
|
||||
# Private Methods
|
||||
func _on_body_entered(body: Node2D) -> void:
|
||||
if body is not PlayerCharacter:
|
||||
return
|
||||
|
||||
loading_zone_transporter.Activate()
|
||||
@@ -0,0 +1 @@
|
||||
uid://g0r5waf50gp5
|
||||
8
Scripts/Objects/Loading Zone/interactive_loading_zone.gd
Normal file
8
Scripts/Objects/Loading Zone/interactive_loading_zone.gd
Normal file
@@ -0,0 +1,8 @@
|
||||
extends Area2D
|
||||
class_name InteractiveLoadingZone
|
||||
|
||||
@export var loading_zone_transporter: LoadingZoneTransporter
|
||||
|
||||
# Public Methods
|
||||
func Activate() -> void:
|
||||
loading_zone_transporter.Activate()
|
||||
@@ -0,0 +1 @@
|
||||
uid://dla7fe0nsbdvv
|
||||
18
Scripts/Objects/Loading Zone/loading_zone_transporter.gd
Normal file
18
Scripts/Objects/Loading Zone/loading_zone_transporter.gd
Normal file
@@ -0,0 +1,18 @@
|
||||
extends Node
|
||||
class_name LoadingZoneTransporter
|
||||
|
||||
signal MapTransitionQueued(map_id: Enums.MapIds, marker_name: String)
|
||||
|
||||
@export var destination_map_id: Enums.MapIds
|
||||
@export var destination_marker_name: String
|
||||
|
||||
var _packed_scene: PackedScene
|
||||
|
||||
# Public Methods
|
||||
func Activate() -> void:
|
||||
MapTransitionQueued.emit(destination_map_id, destination_marker_name)
|
||||
|
||||
|
||||
# Private Methods
|
||||
func _ready() -> void:
|
||||
_packed_scene = MapLoader.GetMap(destination_map_id)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cshtpe5n2iubh
|
||||
15
Scripts/Objects/Mechanisms/pressure_plate.gd
Normal file
15
Scripts/Objects/Mechanisms/pressure_plate.gd
Normal file
@@ -0,0 +1,15 @@
|
||||
extends Area2D
|
||||
|
||||
signal PressurePlateTripped
|
||||
|
||||
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D
|
||||
|
||||
var activated := false
|
||||
|
||||
func _on_body_entered(body: Node2D) -> void:
|
||||
if activated:
|
||||
return
|
||||
|
||||
activated = true
|
||||
animated_sprite_2d.play("activated")
|
||||
PressurePlateTripped.emit()
|
||||
1
Scripts/Objects/Mechanisms/pressure_plate.gd.uid
Normal file
1
Scripts/Objects/Mechanisms/pressure_plate.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cxt7ht66jiac8
|
||||
15
Scripts/Objects/Occlusion/occlusion_culler.gd
Normal file
15
Scripts/Objects/Occlusion/occlusion_culler.gd
Normal file
@@ -0,0 +1,15 @@
|
||||
extends Area2D
|
||||
|
||||
@export var to_alpha := 0.38
|
||||
@export var fade_out_duration := 0.2
|
||||
@export var fade_in_duration := 0.2
|
||||
@export var nodes_to_occlude: Array[Node2D]
|
||||
|
||||
func _on_area_entered(_area: Area2D) -> void:
|
||||
for node in nodes_to_occlude:
|
||||
get_tree().create_tween().tween_property(node, "self_modulate:a", to_alpha, fade_out_duration)
|
||||
|
||||
|
||||
func _on_area_exited(_area: Area2D) -> void:
|
||||
for node in nodes_to_occlude:
|
||||
get_tree().create_tween().tween_property(node, "self_modulate:a", 1.0, fade_in_duration)
|
||||
1
Scripts/Objects/Occlusion/occlusion_culler.gd.uid
Normal file
1
Scripts/Objects/Occlusion/occlusion_culler.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://d4g6s63d0bh4o
|
||||
78
Scripts/Objects/Trees/leaf_spawner.gd
Normal file
78
Scripts/Objects/Trees/leaf_spawner.gd
Normal file
@@ -0,0 +1,78 @@
|
||||
extends Node2D
|
||||
|
||||
@export var leaf_texture: Texture2D
|
||||
@export var spawn_markers: Node2D
|
||||
@export var destination_markers: Node2D
|
||||
|
||||
var _spawn_markers: Array[Marker2D] = []
|
||||
var _destination_markers: Array[Marker2D] = []
|
||||
var _spawn_schedule := 0.0
|
||||
var _spawn_timer := 0.0
|
||||
|
||||
# Private Methods
|
||||
func _ready() -> void:
|
||||
for child in spawn_markers.get_children():
|
||||
_spawn_markers.append(child)
|
||||
|
||||
for child in destination_markers.get_children():
|
||||
_destination_markers.append(child)
|
||||
|
||||
_set_random_spawn_schedule()
|
||||
|
||||
# At spawn, we might want to spawn some leaves sooner...
|
||||
_spawn_schedule -= randf_range(0.0, 15.0)
|
||||
_spawn_schedule = max(0, _spawn_schedule)
|
||||
print("%s - Leaf Spawn Schedule: %f" % [get_parent().name, _spawn_schedule])
|
||||
|
||||
# Debug
|
||||
_spawn_schedule = randf_range(1.0, 3.0)
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
_spawn_timer += delta
|
||||
if _spawn_timer >= _spawn_schedule:
|
||||
_spawn_timer = 0.0
|
||||
_set_random_spawn_schedule()
|
||||
|
||||
var spawn := _get_random_spawn_point()
|
||||
var destination := _get_random_destination_point()
|
||||
|
||||
# TODO Refactor this into scene
|
||||
var sprite := Sprite2D.new()
|
||||
sprite.texture = leaf_texture
|
||||
sprite.position = spawn
|
||||
sprite.rotate(deg_to_rad(randf_range(0, 360)))
|
||||
var tween := get_tree().create_tween().tween_property(sprite, "position", destination, randf_range(2.0, 3.0))
|
||||
tween.finished.connect(
|
||||
func():
|
||||
var timer := get_tree().create_timer(randf_range(8.0, 15.0))
|
||||
timer.timeout.connect(
|
||||
func():
|
||||
if !sprite: return
|
||||
var tween2 := get_tree().create_tween().tween_property(sprite, "self_modulate:a", 0.0, randf_range(4.0, 6.0))
|
||||
tween2.finished.connect(
|
||||
func():
|
||||
if !sprite: return
|
||||
sprite.queue_free()
|
||||
)
|
||||
)
|
||||
)
|
||||
add_child(sprite)
|
||||
|
||||
|
||||
func _set_random_spawn_schedule() -> void:
|
||||
_spawn_schedule = randf_range(20.0, 60.0)
|
||||
|
||||
|
||||
func _get_random_spawn_point() -> Vector2:
|
||||
var idx := randi_range(0, len(_spawn_markers) - 1)
|
||||
var marker := _spawn_markers[idx]
|
||||
return marker.position
|
||||
|
||||
|
||||
func _get_random_destination_point() -> Vector2:
|
||||
var idx := randi_range(0, len(_destination_markers) - 1)
|
||||
var marker := _destination_markers[idx]
|
||||
var offset := Vector2(randf_range(-5.0, 5.0), randf_range(-5.0, 5.0))
|
||||
|
||||
return marker.position + offset
|
||||
1
Scripts/Objects/Trees/leaf_spawner.gd.uid
Normal file
1
Scripts/Objects/Trees/leaf_spawner.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://vmyfl4obus88
|
||||
17
Scripts/Objects/Weapons/Projectiles/base_projectile.gd
Normal file
17
Scripts/Objects/Weapons/Projectiles/base_projectile.gd
Normal file
@@ -0,0 +1,17 @@
|
||||
extends CharacterBody2D
|
||||
class_name BaseProjectile
|
||||
|
||||
@export var direction: Vector2
|
||||
@export var speed := 100
|
||||
|
||||
# Public Methods
|
||||
func SetProjectileStartAndDirection(start_position: Vector2, projectile_direction: Vector2) -> void:
|
||||
position = start_position
|
||||
direction = projectile_direction
|
||||
rotation = projectile_direction.angle()
|
||||
|
||||
|
||||
# Private Methods
|
||||
func _physics_process(delta: float) -> void:
|
||||
velocity = direction * speed * delta
|
||||
move_and_slide()
|
||||
@@ -0,0 +1 @@
|
||||
uid://8q26ldhfyijx
|
||||
29
Scripts/Objects/Weapons/Projectiles/wooden_arrow.gd
Normal file
29
Scripts/Objects/Weapons/Projectiles/wooden_arrow.gd
Normal file
@@ -0,0 +1,29 @@
|
||||
extends BaseProjectile
|
||||
class_name WoodenArrow
|
||||
|
||||
@onready var animation_player: AnimationPlayer = $AnimationPlayer
|
||||
|
||||
var _despawn_queued := false
|
||||
|
||||
# Private Methods
|
||||
func _ready() -> void:
|
||||
speed = 8000
|
||||
|
||||
|
||||
func _on_collision_detector_area_entered(_area: Area2D) -> void:
|
||||
queue_despawn()
|
||||
|
||||
|
||||
func _on_collision_detector_body_entered(body: Node2D) -> void:
|
||||
if body == self: return
|
||||
queue_despawn()
|
||||
|
||||
|
||||
func queue_despawn() -> void:
|
||||
if _despawn_queued: return
|
||||
_despawn_queued = true
|
||||
|
||||
animation_player.play("shaking")
|
||||
await animation_player.animation_finished
|
||||
|
||||
queue_free()
|
||||
1
Scripts/Objects/Weapons/Projectiles/wooden_arrow.gd.uid
Normal file
1
Scripts/Objects/Weapons/Projectiles/wooden_arrow.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://j5yj4piyfql1
|
||||
8
Scripts/Objects/arrow_target.gd
Normal file
8
Scripts/Objects/arrow_target.gd
Normal file
@@ -0,0 +1,8 @@
|
||||
extends Area2D
|
||||
|
||||
signal TargetHit
|
||||
|
||||
func _on_body_entered(body: Node2D) -> void:
|
||||
if body is not CharacterBody2D:
|
||||
return
|
||||
TargetHit.emit()
|
||||
1
Scripts/Objects/arrow_target.gd.uid
Normal file
1
Scripts/Objects/arrow_target.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://6jls1eokv2to
|
||||
22
Scripts/UI/dialogue_box.gd
Normal file
22
Scripts/UI/dialogue_box.gd
Normal file
@@ -0,0 +1,22 @@
|
||||
extends Control
|
||||
class_name DialogueBox
|
||||
|
||||
signal DialogueStarted
|
||||
signal DialogueEnded
|
||||
|
||||
@onready var label: Label = $ColorRect/MarginContainer/Label
|
||||
|
||||
# Public Methods
|
||||
func OnDialogueTriggered(dialogue_name: String) -> void:
|
||||
label.text = tr(dialogue_name)
|
||||
visible = true
|
||||
DialogueStarted.emit()
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if !visible:
|
||||
return
|
||||
|
||||
if Input.is_action_just_pressed("player_interact") and !InputManager.ShouldIgnoreAction("player_interact"):
|
||||
visible = false
|
||||
DialogueEnded.emit()
|
||||
1
Scripts/UI/dialogue_box.gd.uid
Normal file
1
Scripts/UI/dialogue_box.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://d0mlugcfvyksn
|
||||
50
Scripts/dialogue_trigger_connector.gd
Normal file
50
Scripts/dialogue_trigger_connector.gd
Normal file
@@ -0,0 +1,50 @@
|
||||
extends Node
|
||||
|
||||
signal DialogueTriggered(dialogue_name: String)
|
||||
|
||||
@onready var dialogue_box: DialogueBox = $"../Gui/Dialogue Box"
|
||||
|
||||
var dialogue_triggers_in_area: Array[DialogueTrigger] = []
|
||||
|
||||
# Public Methods
|
||||
func OnPlayerInteractScannerAreaEntered(area: Area2D) -> void:
|
||||
if area is not DialogueTrigger or dialogue_triggers_in_area.has(area):
|
||||
return
|
||||
dialogue_triggers_in_area.append(area)
|
||||
|
||||
|
||||
func OnPlayerInteractScannerAreaExited(area: Area2D) -> void:
|
||||
if area is not DialogueTrigger or !dialogue_triggers_in_area.has(area): return
|
||||
dialogue_triggers_in_area.erase(area)
|
||||
|
||||
|
||||
func OnPlayerInteractionActionTriggered() -> void:
|
||||
if dialogue_triggers_in_area.is_empty():
|
||||
return
|
||||
|
||||
var trigger := dialogue_triggers_in_area[0]
|
||||
trigger.Trigger()
|
||||
|
||||
|
||||
# Private Methods
|
||||
func _on_map_changed(map_id: Enums.MapIds) -> void:
|
||||
var player := GroupUtils.GetPlayer()
|
||||
if !player:
|
||||
return
|
||||
|
||||
player.InteractScannerAreaEntered.connect(OnPlayerInteractScannerAreaEntered)
|
||||
player.InteractScannerAreaExited.connect(OnPlayerInteractScannerAreaExited)
|
||||
player.InteractionActionTriggered.connect(OnPlayerInteractionActionTriggered)
|
||||
|
||||
dialogue_box.DialogueStarted.connect(player.OnCutsceneStarted)
|
||||
dialogue_box.DialogueEnded.connect(player.OnCutsceneEnded)
|
||||
|
||||
var dialogue_triggers := GroupUtils.GetAllDialogueTriggers()
|
||||
print("Dialogue Triggers on map [%s]: [%d]" % [Enums.MapIds.keys()[map_id], len(dialogue_triggers)])
|
||||
|
||||
for trigger in dialogue_triggers:
|
||||
trigger.DialogueTriggered.connect(_on_dialogue_triggered)
|
||||
|
||||
|
||||
func _on_dialogue_triggered(dialogue_name: String) -> void:
|
||||
DialogueTriggered.emit(dialogue_name)
|
||||
1
Scripts/dialogue_trigger_connector.gd.uid
Normal file
1
Scripts/dialogue_trigger_connector.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cluyhxrc3pdb
|
||||
@@ -12,5 +12,12 @@ enum Items {
|
||||
BRONZE_KEY, SILVER_KEY, GOLD_KEY,
|
||||
WOOD_SWORD, IRON_SWORD, ROYAL_SWORD,
|
||||
RED_POTION,
|
||||
GOLD_100, GOLD_200, GOLD_300, GOLD_400
|
||||
GOLD_100, GOLD_200, GOLD_300, GOLD_400,
|
||||
WOODEN_BOW
|
||||
}
|
||||
|
||||
enum MapIds {
|
||||
PATH_TO_FOREST_DUNGEON_01,
|
||||
PATH_TO_FOREST_HOME_01,
|
||||
SHOP_01
|
||||
}
|
||||
|
||||
@@ -1,11 +1 @@
|
||||
extends Control
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
pass
|
||||
extends CanvasLayer
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
extends Node2D
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
pass
|
||||
#@export var initial_map: PackedScene
|
||||
#
|
||||
#@onready var world: Node2D = $World
|
||||
#
|
||||
## Called when the node enters the scene tree for the first time.
|
||||
#func _ready() -> void:
|
||||
#var map := initial_map.instantiate()
|
||||
#world.add_child(map)
|
||||
|
||||
46
Scripts/map_transitioner.gd
Normal file
46
Scripts/map_transitioner.gd
Normal file
@@ -0,0 +1,46 @@
|
||||
extends Node
|
||||
|
||||
signal MapChanged(map_id: Enums.MapIds)
|
||||
|
||||
@export var initial_map_id: Enums.MapIds
|
||||
|
||||
@onready var world: Node2D = $"../World"
|
||||
|
||||
# Private Methods
|
||||
func _ready() -> void:
|
||||
var map_scene := MapLoader.GetMap(initial_map_id)
|
||||
var map := map_scene.instantiate()
|
||||
world.add_child(map)
|
||||
await map.ready
|
||||
|
||||
_connect_loading_zone_transporters()
|
||||
MapChanged.emit(initial_map_id)
|
||||
|
||||
|
||||
func _on_map_transition_queued(map_id: Enums.MapIds, marker_name: String) -> void:
|
||||
print("Map Transition Queued: %s" % [Enums.MapIds.keys()[map_id]])
|
||||
var map_scene := MapLoader.GetMap(map_id)
|
||||
MapLoader.SetSpawnMarker(marker_name)
|
||||
|
||||
for child in world.get_children():
|
||||
child.queue_free()
|
||||
await child.tree_exited
|
||||
|
||||
var map := map_scene.instantiate()
|
||||
world.call_deferred("add_child", map)
|
||||
await map.ready
|
||||
|
||||
_connect_loading_zone_transporters()
|
||||
MapChanged.emit(map_id)
|
||||
|
||||
|
||||
func _connect_signals() -> void:
|
||||
_connect_loading_zone_transporters()
|
||||
|
||||
|
||||
func _connect_loading_zone_transporters() -> void:
|
||||
var loading_zone_transporters := GroupUtils.GetAllLoadingZoneTransporters()
|
||||
print("Loading Zones: %d" % len(loading_zone_transporters))
|
||||
|
||||
for transporter in loading_zone_transporters:
|
||||
transporter.MapTransitionQueued.connect(_on_map_transition_queued)
|
||||
1
Scripts/map_transitioner.gd.uid
Normal file
1
Scripts/map_transitioner.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dr7ljodtof1k5
|
||||
@@ -1,11 +1 @@
|
||||
extends Node2D
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user