Skip to content

Commit

Permalink
Write builder only ensures mods exist on LO if separated mod
Browse files Browse the repository at this point in the history
  • Loading branch information
Noggog committed Aug 8, 2024
1 parent 139d390 commit a94dcb9
Show file tree
Hide file tree
Showing 2 changed files with 259 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Mutagen.Bethesda.Installs.DI;
using Mutagen.Bethesda.Plugins.Binary.Parameters;
using Mutagen.Bethesda.Plugins.Binary.Streams;
using Mutagen.Bethesda.Plugins.Meta;
using Mutagen.Bethesda.Plugins.Order;
using Mutagen.Bethesda.Plugins.Records;
using Mutagen.Bethesda.Strings;
Expand Down Expand Up @@ -173,12 +174,17 @@ public BinaryModdedWriteBuilderTargetChoice<TModGetter> WithDefaultLoadOrder()
_loadOrderSetter = (m, p) =>
{
var dataFolder = p._dataFolderGetter?.Invoke(m, p._param) ?? throw new ArgumentNullException("Data folder source was not set");
var lo = LoadOrder.Import<TModGetter>(dataFolder, m.GameRelease, p._param.FileSystem);
return p._param with
var lo = LoadOrder.Import<TModGetter>(dataFolder, m.GameRelease, p._param.FileSystem);
LoadOrder<IModFlagsGetter>? modFlagsLo = null;
if (GameConstants.Get(m.GameRelease).SeparateMasterLoadOrders)
{
LoadOrder = new LoadOrder<IModFlagsGetter>(
modFlagsLo = new LoadOrder<IModFlagsGetter>(
lo.ListedOrder.ResolveAllModsExist(),
disposeItems: false),
disposeItems: false);
}
return p._param with
{
LoadOrder = modFlagsLo,
MastersListOrdering = new MastersListOrderingByLoadOrder(lo),
LowerRangeDisallowedHandler = ALowerRangeDisallowedHandlerOption.AddPlaceholder(lo)
};
Expand All @@ -199,19 +205,22 @@ public BinaryModdedWriteBuilderDataFolderChoice<TModGetter> WithLoadOrder(
{
_loadOrderSetter = (m, p) =>
{
var loArray = loadOrder
.Where(x => x != m.ModKey)
.ToArray();
var dataFolder = p._dataFolderGetter?.Invoke(m, p._param);
if (dataFolder == null)
if (dataFolder == null || !GameConstants.Get(m.GameRelease).SeparateMasterLoadOrders)
{
return p._param with
{
MastersListOrdering = new MastersListOrderingByLoadOrder(loadOrder),
LowerRangeDisallowedHandler = ALowerRangeDisallowedHandlerOption.AddPlaceholder(loadOrder)
MastersListOrdering = new MastersListOrderingByLoadOrder(loArray),
LowerRangeDisallowedHandler = ALowerRangeDisallowedHandlerOption.AddPlaceholder(loArray)
};
}
else
{
var lo = LoadOrder.Import<TModGetter>(
dataFolder.Value, loadOrder,
dataFolder.Value, loArray,
m.GameRelease, p._param.FileSystem);
return p._param with
{
Expand All @@ -234,7 +243,7 @@ public BinaryModdedWriteBuilderDataFolderChoice<TModGetter> WithLoadOrderFromHea
_loadOrderSetter = (m, p) =>
{
var dataFolder = p._dataFolderGetter?.Invoke(m, p._param);
if (dataFolder == null)
if (dataFolder == null || !GameConstants.Get(m.GameRelease).SeparateMasterLoadOrders)
{
var lo = _mod.MasterReferences.Select(x => x.Master).ToArray();
return p._param with
Expand Down
241 changes: 241 additions & 0 deletions Mutagen.Bethesda.UnitTests/Plugins/Builders/BuilderPassthroughTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
using System.IO.Abstractions;
using FluentAssertions;
using Mutagen.Bethesda.Plugins;
using Mutagen.Bethesda.Plugins.Binary.Parameters;
using Mutagen.Bethesda.Plugins.Exceptions;
using Mutagen.Bethesda.Plugins.Records;
using Mutagen.Bethesda.Skyrim;
using Mutagen.Bethesda.Starfield;
using Mutagen.Bethesda.Testing.AutoData;
using Noggog;
using Xunit;

namespace Mutagen.Bethesda.UnitTests.Plugins.Builders;

public class BuilderPassthroughTests
{
public class Payload
{
public Payload(
IFileSystem fileSystem,
DirectoryPath existingDataFolder,
ModKey normalMasterKey,
ModKey smallMasterKey,
ModKey mediumMasterKey,
ModKey originatingKey)
{
NormalMasterKey = normalMasterKey;
SmallMasterKey = smallMasterKey;
MediumMasterKey = mediumMasterKey;
OriginatingKey = originatingKey;
FileSystem = fileSystem;
DataFolder = existingDataFolder;
}

public ModKey NormalMasterKey { get; }
public ModKey SmallMasterKey { get; }
public ModKey MediumMasterKey { get; }
public ModKey OriginatingKey { get; }
public IFileSystem FileSystem { get; }
public DirectoryPath DataFolder { get; }

public async Task<string> WriteMod<TModGetter>(
TModGetter mod,
bool useDataFolder)
where TModGetter : IModGetter
{
var modPath = Path.Combine(DataFolder, mod.ModKey.ToString());
await mod.BeginWrite
.WithLoadOrder(new ModKey[]
{
NormalMasterKey,
MediumMasterKey,
SmallMasterKey
})
.WithDataFolder(DataFolder)
.ToPath(modPath)
.WithFileSystem(FileSystem)
.WriteAsync();
return modPath;
}
}

[Theory, MutagenAutoData]
public async Task NonSeparated(
Payload payload)
{
var normalMaster = new SkyrimMod(payload.NormalMasterKey, SkyrimRelease.SkyrimSE)
{
IsMaster = true,
};
var normalNpc = normalMaster.Npcs.AddNew();
normalNpc.EditorID = "Normal";
var smallMaster = new SkyrimMod(payload.SmallMasterKey, SkyrimRelease.SkyrimSE)
{
IsSmallMaster = true,
};
var smallNpc = smallMaster.Npcs.AddNew();
smallNpc.EditorID = "Small";
var originating = new SkyrimMod(payload.OriginatingKey, SkyrimRelease.SkyrimSE);
var originatingNpc = originating.Npcs.AddNew();
originatingNpc.EditorID = "Originating";

originating.Npcs.GetOrAddAsOverride(normalNpc);
originating.Npcs.GetOrAddAsOverride(smallNpc);

normalMaster.WriteToBinary(Path.Combine(payload.DataFolder, normalMaster.ModKey.FileName), new BinaryWriteParameters()
{
FileSystem = payload.FileSystem
});
smallMaster.WriteToBinary(Path.Combine(payload.DataFolder, smallMaster.ModKey.FileName), new BinaryWriteParameters()
{
FileSystem = payload.FileSystem
});

var modPath = await payload.WriteMod(
originating,
useDataFolder: false);
using var mod = SkyrimMod.Create(SkyrimRelease.SkyrimSE)
.FromPath(modPath)
.WithFileSystem(payload.FileSystem)
.Construct();

mod.Npcs.Should().HaveCount(3);
mod.Npcs.TryGetValue(normalNpc.FormKey, out var normalNpcReimport)
.Should().BeTrue();
normalNpcReimport!.FormKey.Should().Be(normalNpc.FormKey);
mod.Npcs.TryGetValue(smallNpc.FormKey, out var smallNpcReimport)
.Should().BeTrue();
smallNpcReimport!.FormKey.Should().Be(smallNpc.FormKey);
mod.Npcs.TryGetValue(originatingNpc.FormKey, out var originatingNpcReimport)
.Should().BeTrue();
originatingNpcReimport!.FormKey.Should().Be(originatingNpc.FormKey);
}

[Theory, MutagenAutoData]
public async Task Separated(
Payload payload)
{
var normalMaster = new StarfieldMod(payload.NormalMasterKey, StarfieldRelease.Starfield)
{
IsMaster = true,
};
var normalNpc = normalMaster.Npcs.AddNew();
normalNpc.EditorID = "Normal";
var smallMaster = new StarfieldMod(payload.SmallMasterKey, StarfieldRelease.Starfield)
{
IsSmallMaster = true,
};
var smallNpc = smallMaster.Npcs.AddNew();
smallNpc.EditorID = "Small";
var mediumMaster = new StarfieldMod(payload.MediumMasterKey, StarfieldRelease.Starfield)
{
IsMediumMaster = true,
};
var mediumNpc = mediumMaster.Npcs.AddNew();
mediumNpc.EditorID = "Medium";
var originating = new StarfieldMod(payload.OriginatingKey, StarfieldRelease.Starfield);
var originatingNpc = originating.Npcs.AddNew();
originatingNpc.EditorID = "Originating";

originating.Npcs.GetOrAddAsOverride(normalNpc);
originating.Npcs.GetOrAddAsOverride(smallNpc);
originating.Npcs.GetOrAddAsOverride(mediumNpc);

normalMaster.WriteToBinary(Path.Combine(payload.DataFolder, normalMaster.ModKey.FileName), new BinaryWriteParameters()
{
FileSystem = payload.FileSystem
});
smallMaster.WriteToBinary(Path.Combine(payload.DataFolder, smallMaster.ModKey.FileName), new BinaryWriteParameters()
{
FileSystem = payload.FileSystem
});
mediumMaster.WriteToBinary(Path.Combine(payload.DataFolder, mediumMaster.ModKey.FileName), new BinaryWriteParameters()
{
FileSystem = payload.FileSystem
});

var modPath = await payload.WriteMod(
originating,
useDataFolder: false);
using var mod = StarfieldMod.Create(StarfieldRelease.Starfield)
.FromPath(modPath)
.WithLoadOrderFromHeaderMasters()
.WithNoDataFolder()
.WithFileSystem(payload.FileSystem)
.Construct();

Assert.Throws<RecordCollisionException>(() =>
{
mod.Npcs.Should().HaveCount(4);
});
}

[Theory, MutagenAutoData]
public async Task SeparatedWithDataFolder(
Payload payload)
{
var normalMaster = new StarfieldMod(payload.NormalMasterKey, StarfieldRelease.Starfield)
{
IsMaster = true,
};
var normalNpc = normalMaster.Npcs.AddNew();
normalNpc.EditorID = "Normal";
var smallMaster = new StarfieldMod(payload.SmallMasterKey, StarfieldRelease.Starfield)
{
IsSmallMaster = true,
};
var smallNpc = smallMaster.Npcs.AddNew();
smallNpc.EditorID = "Small";
var mediumMaster = new StarfieldMod(payload.MediumMasterKey, StarfieldRelease.Starfield)
{
IsMediumMaster = true,
};
var mediumNpc = mediumMaster.Npcs.AddNew();
mediumNpc.EditorID = "Medium";
var originating = new StarfieldMod(payload.OriginatingKey, StarfieldRelease.Starfield);
var originatingNpc = originating.Npcs.AddNew();
originatingNpc.EditorID = "Originating";

originating.Npcs.GetOrAddAsOverride(normalNpc);
originating.Npcs.GetOrAddAsOverride(smallNpc);
originating.Npcs.GetOrAddAsOverride(mediumNpc);

normalMaster.WriteToBinary(Path.Combine(payload.DataFolder, normalMaster.ModKey.FileName), new BinaryWriteParameters()
{
FileSystem = payload.FileSystem
});
smallMaster.WriteToBinary(Path.Combine(payload.DataFolder, smallMaster.ModKey.FileName), new BinaryWriteParameters()
{
FileSystem = payload.FileSystem
});
mediumMaster.WriteToBinary(Path.Combine(payload.DataFolder, mediumMaster.ModKey.FileName), new BinaryWriteParameters()
{
FileSystem = payload.FileSystem
});

var modPath = await payload.WriteMod(
originating,
useDataFolder: true);
using var mod = StarfieldMod.Create(StarfieldRelease.Starfield)
.FromPath(modPath)
.WithLoadOrderFromHeaderMasters()
.WithDataFolder(payload.DataFolder)
.WithFileSystem(payload.FileSystem)
.Construct();

mod.Npcs.Should().HaveCount(4);
mod.Npcs.TryGetValue(normalNpc.FormKey, out var normalNpcReimport)
.Should().BeTrue();
normalNpcReimport!.FormKey.Should().Be(normalNpc.FormKey);
mod.Npcs.TryGetValue(smallNpc.FormKey, out var smallNpcReimport)
.Should().BeTrue();
smallNpcReimport!.FormKey.Should().Be(smallNpc.FormKey);
mod.Npcs.TryGetValue(mediumNpc.FormKey, out var mediumNpcReimport)
.Should().BeTrue();
mediumNpcReimport!.FormKey.Should().Be(mediumNpc.FormKey);
mod.Npcs.TryGetValue(originatingNpc.FormKey, out var originatingNpcReimport)
.Should().BeTrue();
originatingNpcReimport!.FormKey.Should().Be(originatingNpc.FormKey);
}
}

0 comments on commit a94dcb9

Please sign in to comment.