void BlockSearch(IStructure str) { //in my test case, the y is off by 128 VectorInt3 minWorld = new VectorInt3( str.MinPos.x, str.MinPos.y + 128, str.MinPos.z); VectorInt3 maxWorld = new VectorInt3( str.MaxPos.x, str.MaxPos.y + 128, str.MaxPos.z); for (int x = minWorld.x; x <= maxWorld.x; x++) { for (int y = minWorld.y; y <= maxWorld.y; y++) { for (int z = minWorld.z; z <= maxWorld.z; z++) { IBlock bl = str.GetBlock(x, y, z); mAPI.Log("Block at " + x + ", " + y + ", " + z + " custom name: " + bl.CustomName + ", Damage: " + bl.GetDamage() + ", HitPoints: " + bl.GetHitPoints()); } } } }
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(); } }
public BlockData(IStructure structure, VectorInt3 pos) { _structure = structure; _block = structure?.GetBlock(pos); _device = structure?.GetDevice <IDevice>(pos); Position = pos; if (_device is IContainer c) { Device = new ContainerData(c); } }
private Tuple <ItemsData[], ConcurrentDictionary <string, IContainerSource> > CollectAllItems(IStructure structure) { var allItems = new ConcurrentDictionary <int, ItemsData>(); var containerSource = new ConcurrentDictionary <string, IContainerSource>(); Parallel.ForEach(AllCustomDeviceNames, N => { GetCurrent().GetDevicePositions(N) .ForEach(P => { var container = structure.GetDevice <IContainer>(P); var block = structure.GetBlock(P); if (container == null || block == null) { return; } containerSource.TryAdd(block.CustomName, new ContainerSource() { E = E, Container = container, CustomName = block.CustomName, Position = P }); container.GetContent() .ForEach(I => { EmpyrionScripting.ItemInfos.ItemInfo.TryGetValue(I.id, out ItemInfo details); IItemsSource source = new ItemsSource() { E = E, Id = I.id, Count = I.count, Container = container, CustomName = block.CustomName, Position = P }; allItems.AddOrUpdate(I.id, new ItemsData() { Source = new[] { source }.ToList(), Id = I.id, Count = I.count, Key = details == null ? I.id.ToString() : details.Key, Name = details == null ? I.id.ToString() : details.Name, }, (K, U) => U.AddCount(I.count, source)); }); }); }); return(new Tuple <ItemsData[], ConcurrentDictionary <string, IContainerSource> >(allItems.Values.OrderBy(I => I.Id).ToArray(), containerSource)); }
void CheckLCD(IModApi api, IDevicePosList ammo, IDevicePosList container, IDevicePosList fridge, IDevicePosList harvest, float blockScanDist) { IDevicePosList idpl = mStruct.GetDevices("LCD"); for (int i = 0; i < idpl.Count; i++) { VectorInt3 pos = idpl.GetAt(i); ILcd lcd = mStruct.GetDevice <ILcd>(pos); if (mAmmoLCD.ContainsValue(lcd)) { continue; //already in use } if (mContainerLCD.ContainsValue(lcd)) { continue; //already in use } if (mFridgeLCD.ContainsValue(lcd)) { continue; //already in use } if (mHarvestLCD.ContainsValue(lcd)) { continue; //already in use } api.Log("Unattached LCD Device at pos: " + pos); //find the closest device within BlockScanDistance float blockDist = blockScanDist; float bestDist = float.MaxValue; VectorInt3 bestPos = new VectorInt3(-1, -1, -1); int bestType = -1; IDevice assoc = null; for (int j = 0; j < ammo.Count; j++) { VectorInt3 pos2 = ammo.GetAt(j); float dist = VecDistance(pos, pos2); if (dist < blockDist && dist < bestDist) { assoc = mStruct.GetDevice <IContainer>(pos2); bestDist = dist; bestType = 0; bestPos = pos2; } } for (int j = 0; j < container.Count; j++) { VectorInt3 pos2 = container.GetAt(j); float dist = VecDistance(pos, pos2); if (dist < blockDist && dist < bestDist) { assoc = mStruct.GetDevice <IContainer>(pos2); bestDist = dist; bestType = 1; bestPos = pos2; } } for (int j = 0; j < fridge.Count; j++) { VectorInt3 pos2 = fridge.GetAt(j); float dist = VecDistance(pos, pos2); if (dist < blockDist && dist < bestDist) { assoc = mStruct.GetDevice <IContainer>(pos2); bestDist = dist; bestType = 2; bestPos = pos2; } } for (int j = 0; j < harvest.Count; j++) { VectorInt3 pos2 = harvest.GetAt(j); float dist = VecDistance(pos, pos2); if (dist < blockDist && dist < bestDist) { assoc = mStruct.GetDevice <IContainer>(pos2); bestDist = dist; bestType = 3; bestPos = pos2; } } IBlock lcdBlock = mStruct.GetBlock(pos); if (assoc == null) { api.Log("Null Assoc"); //maybe since this isn't near a device //it can be used for fuel or something CheckForSpecialLCD(lcdBlock, lcd); continue; } if (!mDevicePositions.ContainsKey(lcd)) { mDevicePositions.Add(lcd, pos); } if (!mDevicePositions.ContainsKey(assoc)) { mDevicePositions.Add(assoc, bestPos); } IBlock devBlock = mStruct.GetBlock(bestPos); if (lcdBlock == null) { api.Log("Null block for lcd!"); } else { if (mDeviceBlocks.ContainsKey(lcd)) { api.Log("BadCleanup! Device blocks already has lcd: " + lcd + "!!"); } else { mDeviceBlocks.Add(lcd, lcdBlock); } } if (devBlock == null) { api.Log("Null block for device!"); } else { if (mDeviceBlocks.ContainsKey(assoc)) { api.Log("BadCleanup! Device blocks already has assoc: " + assoc + "!!"); } else { mDeviceBlocks.Add(assoc, devBlock); } } if (bestType == 0) { api.Log("Ammo Assoc"); mAmmoLCD.Add(assoc as IContainer, lcd); } else if (bestType == 1) { api.Log("Con Assoc"); mContainerLCD.Add(assoc as IContainer, lcd); } else if (bestType == 2) { api.Log("Fridge Assoc"); mFridgeLCD.Add(assoc as IContainer, lcd); } else if (bestType == 3) { api.Log("Harv Assoc"); mHarvestLCD.Add(assoc as IContainer, lcd); } } }
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(); } }