@@ -868,12 +868,24 @@ func _apply_all_tooltips() -> void:
868868 _set_tooltip (sides_spin , "Side count for polygon shapes (Pyramid, Prism)" )
869869 _set_tooltip (commit_freeze , "Keep committed cuts frozen (restorable)\n instead of deleting them" )
870870 _set_tooltip (collision_layer_opt , "Physics collision layer for baked geometry" )
871- _set_tooltip (active_material_button , "Active material for Select+Paint brush painting" )
871+ _set_tooltip (
872+ active_material_button ,
873+ (
874+ "Brush-level material override for whole brushes"
875+ + "\n This is separate from per-face materials in the Materials tab"
876+ )
877+ )
872878 # Build tab - Bake options
873879 _set_tooltip (bake_merge_meshes , "Merge meshes during bake for better performance" )
874880 _set_tooltip (bake_generate_lods , "Generate LOD meshes during bake" )
875881 _set_tooltip (bake_lightmap_uv2 , "Generate UV2 for lightmap baking" )
876- _set_tooltip (bake_use_face_materials , "Apply per-face materials from the Materials tab" )
882+ _set_tooltip (
883+ bake_use_face_materials ,
884+ (
885+ "Bake per-face materials into the final mesh"
886+ + "\n Turn off to ignore face assignments and use brush-level materials instead"
887+ )
888+ )
877889 _set_tooltip (bake_navmesh , "Generate navigation mesh during bake" )
878890 _set_tooltip (bake_lightmap_texel , "Lightmap texel density (smaller = higher quality)" )
879891 _set_tooltip (bake_navmesh_cell_size , "Navigation mesh cell size (XZ)" )
@@ -902,13 +914,25 @@ func _apply_all_tooltips() -> void:
902914 _set_tooltip (layer_y_spin , "Vertical Y offset for the active paint layer" )
903915 _set_tooltip (blend_strength_spin , "Blend strength when using the Blend paint tool" )
904916 _set_tooltip (blend_slot_select , "Blend target slot (B, C, or D)" )
905- _set_tooltip (terrain_slot_a_button , "Texture for Slot A (base)" )
917+ _set_tooltip (
918+ terrain_slot_a_button ,
919+ "Choose terrain texture for Slot A (base layer)\n Blend between slots with the Blend paint tool"
920+ )
906921 _set_tooltip (terrain_slot_a_scale , "UV scale for Slot A texture" )
907- _set_tooltip (terrain_slot_b_button , "Texture for Slot B" )
922+ _set_tooltip (
923+ terrain_slot_b_button ,
924+ "Choose terrain texture for Slot B\n Blend between slots with the Blend paint tool"
925+ )
908926 _set_tooltip (terrain_slot_b_scale , "UV scale for Slot B texture" )
909- _set_tooltip (terrain_slot_c_button , "Texture for Slot C" )
927+ _set_tooltip (
928+ terrain_slot_c_button ,
929+ "Choose terrain texture for Slot C\n Blend between slots with the Blend paint tool"
930+ )
910931 _set_tooltip (terrain_slot_c_scale , "UV scale for Slot C texture" )
911- _set_tooltip (terrain_slot_d_button , "Texture for Slot D" )
932+ _set_tooltip (
933+ terrain_slot_d_button ,
934+ "Choose terrain texture for Slot D\n Blend between slots with the Blend paint tool"
935+ )
912936 _set_tooltip (terrain_slot_d_scale , "UV scale for Slot D texture" )
913937 # SurfacePaint tab
914938 _set_tooltip (paint_target_select , "Paint target: Floor (grid) or Surface (UV)" )
@@ -917,21 +941,48 @@ func _apply_all_tooltips() -> void:
917941 _set_tooltip (surface_paint_layer_select , "Active surface paint layer" )
918942 _set_tooltip (surface_paint_layer_add , "Add a new surface paint layer" )
919943 _set_tooltip (surface_paint_layer_remove , "Remove the selected surface paint layer" )
920- _set_tooltip (surface_paint_texture , "Texture for the selected surface paint layer" )
944+ _set_tooltip (
945+ surface_paint_texture ,
946+ (
947+ "Choose the texture for the selected surface-paint layer"
948+ + "\n Requires a selected face and an existing paint layer"
949+ )
950+ )
921951 # Materials tab
922952 _set_tooltip (
923953 face_select_mode ,
924- "Enable per-face selection for material assignment\n Click faces in viewport to select them"
954+ (
955+ "Enable per-face texturing"
956+ + "\n Click faces in the viewport to select them"
957+ + "\n Shift+Click adds more faces"
958+ + "\n Required for per-face assign, UV edit, and surface paint"
959+ )
925960 )
926961 _set_tooltip (material_add , "Add a material to the palette" )
927962 _set_tooltip (material_remove , "Remove selected material from palette" )
928963 _set_tooltip (
929- material_load_prototypes , "Refresh all built-in prototype textures into the palette"
964+ material_load_prototypes ,
965+ (
966+ "Load built-in prototype textures into the palette"
967+ + "\n Use this first if the browser looks empty"
968+ )
969+ )
970+ _set_tooltip (
971+ material_assign ,
972+ (
973+ "Apply the selected material to all selected faces"
974+ + "\n Tip: choose a texture in the browser, then click faces in Face Select Mode"
975+ )
930976 )
931- _set_tooltip (material_assign , "Assign selected material to selected faces" )
932977 _set_tooltip (face_clear , "Clear face selection" )
933978 # UV tab
934- _set_tooltip (uv_reset , "Reset UV coordinates to defaults for selected face" )
979+ _set_tooltip (
980+ uv_reset ,
981+ (
982+ "Reset this face to default projected UVs"
983+ + "\n Use after stretching or before Fit/Center/Left/Right justify"
984+ )
985+ )
935986 # Manage tab
936987 _set_tooltip (floor_btn , "Create a default floor brush" )
937988 _set_tooltip (apply_cuts_btn , "Move pending cuts into the draft brush tree" )
@@ -3663,9 +3714,44 @@ func _on_material_assign() -> void:
36633714 return
36643715 if not level_root :
36653716 return
3717+ var face_count := _count_selected_faces ()
3718+ if face_count == 0 :
3719+ show_toast ("No faces selected — select faces first" , 1 )
3720+ return
36663721 _commit_state_action (
36673722 "Assign Face Material" , "assign_material_to_selected_faces" , [_selected_material_index ]
36683723 )
3724+ var mat_name := _material_display_name (_selected_material_index )
3725+ show_toast (
3726+ "Applied %s to %d face%s " % [mat_name , face_count , "" if face_count == 1 else "s" ], 0
3727+ )
3728+
3729+
3730+ func _count_selected_faces () -> int :
3731+ if not level_root :
3732+ return 0
3733+ var total := 0
3734+ for key in level_root .face_selection .keys ():
3735+ var brush = level_root ._find_brush_by_key (str (key ))
3736+ if not brush :
3737+ continue
3738+ var indices : Array = level_root .face_selection .get (key , [])
3739+ for idx in indices :
3740+ if int (idx ) >= 0 and int (idx ) < brush .faces .size ():
3741+ total += 1
3742+ return total
3743+
3744+
3745+ func _material_display_name (index : int ) -> String :
3746+ if not level_root or not level_root .material_manager :
3747+ return "material"
3748+ var mat = level_root .material_manager .get_material (index )
3749+ if mat == null :
3750+ return "material"
3751+ var name : String = (
3752+ mat .resource_name if mat .resource_name != "" else mat .resource_path .get_file ()
3753+ )
3754+ return name if name != "" else "material"
36693755
36703756
36713757func _on_face_clear () -> void :
@@ -3690,7 +3776,15 @@ func _on_browser_material_double_clicked(index: int) -> void:
36903776 material_browser .set_selected_index (index )
36913777 # Double-click triggers immediate face assignment.
36923778 if level_root and index >= 0 :
3779+ var face_count := _count_selected_faces ()
3780+ if face_count == 0 :
3781+ show_toast ("No faces selected — select faces first" , 1 )
3782+ return
36933783 _commit_state_action ("Assign Face Material" , "assign_material_to_selected_faces" , [index ])
3784+ var mat_name := _material_display_name (index )
3785+ show_toast (
3786+ "Applied %s to %d face%s " % [mat_name , face_count , "" if face_count == 1 else "s" ], 0
3787+ )
36943788
36953789
36963790func _on_browser_context_menu (index : int , global_pos : Vector2 ) -> void :
@@ -3711,19 +3805,34 @@ func _on_material_context_action(id: int) -> void:
37113805 var idx = _material_context_index
37123806 if idx < 0 :
37133807 return
3808+ var mat_name := _material_display_name (idx )
37143809 match id :
37153810 0 : # Apply to Selected Faces
37163811 _selected_material_index = idx
3812+ var face_count := _count_selected_faces ()
3813+ if face_count == 0 :
3814+ show_toast ("No faces selected — select faces first" , 1 )
3815+ return
37173816 _commit_state_action ("Assign Face Material" , "assign_material_to_selected_faces" , [idx ])
3817+ show_toast (
3818+ "Applied %s to %d face%s " % [mat_name , face_count , "" if face_count == 1 else "s" ],
3819+ 0
3820+ )
37183821 1 : # Apply to Whole Brush — assign material to ALL faces on selected brushes
37193822 _selected_material_index = idx
3720- if _selection_nodes .is_empty ():
3823+ var brush_ids := _get_selected_brush_ids ()
3824+ if brush_ids .is_empty ():
37213825 show_toast ("No brushes selected" , 1 )
37223826 return
37233827 _commit_state_action (
3724- "Assign Brush Material" ,
3725- "assign_material_to_whole_brushes" ,
3726- [idx , _get_selected_brush_ids ()]
3828+ "Assign Brush Material" , "assign_material_to_whole_brushes" , [idx , brush_ids ]
3829+ )
3830+ show_toast (
3831+ (
3832+ "Applied %s to %d brush%s "
3833+ % [mat_name , brush_ids .size (), "" if brush_ids .size () == 1 else "es" ]
3834+ ),
3835+ 0
37273836 )
37283837 2 : # Toggle Favorite
37293838 if material_browser :
@@ -4832,7 +4941,7 @@ func _setup_texture_lock_ui() -> void:
48324941 texture_lock_check = CheckBox .new ()
48334942 texture_lock_check .text = "Texture Lock"
48344943 texture_lock_check .button_pressed = true
4835- texture_lock_check .tooltip_text = "Preserve UV alignment when moving or resizing brushes"
4944+ texture_lock_check .tooltip_text = "Keep texture alignment while moving, resizing, hollowing, or clipping brushes"
48364945 texture_lock_check .toggled .connect (_on_texture_lock_toggled )
48374946 brush_vbox .add_child (texture_lock_check )
48384947
0 commit comments