Skip to content

Commit 82056b7

Browse files
committed
- Simplified IMC function call parameters.
- Fixed an error with item root path retrieval - IMC functions now resolve root path using item root path functions. - Fixed an error with Same Model retrieval functions not comparing Secondary Model IDs (relevant for Weapon and Demihuman items)
1 parent a4f0f7c commit 82056b7

File tree

7 files changed

+69
-70
lines changed

7 files changed

+69
-70
lines changed

xivModdingFramework/Items/Categories/Companions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ public async Task<Dictionary<string, char[]>> GetDemiHumanMountTextureEquipPartL
352352

353353
var index = new Index(_gameDirectory);
354354
var imc = new Imc(_gameDirectory, XivDataFile._04_Chara);
355-
var version = (await imc.GetImcInfo(itemModel, itemModel.ModelInfo)).Variant.ToString().PadLeft(4, '0');
355+
var version = (await imc.GetImcInfo(itemModel)).Variant.ToString().PadLeft(4, '0');
356356

357357
var id = itemModel.ModelInfo.PrimaryID.ToString().PadLeft(4, '0');
358358
var bodyVer = itemModel.ModelInfo.SecondaryID.ToString().PadLeft(4, '0');

xivModdingFramework/Items/Categories/Gear.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ public async Task<List<XivRace>> GetRacesForTextures(XivGear xivGear, XivDataFil
327327
{
328328
// Get the material version for the item from the imc file
329329
var imc = new Imc(_gameDirectory, dataFile);
330-
var gearVersion = (await imc.GetImcInfo(xivGear, xivGear.ModelInfo)).Variant.ToString().PadLeft(4, '0');
330+
var gearVersion = (await imc.GetImcInfo(xivGear)).Variant.ToString().PadLeft(4, '0');
331331

332332
var modelID = xivGear.ModelInfo.PrimaryID.ToString().PadLeft(4, '0');
333333

@@ -702,6 +702,7 @@ public async Task<List<IItemModel>> GetSameModelList(IItemModel item)
702702
(await GetGearList())
703703
.Where(it =>
704704
it.ModelInfo.PrimaryID == item.ModelInfo.PrimaryID
705+
&& it.ModelInfo.SecondaryID == item.ModelInfo.SecondaryID
705706
&& it.SecondaryCategory == item.SecondaryCategory).Select(it => it as IItemModel).ToList()
706707
);
707708
}

xivModdingFramework/Items/ItemType.cs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ public static string GetItemRootFolder(this IItem item)
203203
try {
204204
modelInfo = ((IItemModel)item).ModelInfo;
205205
primaryId = modelInfo.PrimaryID.ToString().PadLeft(4, '0');
206-
secondaryId = modelInfo.PrimaryID.ToString().PadLeft(4, '0');
206+
secondaryId = modelInfo.SecondaryID.ToString().PadLeft(4, '0');
207207
} catch(Exception ex)
208208
{
209209
// No-op. If it failed it's one of the types we're not going to use it modelInfo on anyways.
@@ -212,30 +212,30 @@ public static string GetItemRootFolder(this IItem item)
212212

213213
if (primaryType == XivItemType.monster)
214214
{
215-
return "chara/monster/m" + primaryId + "/obj/body/b" + secondaryId + "/";
215+
return "chara/monster/m" + primaryId + "/obj/body/b" + secondaryId;
216216
}
217217
else if (primaryType == XivItemType.demihuman)
218218
{
219-
return "chara/demihuman/d" + primaryId + "/obj/equipment/e" + secondaryId + "/";
219+
return "chara/demihuman/d" + primaryId + "/obj/equipment/e" + secondaryId;
220220
}
221221
else if(primaryType == XivItemType.equipment)
222222
{
223-
return "chara/equipment/e" + primaryId + "/";
223+
return "chara/equipment/e" + primaryId;
224224
}
225225
else if (primaryType == XivItemType.accessory)
226226
{
227-
return "chara/accessory/a" + primaryId + "/";
227+
return "chara/accessory/a" + primaryId;
228228
}
229229
else if (primaryType == XivItemType.ui)
230230
{
231231
var uiItem = (XivUi)item;
232-
return uiItem.UiPath + uiItem.IconNumber.ToString().PadLeft(6, '0') + '/';
232+
return uiItem.UiPath + uiItem.IconNumber.ToString().PadLeft(6, '0');
233233
}
234234
else if (primaryType == XivItemType.furniture)
235235
{
236236
if (item.SecondaryCategory == XivStrings.Paintings)
237237
{
238-
return "ui/icon/" + modelInfo.PrimaryID.ToString().PadLeft(6, '0') + "/";
238+
return "ui/icon/" + modelInfo.PrimaryID.ToString().PadLeft(6, '0');
239239
}
240240
else
241241
{
@@ -249,14 +249,15 @@ public static string GetItemRootFolder(this IItem item)
249249
ret += "outdoor/";
250250
}
251251

252-
ret += "general/" + primaryId + "/";
252+
ret += "general/" + primaryId;
253253
return ret;
254254
}
255255
}
256256
else if (primaryType == XivItemType.weapon)
257257
{
258-
return "chara/weapon/w" + primaryId + "/obj/body/b" + secondaryId + "/";
259-
} else if(primaryType == XivItemType.human)
258+
return "chara/weapon/w" + primaryId + "/obj/body/b" + secondaryId;
259+
}
260+
else if(primaryType == XivItemType.human)
260261
{
261262
var ret = "chara/human/c" + primaryId + "/obj/";
262263
if (secondaryType == XivItemType.body)
@@ -280,17 +281,18 @@ public static string GetItemRootFolder(this IItem item)
280281
ret += "ears/z";
281282
}
282283

283-
ret += secondaryId + "/";
284+
ret += secondaryId;
284285
return ret;
285-
} else if(primaryType == XivItemType.decal)
286+
}
287+
else if(primaryType == XivItemType.decal)
286288
{
287289
if (item.SecondaryCategory == XivStrings.Face_Paint)
288290
{
289-
return "chara/common/texture/decal_face/";
291+
return "chara/common/texture/decal_face";
290292
}
291293
if (item.SecondaryCategory == XivStrings.Equipment_Decals)
292294
{
293-
return "chara/common/texture/decal_equip/";
295+
return "chara/common/texture/decal_equip";
294296
}
295297
}
296298
return "";

xivModdingFramework/Materials/FileTypes/Mtrl.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ private async Task<List<TexTypePath>> GetTexNames(IEnumerable<string> texPathLis
895895
{
896896
// get the items version from the imc file
897897
var imc = new Imc(_gameDirectory, DataFile);
898-
var imcInfo = await imc.GetImcInfo(item, item.ModelInfo);
898+
var imcInfo = await imc.GetImcInfo(item);
899899
variant = imcInfo.Variant;
900900

901901
if (imcInfo.Vfx > 0)
@@ -916,7 +916,8 @@ private async Task<List<TexTypePath>> GetTexNames(IEnumerable<string> texPathLis
916916
bodyVer = xivGear.SecondaryModelInfo.SecondaryID.ToString().PadLeft(4, '0');
917917

918918
var imc = new Imc(_gameDirectory, DataFile);
919-
var imcInfo = await imc.GetImcInfo(item, xivGear.SecondaryModelInfo);
919+
920+
var imcInfo = await imc.GetImcInfo(item, true);
920921
var imcChangedType = imc.ChangedType;
921922
variant = imcInfo.Variant;
922923

@@ -964,7 +965,7 @@ private async Task<List<TexTypePath>> GetTexNames(IEnumerable<string> texPathLis
964965
{
965966
// get the items version from the imc file
966967
var imc = new Imc(_gameDirectory, DataFile);
967-
var imcInfo = await imc.GetImcInfo(itemModel, itemModel.ModelInfo);
968+
var imcInfo = await imc.GetImcInfo(itemModel);
968969
variant = imcInfo.Variant;
969970

970971
if (imcInfo.Vfx > 0)
@@ -985,7 +986,8 @@ private async Task<List<TexTypePath>> GetTexNames(IEnumerable<string> texPathLis
985986
bodyVer = xivGear.SecondaryModelInfo.SecondaryID.ToString().PadLeft(4, '0');
986987

987988
var imc = new Imc(_gameDirectory, DataFile);
988-
var imcInfo = await imc.GetImcInfo(itemModel, xivGear.SecondaryModelInfo);
989+
// Use secondary model info instead.
990+
var imcInfo = await imc.GetImcInfo(itemModel, true);
989991
var imcChangedType = imc.ChangedType;
990992
variant = imcInfo.Variant;
991993

@@ -1026,7 +1028,7 @@ private async Task<string> GetMtrlFolder(IItemModel itemModel, XivRace xivRace,
10261028
{
10271029
// get the items version from the imc file
10281030
var imc = new Imc(_gameDirectory, DataFile);
1029-
var imcInfo = await imc.GetImcInfo(itemModel, itemModel.ModelInfo);
1031+
var imcInfo = await imc.GetImcInfo(itemModel);
10301032
variant = imcInfo.Variant;
10311033
}
10321034

xivModdingFramework/Textures/FileTypes/ATex.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public async Task<XivTex> GetATexData(int offset)
132132
{
133133
// get the vfx version from the imc file
134134
var imc = new Imc(_gameDirectory, _dataFile);
135-
var imcInfo = await imc.GetImcInfo(itemModel, itemModel.ModelInfo);
135+
var imcInfo = await imc.GetImcInfo(itemModel);
136136
int vfx = imcInfo.Vfx;
137137

138138
var id = itemModel.ModelInfo.PrimaryID.ToString().PadLeft(4, '0');

xivModdingFramework/Textures/FileTypes/Tex.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ public async Task<List<string>> GetTexturePartList(IItemModel itemModel, XivRace
203203
bodyVer = xivGear.SecondaryModelInfo.SecondaryID.ToString().PadLeft(4, '0');
204204

205205
var imc = new Imc(_gameDirectory, xivGear.DataFile);
206-
version = (await imc.GetImcInfo(itemModel, xivGear.SecondaryModelInfo)).Variant.ToString().PadLeft(4, '0');
206+
version = (await imc.GetImcInfo(itemModel, true)).Variant.ToString().PadLeft(4, '0');
207207

208208
if (imc.ChangedType)
209209
{
@@ -218,7 +218,7 @@ public async Task<List<string>> GetTexturePartList(IItemModel itemModel, XivRace
218218
{
219219
// Get the mtrl version for the given item from the imc file
220220
var imc = new Imc(_gameDirectory, dataFile);
221-
version = (await imc.GetImcInfo(itemModel, itemModel.ModelInfo)).Variant.ToString().PadLeft(4, '0');
221+
version = (await imc.GetImcInfo(itemModel)).Variant.ToString().PadLeft(4, '0');
222222
}
223223
}
224224

xivModdingFramework/Variants/FileTypes/Imc.cs

Lines changed: 40 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,10 @@ public Imc(DirectoryInfo gameDirectory, XivDataFile dataFile)
5353
/// <param name="item">The item to get the version for</param>
5454
/// <param name="modelInfo">The model info of the item</param>
5555
/// <returns>The XivImc Data</returns>
56-
public async Task<XivImc> GetImcInfo(IItemModel item, XivModelInfo modelInfo = null)
56+
public async Task<XivImc> GetImcInfo(IItemModel item, bool useSecondary = false)
5757
{
5858
var xivImc = new XivImc();
5959

60-
// Set based on item if we don't have one provided directly.
61-
if(modelInfo == null)
62-
{
63-
modelInfo = item.ModelInfo;
64-
}
65-
66-
// If it's still null, error.
67-
if(modelInfo == null)
68-
{
69-
throw new NotSupportedException("Cannot get IMC info.");
70-
}
71-
7260
// These are the offsets to relevant data
7361
// These will need to be changed if data gets added or removed with a patch
7462
const int headerLength = 4;
@@ -78,8 +66,8 @@ public async Task<XivImc> GetImcInfo(IItemModel item, XivModelInfo modelInfo = n
7866
var index = new Index(_gameDirectory);
7967
var dat = new Dat(_gameDirectory);
8068

81-
var itemType = ItemType.GetPrimaryItemType(item);
82-
var imcPath = GetImcPath(modelInfo, itemType);
69+
var itemType = item.GetPrimaryItemType();
70+
var imcPath = GetImcPath(item, useSecondary);
8371

8472
var itemCategory = item.SecondaryCategory;
8573

@@ -90,9 +78,15 @@ public async Task<XivImc> GetImcInfo(IItemModel item, XivModelInfo modelInfo = n
9078
{
9179
if (item.SecondaryCategory == XivStrings.Two_Handed)
9280
{
93-
itemCategory = XivStrings.Hands;
94-
itemType = XivItemType.equipment;
95-
imcPath = GetImcPath(modelInfo, itemType);
81+
// Jank workaround for two handed weapons that are actually gloves.
82+
var tempItem = new XivGear()
83+
{
84+
PrimaryCategory = XivStrings.Gear,
85+
SecondaryCategory = XivStrings.Hands,
86+
Name = item.Name,
87+
ModelInfo = (XivModelInfo) item.ModelInfo.Clone()
88+
};
89+
imcPath = GetImcPath(tempItem);
9690

9791
imcOffset = await index.GetDataOffset(HashGenerator.GetHash(imcPath.Folder),
9892
HashGenerator.GetHash(imcPath.File), _dataFile);
@@ -123,7 +117,12 @@ await Task.Run(() =>
123117
if (itemType == XivItemType.weapon || itemType == XivItemType.monster)
124118
{
125119
// weapons and monsters do not have variant sets
126-
variantOffset = (modelInfo.ImcSubsetID * variantLength) + headerLength;
120+
variantOffset = (item.ModelInfo.ImcSubsetID * variantLength) + headerLength;
121+
if (useSecondary)
122+
{
123+
XivGear gear = (XivGear)item;
124+
variantOffset = (gear.SecondaryModelInfo.ImcSubsetID * variantLength) + headerLength;
125+
}
127126

128127
// use default if offset is out of range
129128
if (variantOffset >= imcData.Length)
@@ -136,7 +135,7 @@ await Task.Run(() =>
136135
// Variant Sets contain 5 variants for each slot
137136
// These can be Head, Body, Hands, Legs, Feet or Ears, Neck, Wrists, LRing, RRing
138137
// This skips to the correct variant set, then to the correct slot within that set for the item
139-
variantOffset = (modelInfo.ImcSubsetID * variantSetLength) +
138+
variantOffset = (item.ModelInfo.ImcSubsetID * variantSetLength) +
140139
(_slotOffsetDictionary[itemCategory] * variantLength) + headerLength;
141140

142141
// use defalut if offset is out of range
@@ -165,24 +164,15 @@ await Task.Run(() =>
165164
/// Gets the full IMC information for a given item
166165
/// </summary>
167166
/// <param name="item"></param>
168-
/// <param name="modelInfo"></param>
167+
/// <param name="useSecondary">Determines if the SecondaryModelInfo should be used instead.(XivGear only)</param>
169168
/// <returns>The ImcData data</returns>
170-
public async Task<FullImcInfo> GetFullImcInfo(IItemModel item, XivModelInfo modelInfo = null)
169+
public async Task<FullImcInfo> GetFullImcInfo(IItemModel item, bool useSecondary = false)
171170
{
172-
if(modelInfo == null)
173-
{
174-
modelInfo = item.ModelInfo;
175-
}
176-
if(modelInfo == null)
177-
{
178-
throw new NotSupportedException("Attempted to get IMC info for invalid item.");
179-
}
180-
181171
var index = new Index(_gameDirectory);
182172
var dat = new Dat(_gameDirectory);
183173

184174
var itemType = ItemType.GetPrimaryItemType(item);
185-
var imcPath = GetImcPath(modelInfo, itemType);
175+
var imcPath = GetImcPath(item, useSecondary);
186176

187177
var imcOffset = await index.GetDataOffset(HashGenerator.GetHash(imcPath.Folder), HashGenerator.GetHash(imcPath.File), _dataFile);
188178

@@ -271,35 +261,39 @@ public async Task<FullImcInfo> GetFullImcInfo(IItemModel item, XivModelInfo mode
271261
/// <param name="modelInfo">The model info of the item</param>
272262
/// <param name="itemType">The type of the item</param>
273263
/// <returns>A touple containing the Folder and File strings</returns>
274-
private static (string Folder, string File) GetImcPath(XivModelInfo modelInfo, XivItemType itemType)
264+
private static (string Folder, string File) GetImcPath(IItemModel item, bool useSecondary = false)
275265
{
276-
string imcFolder;
266+
string imcFolder = item.GetItemRootFolder();
277267
string imcFile;
278268

279-
var modelID = modelInfo.PrimaryID.ToString().PadLeft(4, '0');
280-
var body = modelInfo.SecondaryID.ToString().PadLeft(4, '0');
269+
var primaryId = item.ModelInfo.PrimaryID.ToString().PadLeft(4, '0');
270+
var secondaryId = item.ModelInfo.SecondaryID.ToString().PadLeft(4, '0');
271+
var itemType = item.GetPrimaryItemType();
281272

282273
switch (itemType)
283274
{
284275
case XivItemType.equipment:
285-
imcFolder = $"chara/{itemType}/e{modelID}";
286-
imcFile = $"e{modelID}{ImcExtension}";
276+
imcFile = $"e{primaryId}{ImcExtension}";
277+
if(useSecondary)
278+
{
279+
XivGear gear = (XivGear)item;
280+
var alternateId = gear.SecondaryModelInfo.PrimaryID.ToString().PadLeft(4, '0');
281+
282+
imcFile = $"e{alternateId}{ImcExtension}";
283+
}
284+
287285
break;
288286
case XivItemType.accessory:
289-
imcFolder = $"chara/{itemType}/a{modelID}";
290-
imcFile = $"a{modelID}{ImcExtension}";
287+
imcFile = $"a{primaryId}{ImcExtension}";
291288
break;
292289
case XivItemType.weapon:
293-
imcFolder = $"chara/{itemType}/w{modelID}/obj/body/b{body}";
294-
imcFile = $"b{body}{ImcExtension}";
290+
imcFile = $"b{secondaryId}{ImcExtension}";
295291
break;
296292
case XivItemType.monster:
297-
imcFolder = $"chara/{itemType}/m{modelID}/obj/body/b{body}";
298-
imcFile = $"b{body}{ImcExtension}";
293+
imcFile = $"b{secondaryId}{ImcExtension}";
299294
break;
300295
case XivItemType.demihuman:
301-
imcFolder = $"chara/{itemType}/d{modelID}/obj/equipment/e{body}";
302-
imcFile = $"e{body}{ImcExtension}";
296+
imcFile = $"e{secondaryId}{ImcExtension}";
303297
break;
304298
default:
305299
imcFolder = "";

0 commit comments

Comments
 (0)