fix issue where items were accepted by a belt from opposite travel direction
This commit is contained in:
@@ -27,6 +27,56 @@ QPoint BeltSystem::adjacentTile(QPoint tile, Rotation dir)
|
||||
return tile;
|
||||
}
|
||||
|
||||
Rotation BeltSystem::oppositeRotation(Rotation dir)
|
||||
{
|
||||
switch (dir)
|
||||
{
|
||||
case Rotation::North: return Rotation::South;
|
||||
case Rotation::East: return Rotation::West;
|
||||
case Rotation::South: return Rotation::North;
|
||||
case Rotation::West: return Rotation::East;
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
bool BeltSystem::entersThroughOutputEdge(QPoint tile, Rotation travelDir) const
|
||||
{
|
||||
// An item travelling in travelDir crosses into the tile through the edge
|
||||
// opposite that direction. If that entry edge is one of the tile's output
|
||||
// edges, the tile must refuse the item (REQ-MAT-ACCEPT-DIR).
|
||||
const Rotation entryEdge = oppositeRotation(travelDir);
|
||||
|
||||
const std::map<std::pair<int, int>, BeltTile>::const_iterator beltIt =
|
||||
m_belts.find(key(tile));
|
||||
if (beltIt != m_belts.end())
|
||||
{
|
||||
return entryEdge == beltIt->second.direction;
|
||||
}
|
||||
|
||||
const std::map<std::pair<int, int>, SplitterTile>::const_iterator splIt =
|
||||
m_splitters.find(key(tile));
|
||||
if (splIt != m_splitters.end())
|
||||
{
|
||||
return entryEdge == splIt->second.outputA || entryEdge == splIt->second.outputB;
|
||||
}
|
||||
|
||||
const std::map<std::pair<int, int>, TunnelEntryTile>::const_iterator teIt =
|
||||
m_tunnelEntries.find(key(tile));
|
||||
if (teIt != m_tunnelEntries.end())
|
||||
{
|
||||
return entryEdge == teIt->second.direction;
|
||||
}
|
||||
|
||||
const std::map<std::pair<int, int>, TunnelExitTile>::const_iterator txIt =
|
||||
m_tunnelExits.find(key(tile));
|
||||
if (txIt != m_tunnelExits.end())
|
||||
{
|
||||
return entryEdge == txIt->second.direction;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QPointF BeltSystem::slotWorldPos(QPoint tile, Rotation dir, double progress)
|
||||
{
|
||||
// Map progress [0, 1] along the belt direction to a fractional tile-unit position.
|
||||
@@ -202,6 +252,12 @@ void BeltSystem::reevaluateTunnelPairing()
|
||||
|
||||
bool BeltSystem::tryPutItem(QPoint tile, Item item, Rotation fromDir)
|
||||
{
|
||||
// Refuse items that would enter through the tile's output edge (REQ-MAT-ACCEPT-DIR).
|
||||
if (entersThroughOutputEdge(tile, fromDir))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::map<std::pair<int, int>, BeltTile>::iterator bIt = m_belts.find(key(tile));
|
||||
if (bIt != m_belts.end())
|
||||
{
|
||||
@@ -579,6 +635,13 @@ void BeltSystem::moveItemsToNextTile()
|
||||
const QPoint here = QPoint(it->first.first, it->first.second);
|
||||
const QPoint next = adjacentTile(here, bt.direction);
|
||||
|
||||
// Refuse to hand off into a downstream tile's output edge (REQ-MAT-ACCEPT-DIR);
|
||||
// the item stays blocked at progress 1.0.
|
||||
if (entersThroughOutputEdge(next, bt.direction))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::map<std::pair<int, int>, BeltTile>::iterator nextBelt = m_belts.find(key(next));
|
||||
const std::map<std::pair<int, int>, SplitterTile>::iterator nextSplitter = m_splitters.find(key(next));
|
||||
|
||||
@@ -804,6 +867,12 @@ bool BeltSystem::tryPlaceOnBelt(QPoint tile, Item item)
|
||||
|
||||
bool BeltSystem::tryPushToTile(QPoint dest, Item item, Rotation fromDir)
|
||||
{
|
||||
// Refuse items that would enter through the tile's output edge (REQ-MAT-ACCEPT-DIR).
|
||||
if (entersThroughOutputEdge(dest, fromDir))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tryPlaceOnBelt(dest, item))
|
||||
{
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user