static void DeconstructPart(TextWriter output, IScriptRootData root, IStructure S, DeconstructData deconstructData, IContainer target, VectorInt3 targetPos, string N) { IDeviceLock locked = null; var startTime = DateTime.Now; var maxMilliSeconds = EmpyrionScripting.Configuration.Current.InGameScriptsIntervallMS; try { for (; deconstructData.Y >= deconstructData.MinPos.y; deconstructData.Y--) { for (; deconstructData.X <= deconstructData.MaxPos.x; deconstructData.X++) { for (; deconstructData.Z <= deconstructData.MaxPos.z; deconstructData.Z++) { deconstructData.CheckedBlocks++; var block = S.GetBlock(deconstructData.X, 128 + deconstructData.Y, deconstructData.Z); if (block != null) { block.Get(out var blockType, out _, out _, out _); if (blockType > 0 && blockType != PlayerCoreType) { locked = locked ?? CreateDeviceLock(EmpyrionScripting.ModApi?.Playfield, root.E.S.GetCurrent(), targetPos); if (!locked.Success) { deconstructData.CheckedBlocks--; output.WriteLine($"Container '{N}' is locked"); return; } if (target.AddItems(blockType, 1) > 0) { deconstructData.CheckedBlocks--; output.WriteLine($"Container '{N}' is full"); return; } block.Set(0); deconstructData.RemovedBlocks++; if (deconstructData.RemovedBlocks > 100 && deconstructData.RemovedBlocks % 100 == 0 && (DateTime.Now - startTime).TotalMilliseconds > maxMilliSeconds) { return; } } } } deconstructData.Z = deconstructData.MinPos.z; } deconstructData.X = deconstructData.MinPos.x; } } finally { locked?.Dispose(); } }
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(); } }