|
|
@@ -1,6 +1,7 @@
|
|
|
import type { Signal } from "../assets/SelectSignal";
|
|
|
import {
|
|
|
expandBlockInstances,
|
|
|
+ getPreset,
|
|
|
type BlueprintSignal,
|
|
|
type ClockBlock,
|
|
|
type ClockRow,
|
|
|
@@ -42,6 +43,21 @@ function mergeAdjacent(instances: Instance[]): Instance[][] {
|
|
|
return runs;
|
|
|
}
|
|
|
|
|
|
+function describeRun(run: Instance[]): string {
|
|
|
+ const counts = new Map<string, number>();
|
|
|
+ for (const inst of run) {
|
|
|
+ counts.set(inst.presetId, (counts.get(inst.presetId) ?? 0) + 1);
|
|
|
+ }
|
|
|
+ return [...counts.entries()]
|
|
|
+ .map(([presetId, repeatCount]) => {
|
|
|
+ const preset = getPreset(presetId);
|
|
|
+ const icon =
|
|
|
+ preset.fromItem && preset.toItem ? `[item=${preset.fromItem}]=>[item=${preset.toItem}]` : preset.label;
|
|
|
+ return repeatCount > 1 ? `${repeatCount}x ${icon}` : icon;
|
|
|
+ })
|
|
|
+ .join(" ");
|
|
|
+}
|
|
|
+
|
|
|
export function extractConfig(blueprint: { blueprint: { entities: DeciderCombinator[] } }): ClockConfig | null {
|
|
|
const master = blueprint.blueprint.entities.find((e) => e.player_description?.startsWith("Master Clock"));
|
|
|
if (!master) return null;
|
|
|
@@ -82,8 +98,6 @@ export function buildBlueprint(config: ClockConfig) {
|
|
|
});
|
|
|
id++;
|
|
|
|
|
|
- // Group blocks by row so numbering ("Activation 1", "Activation 2"...)
|
|
|
- // follows each row's own timeline order, left to right.
|
|
|
for (const row of config.rows) {
|
|
|
const rowBlocks = config.blocks.filter((b) => b.rowId === row.id);
|
|
|
const instances: Instance[] = rowBlocks.flatMap((block) =>
|
|
|
@@ -95,33 +109,36 @@ export function buildBlueprint(config: ClockConfig) {
|
|
|
})),
|
|
|
);
|
|
|
const runs = mergeAdjacent(instances);
|
|
|
- runs.forEach((run, index) => {
|
|
|
+ const conditions: DeciderCondition[] = [];
|
|
|
+
|
|
|
+ runs.forEach((run) => {
|
|
|
const start = run[0].start;
|
|
|
const end = run[run.length - 1].start + run[run.length - 1].duration;
|
|
|
- const conditions: DeciderCondition[] = [
|
|
|
- { first_signal: clockSig, constant: start, comparator: "≥" },
|
|
|
+
|
|
|
+ conditions.push(
|
|
|
+ { first_signal: clockSig, constant: start, comparator: "≥", compare_type: "or" },
|
|
|
{ first_signal: clockSig, constant: end, comparator: "<", compare_type: "and" },
|
|
|
- ];
|
|
|
- entities.push({
|
|
|
- entity_number: id,
|
|
|
- name: "decider-combinator",
|
|
|
- position: { x: 0, y: id - 1 },
|
|
|
- direction: 4,
|
|
|
- control_behavior: {
|
|
|
- decider_conditions: {
|
|
|
- conditions,
|
|
|
- outputs: row.signals.map((s) => ({
|
|
|
- signal: sig(s.type, s.name),
|
|
|
- copy_count_from_input: false,
|
|
|
- constant: run[0].count,
|
|
|
- })),
|
|
|
- else_outputs: [],
|
|
|
- },
|
|
|
+ );
|
|
|
+ });
|
|
|
+ entities.push({
|
|
|
+ entity_number: id,
|
|
|
+ name: "decider-combinator",
|
|
|
+ position: { x: 0, y: id - 1 },
|
|
|
+ direction: 4,
|
|
|
+ control_behavior: {
|
|
|
+ decider_conditions: {
|
|
|
+ conditions,
|
|
|
+ outputs: row.signals.map((s) => ({
|
|
|
+ signal: sig(s.type, s.name),
|
|
|
+ copy_count_from_input: false,
|
|
|
+ constant: 1,
|
|
|
+ })),
|
|
|
+ else_outputs: [],
|
|
|
},
|
|
|
- player_description: `Activation ${index + 1}\n` + run.map((r) => `- ${r.count}x ${r.presetId}`).join("\n"),
|
|
|
- });
|
|
|
- id++;
|
|
|
+ },
|
|
|
+ player_description: `${row.name}\n` + runs.map((run) => describeRun(run)).join("\n"),
|
|
|
});
|
|
|
+ id++;
|
|
|
}
|
|
|
|
|
|
const wires: number[][] = [[1, 2, 1, 4]];
|