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));
        }
Пример #2
0
 public static IBlockData[] DevicesOfType(IStructureData structure, DeviceTypeName deviceType)
 {
     return structure?.GetCurrent()
                     .GetDevices(deviceType)?
                     .Values()
                     .Select(V => new BlockData(structure.GetCurrent(), V))
                     .ToArray();
 }
Пример #3
0
        public static IBlockData[] Devices(IStructureData structure, string names)
        {
            var uniqueNames = structure.AllCustomDeviceNames.GetUniqueNames(names);

            return uniqueNames
                .SelectMany(N => structure.GetCurrent().GetDevicePositions(N)
                .Select(V => new BlockData(structure.GetCurrent(), V)))
                .ToArray();
        }
Пример #4
0
 public void WithLockedDevice(IStructureData structure, IBlockData block, Action action, Action lockFailed = null)
 {
     using (var locked = ConveyorHelpers.CreateDeviceLock(ScriptRoot, ScriptRoot.GetCurrentPlayfield(), structure.GetCurrent(), block.Position))
     {
         if (locked.Success)
         {
             action();
         }
         else
         {
             lockFailed?.Invoke();
         }
     }
 }
        private static int MoveItem(ItemsSource 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);
            }

            using (var locked = CreateDeviceLock(EmpyrionScripting.ModApi?.Playfield, targetStructure.GetCurrent(), targetData.Position))
            {
                if (!locked.Success)
                {
                    Log($"DeviceIsLocked (Target): {S.Id} #{S.Count} => {targetData.CustomName}", LogLevel.Debug);
                    return(count);
                }

                if (maxLimit.HasValue)
                {
                    var stock    = target.GetTotalItems(S.Id);
                    var transfer = Math.Max(0, Math.Min(count, maxLimit.Value - stock));
                    return(target.AddItems(S.Id, transfer) + (count - transfer));
                }
                else
                {
                    return(target.AddItems(S.Id, count));
                }
            }
        }
 public IItemsData[] Items(IStructureData structure, string names) => ItemAccessHelpers.Items(ScriptRoot, structure, names);
Пример #7
0
 public T[] GetDevices <T>(IStructureData structure, string names) where T : class, IDevice
 => BlockHelpers.Devices(structure, names)
 .OfType <BlockData>()
 .Select(B => B?.GetStructure()?.GetDevice <T>(B.Position))
 .Where(B => B != null)
 .ToArray();
Пример #8
0
 public IBlockData Block(IStructureData structure, int x, int y, int z) => new BlockData(structure.GetCurrent(), new Eleon.Modding.VectorInt3(x, y, z));
Пример #9
0
 public IBlockData[] DevicesOfType(IStructureData structure, DeviceTypeName deviceType) => BlockHelpers.DevicesOfType(structure, deviceType);
Пример #10
0
 public IBlockData[] Devices(IStructureData structure, string names) => BlockHelpers.Devices(structure, names);
Пример #11
0
 public IList <IItemMoveInfo> Move(IItemsData item, IStructureData structure, string names, int?maxLimit           = null) => ConveyorHelpers.Move(ScriptRoot, item, structure, names, maxLimit);
Пример #12
0
 public bool IsLocked(IStructureData structure, IBlockData block) => ScriptRoot.GetCurrentPlayfield().IsStructureDeviceLocked(structure.GetCurrent().Id, block.Position);
Пример #13
0
 public IList <IItemMoveInfo> Fill(IItemsData item, IStructureData structure, StructureTankType type, int?maxLimit = null) => ConveyorHelpers.Fill(ScriptRoot, item, structure, type, maxLimit ?? 100);
Пример #14
0
        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);
        }
Пример #15
0
        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);
        }
Пример #16
0
 public SignalData(IStructureData structure, SenderSignal signal)
 {
     _Signal    = signal;
     _Structure = structure;
 }