コード例 #1
0
        protected override void OnUpdate()
        {
            var segments = GetComponentDataFromEntity <BeltSegment>();
            var items    = GetBufferFromEntity <BeltItem>();

            Entities.ForEach((Entity e, ref BeltSplitter s) =>
            {
                if (s.Input.Type != ItemType.None)
                {
                    BeltItem i = s.UseOutput2 ? s.Output2 : s.Output1;
                    if (i.Type == ItemType.None)
                    {
                        // move it straight to output
                        if (s.UseOutput2)
                        {
                            s.Output2 = s.Input;
                        }
                        else
                        {
                            s.Output1 = s.Input;
                        }
                        s.Input.Type = ItemType.None;
                        s.UseOutput2 = !s.UseOutput2;
                    }
                }

                ProcessOutput(ref segments, ref items, ref s.Output1, s.Next1);
                ProcessOutput(ref segments, ref items, ref s.Output2, s.Next2);
                // s.
            })
            .WithNativeDisableContainerSafetyRestriction(segments)
            .WithNativeDisableContainerSafetyRestriction(items)
            .ScheduleParallel();
        }
コード例 #2
0
        private static void ProcessOutput(ref ComponentDataFromEntity <BeltSegment> segments,
                                          ref BufferFromEntity <BeltItem> items, ref BeltItem sOutput1, Entity enext)
        {
            if (sOutput1.Type != ItemType.None)
            {
                var next = segments[enext];
                if (next.DistanceToInsertAtStart == 0) // full
                {
                    return;
                }
                if (sOutput1.Distance > 0)
                {
                    sOutput1.Distance--;
                    return;
                }

                if (BeltUpdateSystem.InsertInSegment(ref items, ref segments, sOutput1, enext))
                {
                    sOutput1.Type = ItemType.None;
                }
            }
        }
コード例 #3
0
ファイル: World.cs プロジェクト: theor/Automation
        public void InsertItem(BeltItem segmentItem, Point dropPoint, bool itemWillBeTickedAgain)
        {
            segmentItem.Distance = 0;
            var p       = End;
            var d       = RevDir;
            int itemIdx = 0;

            while (p != dropPoint)
            {
                p.Offset(d);
                Items ??= new List <BeltItem>();
                if (itemIdx < Items.Count)
                {
                    if (Items[itemIdx].Distance == segmentItem.Distance)
                    {
                        segmentItem.Distance = 0;
                        itemIdx++;
                        continue;
                    }
                }
                segmentItem.Distance++;
            }

            if (itemWillBeTickedAgain)
            {
                segmentItem.Distance++;
            }
            // if not last item, patch next one
            if (itemIdx < Items.Count)
            {
                var i = Items[itemIdx];
                i.Distance     = (byte)(i.Distance - segmentItem.Distance - 1);
                Items[itemIdx] = i;
            }
            Items.Insert(itemIdx, segmentItem);
        }
コード例 #4
0
ファイル: BeltUpdateSystem.cs プロジェクト: theor/Automation
            public void Execute(int index)
            {
                Entity e    = SimulationChunksFirstSegment[index];
                int    iter = 0;

                do
                {
                    if (iter++ >= 1000000)
                    {
                        throw new NotImplementedException();
                    }
                    var segment = Segments[e];
                    var items   = Items[e];
                    // Debug.Log($"{e} {segment} {items.Length}");

                    for (int i = 0; i < items.Length; i++)
                    {
                        ref BeltItem item = ref items.ElementAt(i);

                        // simple case, too far from belt end to care about a next segment
                        if (item.Distance > Settings.BeltDistanceSubDiv)
                        {
                            item.Distance--;
                            segment.DistanceToInsertAtStart++;
                            Segments[e] = segment;
                            break;
                        }

                        // no next segment, so BeltDistanceSubDiv is the min distance
                        // continue to move the next item on the belt
                        if (segment.Next == Entity.Null)
                        {
                            continue;
                        }

                        if (!HasBeltSegmentMask.Matches(segment.Next))
                        {
                            if (HasBeltSplitterMask.Matches(segment.Next))
                            {
                                var splitter = Splitters[segment.Next];
                                // no room in input
                                if (splitter.Input.Type != ItemType.None)
                                {
                                    continue;
                                }

                                if (item.Distance > 0) // still inserting
                                {
                                    item.Distance--;
                                    segment.DistanceToInsertAtStart++;
                                    Segments[e] = segment;
                                    break;
                                }

                                // will be update this frame
                                item.Distance           = (ushort)(Settings.BeltDistanceSubDiv);
                                splitter.Input          = item;
                                Splitters[segment.Next] = splitter;
                                items.RemoveAt(i);
                                // Debug.Log("MOVE TO SPLITTER");
                                i--;
                            }

                            continue;
                        }

                        // only move if the next segment has room
                        var nextBeltSegment = Segments[segment.Next];
                        if (nextBeltSegment.DistanceToInsertAtStart == 0)
                        {
                            continue;
                        }

                        if (item.Distance > 0) // still inserting
                        {
                            item.Distance--;
                            segment.DistanceToInsertAtStart++;
                            Segments[e] = segment;
                        }
                        else if (InsertInSegment(ref Items, ref Segments, item, segment.Next))
                        {
                            items.RemoveAt(i);
                            i--;
                        }

                        break;
                    }
                    e = segment.Prev;
                } while (e != Entity.Null);