private static int MoveItem(IScriptRootData root, IItemsSource S, string N, IStructureData targetStructure, int count, int?maxLimit) { var target = targetStructure?.GetCurrent()?.GetDevice <Eleon.Modding.IContainer>(N); if (target == null) { Log($"TargetNoFound: {S.Id} #{S.Count} => {N}", LogLevel.Debug); return(count); } if (!targetStructure.ContainerSource.TryGetValue(N, out var targetData)) { Log($"TargetDataNoFound: {S.Id} #{S.Count} => {N}", LogLevel.Debug); return(count); } var tryMoveCount = maxLimit.HasValue ? Math.Max(0, Math.Min(count, maxLimit.Value - target.GetTotalItems(S.Id))) : count; using var locked = WeakCreateDeviceLock(root, root.GetCurrentPlayfield(), targetStructure.GetCurrent(), targetData.Position); if (!locked.Success) { Log($"DeviceIsLocked (Target): {S.Id} #{S.Count} => {targetData.CustomName}", LogLevel.Debug); return(count); } return(maxLimit.HasValue ? target.AddItems(S.Id, tryMoveCount) + (count - tryMoveCount) : target.AddItems(S.Id, tryMoveCount)); }
static void ProcessBlockPart(TextWriter output, IScriptRootData root, IStructure S, ProcessBlockData processBlockData, IContainer target, VectorInt3 targetPos, string N, int replaceId, Tuple <int, int>[] list, Func <IContainer, int, bool> processBlock) { IDeviceLock locked = null; try { for (; processBlockData.Y >= processBlockData.MinPos.y; processBlockData.Y--) { for (; processBlockData.X <= processBlockData.MaxPos.x; processBlockData.X++) { for (; processBlockData.Z <= processBlockData.MaxPos.z; processBlockData.Z++) { processBlockData.CheckedBlocks++; var block = S.GetBlock(processBlockData.X, 128 + processBlockData.Y, processBlockData.Z); if (block != null) { block.Get(out var blockType, out _, out _, out _); if (list != null && list.Length > 0 && !list.Any(L => L.Item1 <= blockType && L.Item2 >= blockType)) { blockType = 0; } if (blockType > 0 && blockType != PlayerCoreType) { if (EmpyrionScripting.Configuration.Current?.DeconstructBlockSubstitution != null && EmpyrionScripting.Configuration.Current.DeconstructBlockSubstitution.TryGetValue(blockType, out var substituteTo)) { blockType = substituteTo; } if (blockType > 0 && N != null) { locked = locked ?? WeakCreateDeviceLock(root, root.GetCurrentPlayfield(), root.E.S.GetCurrent(), targetPos); if (!locked.Success) { processBlockData.CheckedBlocks--; output.WriteLine($"Container '{N}' is locked"); return; } if (processBlock(target, blockType)) { processBlockData.CheckedBlocks--; output.WriteLine($"Container '{N}' is full"); return; } } block.Set(replaceId); processBlockData.RemovedBlocks++; if (processBlockData.RemovedBlocks > 100 && processBlockData.RemovedBlocks % 100 == 0 && root.TimeLimitReached) { return; } } } } processBlockData.Z = processBlockData.MinPos.z; } processBlockData.X = processBlockData.MinPos.x; } } finally { locked?.Dispose(); } }
public static IList <IItemMoveInfo> Fill(IScriptRootData root, IItemsData item, IStructureData structure, StructureTankType type, int maxLimit) { if (!root.DeviceLockAllowed) { Log($"Fill: NoLockAllowed({root.ScriptId}): {root.CycleCounter} % {EmpyrionScripting.Configuration.Current.DeviceLockOnlyAllowedEveryXCycles}", LogLevel.Debug); return(ItemMoveInfo.Empty); } var specialTransfer = type switch { StructureTankType.Oxygen => structure.OxygenTank, StructureTankType.Fuel => structure.FuelTank, StructureTankType.Pentaxid => structure.PentaxidTank, _ => null, }; if (specialTransfer == null || !specialTransfer.AllowedItem(item.Id)) { return(ItemMoveInfo.Empty); } Log($"Fill Total: #{item.Source.Count}", LogLevel.Debug); var moveInfos = new List <IItemMoveInfo>(); lock (moveLock) item.Source .ForEach(S => { using var locked = WeakCreateDeviceLock(root, root.GetCurrentPlayfield(), S.E?.S.GetCurrent(), S.Position); if (!locked.Success) { Log($"DeviceIsLocked (Source): {S.Id} #{S.Count} => {S.CustomName}", LogLevel.Debug); return; } var count = specialTransfer.ItemsNeededForFill(S.Id, maxLimit); if (count > 0) { count -= S.Container.RemoveItems(S.Id, count); Log($"Move(RemoveItems): {S.CustomName} {S.Id} #{S.Count}->{count}", LogLevel.Debug); } ItemMoveInfo currentMoveInfo = null; if (count > 0) { var startCount = count; count = specialTransfer.AddItems(S.Id, count); if (startCount != count) { moveInfos.Add(currentMoveInfo = new ItemMoveInfo() { Id = S.Id, Count = startCount - count, SourceE = S.E, Source = S.CustomName, DestinationE = structure.E, Destination = type.ToString(), }); } } ; if (count > 0) { count = S.Container.AddItems(S.Id, count); } if (count > 0 && currentMoveInfo != null) { root.GetPlayfieldScriptData().MoveLostItems.Enqueue(new ItemMoveInfo() { Id = S.Id, Count = count, SourceE = S.E, Source = S.CustomName, }); currentMoveInfo.Error = $"{{fill}} error lost #{count} of item {S.Id} in container {S.CustomName} -> add to retry list"; } }, () => root.TimeLimitReached); return(moveInfos); }
public static IList <IItemMoveInfo> Move(IScriptRootData root, IItemsData item, IStructureData structure, string namesSearch, int?maxLimit) { if (!root.DeviceLockAllowed) { Log($"Move: NoLockAllowed({root.ScriptId}): {root.CycleCounter} % {EmpyrionScripting.Configuration.Current.DeviceLockOnlyAllowedEveryXCycles}", LogLevel.Debug); return(ItemMoveInfo.Empty); } if (root.TimeLimitReached) { Log($"Move: TimeLimitReached({root.ScriptId})", LogLevel.Debug); return(ItemMoveInfo.Empty); } var uniqueNames = structure.AllCustomDeviceNames.GetUniqueNames(namesSearch); if (!uniqueNames.Any()) { Log($"NoDevicesFound: {namesSearch}", LogLevel.Debug); return(ItemMoveInfo.Empty); } var moveInfos = new List <IItemMoveInfo>(); lock (moveLock) item.Source .ForEach(S => { using var locked = WeakCreateDeviceLock(root, root.GetCurrentPlayfield(), S.E?.S.GetCurrent(), S.Position); if (!locked.Success) { Log($"DeviceIsLocked (Source): {S.Id} #{S.Count} => {S.CustomName}", LogLevel.Debug); return; } var count = S.Count; count -= S.Container.RemoveItems(S.Id, count); Log($"Move(RemoveItems): {S.CustomName} {S.Id} #{S.Count}->{count}", LogLevel.Debug); ItemMoveInfo currentMoveInfo = null; if (count > 0) { uniqueNames .Where(N => N != S.CustomName) .ForEach(N => { var startCount = count; count = MoveItem(root, S, N, structure, count, maxLimit); if (startCount != count) { var movedCount = startCount - count; moveInfos.Add(currentMoveInfo = new ItemMoveInfo() { Id = S.Id, Count = movedCount, SourceE = S.E, Source = S.CustomName, DestinationE = structure.E, Destination = N, }); Log($"Move(AddItems): {S.CustomName} {S.Id} #{S.Count}->{startCount - count}", LogLevel.Debug); // Für diesen Scriptdurchlauf dieses Item aus der Verarbeitung nehmen S.Count -= movedCount; } ; }, () => root.TimeLimitReached); } if (count > 0) { var retoureCount = count; count = S.Container.AddItems(S.Id, retoureCount); Log($"Move(retoure): {S.CustomName} {retoureCount} -> {count}", LogLevel.Debug); } if (count > 0) { root.GetPlayfieldScriptData().MoveLostItems.Enqueue(new ItemMoveInfo() { Id = S.Id, Count = count, SourceE = S.E, Source = S.CustomName, }); currentMoveInfo.Error = $"{{move}} error lost #{count} of item {S.Id} in container {S.CustomName} -> add to retry list"; } }, () => root.TimeLimitReached); return(moveInfos); }