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(); }
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; } } }
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); }
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);