data(atlas): author hop-0 and hop-1 body catalogs (6 systems)
Systems authored: Sol (GJ 0), Gateway (GJ 71), Ran (GJ 144), Sirius (GJ 244A), ACB (GJ 559B), Struve (GJ 725B). Total: 59 bodies + 10 stations across 6 systems. Named bodies: Mercury, Venus, Earth, Luna, Mars, Phobos, Deimos, Jupiter, Io, Europa, Ganymede, Callisto, Saturn, Titan, Enceladus, Uranus, Neptune (Sol); Threshold, Arden, Verantis (Gateway); Kallast, Vethis (Ran); Edict (Sirius); Sede (ACB); Rush (Struve). Named stations: Kallast Freight Terminal, Conclave, Aperture, Leverage, Quorum, The Stack. Atlas CLI: added commit-system auto-update of star_systems counts, next command for hop-ordered authoring, sync-wiki with full field rendering. Edict naming lore added to Sirius wiki by Miri. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -147,6 +147,11 @@ enum Commands {
|
||||
},
|
||||
/// List systems that have no bodies yet
|
||||
Unfinished,
|
||||
/// List unfinished systems at a specific hop distance (or next available hop)
|
||||
Next {
|
||||
/// Hop distance (omit to find the lowest hop with unfinished systems)
|
||||
hop: Option<i32>,
|
||||
},
|
||||
/// Sync body/station data into wiki page for a system (or all systems)
|
||||
SyncWiki {
|
||||
/// System ID (omit for all systems with bodies)
|
||||
@@ -1187,6 +1192,51 @@ fn cmd_commit_system(conn: &Connection, path: &str) {
|
||||
});
|
||||
}
|
||||
|
||||
// Update star_systems counts from the actual body data
|
||||
let habitable_count: i32 = proposal
|
||||
.bodies
|
||||
.iter()
|
||||
.filter(|b| {
|
||||
b.atmosphere.as_deref() == Some("breathable")
|
||||
&& (b.body_type == "planet" || b.body_type == "moon")
|
||||
})
|
||||
.count() as i32;
|
||||
|
||||
let inhabited_count: i32 = proposal
|
||||
.bodies
|
||||
.iter()
|
||||
.filter(|b| b.inhabited)
|
||||
.count() as i32
|
||||
+ proposal.stations.iter().filter(|s| {
|
||||
s.population.unwrap_or(0) > 0 || s.station_type == "horizon"
|
||||
}).count() as i32;
|
||||
|
||||
let has_gas_giant: i32 = proposal
|
||||
.bodies
|
||||
.iter()
|
||||
.any(|b| b.body_type == "gas_giant")
|
||||
as i32;
|
||||
|
||||
let has_belt: i32 = proposal
|
||||
.bodies
|
||||
.iter()
|
||||
.any(|b| b.body_type == "asteroid_belt")
|
||||
as i32;
|
||||
|
||||
tx.execute(
|
||||
"UPDATE star_systems SET habitable_planet_count = ?1, inhabited_planet_count = ?2,
|
||||
gas_giant = ?3, asteroid_belt = ?4
|
||||
WHERE system_id = ?5",
|
||||
params![
|
||||
habitable_count,
|
||||
inhabited_count,
|
||||
has_gas_giant,
|
||||
has_belt,
|
||||
proposal.system_id,
|
||||
],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
tx.commit().unwrap();
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -1194,11 +1244,15 @@ fn cmd_commit_system(conn: &Connection, path: &str) {
|
||||
system_id: String,
|
||||
bodies_created: usize,
|
||||
stations_created: usize,
|
||||
habitable_count: i32,
|
||||
inhabited_count: i32,
|
||||
}
|
||||
let result = CommitResult {
|
||||
system_id: proposal.system_id,
|
||||
bodies_created: proposal.bodies.len(),
|
||||
stations_created: proposal.stations.len(),
|
||||
habitable_count,
|
||||
inhabited_count,
|
||||
};
|
||||
println!("{}", serde_json::to_string_pretty(&result).unwrap());
|
||||
}
|
||||
@@ -1272,6 +1326,89 @@ fn cmd_unfinished(conn: &Connection) {
|
||||
println!("{}", serde_json::to_string_pretty(&result).unwrap());
|
||||
}
|
||||
|
||||
fn cmd_next(conn: &Connection, hop: Option<i32>) {
|
||||
// Find the target hop — either specified or the lowest with unfinished systems
|
||||
let target_hop: i32 = if let Some(h) = hop {
|
||||
h
|
||||
} else {
|
||||
conn.query_row(
|
||||
"SELECT MIN(g.hop_distance_from_gateway)
|
||||
FROM star_systems s
|
||||
JOIN system_gates g ON s.system_id = g.system_id
|
||||
WHERE s.system_id NOT IN (SELECT DISTINCT system_id FROM bodies)",
|
||||
[],
|
||||
|r| r.get::<_, Option<i32>>(0),
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap_or(-1)
|
||||
};
|
||||
|
||||
if target_hop < 0 {
|
||||
println!(r#"{{"hop": null, "count": 0, "systems": [], "message": "all systems have bodies"}}"#);
|
||||
return;
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct NextSystem {
|
||||
system_id: String,
|
||||
proper_name: Option<String>,
|
||||
star_type: Option<String>,
|
||||
spectral_class: Option<String>,
|
||||
gate_topology: Option<String>,
|
||||
geographic_sector: Option<String>,
|
||||
habitable_planet_count: Option<i32>,
|
||||
inhabited_planet_count: Option<i32>,
|
||||
population: Option<i64>,
|
||||
}
|
||||
|
||||
let mut stmt = conn
|
||||
.prepare(
|
||||
"SELECT s.system_id, s.proper_name, s.star_type, s.spectral_class,
|
||||
g.gate_topology, s.geographic_sector,
|
||||
s.habitable_planet_count, s.inhabited_planet_count,
|
||||
e.population
|
||||
FROM star_systems s
|
||||
JOIN system_gates g ON s.system_id = g.system_id
|
||||
LEFT JOIN system_economy e ON s.system_id = e.system_id
|
||||
WHERE g.hop_distance_from_gateway = ?1
|
||||
AND s.system_id NOT IN (SELECT DISTINCT system_id FROM bodies)
|
||||
ORDER BY s.system_id",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let systems: Vec<NextSystem> = stmt
|
||||
.query_map(params![target_hop], |row| {
|
||||
Ok(NextSystem {
|
||||
system_id: row.get(0)?,
|
||||
proper_name: row.get(1)?,
|
||||
star_type: row.get(2)?,
|
||||
spectral_class: row.get(3)?,
|
||||
gate_topology: row.get(4)?,
|
||||
geographic_sector: row.get(5)?,
|
||||
habitable_planet_count: row.get(6)?,
|
||||
inhabited_planet_count: row.get(7)?,
|
||||
population: row.get(8)?,
|
||||
})
|
||||
})
|
||||
.unwrap()
|
||||
.filter_map(|r| r.ok())
|
||||
.collect();
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct NextResult {
|
||||
hop: i32,
|
||||
count: usize,
|
||||
systems: Vec<NextSystem>,
|
||||
}
|
||||
|
||||
let result = NextResult {
|
||||
hop: target_hop,
|
||||
count: systems.len(),
|
||||
systems,
|
||||
};
|
||||
println!("{}", serde_json::to_string_pretty(&result).unwrap());
|
||||
}
|
||||
|
||||
fn cmd_sync_wiki(conn: &Connection, system_id: Option<&str>, wiki_dir: &str) {
|
||||
// Get list of systems to sync
|
||||
let system_ids: Vec<String> = if let Some(sid) = system_id {
|
||||
@@ -1609,6 +1746,7 @@ fn main() {
|
||||
Commands::CommitSystem { path } => cmd_commit_system(&conn, path),
|
||||
Commands::WipeSystem { system_id } => cmd_wipe_system(&conn, system_id),
|
||||
Commands::Unfinished => cmd_unfinished(&conn),
|
||||
Commands::Next { hop } => cmd_next(&conn, *hop),
|
||||
Commands::SyncWiki { system_id, wiki } => {
|
||||
cmd_sync_wiki(&conn, system_id.as_deref(), wiki)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user