9
9
using xivModdingFramework . General . Enums ;
10
10
using xivModdingFramework . Helpers ;
11
11
using xivModdingFramework . Items ;
12
+ using xivModdingFramework . Items . Categories ;
12
13
using xivModdingFramework . Items . DataContainers ;
13
14
using xivModdingFramework . Items . Enums ;
14
15
using xivModdingFramework . Items . Interfaces ;
@@ -67,9 +68,10 @@ public static async Task<List<IItemModel>> GetSharedMaterialItems(this IItemMode
67
68
var sameModelItems = new List < IItemModel > ( ) ;
68
69
sameModelItems = await item . GetSharedModelItems ( ) ;
69
70
70
- var sameMaterialItems = new List < IItemModel > ( ) ;
71
71
try
72
72
{
73
+ var sameMaterialItems = new List < IItemModel > ( ) ;
74
+
73
75
var imc = new Imc ( XivCache . GameInfo . GameDirectory ) ;
74
76
var originalInfo = await imc . GetImcInfo ( item ) ;
75
77
foreach ( var i in sameModelItems )
@@ -80,14 +82,15 @@ public static async Task<List<IItemModel>> GetSharedMaterialItems(this IItemMode
80
82
sameMaterialItems . Add ( i ) ;
81
83
}
82
84
}
85
+
86
+ sameMaterialItems = sameMaterialItems . OrderBy ( x => x . Name , new ItemNameComparer ( ) ) . ToList ( ) ;
87
+ return sameMaterialItems ;
83
88
} catch
84
89
{
85
- // No IMC file exists for this item.
86
- // It is by requirement the only item of its type then .
87
- sameMaterialItems . Add ( ( IItemModel ) item . Clone ( ) ) ;
90
+ // No IMC file exists for this item.
91
+ // In this case, it affects all items in the same root .
92
+ return sameModelItems ;
88
93
}
89
- sameMaterialItems = sameMaterialItems . OrderBy ( x => x . Name , new ItemNameComparer ( ) ) . ToList ( ) ;
90
- return sameMaterialItems ;
91
94
}
92
95
public static async Task < List < IItemModel > > GetSharedModelItems ( this IItemModel item )
93
96
{
@@ -189,14 +192,16 @@ public bool IsValid()
189
192
// Type -> TypeCode -> Id
190
193
private static readonly string RootFolderFormatSecondary = "obj/{0}/{1}{2}/" ;
191
194
195
+ private static readonly string HousingRootFolderFormat = "bgcommon/hou/{0}/general/{1}/" ;
196
+
197
+
192
198
// pPrefix => pId => sPrefix => sId => Slot
193
199
private static readonly string BaseFileFormatWithSlot = "{0}{1}{2}{3}_{4}" ;
194
200
private static readonly string BaseFileFormatNoSlot = "{0}{1}{2}{3}" ;
195
201
196
202
// {0} = BaseFileFormat
197
203
private static readonly string ModelNameFormat = "{0}.mdl" ;
198
204
199
-
200
205
/// <summary>
201
206
/// Gets the file name base for this root.
202
207
/// Ex c0101f0001_fac
@@ -225,11 +230,6 @@ public string GetBaseFileName()
225
230
}
226
231
227
232
public string GetRootFile ( )
228
- {
229
- return GetRootFolder ( ) + GetBaseFileName ( ) + ".root" ;
230
- }
231
-
232
- public string GetMetaFile ( )
233
233
{
234
234
return GetRootFolder ( ) + GetBaseFileName ( ) + ".meta" ;
235
235
}
@@ -240,23 +240,33 @@ public string GetMetaFile()
240
240
/// <returns></returns>
241
241
public string GetRootFolder ( )
242
242
{
243
- var pId = PrimaryId . ToString ( ) . PadLeft ( 4 , '0' ) ;
244
- var primary = String . Format ( RootFolderFormatPrimary , new string [ ] { XivItemTypes . GetSystemName ( PrimaryType ) , XivItemTypes . GetSystemPrefix ( PrimaryType ) , pId } ) ;
245
-
246
- var secondary = "" ;
247
- if ( SecondaryType != null )
243
+ if ( PrimaryType == XivItemType . indoor || PrimaryType == XivItemType . outdoor )
248
244
{
249
- var sId = SecondaryId . ToString ( ) . PadLeft ( 4 , '0' ) ;
250
- var sType = ( XivItemType ) SecondaryType ;
251
- secondary = String . Format ( RootFolderFormatSecondary , new string [ ] { XivItemTypes . GetSystemName ( sType ) , XivItemTypes . GetSystemPrefix ( sType ) , sId } ) ;
245
+ // BGCommon Dat stuff.
246
+ var pId = PrimaryId . ToString ( ) . PadLeft ( 4 , '0' ) ;
247
+ return String . Format ( HousingRootFolderFormat , new string [ ] { XivItemTypes . GetSystemName ( PrimaryType ) , pId } ) ;
252
248
}
249
+ else
250
+ {
251
+ // All the Dat 4 stuff.
252
+ var pId = PrimaryId . ToString ( ) . PadLeft ( 4 , '0' ) ;
253
+ var primary = String . Format ( RootFolderFormatPrimary , new string [ ] { XivItemTypes . GetSystemName ( PrimaryType ) , XivItemTypes . GetSystemPrefix ( PrimaryType ) , pId } ) ;
254
+
255
+ var secondary = "" ;
256
+ if ( SecondaryType != null )
257
+ {
258
+ var sId = SecondaryId . ToString ( ) . PadLeft ( 4 , '0' ) ;
259
+ var sType = ( XivItemType ) SecondaryType ;
260
+ secondary = String . Format ( RootFolderFormatSecondary , new string [ ] { XivItemTypes . GetSystemName ( sType ) , XivItemTypes . GetSystemPrefix ( sType ) , sId } ) ;
261
+ }
253
262
254
- return primary + secondary ;
263
+ return primary + secondary ;
264
+ }
255
265
}
256
266
257
267
public string GetSimpleModelName ( )
258
268
{
259
- if ( SecondaryType == null )
269
+ if ( PrimaryType == XivItemType . equipment || PrimaryType == XivItemType . accessory )
260
270
{
261
271
throw new NotSupportedException ( "Cannot generate simple model name for this type. EQDP file must Be used." ) ;
262
272
}
@@ -406,6 +416,13 @@ public XivDependencyRoot(XivDependencyRootInfo info)
406
416
// initial crawls up the tree are janky.
407
417
Info . Slot = "top" ;
408
418
}
419
+ } else if ( Info . PrimaryType == XivItemType . indoor )
420
+ {
421
+ Info . Slot = "fun" ;
422
+
423
+ } else if ( Info . PrimaryType == XivItemType . outdoor )
424
+ {
425
+ Info . Slot = "gar" ;
409
426
}
410
427
}
411
428
@@ -482,6 +499,11 @@ public async Task<List<string>> GetModelFiles()
482
499
models . Add ( Info . GetRootFolder ( ) + "model/" + Info . GetRacialModelName ( race ) ) ;
483
500
}
484
501
return models ;
502
+ } else if ( Info . PrimaryType == XivItemType . indoor || Info . PrimaryType == XivItemType . outdoor )
503
+ {
504
+ var _housing = new Housing ( XivCache . GameInfo . GameDirectory , XivCache . GameInfo . GameLanguage ) ;
505
+ var housingAssets = await _housing . GetFurnitureModelParts ( Info . PrimaryId , Info . PrimaryType ) ;
506
+ return housingAssets . Select ( x => x . Value ) . ToList ( ) ;
485
507
} else {
486
508
// The rest of the types just have a single, calculateable model path.
487
509
var folder = Info . GetRootFolder ( ) ;
@@ -560,6 +582,13 @@ public async Task<List<string>> GetTextureFiles(int materialVariant = -1)
560
582
public string GetRawImcFilePath ( )
561
583
{
562
584
var imcPath = "" ;
585
+ if ( Info . PrimaryType == XivItemType . indoor || Info . PrimaryType == XivItemType . outdoor )
586
+ {
587
+ // These types can never have IMC entries.
588
+ return null ;
589
+ }
590
+
591
+
563
592
if ( Info . SecondaryType == null )
564
593
{
565
594
var iPrefix = XivItemTypes . GetSystemPrefix ( Info . PrimaryType ) ;
@@ -889,6 +918,11 @@ public async Task<List<IItemModel>> GetAllItems(int imcSubset = -1)
889
918
items = items . Where ( x => x . ModelInfo . ImcSubsetID == imcSubset ) . ToList ( ) ;
890
919
}
891
920
921
+ if ( items . Count == 0 ) {
922
+ // May as well make a raw item.
923
+ items . Add ( ToRawItem ( ) ) ;
924
+ }
925
+
892
926
items = items . OrderBy ( x => x . Name , new ItemNameComparer ( ) ) . ToList ( ) ;
893
927
894
928
return items ;
@@ -955,18 +989,8 @@ internal static class XivDependencyGraph
955
989
XivItemType . monster ,
956
990
XivItemType . demihuman ,
957
991
XivItemType . human ,
958
-
959
- // XivItemType.body, // Needs some extra custom handling still for skin materials.
960
-
961
- /*
962
- // These types need more work for dependency suppport.
963
-
964
- // Furniture primarily needs the appropriate function for resolving the model files,
965
- // and the meta sgd(sp?) file that they have instead of an IMC file.
966
992
XivItemType . indoor ,
967
993
XivItemType . outdoor ,
968
- */
969
-
970
994
} ;
971
995
972
996
// Captures the file extension of a file (even if it has a binary extension)
@@ -993,6 +1017,12 @@ internal static class XivDependencyGraph
993
1017
994
1018
private static readonly Regex PrimaryExtractionRegex = new Regex ( "^chara\\ /([a-z]+)\\ /[a-z]([0-9]{4})(?:\\ /obj\\ /([a-z]+)\\ /[a-z]([0-9]{4})\\ /?)?.*$" ) ;
995
1019
1020
+
1021
+ // Group 0 == Full File path
1022
+ // Group 1 == Type (indoor/outdoor)
1023
+ // Group 2 == Primary Id
1024
+ private static readonly Regex HousingExtractionRegex = new Regex ( "^bgcommon/hou/([a-z]+)/general/([0-9]+)/?.*$" ) ;
1025
+
996
1026
/// <summary>
997
1027
/// Returns all parent files that this child file depends on as part of its rendering process.
998
1028
/// </summary>
@@ -1110,6 +1140,12 @@ public static async Task<List<string>> GetSiblingFiles(string internalFilePath)
1110
1140
siblings . Add ( c ) ;
1111
1141
}
1112
1142
}
1143
+
1144
+ if ( siblings . Count == 0 )
1145
+ {
1146
+ siblings . Add ( internalFilePath ) ;
1147
+ }
1148
+
1113
1149
return siblings . ToList ( ) ;
1114
1150
}
1115
1151
@@ -1162,7 +1198,7 @@ public static async Task<List<string>> GetChildFiles(string internalFilePath)
1162
1198
{
1163
1199
var dataFile = IOUtil . GetDataFileFromPath ( internalFilePath ) ;
1164
1200
var _mtrl = new Mtrl ( XivCache . GameInfo . GameDirectory , dataFile , XivCache . GameInfo . GameLanguage ) ;
1165
- var mtrlChildren = await _mtrl . GetTexturePathsFromMtrlPath ( internalFilePath , false ) ;
1201
+ var mtrlChildren = await _mtrl . GetTexturePathsFromMtrlPath ( internalFilePath , false , false ) ;
1166
1202
return mtrlChildren ;
1167
1203
} catch
1168
1204
{
@@ -1291,7 +1327,6 @@ public static XivDependencyRoot CreateDependencyRoot(XivDependencyRootInfo info)
1291
1327
// they'll have their root resolved via modlist, if one exists for them.
1292
1328
if ( info . PrimaryType == XivItemType . equipment
1293
1329
|| info . PrimaryType == XivItemType . accessory
1294
- || info . PrimaryType == XivItemType . human
1295
1330
|| info . PrimaryType == XivItemType . demihuman )
1296
1331
{
1297
1332
return null ;
@@ -1300,7 +1335,7 @@ public static XivDependencyRoot CreateDependencyRoot(XivDependencyRootInfo info)
1300
1335
1301
1336
// Only these types can get away without a secondary type.
1302
1337
if ( info . SecondaryType == null ) {
1303
- if ( info . PrimaryType != XivItemType . equipment && info . PrimaryType != XivItemType . accessory ) {
1338
+ if ( info . PrimaryType != XivItemType . equipment && info . PrimaryType != XivItemType . accessory && info . PrimaryType != XivItemType . indoor && info . PrimaryType != XivItemType . outdoor ) {
1304
1339
return null ;
1305
1340
}
1306
1341
}
@@ -1384,7 +1419,18 @@ public static XivDependencyRootInfo ExtractRootInfo(string internalFilePath)
1384
1419
info . Slot = match . Groups [ 1 ] . Value ;
1385
1420
}
1386
1421
}
1422
+ else
1423
+ {
1424
+ // Might be a housing item.
1425
+ match = HousingExtractionRegex . Match ( internalFilePath ) ;
1426
+ if ( match . Success )
1427
+ {
1428
+ info . PrimaryType = XivItemTypes . FromSystemName ( match . Groups [ 1 ] . Value ) ;
1429
+ info . PrimaryId = Int32 . Parse ( match . Groups [ 2 ] . Value ) ;
1387
1430
1431
+ info . Slot = info . PrimaryType == XivItemType . indoor ? "fun" : "gar" ;
1432
+ }
1433
+ }
1388
1434
1389
1435
return info ;
1390
1436
}
0 commit comments