@@ -1646,7 +1646,7 @@ public static async Task<List<XivDependencyRoot>> GetDependencyRoots(string inte
1646
1646
/// <param name="primary"></param>
1647
1647
/// <param name="secondary"></param>
1648
1648
/// <returns></returns>
1649
- private static async Task < List < XivDependencyRootInfo > > TestAllRoots ( Dictionary < string , XivDependencyRootInfo > combinedHashes , XivItemType primary , XivItemType secondary ) {
1649
+ private static async Task < List < XivDependencyRootInfo > > TestAllRoots ( Dictionary < int , HashSet < int > > Hashes , XivItemType primary , XivItemType secondary ) {
1650
1650
1651
1651
1652
1652
var result = new List < XivDependencyRootInfo > ( 3000 ) ;
@@ -1659,53 +1659,68 @@ await Task.Run(() => {
1659
1659
root . SecondaryType = ( secondary == XivItemType . none ? null : ( XivItemType ? ) secondary ) ;
1660
1660
var eqp = new Eqp ( XivCache . GameInfo . GameDirectory ) ;
1661
1661
var races = ( XivRace [ ] ) Enum . GetValues ( typeof ( XivRace ) ) ;
1662
+ var slots = XivItemTypes . GetAvailableSlots ( primary ) ;
1663
+ if ( secondary != XivItemType . none )
1664
+ {
1665
+ slots = XivItemTypes . GetAvailableSlots ( secondary ) ;
1666
+
1667
+ if ( primary == XivItemType . human && secondary == XivItemType . body )
1668
+ {
1669
+ slots = XivItemTypes . GetAvailableSlots ( XivItemType . equipment ) ;
1670
+ slots . Add ( "" ) ;
1671
+ }
1672
+ }
1673
+
1674
+ if ( slots . Count == 0 )
1675
+ {
1676
+ slots . Add ( "" ) ;
1677
+ }
1678
+
1679
+ var usesImc = Imc . UsesImc ( root ) ;
1662
1680
1663
1681
for ( int p = 0 ; p < 10000 ; p ++ )
1664
1682
{
1665
1683
root . PrimaryId = p ;
1666
1684
1667
1685
if ( secondary == XivItemType . none )
1668
1686
{
1687
+ var folder = root . GetRootFolder ( ) ;
1688
+ folder = folder . Substring ( 0 , folder . Length - 1 ) ;
1669
1689
if ( primary == XivItemType . indoor || primary == XivItemType . outdoor )
1670
1690
{
1671
- // For furniture, they're valid as long as they have an SGD file we can find.
1672
- var folder = root . GetRootFolder ( ) + "asset" ;
1673
- var file = root . GetSgdName ( ) ;
1691
+ // For furniture, they're valid as long as they have an assets folder we can find.
1692
+ var assetFolder = folder + "/ asset" ;
1693
+ var folderHash = HashGenerator . GetHash ( assetFolder ) ;
1674
1694
1675
- var folderHash = HashGenerator . GetHash ( folder ) ;
1676
- var fileHash = HashGenerator . GetHash ( file ) ;
1677
- var key = fileHash . ToString ( ) + folderHash . ToString ( ) ;
1678
- if ( combinedHashes . ContainsKey ( key ) )
1695
+ var sgdName = root . GetSgdName ( ) ;
1696
+ var sgdHash = HashGenerator . GetHash ( sgdName ) ;
1697
+
1698
+ if ( Hashes . ContainsKey ( folderHash ) && Hashes [ folderHash ] . Contains ( sgdHash ) )
1679
1699
{
1680
1700
result . Add ( ( XivDependencyRootInfo ) root . Clone ( ) ) ;
1681
1701
}
1682
1702
}
1683
1703
else
1684
1704
{
1685
- var folder = root . GetRootFolder ( ) + "model" ;
1705
+ // Test to see if the IMC file exists.
1686
1706
var folderHash = HashGenerator . GetHash ( folder ) ;
1687
- var slots = XivItemTypes . GetAvailableSlots ( root . PrimaryType ) ;
1707
+ var imcName = root . GetBaseFileName ( false ) + ".imc" ;
1708
+ var imcHash = HashGenerator . GetHash ( imcName ) ;
1688
1709
1689
- // For these, just let the EDP module verify if there are any races availble for the item?
1690
- foreach ( var slot in slots )
1710
+ if ( Hashes . ContainsKey ( folderHash ) && Hashes [ folderHash ] . Contains ( imcHash ) )
1691
1711
{
1692
- root . Slot = slot ;
1693
-
1694
- // Check every possible race code, not just playables?
1695
- //for (int s = 0; s < 10000; s++)
1696
- foreach ( var race in races )
1712
+ foreach ( var slot in slots )
1697
1713
{
1698
- //var modelName = root.GetRacialModelName(s);
1699
- var modelName = root . GetRacialModelName ( race ) ;
1700
- var fileHash = HashGenerator . GetHash ( modelName ) ;
1701
- var key = fileHash . ToString ( ) + folderHash . ToString ( ) ;
1702
- if ( combinedHashes . ContainsKey ( key ) )
1714
+ var sl = slot == "" ? null : slot ;
1715
+ var nRoot = new XivDependencyRootInfo ( )
1703
1716
{
1704
- result . Add ( ( XivDependencyRootInfo ) root . Clone ( ) ) ;
1705
-
1706
- // We don't care how many models there are, just that there *are* any models.
1707
- break ;
1708
- }
1717
+ PrimaryId = root . PrimaryId ,
1718
+ PrimaryType = root . PrimaryType ,
1719
+ SecondaryId = root . SecondaryId ,
1720
+ SecondaryType = root . SecondaryType ,
1721
+ Slot = sl
1722
+ } ;
1723
+ result . Add ( nRoot ) ;
1709
1724
}
1710
1725
}
1711
1726
}
@@ -1715,36 +1730,105 @@ await Task.Run(() => {
1715
1730
for ( int s = 0 ; s < 10000 ; s ++ )
1716
1731
{
1717
1732
root . SecondaryId = s ;
1718
- var folder = root . GetRootFolder ( ) + "model" ;
1719
- var folderHash = HashGenerator . GetHash ( folder ) ;
1720
- var slots = XivItemTypes . GetAvailableSlots ( ( XivItemType ) root . SecondaryType ) ;
1733
+ var folder = root . GetRootFolder ( ) ;
1734
+ folder = folder . Substring ( 0 , folder . Length - 1 ) ;
1721
1735
1722
- if ( primary == XivItemType . human && secondary == XivItemType . body )
1736
+ // If their root folder exists (has an IMC entry in it) they're valid.
1737
+ if ( usesImc )
1723
1738
{
1724
- // Human body gets to be a special snowflake.
1725
- slots = XivItemTypes . GetAvailableSlots ( XivItemType . equipment ) ;
1726
- }
1739
+ // Test to see if the IMC file exists.
1740
+ var folderHash = HashGenerator . GetHash ( folder ) ;
1741
+ var imcName = XivItemTypes . GetSystemPrefix ( ( XivItemType ) root . SecondaryType ) + root . SecondaryId . ToString ( ) . PadLeft ( 4 , '0' ) + ".imc" ;
1742
+ var imcHash = HashGenerator . GetHash ( imcName ) ;
1727
1743
1728
- if ( slots . Count == 0 )
1729
- {
1730
- slots . Add ( "" ) ;
1731
- }
1732
- foreach ( var slot in slots )
1733
- {
1734
- if ( slot == "" )
1735
- {
1736
- root . Slot = null ;
1737
- }
1738
- else
1744
+ if ( Hashes . ContainsKey ( folderHash ) && Hashes [ folderHash ] . Contains ( imcHash ) )
1739
1745
{
1740
- root . Slot = slot ;
1746
+ foreach ( var slot in slots )
1747
+ {
1748
+ var sl = slot == "" ? null : slot ;
1749
+ var nRoot = new XivDependencyRootInfo ( )
1750
+ {
1751
+ PrimaryId = root . PrimaryId ,
1752
+ PrimaryType = root . PrimaryType ,
1753
+ SecondaryId = root . SecondaryId ,
1754
+ SecondaryType = root . SecondaryType ,
1755
+ Slot = sl
1756
+ } ;
1757
+ result . Add ( nRoot ) ;
1758
+ }
1741
1759
}
1742
- var modelName = root . GetSimpleModelName ( ) ;
1743
- var fileHash = HashGenerator . GetHash ( modelName ) ;
1744
- var key = fileHash . ToString ( ) + folderHash . ToString ( ) ;
1745
- if ( combinedHashes . ContainsKey ( key ) )
1760
+ }
1761
+ else if ( ! usesImc )
1762
+ {
1763
+
1764
+ var mfolder = folder + "/model" ;
1765
+ var mfolderHash = HashGenerator . GetHash ( mfolder ) ;
1766
+ var matFolder = folder + "/material" ;
1767
+ var matFolderHash = HashGenerator . GetHash ( matFolder ) ;
1768
+ var matFolder1 = folder + "/material/v0001" ;
1769
+ var matFolder1Hash = HashGenerator . GetHash ( matFolder1 ) ;
1770
+ var texFolder = folder + "/texture" ;
1771
+ var texFolderHash = HashGenerator . GetHash ( texFolder ) ;
1772
+
1773
+ // Things that don't use IMC files are basically only the human tree, which is a complete mess.
1774
+ foreach ( var slot in slots )
1746
1775
{
1747
- result . Add ( ( XivDependencyRootInfo ) root . Clone ( ) ) ;
1776
+ var sl = slot == "" ? null : slot ;
1777
+ var nRoot = new XivDependencyRootInfo ( )
1778
+ {
1779
+ PrimaryId = root . PrimaryId ,
1780
+ PrimaryType = root . PrimaryType ,
1781
+ SecondaryId = root . SecondaryId ,
1782
+ SecondaryType = root . SecondaryType ,
1783
+ Slot = sl
1784
+ } ;
1785
+
1786
+ // If they have an MDL or MTRL we can resolve, they're valid.
1787
+
1788
+ var mdlFile = nRoot . GetBaseFileName ( true ) + ".mdl" ;
1789
+ var mdlFileHash = HashGenerator . GetHash ( mdlFile ) ;
1790
+
1791
+ var mtrlFile = "mt_" + nRoot . GetBaseFileName ( true ) + "_a.mtrl" ;
1792
+ var mtrlFileHash = HashGenerator . GetHash ( mtrlFile ) ;
1793
+
1794
+ var hasModel = Hashes . ContainsKey ( mfolderHash ) && Hashes [ mfolderHash ] . Contains ( mdlFileHash ) ;
1795
+ var hasMat = Hashes . ContainsKey ( matFolderHash ) && Hashes [ matFolderHash ] . Contains ( mtrlFileHash ) ;
1796
+ var hasMat1 = Hashes . ContainsKey ( matFolder1Hash ) && Hashes [ matFolder1Hash ] . Contains ( mtrlFileHash ) ;
1797
+ var hasTex = Hashes . ContainsKey ( texFolderHash ) ;
1798
+
1799
+
1800
+ if ( hasMat || hasMat1 || hasModel )
1801
+ {
1802
+ if ( secondary == XivItemType . body )
1803
+ {
1804
+ var nRoot2 = new XivDependencyRootInfo ( )
1805
+ {
1806
+ PrimaryId = root . PrimaryId ,
1807
+ PrimaryType = root . PrimaryType ,
1808
+ SecondaryId = root . SecondaryId ,
1809
+ SecondaryType = root . SecondaryType ,
1810
+ Slot = null
1811
+ } ;
1812
+ result . Add ( nRoot2 ) ;
1813
+ }
1814
+ else
1815
+ {
1816
+ foreach ( var slot2 in slots )
1817
+ {
1818
+ var sl2 = slot2 == "" ? null : slot2 ;
1819
+ var nRoot2 = new XivDependencyRootInfo ( )
1820
+ {
1821
+ PrimaryId = root . PrimaryId ,
1822
+ PrimaryType = root . PrimaryType ,
1823
+ SecondaryId = root . SecondaryId ,
1824
+ SecondaryType = root . SecondaryType ,
1825
+ Slot = sl2
1826
+ } ;
1827
+ result . Add ( nRoot2 ) ;
1828
+ }
1829
+ }
1830
+ break ;
1831
+ }
1748
1832
}
1749
1833
}
1750
1834
}
@@ -1771,21 +1855,10 @@ public static async Task CacheAllRealRoots()
1771
1855
{
1772
1856
ResetRootCache ( ) ;
1773
1857
var index = new Index ( XivCache . GameInfo . GameDirectory ) ;
1774
- var mergedHashes = await index . GetFileDictionary ( XivDataFile . _04_Chara ) ;
1775
-
1776
- var mergedDict = new Dictionary < string , XivDependencyRootInfo > ( ) ;
1777
- foreach ( var kv in mergedHashes )
1778
- {
1779
- mergedDict . Add ( kv . Key , new XivDependencyRootInfo ( ) ) ;
1780
- }
1781
1858
1782
- var bgcHashes = await index . GetFileDictionary ( XivDataFile . _01_Bgcommon ) ;
1859
+ var hashes = await index . GetAllHashes ( XivDataFile . _04_Chara ) ;
1860
+ var bgcHashes = await index . GetAllHashes ( XivDataFile . _01_Bgcommon ) ;
1783
1861
1784
- var bgcHashDict = new Dictionary < string , XivDependencyRootInfo > ( ) ;
1785
- foreach ( var kv in bgcHashes )
1786
- {
1787
- bgcHashDict . Add ( kv . Key , new XivDependencyRootInfo ( ) ) ;
1788
- }
1789
1862
1790
1863
var types = new Dictionary < XivItemType , List < XivItemType > > ( ) ;
1791
1864
foreach ( var type in DependencySupportedTypes )
@@ -1802,11 +1875,9 @@ public static async Task CacheAllRealRoots()
1802
1875
types [ XivItemType . demihuman ] . Add ( XivItemType . equipment ) ;
1803
1876
types [ XivItemType . equipment ] . Add ( XivItemType . none ) ;
1804
1877
types [ XivItemType . accessory ] . Add ( XivItemType . none ) ;
1805
- types [ XivItemType . indoor ] . Add ( XivItemType . none ) ;
1806
1878
types [ XivItemType . outdoor ] . Add ( XivItemType . none ) ;
1807
1879
1808
1880
1809
-
1810
1881
var tasks = new List < Task < List < XivDependencyRootInfo > > > ( ) ;
1811
1882
foreach ( var kv in types )
1812
1883
{
@@ -1815,11 +1886,11 @@ public static async Task CacheAllRealRoots()
1815
1886
{
1816
1887
if ( primary == XivItemType . indoor || primary == XivItemType . outdoor )
1817
1888
{
1818
- tasks . Add ( TestAllRoots ( bgcHashDict , primary , secondary ) ) ;
1889
+ tasks . Add ( TestAllRoots ( bgcHashes , primary , secondary ) ) ;
1819
1890
}
1820
1891
else
1821
1892
{
1822
- tasks . Add ( TestAllRoots ( mergedDict , primary , secondary ) ) ;
1893
+ tasks . Add ( TestAllRoots ( hashes , primary , secondary ) ) ;
1823
1894
}
1824
1895
}
1825
1896
}
0 commit comments