Closed levicki closed 2 years ago
Yes, it is intended behavior. Your unlocked bonus powers are stored in the GamerProfile
file. The Power
plots are just here to enumerate what you have unlocked. There is nothing I can do about it unfortunately.
Feature request to have that decoded then?
@KarlitosVII Are you sure those are stored in %USERPROFILE%\Documents\Bioware\Mass Effect Legendary Edition\TrilogyGameProfile
and not in %USERPROFILE%\Documents\Bioware\Mass Effect Legendary Edition\Save\ME3\Local_Profile
?
I thought it would be possible to add editing of that file as well.
@KarlitosVII Can you at least point me to any information about what method of compression or obfuscation might have been used by the game when saving those files? From my brief analysis of Local_Profile
I see that it contains the name of current character save folder in almost plain text.
For example, my character save folder is Xenia_13_Sentinel_040322_4f74eef
and in the Local_Profile
the string is Xcnia603_SenrineB^040320_4f0eef
. A little bit further there is a string C_Kovenrward
which I assume is actually something like `??MoveForward' (i.e. the keyboard mappings seem to be in there too because I lost them when the file got corrupted).
I have tried figuring out the file format by comparing files after unlocking each power, but it doesn't seem that the whole file is compressed with any standard algorithm (yet the partially mangled strings would suggest some light/fast compression), nor there seem to be any sort of fixed header. Any pointers would be appreciated.
@KarlitosVII I just found this in SFXGame.pcc
file in SFXProfileSettings
class using Package Editor, maybe it will be useful:
BonusPowerUnlockDataArray = (
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_Carnage", BonusPowerID = 1, PlotConditionalID = 1282, PlotStateID = 22113, srTitle = $668831},
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_Marksman", BonusPowerID = 2, PlotConditionalID = 1278, PlotStateID = 22109, srTitle = $572088},
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_ProximityMine", BonusPowerID = 4, PlotConditionalID = 1274, PlotStateID = 22105, srTitle = $572665},
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_Decoy", BonusPowerID = 8, PlotConditionalID = 1272, PlotStateID = 22103, srTitle = $674631},
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_ProtectorDrone", BonusPowerID = 16, PlotConditionalID = 1270, PlotStateID = 22101, srTitle = $663224},
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_EnergyDrain", BonusPowerID = 32, PlotConditionalID = 1269, PlotStateID = 22100, srTitle = $205894},
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_InfernoGrenade", BonusPowerID = 64, PlotConditionalID = 1277, PlotStateID = 22108, srTitle = $349055},
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_Reave", BonusPowerID = 128, PlotConditionalID = 1276, PlotStateID = 22107, srTitle = $314878},
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_Stasis", BonusPowerID = 256, PlotConditionalID = 1280, PlotStateID = 22111, srTitle = $127059},
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_WarpAmmo", BonusPowerID = 512, PlotConditionalID = 1279, PlotStateID = 22110, srTitle = $501005},
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_Barrier", BonusPowerID = 1024, PlotConditionalID = 1275, PlotStateID = 22106, srTitle = $93973},
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_GethShieldBoost", BonusPowerID = 2048, PlotConditionalID = 1271, PlotStateID = 22102, srTitle = $314066},
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_Fortification", BonusPowerID = 4096, PlotConditionalID = 1281, PlotStateID = 22112, srTitle = $314036},
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_ArmorPiercingAmmo", BonusPowerID = 8192, PlotConditionalID = 1273, PlotStateID = 22104, srTitle = $93965},
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_Slam", BonusPowerID = 16384, PlotConditionalID = 1283, PlotStateID = 22114, srTitle = $542178},
{PowerClassName = "SFXGameContent.SFXPowerCustomAction_DarkChannel", BonusPowerID = 32768, PlotConditionalID = 1284, PlotStateID = 22115, srTitle = $716448}
)
For the power to unlock, PlotStateID
has to be set as well.
Power unlocks are stored in the profile settings as a bitmask in a single 32-bit integer:
public final function bool IsBonusPowerUnlocked(int BonusPowerID)
{
local int UnlockedPowers;
GetProfileSettingValueInt(96, UnlockedPowers);
if ((UnlockedPowers & BonusPowerID) == BonusPowerID) {
return TRUE;
} else {
return FALSE;
}
}
I presume 96 might be the offset in the profile. If they aren't unlocked in the profile, their PlotStateIDs get reset:
public final function UpdateBonusPowerPlotStates()
{
local int idx;
local BioWorldInfo WI;
local BioGlobalVariableTable VarTable;
WI = BioWorldInfo(Class'WorldInfo'.static.GetWorldInfo());
if (WI == None) {
return;
}
VarTable = WI.GetGlobalVariables();
if (VarTable == None) {
return;
}
for (idx = 0; idx < BonusPowerUnlockDataArray.Length; idx++) {
if (IsBonusPowerUnlocked(BonusPowerUnlockDataArray[idx].BonusPowerID) == TRUE) {
VarTable.SetBool(BonusPowerUnlockDataArray[idx].PlotStateID, TRUE, FALSE, TRUE);
continue;
}
VarTable.SetBool(BonusPowerUnlockDataArray[idx].PlotStateID, FALSE, FALSE, TRUE);
}
}
Maybe one day we figure out the profile format as well.
As the title says, once your
local_profile
file in the Saves directory gets corrupted, loading any save from any career with bonus powers marked as unlocked and avaialble doesn't do anything -- the console for purchasing them in the Medbay is empty.I guess this is more of a feature request -- there should be a way to edit
local_profile
as well (old local profile editor for the original ME3 cannot decompress the new file), and set the bonus powers to unlocked.