122 lines
3.3 KiB
GDScript
122 lines
3.3 KiB
GDScript
extends CharacterBody3D
|
|
|
|
@export var move_speed := 7.0
|
|
@export var acceleration := 18.0
|
|
@export var rotation_speed := 12.0
|
|
@export var camera_rig: Node3D
|
|
|
|
@export var simulation_manager: Node
|
|
|
|
@export var pantry_storage: StorageNode
|
|
@export var guard_site: ActivitySite
|
|
@export var study_site: ActivitySite
|
|
|
|
@export var stomach_capacity_for_food := 5
|
|
@export var interaction_range := 3.0
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
var input := Input.get_vector("move_left", "move_right", "move_forward", "move_backward")
|
|
|
|
var forward := -camera_rig.global_transform.basis.z
|
|
var right := camera_rig.global_transform.basis.x
|
|
|
|
forward.y = 0
|
|
right.y = 0
|
|
|
|
forward = forward.normalized()
|
|
right = right.normalized()
|
|
|
|
var direction := (right * input.x + forward * -input.y).normalized()
|
|
|
|
var target_velocity := direction * move_speed
|
|
|
|
velocity.x = move_toward(velocity.x, target_velocity.x, acceleration * delta)
|
|
velocity.z = move_toward(velocity.z, target_velocity.z, acceleration * delta)
|
|
|
|
if not is_on_floor():
|
|
velocity.y -= 30.0 * delta
|
|
else:
|
|
velocity.y = 0.0
|
|
|
|
move_and_slide()
|
|
|
|
if direction.length() > 0.01:
|
|
var target_angle := atan2(direction.x, direction.z)
|
|
rotation.y = lerp_angle(rotation.y, target_angle, rotation_speed * delta)
|
|
|
|
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
# keep your camera mouse code here too
|
|
if event.is_action_pressed("interact"):
|
|
try_interact()
|
|
|
|
|
|
func try_interact() -> void:
|
|
if simulation_manager == null:
|
|
return
|
|
|
|
if try_harvest_resource_node():
|
|
return
|
|
|
|
if is_near_activity_site(guard_site):
|
|
simulation_manager.add_safety(3.0)
|
|
print("Player helped guard the village.")
|
|
elif is_near_activity_site(study_site):
|
|
simulation_manager.add_knowledge(2.0)
|
|
print("Player shared knowledge.")
|
|
elif is_near_storage(pantry_storage):
|
|
simulation_manager.eat_food(stomach_capacity_for_food)
|
|
print("Player ate food from the village supply.")
|
|
|
|
|
|
func try_harvest_resource_node() -> bool:
|
|
if not simulation_manager.has_method("find_resource_node_for_player"):
|
|
push_error("Player: SimulationManager cannot find ResourceNodes")
|
|
return false
|
|
var node: ResourceNode = simulation_manager.find_resource_node_for_player(
|
|
global_position, interaction_range
|
|
)
|
|
if node == null:
|
|
return false
|
|
|
|
if not node.is_enabled():
|
|
print("%s is unavailable." % node.node_id)
|
|
return true
|
|
|
|
if node.is_depleted():
|
|
print("%s is depleted." % node.node_id)
|
|
return true
|
|
|
|
if not simulation_manager.has_method("harvest_resource_node"):
|
|
push_error("Player: SimulationManager cannot harvest ResourceNodes")
|
|
return true
|
|
|
|
var extracted: float = simulation_manager.harvest_resource_node(node)
|
|
if extracted > 0.0:
|
|
print("Player gathered %s %s from %s." % [extracted, node.resource_id, node.node_id])
|
|
else:
|
|
print("%s could not be harvested." % node.node_id)
|
|
return true
|
|
|
|
|
|
func is_near(zone: Marker3D) -> bool:
|
|
if zone == null:
|
|
return false
|
|
|
|
return global_position.distance_to(zone.global_position) <= interaction_range
|
|
|
|
|
|
func is_near_storage(storage_node: StorageNode) -> bool:
|
|
if storage_node == null:
|
|
return false
|
|
|
|
return global_position.distance_to(storage_node.get_interaction_position()) <= interaction_range
|
|
|
|
|
|
func is_near_activity_site(activity_site: ActivitySite) -> bool:
|
|
if activity_site == null:
|
|
return false
|
|
|
|
return global_position.distance_to(activity_site.get_interaction_position()) <= interaction_range
|