3 protected int m_iIndex;
4 protected int m_iGridUpdateId =
int.MIN;
5 protected ref array<SCR_ResourceComponent> m_aStaticItems = {};
6 protected ref array<SCR_ResourceComponent> m_aDynamicItems = {};
45 array<SCR_ResourceComponent> GetResourceDynamicItems()
48 while (m_aDynamicItems.RemoveItem(
null));
50 return m_aDynamicItems;
54 array<SCR_ResourceComponent> GetResourceStaticItems()
57 while (m_aStaticItems.RemoveItemOrdered(
null));
59 return m_aStaticItems;
71 void SetGridUpdateId(
int gridUpdateId)
80 int RegisterDynamicItem(notnull SCR_ResourceComponent item,
int gridUpdateId)
85 return m_aDynamicItems.Insert(item);
89 bool UnregisterDynamicItem(notnull SCR_ResourceComponent item,
int gridUpdateId)
94 return m_aDynamicItems.RemoveItem(item);
98 int RegisterStaticItem(notnull SCR_ResourceComponent item,
int gridUpdateId)
103 return m_aStaticItems.Insert(item);
107 bool UnregisterStaticItem(notnull SCR_ResourceComponent item,
int gridUpdateId)
112 return m_aStaticItems.RemoveItemOrdered(item);
116 void MoveStaticItem(notnull SCR_ResourceComponent item,
int gridUpdateId)
121 m_aStaticItems.RemoveItemOrdered(item);
122 m_aStaticItems.Insert(item);
126 void MoveDynamicItem(notnull SCR_ResourceComponent item,
int gridUpdateId)
147 void PromoteResourceItemToDynamic(notnull SCR_ResourceComponent item)
149 m_aStaticItems.RemoveItemOrdered(item);
150 m_aDynamicItems.Insert(item);
154 void PromoteResourceItemToStatic(notnull SCR_ResourceComponent item)
156 m_aDynamicItems.RemoveItem(item);
157 m_aStaticItems.Insert(item);
170 static const int CELL_POWER = 4;
171 static const int CELL_SIZE_MINUS_1 = (1 << CELL_POWER) - 1;
173 protected ref map<int, ref SCR_ResourceGridCell>
m_Cells;
202 return x | z << CELL_POWER;
208 return x | z << CELL_POWER;
221 Debug.Error2(
"SCR_ResourceGrid",
"Maximum grid update id has been reached.");
258 int previousMins, previousMaxs;
261 item.GetGridContainersBounds(previousMins, previousMaxs);
264 if (previousMins == 0xFFFFFFFF || previousMaxs == 0xFFFFFFFF)
268 int prevMinX = previousMins & CELL_SIZE_MINUS_1;
269 int prevMinY = previousMins >> CELL_POWER;
270 int prevMaxX = previousMaxs & CELL_SIZE_MINUS_1;
271 int prevMaxY = previousMaxs >> CELL_POWER;
273 vector boundsMins, boundsMaxs;
275 item.GetGridContainersWorldBoundingBox(boundsMins, boundsMaxs);
277 int minX = (
int)boundsMins[0] >> CELL_POWER;
278 int minY = (
int)boundsMins[2] >> CELL_POWER;
279 int maxX = (
int)boundsMaxs[0] >> CELL_POWER;
280 int maxY = (
int)boundsMaxs[2] >> CELL_POWER;
284 for (
int y = prevMinY; y <= prevMaxY; ++y)
286 for (
int x = prevMinX; x <= prevMaxX; ++x)
288 gridCell =
m_Cells[y << CELL_POWER | x];
293 if ((x >= minX && x <= maxX) && (y >= minY && y <= maxY))
300 int currentCellPosition;
302 for (
int y = minY; y <= maxY; ++y)
304 for (
int x = minX; x <= maxX; ++x)
306 if (x >= prevMinX && x <= prevMaxX && y >= prevMinY && y <= prevMaxY)
313 currentCellPosition = y << CELL_POWER | x;
314 gridCell =
m_Cells[currentCellPosition];
323 item.SetGridContainersBounds(minY << CELL_POWER | minX, maxY << CELL_POWER | maxX);
330 int previousMins, previousMaxs;
333 item.GetGridContainersBounds(previousMins, previousMaxs);
336 if (previousMins == 0xFFFFFFFF || previousMaxs == 0xFFFFFFFF)
340 int prevMinX = previousMins & CELL_SIZE_MINUS_1;
341 int prevMinY = previousMins >> CELL_POWER;
342 int prevMaxX = previousMaxs & CELL_SIZE_MINUS_1;
343 int prevMaxY = previousMaxs >> CELL_POWER;
345 vector boundsMins, boundsMaxs;
347 item.GetGridContainersWorldBoundingBox(boundsMins, boundsMaxs);
349 int minX = (
int)boundsMins[0] >> CELL_POWER;
350 int minY = (
int)boundsMins[2] >> CELL_POWER;
351 int maxX = (
int)boundsMaxs[0] >> CELL_POWER;
352 int maxY = (
int)boundsMaxs[2] >> CELL_POWER;
356 for (
int y = prevMinY; y <= prevMaxY; ++y)
358 for (
int x = prevMinX; x <= prevMaxX; ++x)
360 gridCell =
m_Cells[y << CELL_POWER | x];
365 if (x >= minX && x <= maxX && y >= minY && y <= maxY)
372 int currentCellPosition;
374 for (
int y = minY; y <= maxY; ++y)
376 for (
int x = minX; x <= maxX; ++x)
378 if (x >= prevMinX && x <= prevMaxX && y >= prevMinY && y <= prevMaxY)
385 currentCellPosition = y << CELL_POWER | x;
386 gridCell =
m_Cells[currentCellPosition];
395 item.SetGridContainersBounds(minY << CELL_POWER | minX, maxY << CELL_POWER | maxX);
402 array<SCR_ResourceGridCell> cells = {};
405 item.GetGridContainersBounds(mins, maxs);
410 cell.PromoteResourceItemToDynamic(item);
417 array<SCR_ResourceGridCell> cells = {};
420 item.GetGridContainersBounds(mins, maxs);
425 cell.PromoteResourceItemToStatic(item);
430 protected void QueryGridCells(
int mins,
int maxs, inout notnull array<SCR_ResourceGridCell> gridCells)
433 int minX = mins & CELL_SIZE_MINUS_1;
434 int minY = mins >> CELL_POWER;
435 int maxX = maxs & CELL_SIZE_MINUS_1;
436 int maxY = maxs >> CELL_POWER;
440 for (
int y = minY; y <= maxY; ++y)
442 for (
int x = minX; x <= maxX; ++x)
444 gridCell =
m_Cells[y << CELL_POWER | x];
449 gridCells.Insert(gridCell);
458 int minX = (
int)boundsMins[0] >> CELL_POWER;
459 int minY = (
int)boundsMins[2] >> CELL_POWER;
460 int maxX = (
int)boundsMaxs[0] >> CELL_POWER;
461 int maxY = (
int)boundsMaxs[2] >> CELL_POWER;
465 for (
int y = minY; y <= maxY; ++y)
467 for (
int x = minX; x <= maxX; ++x)
469 gridCell =
m_Cells[y << CELL_POWER | x];
474 foreach (SCR_ResourceComponent item: gridCell.GetResourceStaticItems())
479 foreach (SCR_ResourceComponent item: gridCell.GetResourceDynamicItems())
491 int minX = mins & CELL_SIZE_MINUS_1;
492 int minY = mins >> CELL_POWER;
493 int maxX = maxs & CELL_SIZE_MINUS_1;
494 int maxY = maxs >> CELL_POWER;
498 for (
int y = minY; y <= maxY; ++y)
500 for (
int x = minX; x <= maxX; ++x)
502 gridCell =
m_Cells[y << CELL_POWER | x];
507 foreach (SCR_ResourceComponent item: gridCell.GetResourceStaticItems())
512 foreach (SCR_ResourceComponent item: gridCell.GetResourceDynamicItems())
524 int minX = (
int)boundsMins[0] >> CELL_POWER;
525 int minY = (
int)boundsMins[2] >> CELL_POWER;
526 int maxX = (
int)boundsMaxs[0] >> CELL_POWER;
527 int maxY = (
int)boundsMaxs[2] >> CELL_POWER;
530 array<SCR_ResourceComponent> gridCellItems;
531 SCR_ResourceComponent item;
533 for (
int y = minY; y <= maxY; ++y)
535 for (
int x = minX; x <= maxX; ++x)
537 gridCell =
m_Cells[y << CELL_POWER | x];
539 if (!gridCell || gridCell.GetGridUpdateId() <= gridUpdateId)
542 gridCellItems = gridCell.GetResourceStaticItems();
544 for (
int idx = gridCellItems.Count() - 1; idx >= 0; --idx)
546 item = gridCellItems[idx];
548 if (item.IsGridUpdateIdGreaterThan(gridUpdateId))
554 gridCellItems = gridCell.GetResourceDynamicItems();
556 for (
int idx = gridCellItems.Count() - 1; idx >= 0; --idx)
558 item = gridCellItems[idx];
560 if (item.IsGridUpdateIdGreaterThan(gridUpdateId))
571 int minX = mins & CELL_SIZE_MINUS_1;
572 int minY = mins >> CELL_POWER;
573 int maxX = maxs & CELL_SIZE_MINUS_1;
574 int maxY = maxs >> CELL_POWER;
577 array<SCR_ResourceComponent> gridCellItems;
578 SCR_ResourceComponent item;
580 for (
int y = minY; y <= maxY; ++y)
582 for (
int x = minX; x <= maxX; ++x)
584 gridCell =
m_Cells[y << CELL_POWER | x];
586 if (!gridCell || gridCell.GetGridUpdateId() <= gridUpdateId)
589 gridCellItems = gridCell.GetResourceStaticItems();
591 for (
int idx = gridCellItems.Count() - 1; idx >= 0; --idx)
593 item = gridCellItems[idx];
595 if (item.IsGridUpdateIdGreaterThan(gridUpdateId))
601 gridCellItems = gridCell.GetResourceDynamicItems();
603 for (
int idx = gridCellItems.Count() - 1; idx >= 0; --idx)
605 item = gridCellItems[idx];
607 if (item.IsGridUpdateIdGreaterThan(gridUpdateId))
615 void UpdateInteractor(notnull SCR_ResourceInteractor interactor,
bool useFrameBudget =
false)
617 int gridUpdateId = interactor.GetGridUpdateId();
618 vector interactorOrigin = interactor.GetOwnerOrigin();
619 bool hasInteractorMoved = vector.DistanceSq(interactorOrigin, interactor.GetLastPosition()) > SCR_ResourceComponent.UPDATE_DISTANCE_TRESHOLD_SQUARE;
621 if (!hasInteractorMoved && gridUpdateId ==
m_iGridUpdateId || interactor.IsIsolated())
624 float resourceGridRange = interactor.GetResourceGridRange();
625 vector boundsOffset = vector.One * resourceGridRange;
630 if (hasInteractorMoved)
632 QueryContainers(interactorOrigin - boundsOffset, interactorOrigin + boundsOffset, resourceType);
634 for (
int idx = containerQueue.GetContainerCount() - 1; idx >= 0; --idx)
636 container = containerQueue.GetContainerAt(idx);
638 if (!container || container.IsIsolated())
646 QueryContainers(interactorOrigin - boundsOffset, interactorOrigin + boundsOffset, resourceType, gridUpdateId);
648 for (
int idx = containerQueue.GetContainerCount() - 1; idx >= 0; --idx)
650 container = containerQueue.GetContainerAt(idx);
652 if (!container || container.IsIsolated())
655 if (container.IsGridUpdateIdGreaterThan(gridUpdateId))
667 for (
int idx = containerCount - 1; idx >= 0; --idx)
671 if (interactor.CanInteractWith(container) && container.IsInRange(interactorOrigin, resourceGridRange))
673 if (!container.IsInteractorLinked(interactor))
674 interactor.RegisterContainerForced(container);
677 interactor.UnregisterContainer(container);
681 interactor.UpdateLastPosition();
683 interactor.Replicate();
699 array<SCR_ResourceGenerator>
QueryGenerators(vector mins, vector maxs, vector transform[4])
708 if (item.GetOwner().GetOrigin() == vector.Zero)
711 vector boundsMins, boundsMaxs;
713 item.GetGridContainersWorldBoundingBox(boundsMins, boundsMaxs);
716 int currentCellPosition;
717 int minX = (
int)boundsMins[0] >> CELL_POWER;
718 int minY = (
int)boundsMins[2] >> CELL_POWER;
719 int maxX = (
int)boundsMaxs[0] >> CELL_POWER;
720 int maxY = (
int)boundsMaxs[2] >> CELL_POWER;
722 for (
int y = minY; y <= maxY; ++y)
724 for (
int x = minX; x <= maxX; ++x)
726 currentCellPosition = y << CELL_POWER | x;
727 currentCell =
m_Cells[currentCellPosition];
732 currentCell =
m_Cells[currentCellPosition];
739 item.SetGridContainersBounds(minY << CELL_POWER | minX, maxY << CELL_POWER | maxX);
749 int previousMins, previousMaxs;
752 item.GetGridContainersBounds(previousMins, previousMaxs);
755 if (previousMins == 0xFFFFFFFF || previousMaxs == 0xFFFFFFFF)
759 int prevMinX = previousMins & CELL_SIZE_MINUS_1;
760 int prevMinY = previousMins >> CELL_POWER;
761 int prevMaxX = previousMaxs & CELL_SIZE_MINUS_1;
762 int prevMaxY = previousMaxs >> CELL_POWER;
765 for (
int y = prevMinY; y <= prevMaxY; ++y)
767 for (
int x = prevMinX; x <= prevMaxX; ++x)
769 gridCell =
m_Cells[y << CELL_POWER | x];
780 item.SetGridContainersBounds(0xFFFFFFFF, 0xFFFFFFFF);
781 item.SetGridUpdateId(
int.MIN);
789 vector coordinateSizes;
790 BaseWorld world =
GetGame().GetWorld();
791 m_Cells =
new map<int, ref SCR_ResourceGridCell>();
795 world.GetBoundBox(mins, maxs);
797 coordinateSizes = maxs - mins;