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_zone: Marker3D @export var study_zone: Marker3D @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(guard_zone): simulation_manager.add_safety(3.0) print("Player helped guard the village.") elif is_near(study_zone): 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