Their buffers were unioned over every recipe of their type, so a single smelter accepted all four ores at once, held three kinds of ingot, and ran whichever recipe happened to be satisfiable. Four recipes coexisted in one building. They now hold exactly one recipe, sized and cleared like any other building's, with one addition: while none is set, the first material offered at an input port that one of their recipes consumes selects it. That hook sits at both intake paths -- the belt pull and the direct coupling -- because a building that accepts nothing would otherwise leave a coupled producer stuck at its port for good. Ports are walked in order and config order breaks a tie, so the choice is deterministic. Once set the recipe never changes on its own, so a material belonging to another of its recipes is simply refused. Changing it is the player's, through the ordinary dialog, which clears the buffers and thereby also frees a building left holding part of a cycle nothing feeds any more; the dialog's clearing option reads (Auto) there, since it returns the building to selecting its own. Falling out of this: gatherCandidateRecipes collapses to getSelectedRecipe, so tickProduction loses its candidate loop; initAutoBuffers and its union are gone; these buildings can now be grey; and AutoProductionContent is deleted, its two reasons for existing (the buffer-chip union and the "recipe it ran last" fallback) having been artefacts of holding no recipe. Also makes them configurable for blueprint purposes -- they carry a recipe now, so a blueprint of one has something to transfer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ne3mejABZoLWKLh8fgpM3x
70 lines
2.2 KiB
C++
70 lines
2.2 KiB
C++
#pragma once
|
|
|
|
#include <vector>
|
|
|
|
#include "entt/entity/entity.hpp"
|
|
|
|
#include "BuildingId.h"
|
|
#include "SelectionContext.h"
|
|
|
|
class QWidget;
|
|
class SelectionContent;
|
|
class Simulation;
|
|
|
|
// What is currently selected, in the selection panel's terms. The two categories are
|
|
// mutually exclusive (REQ-UI-SELECTION-CATEGORIES): either buildings is non-empty, or
|
|
// actors and/or debris are, never both.
|
|
struct SelectionRequest
|
|
{
|
|
std::vector<BuildingId> buildings;
|
|
std::vector<entt::entity> actors;
|
|
std::vector<entt::entity> debris;
|
|
|
|
bool isEmpty() const
|
|
{
|
|
return buildings.empty() && actors.empty() && debris.empty();
|
|
}
|
|
};
|
|
|
|
// One entry of the content catalog (REQ-UI-SELECTION-CONTENT). Selections that share an
|
|
// entry get the same content and differ only in the name and symbol in the header.
|
|
enum class SelectionContentKind
|
|
{
|
|
None, // nothing selected: the panel hides itself entirely
|
|
RecipeProduction, // Miner, Assembler, Smelter, Reprocessing Plant
|
|
Shipyard,
|
|
Storage, // Salvage Bay
|
|
Hq,
|
|
Belt, // Belt, Tunnel Entry, Tunnel Exit
|
|
Splitter,
|
|
MultiBuilding,
|
|
Ship,
|
|
Station,
|
|
Debris,
|
|
FieldMulti,
|
|
};
|
|
|
|
// Identifies the card on screen. The panel rebuilds when this changes and only refreshes
|
|
// otherwise, so a construction site finishing swaps the card while a progress counter
|
|
// running does not.
|
|
struct ContentKey
|
|
{
|
|
SelectionContentKind kind = SelectionContentKind::None;
|
|
bool isSite = false;
|
|
|
|
bool operator==(const ContentKey& other) const
|
|
{
|
|
return kind == other.kind && isSite == other.isSite;
|
|
}
|
|
bool operator!=(const ContentKey& other) const { return !(*this == other); }
|
|
};
|
|
|
|
// The card this selection calls for. This is where REQ-UI-SELECTION-AGGREGATE is
|
|
// decided: a multi-selection that aggregates resolves to the single-object kind, and
|
|
// everything else to one of the two count summaries.
|
|
ContentKey chooseContent(const SelectionRequest& request, Simulation& sim);
|
|
|
|
// Builds the card. Returns nullptr for SelectionContentKind::None.
|
|
SelectionContent* createContent(const ContentKey& key, const SelectionRequest& request,
|
|
const SelectionContext& context, QWidget* parent);
|