public void FormLink_Direct_Resolve_MarkerInterface_DeepRecord_Linked(LinkCacheTestTypes cacheType) { var mod = new SkyrimMod(TestConstants.PluginModKey, SkyrimRelease.SkyrimLE); var worldspace = mod.Worldspaces.AddNew(); var subBlock = new WorldspaceSubBlock(); var cell = new Cell(mod.GetNextFormKey(), SkyrimRelease.SkyrimLE); subBlock.Items.Add(cell); var placedNpc = new PlacedNpc(mod.GetNextFormKey(), SkyrimRelease.SkyrimLE); cell.Temporary.Add(placedNpc); var block = new WorldspaceBlock(); block.Items.Add(subBlock); worldspace.SubCells.Add(block); var(style, package) = GetLinkCache(mod, cacheType); var placedFormLink = new FormLink <IPlacedGetter>(placedNpc.FormKey); WrapPotentialThrow(cacheType, style, () => { Assert.Same(placedNpc, placedFormLink.TryResolve(package)); }); var cellFormLink = new FormLink <ICellGetter>(cell.FormKey); WrapPotentialThrow(cacheType, style, () => { Assert.Same(cell, cellFormLink.TryResolve(package)); }); var worldspaceFormLink = new FormLink <IWorldspaceGetter>(worldspace.FormKey); WrapPotentialThrow(cacheType, style, () => { Assert.Same(worldspace, worldspaceFormLink.TryResolve(package)); }); }
public void ParentRefs() { WarmupSkyrim.Init(); var mod = new SkyrimMod(TestConstants.PluginModKey, SkyrimRelease.SkyrimSE); var worldspace = mod.Worldspaces.AddNew(); var block = new WorldspaceBlock() { BlockNumberX = 2, BlockNumberY = 3, GroupType = GroupTypeEnum.ExteriorCellBlock, }; var subBlock = new WorldspaceSubBlock() { BlockNumberX = 4, BlockNumberY = 5, GroupType = GroupTypeEnum.ExteriorCellSubBlock, }; block.Items.Add(subBlock); worldspace.SubCells.Add(block); var cell = new Cell(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); subBlock.Items.Add(cell); var placedNpc = new PlacedNpc(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); cell.Persistent.Add(placedNpc); var placedObj = new PlacedObject(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); cell.Persistent.Add(placedObj); var cache = mod.ToImmutableLinkCache(); var contexts = mod.EnumerateMajorRecordContexts <IPlacedObject, IPlacedObjectGetter>(linkCache: cache).ToArray(); contexts.Should().HaveCount(1); var baseContext = contexts[0]; var cellContext = baseContext.Parent; cellContext.Should().BeOfType(typeof(ModContext <ISkyrimMod, ISkyrimModGetter, ICell, ICellGetter>)); cellContext !.Record.Should().Be(cell); var subBlockContext = cellContext.Parent; subBlockContext !.Record.Should().Be(subBlock); var blockContext = subBlockContext.Parent; blockContext !.Record.Should().Be(block); var worldspaceContext = blockContext.Parent; worldspaceContext !.Record.Should().Be(worldspace); baseContext.IsUnderneath <IWorldspaceGetter>().Should().BeTrue(); baseContext.TryGetParent <IWorldspaceGetter>(out var worldParent).Should().BeTrue(); worldParent.Should().Be(worldspace); baseContext.TryGetParentContext <IWorldspace, IWorldspaceGetter>(out var worldParentContext).Should().BeTrue(); worldParentContext !.Record.Should().Be(worldspace); }
public void FormLink_LoadOrder_TryResolve_DeepRecord_Linked(LinkCacheTestTypes cacheType) { var mod = new SkyrimMod(TestConstants.PluginModKey, SkyrimRelease.SkyrimLE); var worldspace = mod.Worldspaces.AddNew(); var subBlock = new WorldspaceSubBlock(); var cell = new Cell(mod.GetNextFormKey(), SkyrimRelease.SkyrimLE); subBlock.Items.Add(cell); var placedNpc = new PlacedNpc(mod.GetNextFormKey(), SkyrimRelease.SkyrimLE); cell.Temporary.Add(placedNpc); var block = new WorldspaceBlock(); block.Items.Add(subBlock); worldspace.SubCells.Add(block); var loadOrder = new LoadOrder <ISkyrimModGetter>() { mod, new SkyrimMod(TestConstants.PluginModKey2, SkyrimRelease.SkyrimLE), }; var(style, package) = GetLinkCache(loadOrder, cacheType); FormLink <IPlacedNpc> placedFormLink = new FormLink <IPlacedNpc>(placedNpc.FormKey); WrapPotentialThrow(cacheType, style, () => { Assert.True(placedFormLink.TryResolve(package, out var linkedPlacedNpc)); Assert.Same(placedNpc, linkedPlacedNpc); }); FormLink <ICell> cellFormLink = new FormLink <ICell>(cell.FormKey); WrapPotentialThrow(cacheType, style, () => { Assert.True(cellFormLink.TryResolve(package, out var linkedCell)); Assert.Same(cell, linkedCell); }); FormLink <IWorldspace> worldspaceFormLink = new FormLink <IWorldspace>(worldspace.FormKey); WrapPotentialThrow(cacheType, style, () => { Assert.True(worldspaceFormLink.TryResolve(package, out var linkedWorldspace)); Assert.Same(worldspace, linkedWorldspace); }); }
public void SetModKeys() { WarmupSkyrim.Init(); var mod = new SkyrimMod(TestConstants.PluginModKey, SkyrimRelease.SkyrimSE); var worldspace = mod.Worldspaces.AddNew(); var block = new WorldspaceBlock() { BlockNumberX = 2, BlockNumberY = 3, GroupType = GroupTypeEnum.ExteriorCellBlock, }; var subBlock = new WorldspaceSubBlock() { BlockNumberX = 4, BlockNumberY = 5, GroupType = GroupTypeEnum.ExteriorCellSubBlock, }; block.Items.Add(subBlock); worldspace.SubCells.Add(block); var cell = new Cell(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); subBlock.Items.Add(cell); var placedNpc = new PlacedNpc(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); cell.Persistent.Add(placedNpc); var placedObj = new PlacedObject(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); cell.Persistent.Add(placedObj); var cache = mod.ToImmutableLinkCache(); var contexts = mod.EnumerateMajorRecordContexts <IPlacedObject, IPlacedObjectGetter>(linkCache: cache).ToArray(); contexts.Should().HaveCount(1); contexts[0].ModKey.Should().Be(TestConstants.PluginModKey); }
public void FormLink_Direct_TryResolveContext_DeepRecord_Linked(LinkCacheTestTypes cacheType, AContextRetriever contextRetriever) { var mod = new SkyrimMod(TestConstants.PluginModKey, SkyrimRelease.SkyrimLE); var worldspace = mod.Worldspaces.AddNew(); var subBlock = new WorldspaceSubBlock(); var cell = new Cell(mod.GetNextFormKey(), SkyrimRelease.SkyrimLE); subBlock.Items.Add(cell); var placedNpc = new PlacedNpc(mod.GetNextFormKey(), SkyrimRelease.SkyrimLE); cell.Temporary.Add(placedNpc); var block = new WorldspaceBlock(); block.Items.Add(subBlock); worldspace.SubCells.Add(block); var(style, package) = GetLinkCache(mod, cacheType); var placedFormLink = new FormLink <IPlacedNpcGetter>(placedNpc.FormKey); WrapPotentialThrow(cacheType, style, () => { Assert.True(contextRetriever.TryResolveContext <IPlacedNpc, IPlacedNpcGetter>(placedFormLink, package, out var linkedPlacedNpc)); linkedPlacedNpc.Record.Should().BeSameAs(placedNpc); linkedPlacedNpc.ModKey.Should().Be(TestConstants.PluginModKey); linkedPlacedNpc.Parent.Record.Should().Be(cell); var cellFormLink = new FormLink <ICellGetter>(cell.FormKey); Assert.True(contextRetriever.TryResolveContext <ICell, ICellGetter>(cellFormLink, package, out var linkedCell)); linkedCell.Record.Should().BeSameAs(cell); linkedCell.ModKey.Should().Be(TestConstants.PluginModKey); linkedCell.Parent.Record.Should().Be(subBlock); var worldspaceFormLink = new FormLink <IWorldspaceGetter>(worldspace.FormKey); Assert.True(contextRetriever.TryResolveContext <IWorldspace, IWorldspaceGetter>(worldspaceFormLink, package, out var linkedWorldspace)); linkedWorldspace.Record.Should().BeSameAs(worldspace); linkedWorldspace.ModKey.Should().Be(TestConstants.PluginModKey); linkedWorldspace.Parent.Should().BeNull(); }); }
public void ComplexOverrides() { WarmupSkyrim.Init(); // Construct base mod const string Mod1Name = "Mod1"; var mod = new SkyrimMod(TestConstants.PluginModKey, SkyrimRelease.SkyrimSE); var worldspace = mod.Worldspaces.AddNew(); worldspace.EditorID = Mod1Name; var block = new WorldspaceBlock() { BlockNumberX = 2, BlockNumberY = 3, GroupType = GroupTypeEnum.ExteriorCellBlock, }; var subBlock = new WorldspaceSubBlock() { BlockNumberX = 4, BlockNumberY = 5, GroupType = GroupTypeEnum.ExteriorCellSubBlock, }; block.Items.Add(subBlock); worldspace.SubCells.Add(block); var cell = new Cell(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); cell.EditorID = Mod1Name; subBlock.Items.Add(cell); var placedObj = new PlacedObject(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); placedObj.EditorID = Mod1Name; cell.Persistent.Add(placedObj); // Override cell in 2nd mod const string Mod2Name = "Mod2"; var mod2 = new SkyrimMod(TestConstants.PluginModKey2, SkyrimRelease.SkyrimSE); var worldspace2 = new Worldspace(worldspace.FormKey, SkyrimRelease.SkyrimSE); worldspace2.EditorID = Mod2Name; mod2.Worldspaces.Add(worldspace2); var block2 = new WorldspaceBlock() { BlockNumberX = 2, BlockNumberY = 3, GroupType = GroupTypeEnum.ExteriorCellBlock, }; var subBlock2 = new WorldspaceSubBlock() { BlockNumberX = 4, BlockNumberY = 5, GroupType = GroupTypeEnum.ExteriorCellSubBlock, }; block2.Items.Add(subBlock2); worldspace2.SubCells.Add(block2); var cell2 = new Cell(cell.FormKey, SkyrimRelease.SkyrimSE); cell2.EditorID = Mod2Name; subBlock2.Items.Add(cell2); // Override worldspace in 3rd mod const string Mod3Name = "Mod3"; var mod3 = new SkyrimMod(TestConstants.PluginModKey3, SkyrimRelease.SkyrimSE); var worldspace3 = new Worldspace(worldspace.FormKey, SkyrimRelease.SkyrimSE); worldspace3.EditorID = Mod3Name; mod3.Worldspaces.Add(worldspace3); // Override in 4th, and check sources var loadOrder = new LoadOrder <ISkyrimModGetter>(mod.AsEnumerable().And(mod2).And(mod3)); var cache = loadOrder.ToImmutableLinkCache(); var contexts = mod.EnumerateMajorRecordContexts <IPlaced, IPlacedGetter>(linkCache: cache).ToArray(); contexts.Should().HaveCount(1); var mod4 = new SkyrimMod(TestConstants.PluginModKey4, SkyrimRelease.SkyrimSE); var placedObjOverride = contexts[0].GetOrAddAsOverride(mod4); placedObjOverride.EditorID.Should().Be(Mod1Name); var cellOverride = mod4.Worldspaces.First().SubCells.First().Items.First().Items.First(); cellOverride.EditorID.Should().Be(Mod2Name); var worldspaceOverride = mod4.Worldspaces.First(); worldspaceOverride.EditorID.Should().Be(Mod3Name); }
public void IPlacedInWorldspace() { WarmupSkyrim.Init(); var mod = new SkyrimMod(TestConstants.PluginModKey, SkyrimRelease.SkyrimSE); var worldspace = mod.Worldspaces.AddNew(); var block = new WorldspaceBlock() { BlockNumberX = 2, BlockNumberY = 3, GroupType = GroupTypeEnum.ExteriorCellBlock, }; var subBlock = new WorldspaceSubBlock() { BlockNumberX = 4, BlockNumberY = 5, GroupType = GroupTypeEnum.ExteriorCellSubBlock, }; block.Items.Add(subBlock); worldspace.SubCells.Add(block); var cell1 = new Cell(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); var cell2 = new Cell(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); subBlock.Items.Add(cell1); subBlock.Items.Add(cell2); var block2 = new WorldspaceBlock() { BlockNumberX = 5, BlockNumberY = 6, GroupType = GroupTypeEnum.ExteriorCellBlock, }; var subBlock2 = new WorldspaceSubBlock() { BlockNumberX = 8, BlockNumberY = 9, GroupType = GroupTypeEnum.ExteriorCellSubBlock, }; block2.Items.Add(subBlock2); worldspace.SubCells.Add(block2); var cell3 = new Cell(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); subBlock2.Items.Add(cell3); var placedNpc = new PlacedNpc(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); cell2.Persistent.Add(placedNpc); var placedObj = new PlacedObject(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); cell2.Persistent.Add(placedObj); var cache = mod.ToImmutableLinkCache(); var contexts = mod.EnumerateMajorRecordContexts <IPlaced, IPlacedGetter>(linkCache: cache).ToArray(); Assert.Equal(2, contexts.Length); var mod2 = new SkyrimMod(TestConstants.PluginModKey2, SkyrimRelease.SkyrimSE); var placedNpcOverride = contexts[0].GetOrAddAsOverride(mod2); var placedObjOverride = contexts[1].GetOrAddAsOverride(mod2); Assert.Equal(placedNpc.FormKey, placedNpcOverride.FormKey); Assert.Equal(placedObj.FormKey, placedObjOverride.FormKey); mod2.Worldspaces.Should().HaveCount(1); mod2.Worldspaces.First().SubCells.Should().HaveCount(1); mod2.Worldspaces.First().SubCells.First().Items.Should().HaveCount(1); mod2.Worldspaces.First().SubCells.First().Items.First().Items.Should().HaveCount(1); mod2.Worldspaces.First().SubCells.First().Items.First().Items.First().Persistent.Should().HaveCount(2); Assert.Same(placedNpcOverride, mod2.Worldspaces.First().SubCells.First().Items.First().Items.First().Persistent.First()); }
internal static IEnumerable <IModContext <IOblivionMod, IOblivionModGetter, IMajorRecordCommon, IMajorRecordCommonGetter> > EnumerateMajorRecordContexts( this IReadOnlyList <IWorldspaceBlockGetter> worldspaceBlocks, IWorldspaceGetter worldspace, ILinkCache linkCache, Type type, ModKey modKey, IModContext?parent, bool throwIfUnknown, Func <IOblivionMod, IWorldspaceGetter, IWorldspace> getOrAddAsOverride) { foreach (var readOnlyBlock in worldspaceBlocks) { var blockNumX = readOnlyBlock.BlockNumberX; var blockNumY = readOnlyBlock.BlockNumberY; var blockModified = readOnlyBlock.LastModified; var blockContext = new ModContext <IWorldspaceBlockGetter>( modKey: modKey, parent: parent, record: readOnlyBlock); foreach (var readOnlySubBlock in readOnlyBlock.Items) { var subBlockNumY = readOnlySubBlock.BlockNumberY; var subBlockNumX = readOnlySubBlock.BlockNumberX; var subBlockModified = readOnlySubBlock.LastModified; var subBlockContext = new ModContext <IWorldspaceSubBlockGetter>( modKey: modKey, parent: blockContext, record: readOnlySubBlock); foreach (var readOnlyCell in readOnlySubBlock.Items) { Func <IOblivionMod, ICellGetter, bool, string?, ICell> cellGetter = (mod, copyCell, dup, edid) => { var worldspaceCopy = getOrAddAsOverride(mod, worldspace); var formKey = copyCell.FormKey; var retrievedBlock = worldspaceCopy.SubCells.FirstOrDefault(x => x.BlockNumberX == blockNumX && x.BlockNumberY == blockNumY); if (retrievedBlock == null) { retrievedBlock = new WorldspaceBlock() { BlockNumberX = blockNumX, BlockNumberY = blockNumY, GroupType = GroupTypeEnum.ExteriorCellBlock, LastModified = blockModified, }; worldspaceCopy.SubCells.Add(retrievedBlock); } var subBlock = retrievedBlock.Items.FirstOrDefault(x => x.BlockNumberX == subBlockNumX && x.BlockNumberY == subBlockNumY); if (subBlock == null) { subBlock = new WorldspaceSubBlock() { BlockNumberX = subBlockNumX, BlockNumberY = subBlockNumY, GroupType = GroupTypeEnum.ExteriorCellSubBlock, LastModified = readOnlySubBlock.LastModified, }; retrievedBlock.Items.Add(subBlock); } var cell = subBlock.Items.FirstOrDefault(cell => cell.FormKey == formKey); if (cell == null) { if (dup) { cell = copyCell.Duplicate(mod.GetNextFormKey(edid), CellCopyMask); } else { cell = copyCell.DeepCopy(CellCopyMask); } subBlock.Items.Add(cell); } return(cell); }; if (LoquiRegistration.TryGetRegister(type, out var regis) && regis.ClassType == typeof(Cell)) { yield return(new ModContext <IOblivionMod, IOblivionModGetter, IMajorRecordCommon, IMajorRecordCommonGetter>( modKey: modKey, record: readOnlyCell, getOrAddAsOverride: (m, r) => cellGetter(m, (ICellGetter)r, false, default(string?)), duplicateInto: (m, r, e) => cellGetter(m, (ICellGetter)r, true, e), parent: subBlockContext)); } else { foreach (var con in CellCommon.Instance.EnumerateMajorRecordContexts( readOnlyCell, linkCache, type, modKey, subBlockContext, throwIfUnknown, (m, c) => cellGetter(m, c, false, default(string?)), (m, c, e) => cellGetter(m, c, true, e))) { yield return(con); } } } } } }
public void CellInWorldspace() { WarmupSkyrim.Init(); var mod = new SkyrimMod(Utility.PluginModKey, SkyrimRelease.SkyrimSE); var worldspace = mod.Worldspaces.AddNew(); var block = new WorldspaceBlock() { BlockNumberX = 2, BlockNumberY = 3, GroupType = GroupTypeEnum.ExteriorCellBlock, }; var subBlock = new WorldspaceSubBlock() { BlockNumberX = 4, BlockNumberY = 5, GroupType = GroupTypeEnum.ExteriorCellSubBlock, }; block.Items.Add(subBlock); worldspace.SubCells.Add(block); var cell1 = new Cell(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); var cell2 = new Cell(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); subBlock.Items.Add(cell1); subBlock.Items.Add(cell2); var block2 = new WorldspaceBlock() { BlockNumberX = 5, BlockNumberY = 6, GroupType = GroupTypeEnum.ExteriorCellBlock, }; var subBlock2 = new WorldspaceSubBlock() { BlockNumberX = 8, BlockNumberY = 9, GroupType = GroupTypeEnum.ExteriorCellSubBlock, }; block2.Items.Add(subBlock2); worldspace.SubCells.Add(block2); var cell3 = new Cell(mod.GetNextFormKey(), SkyrimRelease.SkyrimSE); subBlock2.Items.Add(cell3); var cache = mod.ToImmutableLinkCache(); var contexts = mod.EnumerateMajorRecordContexts <ICell, ICellGetter>(linkCache: cache).ToArray(); Assert.Equal(3, contexts.Length); Assert.Same(contexts[0].Record, cell1); Assert.Same(contexts[1].Record, cell2); Assert.Same(contexts[2].Record, cell3); var mod2 = new SkyrimMod(Utility.PluginModKey2, SkyrimRelease.SkyrimSE); var cell2Override = contexts[1].GetOrAddAsOverride(mod2); Assert.Equal(cell2.FormKey, cell2Override.FormKey); mod2.Worldspaces.Should().HaveCount(1); mod2.Worldspaces.First().SubCells.Should().HaveCount(1); mod2.Worldspaces.First().SubCells.First().Items.Should().HaveCount(1); mod2.Worldspaces.First().SubCells.First().Items.First().Items.Should().HaveCount(1); Assert.Same(cell2Override, mod2.Worldspaces.First().SubCells.First().Items.First().Items.First()); }
internal static IEnumerable <IModContext <ISkyrimMod, IMajorRecordCommon, IMajorRecordCommonGetter> > EnumerateMajorRecordContexts( this IReadOnlyList <IWorldspaceBlockGetter> worldspaceBlocks, IWorldspaceGetter worldspace, ILinkCache linkCache, Type type, ModKey modKey, IModContext?parent, bool throwIfUnknown, Func <ISkyrimMod, IWorldspaceGetter, IWorldspace> getter) { foreach (var readOnlyBlock in worldspaceBlocks) { var blockNumX = readOnlyBlock.BlockNumberX; var blockNumY = readOnlyBlock.BlockNumberY; var blockContext = new ModContext <IWorldspaceBlockGetter>( modKey: modKey, parent: parent, record: readOnlyBlock); foreach (var readOnlySubBlock in readOnlyBlock.Items) { var subBlockNumY = readOnlySubBlock.BlockNumberY; var subBlockNumX = readOnlySubBlock.BlockNumberX; var subBlockContext = new ModContext <IWorldspaceSubBlockGetter>( modKey: modKey, parent: blockContext, record: readOnlySubBlock); foreach (var readOnlyCell in readOnlySubBlock.Items) { Func <ISkyrimMod, ICellGetter, ICell> cellGetter = (mod, copyCell) => { var worldspaceCopy = getter(mod, worldspace); var formKey = copyCell.FormKey; var retrievedBlock = worldspaceCopy.SubCells.FirstOrDefault(x => x.BlockNumberX == blockNumX && x.BlockNumberY == blockNumY); if (retrievedBlock == null) { retrievedBlock = new WorldspaceBlock() { BlockNumberX = blockNumX, BlockNumberY = blockNumY, GroupType = GroupTypeEnum.ExteriorCellBlock, }; worldspaceCopy.SubCells.Add(retrievedBlock); } var subBlock = retrievedBlock.Items.FirstOrDefault(x => x.BlockNumberX == subBlockNumX && x.BlockNumberY == subBlockNumY); if (subBlock == null) { subBlock = new WorldspaceSubBlock() { BlockNumberX = subBlockNumX, BlockNumberY = subBlockNumY, GroupType = GroupTypeEnum.ExteriorCellSubBlock, }; retrievedBlock.Items.Add(subBlock); } var cell = subBlock.Items.FirstOrDefault(cell => cell.FormKey == formKey); if (cell == null) { cell = copyCell.DeepCopy(CellCopyMask); subBlock.Items.Add(cell); } return(cell); }; if (LoquiRegistration.TryGetRegister(type, out var regis) && regis.ClassType == typeof(Cell)) { yield return(new ModContext <ISkyrimMod, IMajorRecordCommon, IMajorRecordCommonGetter>( modKey: modKey, record: readOnlyCell, getter: (m, r) => cellGetter(m, (ICellGetter)r), parent: subBlockContext)); } else { foreach (var con in CellCommon.Instance.EnumerateMajorRecordContexts(readOnlyCell, linkCache, type, modKey, subBlockContext, throwIfUnknown, cellGetter)) { yield return(con); } } } } } }