share BuildingSystem's free functions instead of copying them
This commit is contained in:
@@ -38,3 +38,17 @@ std::string buildingTypeId(BuildingType type)
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isAutoRecipeBuildingType(BuildingType type)
|
||||||
|
{
|
||||||
|
return type == BuildingType::Smelter
|
||||||
|
|| type == BuildingType::ReprocessingPlant;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isBeltSubsystemType(BuildingType type)
|
||||||
|
{
|
||||||
|
return type == BuildingType::Belt
|
||||||
|
|| type == BuildingType::Splitter
|
||||||
|
|| type == BuildingType::TunnelEntry
|
||||||
|
|| type == BuildingType::TunnelExit;
|
||||||
|
}
|
||||||
|
|||||||
@@ -29,3 +29,13 @@ std::optional<BuildingType> parseBuildingType(const std::string& id);
|
|||||||
|
|
||||||
// Canonical id string for a BuildingType. The inverse of parseBuildingType.
|
// Canonical id string for a BuildingType. The inverse of parseBuildingType.
|
||||||
std::string buildingTypeId(BuildingType type);
|
std::string buildingTypeId(BuildingType type);
|
||||||
|
|
||||||
|
// Smelter and Reprocessing Plant have no player-selected recipe
|
||||||
|
// (REQ-BLD-SMELTER, REQ-BLD-REPROCESSING). They auto-process whatever inputs
|
||||||
|
// they receive, matching against every recipe of their building type.
|
||||||
|
bool isAutoRecipeBuildingType(BuildingType type);
|
||||||
|
|
||||||
|
// Belts, splitters, and tunnel ends keep their runtime data in the belt subsystem
|
||||||
|
// rather than in the Building instance, so placing/removing them must register or
|
||||||
|
// unregister a tile with BeltSystem.
|
||||||
|
bool isBeltSubsystemType(BuildingType type);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ SET(HDRS
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/ItemType.h
|
${CMAKE_CURRENT_SOURCE_DIR}/ItemType.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Item.h
|
${CMAKE_CURRENT_SOURCE_DIR}/Item.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Port.h
|
${CMAKE_CURRENT_SOURCE_DIR}/Port.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/PortGeometry.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/SchematicChoiceOption.h
|
${CMAKE_CURRENT_SOURCE_DIR}/SchematicChoiceOption.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/DisplayName.h
|
${CMAKE_CURRENT_SOURCE_DIR}/DisplayName.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/BeltDragPath.h
|
${CMAKE_CURRENT_SOURCE_DIR}/BeltDragPath.h
|
||||||
|
|||||||
45
src/lib/core/PortGeometry.h
Normal file
45
src/lib/core/PortGeometry.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QPoint>
|
||||||
|
|
||||||
|
#include "Rotation.h"
|
||||||
|
|
||||||
|
// Geometry of a building's input/output ports. A Port names the tile *outside* the
|
||||||
|
// building together with the direction items flow across it; these helpers give the
|
||||||
|
// building body tile on the other side of that edge, which is where the virtual
|
||||||
|
// input/output belt lives.
|
||||||
|
//
|
||||||
|
// Shared by the simulation (which moves items across the edge) and the renderer
|
||||||
|
// (which draws the virtual belt), so the two cannot disagree about which tile a
|
||||||
|
// port belongs to.
|
||||||
|
|
||||||
|
// The building body tile that owns an output port, given the port's outside tile
|
||||||
|
// (port.tile) and its facing direction. The virtual output belt occupies this tile
|
||||||
|
// and flows toward port.tile (REQ-MAT-OUTPUT-EMERGE).
|
||||||
|
inline QPoint outputBodyTile(QPoint portTile, Rotation direction)
|
||||||
|
{
|
||||||
|
switch (direction)
|
||||||
|
{
|
||||||
|
case Rotation::East: return portTile + QPoint(-1, 0);
|
||||||
|
case Rotation::West: return portTile + QPoint( 1, 0);
|
||||||
|
case Rotation::North: return portTile + QPoint( 0, 1);
|
||||||
|
case Rotation::South: return portTile + QPoint( 0, -1);
|
||||||
|
}
|
||||||
|
return portTile;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The building body tile an input port feeds into, given the port's outside belt
|
||||||
|
// tile (port.tile) and its inward flow direction. The virtual input belt occupies
|
||||||
|
// this tile and flows from the outer edge (progress 0.0) to the centre (0.5)
|
||||||
|
// (REQ-MAT-INPUT-INTAKE).
|
||||||
|
inline QPoint inputBodyTile(QPoint portTile, Rotation inwardDirection)
|
||||||
|
{
|
||||||
|
switch (inwardDirection)
|
||||||
|
{
|
||||||
|
case Rotation::East: return portTile + QPoint( 1, 0);
|
||||||
|
case Rotation::West: return portTile + QPoint(-1, 0);
|
||||||
|
case Rotation::North: return portTile + QPoint( 0, -1);
|
||||||
|
case Rotation::South: return portTile + QPoint( 0, 1);
|
||||||
|
}
|
||||||
|
return portTile;
|
||||||
|
}
|
||||||
@@ -6,63 +6,13 @@
|
|||||||
#include <random>
|
#include <random>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#include "PortGeometry.h"
|
||||||
#include "StateChecksum.h"
|
#include "StateChecksum.h"
|
||||||
#include "SurfaceMask.h"
|
#include "SurfaceMask.h"
|
||||||
#include "tracing.h"
|
#include "tracing.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// Smelter and Reprocessing Plant have no player-selected recipe
|
|
||||||
// (REQ-BLD-SMELTER, REQ-BLD-REPROCESSING). They auto-process whatever inputs
|
|
||||||
// they receive, matching against every recipe of their building type.
|
|
||||||
bool isAutoRecipeBuildingType(BuildingType type)
|
|
||||||
{
|
|
||||||
return type == BuildingType::Smelter
|
|
||||||
|| type == BuildingType::ReprocessingPlant;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Belts, splitters, and tunnel ends keep their runtime data in the belt subsystem
|
|
||||||
// rather than in the Building instance, so placing/removing them must register or
|
|
||||||
// unregister a tile with BeltSystem.
|
|
||||||
bool isBeltSubsystemType(BuildingType type)
|
|
||||||
{
|
|
||||||
return type == BuildingType::Belt
|
|
||||||
|| type == BuildingType::Splitter
|
|
||||||
|| type == BuildingType::TunnelEntry
|
|
||||||
|| type == BuildingType::TunnelExit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The building body tile that owns an output port, given the port's outside tile
|
|
||||||
// (port.tile) and its facing direction. The virtual output belt occupies this tile
|
|
||||||
// and flows toward port.tile (REQ-MAT-OUTPUT-EMERGE).
|
|
||||||
QPoint outputBodyTile(QPoint portTile, Rotation direction)
|
|
||||||
{
|
|
||||||
switch (direction)
|
|
||||||
{
|
|
||||||
case Rotation::East: return portTile + QPoint(-1, 0);
|
|
||||||
case Rotation::West: return portTile + QPoint( 1, 0);
|
|
||||||
case Rotation::North: return portTile + QPoint( 0, 1);
|
|
||||||
case Rotation::South: return portTile + QPoint( 0, -1);
|
|
||||||
}
|
|
||||||
return portTile;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The building body tile an input port feeds into, given the port's outside belt
|
|
||||||
// tile (port.tile) and its inward flow direction. The virtual input belt occupies
|
|
||||||
// this tile and flows from the outer edge (progress 0.0) to the centre (0.5)
|
|
||||||
// (REQ-MAT-INPUT-INTAKE).
|
|
||||||
QPoint inputBodyTile(QPoint portTile, Rotation inwardDirection)
|
|
||||||
{
|
|
||||||
switch (inwardDirection)
|
|
||||||
{
|
|
||||||
case Rotation::East: return portTile + QPoint( 1, 0);
|
|
||||||
case Rotation::West: return portTile + QPoint(-1, 0);
|
|
||||||
case Rotation::North: return portTile + QPoint( 0, -1);
|
|
||||||
case Rotation::South: return portTile + QPoint( 0, 1);
|
|
||||||
}
|
|
||||||
return portTile;
|
|
||||||
}
|
|
||||||
|
|
||||||
// An input belt accepts a new item at progress 0.0 only when it holds fewer than
|
// An input belt accepts a new item at progress 0.0 only when it holds fewer than
|
||||||
// three items and the entry slot is clear (nothing within a quarter tile of 0.0),
|
// three items and the entry slot is clear (nothing within a quarter tile of 0.0),
|
||||||
// matching the belt packing used elsewhere (REQ-GW-BELT-CAPACITY).
|
// matching the belt packing used elsewhere (REQ-GW-BELT-CAPACITY).
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
#include "HealthComponent.h"
|
#include "HealthComponent.h"
|
||||||
#include "HqProxyComponent.h"
|
#include "HqProxyComponent.h"
|
||||||
#include "ItemIconCache.h"
|
#include "ItemIconCache.h"
|
||||||
|
#include "PortGeometry.h"
|
||||||
#include "PositionComponent.h"
|
#include "PositionComponent.h"
|
||||||
#include "RepairBehavior.h"
|
#include "RepairBehavior.h"
|
||||||
#include "SalvageScrapBehavior.h"
|
#include "SalvageScrapBehavior.h"
|
||||||
@@ -166,18 +167,6 @@ Rotation rotateCounterClockwise(Rotation r)
|
|||||||
return Rotation::East;
|
return Rotation::East;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint portBodyTile(QPoint portTile, Rotation direction)
|
|
||||||
{
|
|
||||||
switch (direction)
|
|
||||||
{
|
|
||||||
case Rotation::East: return portTile + QPoint(-1, 0);
|
|
||||||
case Rotation::West: return portTile + QPoint( 1, 0);
|
|
||||||
case Rotation::North: return portTile + QPoint( 0, 1);
|
|
||||||
case Rotation::South: return portTile + QPoint( 0, -1);
|
|
||||||
}
|
|
||||||
return portTile;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill color for a building's status light per its production state
|
// Fill color for a building's status light per its production state
|
||||||
// (REQ-UI-STATUS-LIGHT).
|
// (REQ-UI-STATUS-LIGHT).
|
||||||
QColor statusLightFill(ProductionStatus status, const StatusLightVisuals& sl)
|
QColor statusLightFill(ProductionStatus status, const StatusLightVisuals& sl)
|
||||||
@@ -1341,7 +1330,7 @@ void GameWorldView::drawBuildings(QPainter& painter)
|
|||||||
|
|
||||||
for (const Port& port : b.outputPorts)
|
for (const Port& port : b.outputPorts)
|
||||||
{
|
{
|
||||||
drawPortGlyph(painter, portBodyTile(port.tile, port.direction),
|
drawPortGlyph(painter, outputBodyTile(port.tile, port.direction),
|
||||||
port.direction, bv.outline, /*centered*/ false);
|
port.direction, bv.outline, /*centered*/ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1441,7 +1430,7 @@ void GameWorldView::drawBuildings(QPainter& painter)
|
|||||||
for (const Port& port : siteMask.outputPorts)
|
for (const Port& port : siteMask.outputPorts)
|
||||||
{
|
{
|
||||||
const QPoint absBody = s.anchor
|
const QPoint absBody = s.anchor
|
||||||
+ portBodyTile(port.tile, port.direction);
|
+ outputBodyTile(port.tile, port.direction);
|
||||||
drawPortGlyph(painter, absBody, port.direction, bv.outline,
|
drawPortGlyph(painter, absBody, port.direction, bv.outline,
|
||||||
/*centered*/ false);
|
/*centered*/ false);
|
||||||
}
|
}
|
||||||
@@ -2215,7 +2204,7 @@ void GameWorldView::drawBuildingGhost(QPainter& painter, BuildingType type,
|
|||||||
|
|
||||||
for (const Port& port : parsed.outputPorts)
|
for (const Port& port : parsed.outputPorts)
|
||||||
{
|
{
|
||||||
drawPortGlyph(painter, anchorTile + portBodyTile(port.tile, port.direction),
|
drawPortGlyph(painter, anchorTile + outputBodyTile(port.tile, port.direction),
|
||||||
port.direction, lineColor, /*centered*/ false);
|
port.direction, lineColor, /*centered*/ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,20 +84,6 @@ bool hasRecipeSelection(BuildingType type)
|
|||||||
|| type == BuildingType::Shipyard;
|
|| type == BuildingType::Shipyard;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-recipe buildings have no selected recipe; their production is driven by
|
|
||||||
// whatever inputs they receive.
|
|
||||||
bool isAutoRecipeBuilding(BuildingType type)
|
|
||||||
{
|
|
||||||
return type == BuildingType::Smelter
|
|
||||||
|| type == BuildingType::ReprocessingPlant;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isBeltLike(BuildingType type)
|
|
||||||
{
|
|
||||||
return type == BuildingType::Belt || type == BuildingType::Splitter
|
|
||||||
|| type == BuildingType::TunnelEntry || type == BuildingType::TunnelExit;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString rotationLabel(Rotation r)
|
QString rotationLabel(Rotation r)
|
||||||
{
|
{
|
||||||
switch (r)
|
switch (r)
|
||||||
@@ -313,7 +299,7 @@ void SelectedBuildingPanel::buildSingle(BuildingId id)
|
|||||||
|
|
||||||
// Belt "Clear" removes items from a live belt tile; a construction site has
|
// Belt "Clear" removes items from a live belt tile; a construction site has
|
||||||
// none and is not registered with BeltSystem yet, so hide it for sites.
|
// none and is not registered with BeltSystem yet, so hide it for sites.
|
||||||
if (isBeltLike(type) && !m_singleIsSite)
|
if (isBeltSubsystemType(type) && !m_singleIsSite)
|
||||||
{
|
{
|
||||||
m_clearBeltBtn->show();
|
m_clearBeltBtn->show();
|
||||||
}
|
}
|
||||||
@@ -394,7 +380,7 @@ void SelectedBuildingPanel::refreshBuffers(const Building* b)
|
|||||||
// Auto-recipe buildings (Smelter, Reprocessing Plant) have no selected
|
// Auto-recipe buildings (Smelter, Reprocessing Plant) have no selected
|
||||||
// recipe; while a cycle runs, resolve the recipe actually in production so
|
// recipe; while a cycle runs, resolve the recipe actually in production so
|
||||||
// the cycle time and progress can be shown (REQ-UI-PRODUCTION-PROGRESS).
|
// the cycle time and progress can be shown (REQ-UI-PRODUCTION-PROGRESS).
|
||||||
if (!recipe && isAutoRecipeBuilding(b->type) && b->production.has_value())
|
if (!recipe && isAutoRecipeBuildingType(b->type) && b->production.has_value())
|
||||||
{
|
{
|
||||||
recipe = m_config->recipes.findRecipeDef(b->production->recipeId, b->type);
|
recipe = m_config->recipes.findRecipeDef(b->production->recipeId, b->type);
|
||||||
}
|
}
|
||||||
@@ -488,7 +474,7 @@ void SelectedBuildingPanel::refreshBuffers(const Building* b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isProductionBuilding(b->type)
|
if (isProductionBuilding(b->type)
|
||||||
&& (recipe || shipDef || isAutoRecipeBuilding(b->type)))
|
&& (recipe || shipDef || isAutoRecipeBuildingType(b->type)))
|
||||||
{
|
{
|
||||||
if (recipe || shipDef)
|
if (recipe || shipDef)
|
||||||
{
|
{
|
||||||
@@ -683,7 +669,7 @@ void SelectedBuildingPanel::buildMulti(const std::vector<BuildingId>& ids)
|
|||||||
{
|
{
|
||||||
text += buildingTypeName(entry.first) + " x "
|
text += buildingTypeName(entry.first) + " x "
|
||||||
+ QString::number(entry.second) + "\n";
|
+ QString::number(entry.second) + "\n";
|
||||||
if (isBeltLike(entry.first))
|
if (isBeltSubsystemType(entry.first))
|
||||||
{
|
{
|
||||||
hasBelt = true;
|
hasBelt = true;
|
||||||
}
|
}
|
||||||
@@ -832,7 +818,7 @@ void SelectedBuildingPanel::onClearBelt()
|
|||||||
for (BuildingId id : m_selectedBuildingIds)
|
for (BuildingId id : m_selectedBuildingIds)
|
||||||
{
|
{
|
||||||
const Building* b = m_sim->getBuildings().findBuilding(id);
|
const Building* b = m_sim->getBuildings().findBuilding(id);
|
||||||
if (b && isBeltLike(b->type))
|
if (b && isBeltSubsystemType(b->type))
|
||||||
{
|
{
|
||||||
for (const QPoint& cell : b->bodyCells)
|
for (const QPoint& cell : b->bodyCells)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user