@@ -6,7 +6,7 @@ use crate::resource_pack::files::model::Model;
66use crate :: resource_pack:: files:: sound:: Sound ;
77use crate :: resource_pack:: files:: texture:: Texture ;
88use crate :: resource_pack:: identifier:: Identifier ;
9- use crate :: resource_pack:: mapping:: Mapping ;
9+ use crate :: resource_pack:: mapping:: { self , Mapping } ;
1010use crate :: resource_pack:: resource_pack:: ResourcePack ;
1111use crate :: { LogLevel , LogMessage } ;
1212use serde_json:: json;
@@ -18,10 +18,11 @@ pub fn rename_files(
1818 pack : & ResourcePack ,
1919 mapping : & mut Mapping ,
2020) {
21+ let id_counter = & mapping:: get_id_usage_counter ( ) ;
2122 rename_overlays ( pack, mapping) ;
22- rename_models ( pack, mapping) ;
23- rename_textures ( logger, & pack, mapping) ;
24- rename_sounds ( pack, mapping) ;
23+ rename_models ( pack, mapping, id_counter ) ;
24+ rename_textures ( logger, & pack, mapping, id_counter ) ;
25+ rename_sounds ( pack, mapping, id_counter ) ;
2526}
2627
2728fn rename_overlays ( pack : & ResourcePack , mapping : & mut Mapping ) {
@@ -51,31 +52,46 @@ fn rename_overlays(pack: &ResourcePack, mapping: &mut Mapping) {
5152 }
5253}
5354
54- fn rename_sounds ( pack : & ResourcePack , mapping : & mut Mapping ) {
55- let mut count = 0 ;
56- for x in pack. sounds . clone ( ) . iter ( ) {
57- let identifier = x. identifier . to_string ( ) ;
58- if x. identifier . namespace == "minecraft" {
59- // Skip sounds if they are overwriting Minecraft files
60- if builtin_files:: is_in_sounds ( identifier. as_str ( ) ) {
61- continue ;
62- }
63- }
55+ fn rename_sounds ( pack : & ResourcePack , mapping : & mut Mapping , id_counter : & mapping:: IdUsageCounter ) {
56+ let mut sounds: Vec < ( String , Sound ) > = pack
57+ . sounds
58+ . iter ( )
59+ . map ( |entry| ( entry. key ( ) . clone ( ) , entry. value ( ) . clone ( ) ) )
60+ . collect ( ) ;
61+
62+ sounds. retain ( |( _, x) | {
63+ !( x. identifier . namespace == "minecraft"
64+ && builtin_files:: is_in_sounds ( x. identifier . to_string ( ) . as_str ( ) ) )
65+ } ) ;
66+
67+ sounds. sort_by ( |( _, a) , ( _, b) | {
68+ let a_id = a. identifier . to_string ( ) ;
69+ let b_id = b. identifier . to_string ( ) ;
70+
71+ let a_usage = id_counter. get_usage_count ( & a_id, mapping:: IdCategory :: Sound ) ;
72+ let b_usage = id_counter. get_usage_count ( & b_id, mapping:: IdCategory :: Sound ) ;
73+
74+ // Higher usage first
75+ b_usage
76+ . cmp ( & a_usage)
77+ // Stable deterministic fallback so the same resource pack is generated each time
78+ . then_with ( || a_id. cmp ( & b_id) )
79+ } ) ;
80+
81+ for ( count, ( key, mut sound) ) in sounds. into_iter ( ) . enumerate ( ) {
82+ let identifier = sound. identifier . to_string ( ) ;
6483 if let Some ( mapped) = mapping. sound_mappings . get ( & identifier) {
65- let mut new_sound: Sound = x. clone ( ) ;
66- new_sound. identifier . path = mapped. clone ( ) ;
67- pack. sounds . remove ( & x. key ( ) . to_string ( ) ) ;
68- pack. sounds . insert ( new_sound. path ( ) , new_sound) ;
84+ sound. identifier . path = mapped. clone ( ) ;
85+ pack. sounds . remove ( & key) ;
86+ pack. sounds . insert ( sound. path ( ) , sound) ;
6987 } else {
7088 let new_identifier = Identifier :: new ( "_" , generate_short_name ( count) ) ;
7189 mapping
7290 . sound_mappings
7391 . insert ( identifier, new_identifier. to_string ( ) ) ;
74- let mut new_sound: Sound = x. clone ( ) ;
75- new_sound. identifier = new_identifier;
76- pack. sounds . remove ( & x. key ( ) . to_string ( ) ) ;
77- pack. sounds . insert ( new_sound. path ( ) , new_sound) ;
78- count += 1 ;
92+ sound. identifier = new_identifier;
93+ pack. sounds . remove ( & key) ;
94+ pack. sounds . insert ( sound. path ( ) , sound) ;
7995 }
8096 }
8197}
@@ -84,56 +100,72 @@ fn rename_textures(
84100 logger : & UnboundedSender < LogMessage > ,
85101 pack : & & ResourcePack ,
86102 mapping : & mut Mapping ,
103+ id_counter : & mapping:: IdUsageCounter ,
87104) {
105+ let mut textures: Vec < ( String , Texture ) > = pack
106+ . textures
107+ . iter ( )
108+ . map ( |entry| ( entry. key ( ) . clone ( ) , entry. value ( ) . clone ( ) ) )
109+ . collect ( ) ;
110+
111+ textures. retain ( |( _, x) | {
112+ !( x. identifier . namespace == "minecraft"
113+ && builtin_files:: is_in_textures ( x. identifier . to_string ( ) . as_str ( ) ) )
114+ } ) ;
115+
116+ textures. sort_by ( |( _, a) , ( _, b) | {
117+ let a_id = a. identifier . to_string ( ) ;
118+ let b_id = b. identifier . to_string ( ) ;
119+
120+ let a_usage = id_counter. get_usage_count ( & a_id, mapping:: IdCategory :: Texture ) ;
121+ let b_usage = id_counter. get_usage_count ( & b_id, mapping:: IdCategory :: Texture ) ;
122+
123+ // Higher usage first
124+ b_usage
125+ . cmp ( & a_usage)
126+ // Stable deterministic fallback so the same resource pack is generated each time
127+ . then_with ( || a_id. cmp ( & b_id) )
128+ } ) ;
129+
88130 let mut per_folder_count: HashMap < String , usize > = HashMap :: new ( ) ;
89131 let font_textures = get_font_textures ( pack) ;
90- for x in pack. textures . clone ( ) . iter ( ) {
91- let identifier = x. identifier . to_string ( ) ;
92- if x. identifier . namespace == "minecraft" {
93- // Skip textures if they are overwriting Minecraft files
94- if builtin_files:: is_in_textures ( identifier. as_str ( ) ) {
95- continue ;
96- }
97- }
132+ for ( _, ( key, mut texture) ) in textures. into_iter ( ) . enumerate ( ) {
133+ let identifier = texture. identifier . to_string ( ) ;
98134 if let Some ( mapped) = mapping. texture_mappings . get ( & identifier) {
99- let mut new_texture: Texture = x. clone ( ) ;
100- new_texture. identifier . path = mapped. clone ( ) ;
101- pack. textures . remove ( x. key ( ) ) ;
102- let new_path = new_texture. path ( ) ;
103- if let Some ( mcmeta) = pack
104- . json_files
105- . remove ( format ! ( "{}.mcmeta" , x. key( ) ) . as_str ( ) )
106- {
135+ texture. identifier . path = mapped. clone ( ) ;
136+ pack. textures . remove ( & key) ;
137+ let new_path = texture. path ( ) ;
138+ if let Some ( mcmeta) = pack. json_files . remove ( format ! ( "{}.mcmeta" , key) . as_str ( ) ) {
107139 pack. json_files
108140 . insert ( format ! ( "{}.mcmeta" , new_path) , mcmeta. 1 ) ;
109141 } ;
110- pack. textures . insert ( new_path, new_texture ) ;
142+ pack. textures . insert ( new_path, texture ) ;
111143 } else {
112144 let mut in_items = false ;
113145 let mut in_blocks = false ;
114- let in_font = font_textures. contains ( & x . identifier . to_string ( ) ) ;
146+ let in_font = font_textures. contains ( & texture . identifier . to_string ( ) ) ;
115147 let mut aliases = Vec :: new ( ) ;
116148 for atlas in & pack. atlases {
117- if atlas. overlay != x . overlay {
149+ if atlas. overlay != texture . overlay {
118150 continue ;
119151 }
120152 match atlas. atlas_type {
121153 AtlasType :: Blocks => {
122- if let Some ( id) = atlas. get_identifier ( & x . identifier ) {
154+ if let Some ( id) = atlas. get_identifier ( & texture . identifier ) {
123155 in_blocks = true ;
124156 aliases. push ( id) ;
125157 }
126158 }
127159 AtlasType :: Items => {
128- if let Some ( id) = atlas. get_identifier ( & x . identifier ) {
160+ if let Some ( id) = atlas. get_identifier ( & texture . identifier ) {
129161 in_items = true ;
130162 aliases. push ( id) ;
131163 }
132164 }
133165 _ => { }
134166 }
135167 }
136- match builtin_files:: get_atlas ( x . identifier . path . as_str ( ) ) {
168+ match builtin_files:: get_atlas ( texture . identifier . path . as_str ( ) ) {
137169 Some ( AtlasType :: Blocks ) => {
138170 in_blocks = true ;
139171 }
@@ -148,7 +180,7 @@ fn rename_textures(
148180 level : LogLevel :: Warning ,
149181 message : format ! (
150182 "'{}' is both in blocks and items atlas. Using blocks atlas." ,
151- x . path( )
183+ texture . path( )
152184 ) ,
153185 } ) ;
154186 }
@@ -166,18 +198,14 @@ fn rename_textures(
166198 mapping
167199 . texture_mappings
168200 . insert ( identifier, new_identifier. to_string ( ) ) ;
169- let mut new_texture: Texture = x. clone ( ) ;
170- new_texture. identifier = new_identifier;
171- pack. textures . remove ( x. key ( ) ) ;
172- let new_path = new_texture. path ( ) ;
173- if let Some ( mcmeta) = pack
174- . json_files
175- . remove ( format ! ( "{}.mcmeta" , x. key( ) ) . as_str ( ) )
176- {
201+ texture. identifier = new_identifier;
202+ pack. textures . remove ( & key) ;
203+ let new_path = texture. path ( ) ;
204+ if let Some ( mcmeta) = pack. json_files . remove ( format ! ( "{}.mcmeta" , key) . as_str ( ) ) {
177205 pack. json_files
178206 . insert ( format ! ( "{}.mcmeta" , new_path) , mcmeta. 1 ) ;
179207 } ;
180- pack. textures . insert ( new_path, new_texture ) ;
208+ pack. textures . insert ( new_path, texture ) ;
181209 * count += 1 ;
182210 }
183211 }
@@ -229,31 +257,46 @@ fn rebuild_atlas(pack: &ResourcePack) {
229257 }
230258}
231259
232- fn rename_models ( pack : & ResourcePack , mapping : & mut Mapping ) {
233- let mut count = 0 ;
234- for x in pack. models . clone ( ) . iter ( ) {
235- let identifier = x. identifier . to_string ( ) ;
236- if x. identifier . namespace == "minecraft" {
237- // Skip models if they are overwriting Minecraft files
238- if builtin_files:: is_in_models ( identifier. as_str ( ) ) {
239- continue ;
240- }
241- }
260+ fn rename_models ( pack : & ResourcePack , mapping : & mut Mapping , id_counter : & mapping:: IdUsageCounter ) {
261+ let mut models: Vec < ( String , Model ) > = pack
262+ . models
263+ . iter ( )
264+ . map ( |entry| ( entry. key ( ) . clone ( ) , entry. value ( ) . clone ( ) ) )
265+ . collect ( ) ;
266+
267+ models. retain ( |( _, x) | {
268+ !( x. identifier . namespace == "minecraft"
269+ && builtin_files:: is_in_models ( x. identifier . to_string ( ) . as_str ( ) ) )
270+ } ) ;
271+
272+ models. sort_by ( |( _, a) , ( _, b) | {
273+ let a_id = a. identifier . to_string ( ) ;
274+ let b_id = b. identifier . to_string ( ) ;
275+
276+ let a_usage = id_counter. get_usage_count ( & a_id, mapping:: IdCategory :: Model ) ;
277+ let b_usage = id_counter. get_usage_count ( & b_id, mapping:: IdCategory :: Model ) ;
278+
279+ // Higher usage first
280+ b_usage
281+ . cmp ( & a_usage)
282+ // Stable deterministic fallback so the same resource pack is generated each time
283+ . then_with ( || a_id. cmp ( & b_id) )
284+ } ) ;
285+
286+ for ( count, ( key, mut model) ) in models. into_iter ( ) . enumerate ( ) {
287+ let identifier = model. identifier . to_string ( ) ;
242288 if let Some ( mapped) = mapping. model_mappings . get ( & identifier) {
243- let mut new_model: Model = x. clone ( ) ;
244- new_model. identifier . path = mapped. clone ( ) ;
245- pack. models . remove ( & x. key ( ) . to_string ( ) ) ;
246- pack. models . insert ( new_model. path ( ) , new_model) ;
289+ model. identifier . path = mapped. clone ( ) ;
290+ pack. models . remove ( & key) ;
291+ pack. models . insert ( model. path ( ) , model) ;
247292 } else {
248293 let new_identifier = Identifier :: new ( "_" , generate_short_name ( count) ) ;
249294 mapping
250295 . model_mappings
251296 . insert ( identifier, new_identifier. to_string ( ) ) ;
252- let mut new_model: Model = x. clone ( ) ;
253- new_model. identifier = new_identifier;
254- pack. models . remove ( & x. key ( ) . to_string ( ) ) ;
255- pack. models . insert ( new_model. path ( ) , new_model) ;
256- count += 1 ;
297+ model. identifier = new_identifier;
298+ pack. models . remove ( & key) ;
299+ pack. models . insert ( model. path ( ) , model) ;
257300 }
258301 }
259302}
0 commit comments