extends Marker3D class_name AimTarget signal locked_changed(is_locked : bool) @export var enabled : bool = true @export var priority : float = 0.0 #plus c'est haut, plus la cible est favorisee @export_group("Indicator") @export var indicator : Node3D #optionnel : ton propre visuel (remplace le losange par defaut) @export var show_default_diamond : bool = true @export var diamond_size : float = 0.3 @export var diamond_color : Color = Color(1.0, 0.85, 0.2, 0.95) @export var diamond_offset : Vector3 = Vector3.ZERO #decalage par rapport a la node (ex. (0, 0.5, 0) pour le mettre au-dessus) var is_locked : bool = false func _ready() -> void: add_to_group("aim_targets") if indicator == null and show_default_diamond: indicator = create_diamond() add_child(indicator) if indicator: indicator.visible = false func create_diamond() -> MeshInstance3D: #carre incline a 45 degres, oriente vers la camera #(la rotation est appliquee directement aux sommets, car le billboard ignore la rotation de la node) var half : float = diamond_size * 0.3 var corners : Array[Vector3] = [ Vector3(-half, -half, 0.0), Vector3(half, -half, 0.0), Vector3(half, half, 0.0), Vector3(-half, half, 0.0), ] for i in corners.size(): corners[i] = corners[i].rotated(Vector3.BACK, deg_to_rad(45.0)) var st := SurfaceTool.new() st.begin(Mesh.PRIMITIVE_TRIANGLES) for i in [0, 1, 2, 0, 2, 3]: st.add_vertex(corners[i]) var mat := StandardMaterial3D.new() mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED mat.albedo_color = diamond_color mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA mat.billboard_mode = BaseMaterial3D.BILLBOARD_ENABLED mat.cull_mode = BaseMaterial3D.CULL_DISABLED mat.no_depth_test = true #reste visible meme a travers le modele de la cible mat.render_priority = 100 var mesh_instance := MeshInstance3D.new() mesh_instance.mesh = st.commit() mesh_instance.material_override = mat mesh_instance.position = diamond_offset mesh_instance.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF return mesh_instance func set_locked(value : bool) -> void: if is_locked == value: return is_locked = value if indicator: indicator.visible = value locked_changed.emit(value) #func try_mount(target_pokemon : PokemonData) -> bool: #if !MountRegistry.can_mount_on(target_pokemon, MountProfile.Surface.GROUND): #return false #play_char.current_mount = target_pokemon #transitioned.emit(self, "MountedState") #return true