Skip to content

Commit 37cd8e5

Browse files
Merge pull request #2 from TexTools/master
why am i doing this
2 parents 7e7cee8 + d1ab801 commit 37cd8e5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+13918
-8133
lines changed

xivModdingFramework/Cache/XivCache.cs

Lines changed: 396 additions & 166 deletions
Large diffs are not rendered by default.

xivModdingFramework/Cache/XivDependencyGraph.cs

Lines changed: 492 additions & 300 deletions
Large diffs are not rendered by default.

xivModdingFramework/Exd/FileTypes/Ex.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ await Task.Run(() =>
154154
/// <returns>A dictionary containing the Index and Raw Data of the ex file</returns>
155155
public async Task<Dictionary<int, byte[]>> ReadExData(XivEx exFile)
156156
{
157-
var exdNameOffsetDictionary = new Dictionary<int, string>();
157+
var exdNameOffsetDictionary = new Dictionary<long, string>();
158158
var exdDataDictionary = new Dictionary<int, byte[]>();
159159
var errorString = "";
160160

xivModdingFramework/General/CMP.cs

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Dynamic;
4+
using System.IO;
5+
using System.Linq;
6+
using System.Text;
7+
using System.Text.RegularExpressions;
8+
using System.Threading.Tasks;
9+
using xivModdingFramework.Cache;
10+
using xivModdingFramework.General.DataContainers;
11+
using xivModdingFramework.General.Enums;
12+
using xivModdingFramework.Helpers;
13+
using xivModdingFramework.Items.DataContainers;
14+
using xivModdingFramework.Mods;
15+
using xivModdingFramework.Mods.DataContainers;
16+
using xivModdingFramework.SqPack.DataContainers;
17+
using xivModdingFramework.SqPack.FileTypes;
18+
19+
namespace xivModdingFramework.General
20+
{
21+
/// <summary>
22+
/// Class for manipulating FFXIV CharaMakeParameter files.
23+
/// </summary>
24+
public static class CMP
25+
{
26+
const string HumanCmpPath = "chara/xls/charamake/human.cmp";
27+
const string RgspPathFormat = "chara/xls/charamake/rgsp/{0}-{1}.rgsp";
28+
static readonly Regex RgspPathExtractFormat = new Regex("^chara\\/xls\\/charamake\\/rgsp\\/([0-9]+)-([0-9]+).rgsp$");
29+
30+
31+
/// <summary>
32+
/// Applies a custom .rgsp file to the main Human.CMP file.
33+
/// </summary>
34+
/// <param name="filePath"></param>
35+
/// <param name="index"></param>
36+
/// <param name="modlist"></param>
37+
/// <returns></returns>
38+
internal static async Task ApplyRgspFile(string filePath, IndexFile index = null, ModList modlist = null)
39+
{
40+
var _dat = new Dat(XivCache.GameInfo.GameDirectory);
41+
var rgspData = await _dat.GetType2Data(filePath, false, index, modlist);
42+
43+
var rgsp = new RacialGenderScalingParameter(rgspData);
44+
45+
await SetScalingParameter(rgsp, index, modlist);
46+
}
47+
48+
/// <summary>
49+
/// Disables the .rgsp file for this race, if it exists, and restores the .cmp file for the race back to default.
50+
/// </summary>
51+
/// <param name="race"></param>
52+
/// <param name="gender"></param>
53+
/// <returns></returns>
54+
public static async Task DisableRgspMod(XivSubRace race, XivGender gender)
55+
{
56+
var path = GetRgspPath(race, gender);
57+
var _modding = new Modding(XivCache.GameInfo.GameDirectory);
58+
59+
60+
var modlist = await _modding.GetModListAsync();
61+
var mod = modlist.Mods.FirstOrDefault(x => x.fullPath == path);
62+
if (mod != null && mod.enabled)
63+
{
64+
await _modding.ToggleModStatus(path, false);
65+
} else
66+
{
67+
var def = await GetScalingParameter(race, gender, true);
68+
await SetScalingParameter(def);
69+
}
70+
71+
}
72+
73+
internal static async Task RestoreDefaultScaling(string rgspPath, IndexFile index = null, ModList modlist = null)
74+
{
75+
var match = RgspPathExtractFormat.Match(rgspPath);
76+
if (!match.Success) throw new InvalidDataException("Invalid .RGSP file path.");
77+
78+
var race = (XivSubRace) Int32.Parse(match.Groups[1].Value);
79+
var gender = (XivGender) Int32.Parse(match.Groups[2].Value);
80+
81+
await RestoreDefaultScaling(race, gender, index, modlist);
82+
}
83+
84+
internal static string GetModFileNameFromRgspPath(string path)
85+
{
86+
var match = RgspPathExtractFormat.Match(path);
87+
if (!match.Success) return null;
88+
89+
var race = (XivSubRace)Int32.Parse(match.Groups[1].Value);
90+
var gender = (XivGender)Int32.Parse(match.Groups[2].Value);
91+
92+
var name = race.GetDisplayName() + " - " + gender.ToString();
93+
return name;
94+
}
95+
96+
public static string GetRgspPath(XivSubRace race, XivGender gender)
97+
{
98+
var subraceId = (int)race;
99+
var genderId = (int)gender;
100+
var rgspFilePath = String.Format(RgspPathFormat, subraceId, genderId);
101+
return rgspFilePath;
102+
}
103+
104+
/// <summary>
105+
/// Restores the default settings back into the CMP file.
106+
/// Does NOT delete .rgsp entry.
107+
/// </summary>
108+
/// <param name="race"></param>
109+
/// <param name="gender"></param>
110+
/// <param name="index"></param>
111+
/// <param name="modlist"></param>
112+
/// <returns></returns>
113+
internal static async Task RestoreDefaultScaling(XivSubRace race, XivGender gender, IndexFile index = null, ModList modlist = null)
114+
{
115+
var defaults = await GetScalingParameter(race, gender, true, index, modlist);
116+
await SetScalingParameter(defaults, index, modlist);
117+
}
118+
119+
/// <summary>
120+
/// Saves a racial scaling entry to file.
121+
/// </summary>
122+
/// <param name="rgsp"></param>
123+
/// <param name=""></param>
124+
/// <returns></returns>
125+
public static async Task SaveScalingParameter(RacialGenderScalingParameter rgsp, string sourceApplication, IndexFile index = null, ModList modlist = null)
126+
{
127+
128+
// Write the .rgsp file and let the DAT functions handle applying it.
129+
var rgspFilePath = GetRgspPath(rgsp.Race, rgsp.Gender);
130+
131+
var bytes = rgsp.GetBytes();
132+
133+
134+
var dummyItem = new XivGenericItemModel();
135+
dummyItem.Name = rgsp.Race.GetDisplayName() + " - " + rgsp.Gender.ToString();
136+
dummyItem.SecondaryCategory = "Racial Scaling";
137+
138+
var _dat = new Dat(XivCache.GameInfo.GameDirectory);
139+
await _dat.ImportType2Data(bytes, rgspFilePath, sourceApplication, dummyItem , index, modlist);
140+
}
141+
142+
143+
144+
public static async Task<RacialGenderScalingParameter> GetScalingParameter(XivSubRace race, XivGender gender, bool forceOriginal = false, IndexFile index = null, ModList modlist = null)
145+
{
146+
var cmp = await GetCharaMakeParameterSet(forceOriginal, index, modlist);
147+
148+
return cmp.GetScalingParameter(race, gender);
149+
}
150+
151+
/// <summary>
152+
/// Performs the base level alteration to the CMP file, without going through .rgsp files.
153+
/// </summary>
154+
/// <param name="data"></param>
155+
/// <param name="index"></param>
156+
/// <param name="modlist"></param>
157+
/// <returns></returns>
158+
private static async Task SetScalingParameter(RacialGenderScalingParameter data, IndexFile index = null, ModList modlist = null)
159+
{
160+
var cmp = await GetCharaMakeParameterSet(false, index, modlist);
161+
cmp.SetScalingParameter(data);
162+
await SaveCharaMakeParameterSet(cmp, index, modlist);
163+
}
164+
165+
private static async Task<CharaMakeParameterSet> GetCharaMakeParameterSet(bool forceOriginal = false, IndexFile index = null, ModList modlist = null)
166+
{
167+
var _dat = new Dat(XivCache.GameInfo.GameDirectory);
168+
169+
var data = await _dat.GetType2Data(HumanCmpPath, forceOriginal, index, modlist);
170+
var cmp = new CharaMakeParameterSet(data);
171+
172+
173+
return cmp;
174+
}
175+
176+
private static async Task SaveCharaMakeParameterSet(CharaMakeParameterSet cmp, IndexFile index = null, ModList modlist = null)
177+
{
178+
var _dat = new Dat(XivCache.GameInfo.GameDirectory);
179+
var dummyItem = new XivGenericItemModel();
180+
dummyItem.Name = "human.cmp";
181+
dummyItem.SecondaryCategory = Constants.InternalModSourceName;
182+
183+
await _dat.ImportType2Data(cmp.GetBytes(), HumanCmpPath, Constants.InternalModSourceName, dummyItem, index, modlist);
184+
}
185+
186+
}
187+
}

0 commit comments

Comments
 (0)