Commit Graph

40 Commits

Author SHA1 Message Date
64bc6cfe8f target single-building transfers by hovering, not by footprint coincidence
Coincidence required the ghost's anchor to land exactly on the target's
anchor, so on a 2x2 assembler three of its four tiles read as an ordinary
overlap and went red: you had to find the top-left tile before the copy
gesture would fire. A single-building blueprint now finds its target by
hit-testing the cursor instead -- any body tile, any facing -- and its ghost
snaps onto the target so it shows what the click will act on.

A constellation is unchanged: it is placed as a layout, so its ghosts stay
where the blueprint puts them and still need coincidence plus a matching
rotation. The old "single-building blueprints ignore target rotation"
carve-out is gone, subsumed by hovering.

blueprintHoldsOneBuilding becomes std::optional<QPoint> hoverTile, which
carries both facts in one parameter: set means "single-building blueprint,
cursor here". BlueprintGhostResolved gains ghostAnchor/ghostRotation so the
snap comes out of the classifier both callers already share, rather than
the renderer working it out separately.

Note the shipyard, which I had cited as the motivating case, is not one: its
mask needs A cells on asteroid and S cells in space, and the asteroid edge
is vertical, so a rotated shipyard can never be placed at all. Rotation was
never the real problem here; alignment was.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JcReq7hVk4KUPhTDKWAG7K
2026-08-06 20:24:32 +02:00
49e1c0ef20 let any blueprint transfer configuration, not just single-building ones
Implements 0593f48. A coinciding building of a configurable type now takes
the blueprint's settings whatever the blueprint's size, so dropping a
constellation over a partial copy of itself configures what is already
standing there instead of leaving it blank.

The whole behaviour change is one branch in resolveBlueprintGhost: at a
matching rotation, a coinciding building transfers if its type has settings
and is a compatible overlap otherwise; at a differing rotation only a
single-building blueprint still transfers. GameWorldView and WorldRenderer
needed nothing -- they already switch on the action, already exclude
transfers from the cost, and already tint them.

blueprintHoldsOneBuilding survives only as that rotation carve-out, and the
header now says so.

Note for anyone testing this by hand: the carve-out is narrower than it
reads. It is only reachable for footprints that survive rotation -- 1x1
bodies like the splitter, or fully filled symmetric ones. A miner's body is
L-shaped ("AA" / "A>"), so a rotated miner ghost covers different tiles and
coincides with nothing at all. That is the coincidence test doing its job,
not these rules, but it cost one wrong test before it was noticed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JcReq7hVk4KUPhTDKWAG7K
2026-08-06 19:59:41 +02:00
3cf35b669e implement blueprint compatible overlap and configuration transfer
Implements the two rules specified in 128bf81, which restore the
copy-settings capability removed in 648241b as a property of blueprint
placement: press C on one configured building, then click same-type
buildings to stamp its settings across the factory.

The ghost colour and the click path already shared one predicate,
canPlaceBuilding, which is what kept preview and outcome from disagreeing.
The new rules make that answer four-valued, so the shared predicate becomes
a shared classifier: resolveBlueprintGhost in PlacementRules returns
PlaceNew / CompatibleOverlap / Transfer / Invalid, and both callers switch
on it. Putting it in lib rather than in the view is the whole testability
story -- src/ui is off the test include path.

findRotateInPlaceTarget is now the tunnel guard plus a shared
findCoincidingSameTypeBuilding core, so the two rules cannot drift apart;
its existing tests pass untouched. Blueprint placement no longer emits
RotateInPlaceCommand at all. Builder mode and the belt drag are unchanged.

transferConfigTo sends every field unconditionally, so a field the
blueprint stores nothing for clears the target's rather than leaving it.
The simulation's unchanged-value guards absorb the no-op case, which is
what keeps clicking an already-matching building free of buffer and
production-progress loss.

drawBuildingGhost's bool valid becomes GhostTint{Normal,Invalid,Transfer};
the transfer colour is taken at full RGB like the invalid one so it does
not double-dim against the ghost opacity. visuals.toml regains the overlay
colour under the name config_transfer, with its VisualsConfig field and
loader line -- overlay keys are mandatory, so the three move together.

The six new resolveBlueprintGhost cases failed on first run because the
test buildings were anchored in space: BuildingSystem::place skips the
terrain rules, resolveBlueprintGhost applies them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JcReq7hVk4KUPhTDKWAG7K
2026-08-06 19:20:34 +02:00
949937d2c2 re-use PlacementFixture in BuildingTests 2026-08-05 07:53:08 +02:00
60260540cd make deconstruction its own system 2026-08-05 07:10:46 +02:00
1f4503176b make construction its own system (extracted from BuildingSystem) 2026-08-05 06:57:12 +02:00
114a43b205 make BuildingSystem stateless: FactoryState becomes a parameter 2026-08-05 06:50:11 +02:00
d87d063b10 move the placement rules and the config-dependent queries off BuildingSystem 2026-08-05 06:49:49 +02:00
9c3be0fbd0 extract the production rules as free functions over config and building 2026-08-05 06:49:15 +02:00
58b94223f7 migrate every factory query off BuildingSystem onto the free functions 2026-08-05 06:46:13 +02:00
46932e4abf move FactoryState ownership out of BuildingSystem to Simulation 2026-08-05 06:43:52 +02:00
1150985c1f share one loadTestConfig() helper across the tests 2026-08-03 21:05:28 +02:00
3671e1d7e6 fix splitter filters being lost when rotating in place and add test 2026-08-03 20:49:10 +02:00
e20a0bba67 Rename Demolish to Deconstruct 2026-07-22 21:40:42 +02:00
b2ce20e6ad Add deconstruction queue 2026-07-22 21:37:56 +02:00
a75222f111 Never rotate tunnels in place 2026-07-21 21:14:27 +02:00
4ca5b332cd Snap belt-drag end tile to a building's input edge 2026-07-21 21:09:07 +02:00
1cbc695bc5 Add building status light 2026-07-20 22:19:58 +02:00
9622fa4345 Use std::optional instead of sentinel values for absent data 2026-07-20 20:27:20 +02:00
d412c69f82 Prefix all getters with "get" 2026-07-19 21:17:38 +02:00
486296feee Allow direct output-to-input port coupling between adjacent buildings 2026-07-14 20:23:24 +02:00
c9f14970a1 Animate items entering building input ports 2026-07-14 20:21:25 +02:00
6a8c456aa1 Animate items emerging from building output ports 2026-07-14 20:18:47 +02:00
af8a2224c0 fix issue where items were accepted by a belt from opposite travel direction 2026-07-14 20:15:39 +02:00
dd7c997816 Auto-process smelter and reprocessing plant (no recipe selection) 2026-07-12 21:35:23 +02:00
d271d65678 allow to set the recipe already for construction sites 2026-06-22 22:15:56 +02:00
e5017ab3c5 fix issue where construction sites could be placed outside of game world and add tests 2026-06-22 21:13:01 +02:00
1ea1cc59fb show threat rate in debug output 2026-06-14 13:39:10 +02:00
54a6056b77 implicit item locking 2026-06-12 16:14:21 +02:00
7669245229 use meters in config 2026-06-05 20:09:20 +02:00
b57299fd2a rename EntityId to BuildingId 2026-05-23 07:53:56 +02:00
d08bf5d37b implement ship modules 2026-05-18 08:54:26 +02:00
2770bf96be allow to rotate buildings in place 2026-04-29 21:51:04 +02:00
7e0104e9b8 fix config data paths 2026-04-29 21:32:32 +02:00
55997ef851 store belts as buildings and fix issue that belts could not be selected 2026-04-24 21:09:28 +02:00
807ccc2ddf implement belts are now added to the build queue 2026-04-22 21:54:07 +02:00
d92ccbfae2 fix tests 2026-04-22 21:21:53 +02:00
f29dc9862a dont require output belts to be aligned with output ports 2026-04-22 21:15:39 +02:00
393c49e1bb fix issue where shipyard did not produce anything 2026-04-21 22:17:48 +02:00
bf29cc40e3 implement building system 2026-04-19 20:53:08 +02:00