17
17
using xivModdingFramework . Models . DataContainers ;
18
18
using xivModdingFramework . Models . FileTypes ;
19
19
using xivModdingFramework . Mods ;
20
+ using xivModdingFramework . Mods . DataContainers ;
21
+ using xivModdingFramework . Mods . FileTypes ;
20
22
using xivModdingFramework . Resources ;
23
+ using xivModdingFramework . SqPack . DataContainers ;
21
24
using xivModdingFramework . SqPack . FileTypes ;
22
25
using xivModdingFramework . Variants . FileTypes ;
23
26
using static xivModdingFramework . Cache . XivCache ;
@@ -492,14 +495,25 @@ public override int GetHashCode()
492
495
/// Gets all the model files in this dependency chain.
493
496
/// </summary>
494
497
/// <returns></returns>
495
- public async Task < List < string > > GetModelFiles ( )
498
+ public async Task < List < string > > GetModelFiles ( IndexFile index = null , ModList modlist = null )
496
499
{
497
500
// Some chains have no meta entries, and jump straight to models.
498
501
// Try to resolve Meta files first.
499
502
if ( Info . PrimaryType == XivItemType . equipment || Info . PrimaryType == XivItemType . accessory )
500
503
{
501
504
var _eqp = new Eqp ( XivCache . GameInfo . GameDirectory ) ;
502
- var races = await _eqp . GetAvailableRacialModels ( Info . PrimaryId , Info . Slot , false , true ) ;
505
+
506
+ List < XivRace > races = null ;
507
+ if ( index != null )
508
+ {
509
+ var metadata = await ItemMetadata . GetFromCachedIndex ( this , index ) ;
510
+ races = metadata . EqdpEntries . Where ( x => x . Value . bit1 ) . Select ( x => x . Key ) . ToList ( ) ;
511
+ }
512
+ else
513
+ {
514
+ races = await _eqp . GetAvailableRacialModels ( Info . PrimaryId , Info . Slot , false , true ) ;
515
+ }
516
+
503
517
var models = new List < string > ( ) ;
504
518
foreach ( var race in races )
505
519
{
@@ -523,8 +537,13 @@ public async Task<List<string>> GetModelFiles()
523
537
if ( Info . PrimaryType == XivItemType . human && Info . SecondaryType != XivItemType . hair && Info . SecondaryId / 100 >= 1 )
524
538
{
525
539
// For human types, if their model is missing, the version 00xx is used instead.
526
- var index = new Index ( XivCache . GameInfo . GameDirectory ) ;
527
- if ( ! ( await index . FileExists ( modelPath ) ) )
540
+ if ( index == null )
541
+ {
542
+ var _index = new Index ( XivCache . GameInfo . GameDirectory ) ;
543
+ index = await _index . GetIndexFile ( IOUtil . GetDataFileFromPath ( modelPath ) , false , true ) ;
544
+ }
545
+
546
+ if ( ! ( index . FileExists ( modelPath ) ) )
528
547
{
529
548
var replacementNumber = ( Info . SecondaryId % 100 ) ;
530
549
var alteredRoot = new XivDependencyRoot ( Info . PrimaryType , Info . PrimaryId , Info . SecondaryType , replacementNumber , Info . Slot ) ;
@@ -546,8 +565,9 @@ public async Task<List<string>> GetModelFiles()
546
565
/// Subsets of this data may be accessed with XivDependencyGraph::GetChildFiles(internalFilePath).
547
566
/// </summary>
548
567
/// <returns></returns>
549
- public async Task < List < string > > GetMaterialFiles ( int materialVariant = - 1 )
568
+ public async Task < List < string > > GetMaterialFiles ( int materialVariant = - 1 , IndexFile index = null , ModList modlist = null )
550
569
{
570
+ var useCache = index == null ;
551
571
552
572
var materials = new HashSet < string > ( ) ;
553
573
if ( Info . PrimaryType == XivItemType . human && Info . SecondaryType == XivItemType . body )
@@ -560,8 +580,13 @@ public async Task<List<string>> GetMaterialFiles(int materialVariant = -1)
560
580
var path = $ "chara/human/c{ primary } /obj/body/b{ body } /material/v0001/mt_c{ primary } b{ body } _a.mtrl";
561
581
562
582
// Just validate it exists and call it a day.
563
- var index = new Index ( XivCache . GameInfo . GameDirectory ) ;
564
- var exists = await index . FileExists ( path ) ;
583
+ if ( index == null )
584
+ {
585
+ var _index = new Index ( XivCache . GameInfo . GameDirectory ) ;
586
+ index = await _index . GetIndexFile ( IOUtil . GetDataFileFromPath ( path ) , false , true ) ;
587
+ }
588
+
589
+ var exists = index . FileExists ( path ) ;
565
590
if ( exists )
566
591
{
567
592
materials . Add ( path ) ;
@@ -582,7 +607,7 @@ public async Task<List<string>> GetMaterialFiles(int materialVariant = -1)
582
607
}
583
608
else
584
609
{
585
- var models = await GetModelFiles ( ) ;
610
+ var models = await GetModelFiles ( index , modlist ) ;
586
611
if ( models != null && models . Count > 0 )
587
612
{
588
613
var dataFile = IOUtil . GetDataFileFromPath ( models [ 0 ] ) ;
@@ -598,51 +623,69 @@ public async Task<List<string>> GetMaterialFiles(int materialVariant = -1)
598
623
599
624
foreach ( var model in models )
600
625
{
601
- var mdlMats = await XivCache . GetChildFiles ( model ) ;
602
- if ( materialVariant <= 0 )
626
+ List < string > mdlMats = null ;
627
+ if ( useCache )
603
628
{
604
- foreach ( var mat in mdlMats )
629
+ mdlMats = await XivCache . GetChildFiles ( model ) ;
630
+ } else
631
+ {
632
+ if ( index . Get8xDataOffset ( model ) != 0 )
605
633
{
606
- var m = mat ;
634
+ mdlMats = await _mdl . GetReferencedMaterialPaths ( model , - 1 , false , false , index , modlist ) ;
635
+ }
636
+ }
607
637
608
- // Human types have their material ID automatically changed over.
609
- if ( Info . PrimaryType == XivItemType . human && Info . SecondaryType != XivItemType . hair )
638
+ if ( mdlMats != null )
639
+ {
640
+ if ( materialVariant <= 0 )
641
+ {
642
+ foreach ( var mat in mdlMats )
610
643
{
611
- m = secondaryRex . Replace ( m , secondaryTypePrefix + Info . SecondaryId . ToString ( ) . PadLeft ( 4 , '0' ) ) ;
644
+ var m = mat ;
645
+
646
+ // Human types have their material ID automatically changed over.
647
+ if ( Info . PrimaryType == XivItemType . human && Info . SecondaryType != XivItemType . hair )
648
+ {
649
+ m = secondaryRex . Replace ( m , secondaryTypePrefix + Info . SecondaryId . ToString ( ) . PadLeft ( 4 , '0' ) ) ;
650
+ }
651
+ materials . Add ( m ) ;
612
652
}
613
- materials . Add ( m ) ;
614
653
}
615
- }
616
- else
617
- {
618
- var replacement = "v" + materialVariant . ToString ( ) . PadLeft ( 4 , '0' ) ;
619
- foreach ( var mat in mdlMats )
654
+ else
620
655
{
621
- // Replace any material set references with the new one.
622
- // The hash set will scrub us down to just a single copy.
623
- // This is faster than re-scanning the MDL file.
624
- // And a little more thorough than simply skipping over non-matching refs.
625
- // Since some materials may not have variant references.
626
- var m = _materialSetRegex . Replace ( mat , replacement ) ;
627
-
628
- // Human types have their material ID automatically fixed to match.
629
- if ( Info . PrimaryType == XivItemType . human && Info . SecondaryType != XivItemType . hair )
656
+ var replacement = "v" + materialVariant . ToString ( ) . PadLeft ( 4 , '0' ) ;
657
+ foreach ( var mat in mdlMats )
630
658
{
631
- m = secondaryRex . Replace ( m , secondaryTypePrefix + Info . SecondaryId . ToString ( ) . PadLeft ( 4 , '0' ) ) ;
659
+ // Replace any material set references with the new one.
660
+ // The hash set will scrub us down to just a single copy.
661
+ // This is faster than re-scanning the MDL file.
662
+ // And a little more thorough than simply skipping over non-matching refs.
663
+ // Since some materials may not have variant references.
664
+ var m = _materialSetRegex . Replace ( mat , replacement ) ;
665
+
666
+ // Human types have their material ID automatically fixed to match.
667
+ if ( Info . PrimaryType == XivItemType . human && Info . SecondaryType != XivItemType . hair )
668
+ {
669
+ m = secondaryRex . Replace ( m , secondaryTypePrefix + Info . SecondaryId . ToString ( ) . PadLeft ( 4 , '0' ) ) ;
670
+ }
671
+ materials . Add ( m ) ;
632
672
}
633
- materials . Add ( m ) ;
634
673
}
635
674
}
636
675
}
637
676
}
638
677
}
639
678
640
679
// Here we get to get a little fancy.
641
- var _modding = new Modding ( XivCache . GameInfo . GameDirectory ) ;
642
- var modList = _modding . GetModList ( ) ;
680
+ if ( modlist == null )
681
+ {
682
+ var _modding = new Modding ( XivCache . GameInfo . GameDirectory ) ;
683
+ modlist = _modding . GetModList ( ) ;
684
+ }
685
+
643
686
var rootFolder = Info . GetRootFolder ( ) ;
644
687
var variantRep = "v" + materialVariant . ToString ( ) . PadLeft ( 4 , '0' ) ;
645
- foreach ( var mod in modList . Mods )
688
+ foreach ( var mod in modlist . Mods )
646
689
{
647
690
if ( ! mod . enabled ) continue ;
648
691
@@ -673,15 +716,29 @@ public async Task<List<string>> GetMaterialFiles(int materialVariant = -1)
673
716
/// Subsets of this data may be accessed with XivDependencyGraph::GetChildFiles(internalFilePath).
674
717
/// </summary>
675
718
/// <returns></returns>
676
- public async Task < List < string > > GetTextureFiles ( int materialVariant = - 1 )
719
+ public async Task < List < string > > GetTextureFiles ( int materialVariant = - 1 , IndexFile index = null , ModList modlist = null )
677
720
{
678
- var materials = await GetMaterialFiles ( materialVariant ) ;
721
+ var materials = await GetMaterialFiles ( materialVariant , index , modlist ) ;
679
722
var textures = new HashSet < string > ( ) ;
680
723
if ( materials != null && materials . Count > 0 )
681
724
{
682
725
foreach ( var mat in materials )
683
726
{
684
- var mtrlTexs = await XivCache . GetChildFiles ( mat ) ;
727
+ List < string > mtrlTexs = new List < string > ( ) ;
728
+ if ( index == null )
729
+ {
730
+ mtrlTexs = await XivCache . GetChildFiles ( mat ) ;
731
+ } else
732
+ {
733
+ var dataFile = IOUtil . GetDataFileFromPath ( mat ) ;
734
+
735
+ if ( index . Get8xDataOffset ( mat ) != 0 )
736
+ {
737
+ var _mtrl = new Mtrl ( XivCache . GameInfo . GameDirectory , dataFile , XivCache . GameInfo . GameLanguage ) ;
738
+ mtrlTexs = await _mtrl . GetTexturePathsFromMtrlPath ( mat , false , false , index , modlist ) ;
739
+ }
740
+ }
741
+
685
742
foreach ( var tex in mtrlTexs )
686
743
{
687
744
textures . Add ( tex ) ;
0 commit comments