extends CharacterBody3D # --- ÉTATS DU CLIENT --- enum State { ENTERING, WAITING, LEAVING } var current_state: State = State.ENTERING # --- PARAMÈTRES --- @export var speed: float = 4 @export var entry_path: Array[Marker3D] @export var exit_path: Array[Marker3D] var current_path_index: int = 0 var possible_pies = [] var possible_toppings = [] var possible_language = [ Sauvegarde.language, "jap", "all", "jap", "all" ] var pie_icons = {} var topping_icons = {} var desired_pie: String = "" var desired_topping: String = "" var choosen_lang : String = Sauvegarde.language var ready_to_take_pie : bool = false # --- RÉFÉRENCES UI --- @onready var sprite: Sprite3D = $Sprite3D @onready var label: RichTextLabel = $Sprite3D/SubViewport/RichTextLabel @onready var mesh: MeshInstance3D = $character/Root/Skeleton3D/characterMedium @onready var anim_player: AnimationPlayer = $character/AnimationPlayer @onready var sprite_e: Sprite3D = $Sprite3DE var player # given by client_spwaner var is_close_to_waiting = false func _ready() -> void: mesh.set_instance_shader_parameter("skin_index", randi_range(1, 16)) sprite.visible = false if player.cpt_client > 1: choosen_lang = possible_language.pick_random() possible_pies = [Sauvegarde.get_text("pie1", choosen_lang), Sauvegarde.get_text("pie2", choosen_lang), Sauvegarde.get_text("pie3", choosen_lang)] possible_toppings = [Sauvegarde.get_text("topping1", choosen_lang), Sauvegarde.get_text("topping2", choosen_lang), "Aucun"] pie_icons = { Sauvegarde.get_text("pie1", choosen_lang): "res://assets/img/ui/client/orange.png", Sauvegarde.get_text("pie2", choosen_lang): "res://assets/img/ui/client/yellow.png", Sauvegarde.get_text("pie3", choosen_lang): "res://assets/img/ui/client/purple.png", } topping_icons = { Sauvegarde.get_text("topping1", choosen_lang): "res://assets/img/ui/client/meringue.png", Sauvegarde.get_text("topping2", choosen_lang): "res://assets/img/ui/client/croisillon.png", } desired_pie = possible_pies.pick_random() desired_topping = possible_toppings.pick_random() var p_icon var order_text func _physics_process(delta: float) -> void: if !player.one_time_cpt_feather: queue_free() if not is_on_floor(): velocity.y -= 9.8 * delta match current_state: State.ENTERING: if is_close_to_waiting: anim_player.play("talking") else: anim_player.play("walking") move_along_path(entry_path, delta) State.WAITING: anim_player.play("talking") velocity.x = move_toward(velocity.x, 0, speed) velocity.z = move_toward(velocity.z, 0, speed) State.LEAVING: anim_player.play("walking") move_along_path(exit_path, delta) move_and_slide() # --- FONCTION DE DÉPLACEMENT --- func move_along_path(path_array: Array[Marker3D], delta: float) -> void: if path_array.is_empty() or current_path_index >= path_array.size(): if current_state == State.ENTERING: start_waiting() elif current_state == State.LEAVING: queue_free() return # special pour l'attente if current_path_index >= path_array.size()-1: var targ = path_array[current_path_index].global_position if global_position.distance_to(Vector3(targ.x, global_position.y, targ.z)) < 4: is_close_to_waiting = true else: is_close_to_waiting = false look_at( targ ) var target = path_array[current_path_index].global_position var direction = global_position.direction_to(target) direction.y = 0 direction = direction.normalized() if global_position.distance_to(Vector3(target.x, global_position.y, target.z)) > 0.5: velocity.x = direction.x * speed velocity.z = direction.z * speed var target_angle = atan2(velocity.x, velocity.z) rotation.y = lerp_angle(rotation.y, target_angle, 10.0 * delta) else: current_path_index += 1 # --- ACTIONS DU CLIENT --- func start_waiting() -> void: ready_to_take_pie = true current_state = State.WAITING velocity = Vector3.ZERO p_icon = pie_icons[ desired_pie ] order_text = Sauvegarde.get_text("desire", choosen_lang) + desired_pie order_text += " [img=60]" + p_icon + "[/img]" if desired_topping != "Aucun": var t_icon = topping_icons[ desired_topping ] order_text += "\n+ " + desired_topping + " [img=80]" + t_icon + "[/img]" show_order() # pour tests #await get_tree().create_timer( 3 ).timeout #leave_store() # FONCTION MISE À JOUR : Le joueur doit donner la tarte ET le nappage func give_item(pie_given: String, topping_given: String) -> void: if current_state != State.WAITING: return sprite_e.visible = false # On vérifie les deux conditions if pie_given == desired_pie and topping_given == desired_topping: set_dialogue( Sauvegarde.get_text("goodpie", choosen_lang) ) leave_store() elif pie_given == desired_pie and topping_given != desired_topping: set_dialogue( Sauvegarde.get_text("mixpie", choosen_lang) ) await get_tree().create_timer(4).timeout show_order() else: set_dialogue( Sauvegarde.get_text("badpie", choosen_lang) ) await get_tree().create_timer(4).timeout show_order() func leave_store() -> void: player._end_action() ready_to_take_pie = false await get_tree().create_timer(2.0).timeout sprite.visible = false current_path_index = 0 current_state = State.LEAVING func set_dialogue(text: String) -> void: label.text = text func show_order(): set_dialogue(order_text) sprite.visible = true func _on_area_3de_body_entered(body: Node3D) -> void: if body.is_in_group("player"): if current_state == State.WAITING: sprite_e.visible = true func _on_area_3de_body_exited(body: Node3D) -> void: if body.is_in_group("player"): sprite_e.visible = false