Fix atlas capital labels: realm name/culture block was colliding with the settlement's own name
Capitals systematically lost their own settlement-name label in the atlas export to the higher-priority realm name at the same point -- the previous offsets (font*0.9 up for the realm name, font*0.62 back down for the culture line) weren't nearly enough clearance, so the two boxes still overlapped and the settlement's own label got dropped by the collision check every time. Replaced the ad-hoc offsets with an explicit bottom-up stack: settlement's own label box (unshifted, drawn separately) -> culture line positioned strictly above its top edge with a real gap -> realm name positioned strictly above the culture line. Uses a conservative worst-case settlement font (City tier) as the clearance baseline so it holds regardless of which tier the capital actually is. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TMfyZv91tonDnPJqbaTVJE
This commit is contained in:
parent
dae6981dc9
commit
f18ff8f254
@ -619,10 +619,17 @@ void Viewer::exportAtlasImage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Realm names (kingdoms/empires), regardless of the current colour mode -- an atlas is a
|
// Realm names (kingdoms/empires), regardless of the current colour mode -- an atlas is a
|
||||||
// reference, not "what you're currently looking at". Offset above the capital's own marker/name
|
// reference, not "what you're currently looking at". Stacked *cleanly above* the capital's own
|
||||||
// (rather than sharing its exact anchor point) so the two don't fight over the same box in the
|
// settlement-name box (drawn separately below, unshifted at this same point) with a guaranteed
|
||||||
// decluttering pass below; city-states are skipped (bare settlement name already covers them).
|
// gap -- not just "offset a bit", which previously still let the realm-name/culture block
|
||||||
|
// overlap the settlement's own label at the same point often enough that the (higher-priority)
|
||||||
|
// realm name would win the collision check and the capital's own name would silently vanish, so
|
||||||
|
// a capital never showed its own identity, only "Duchy of X" (built from that same name).
|
||||||
|
// City-states are skipped (their bare settlement name already covers them -- there's no separate
|
||||||
|
// realm identity to show).
|
||||||
if (!planet.nationList().empty()) {
|
if (!planet.nationList().empty()) {
|
||||||
|
const float pad = 3.0f; // matches the collision-box padding below
|
||||||
|
const float settleFontMax = 17.0f * labelScale; // worst case: a City-tier capital's own label
|
||||||
for (const Nation& nat : planet.nationList()) {
|
for (const Nation& nat : planet.nationList()) {
|
||||||
if (nat.tier == NationTier::CityState || nat.name.empty()) continue;
|
if (nat.tier == NationTier::CityState || nat.name.empty()) continue;
|
||||||
if (nat.capital < 0 || nat.capital >= (int)planet.settlements.size()) continue;
|
if (nat.capital < 0 || nat.capital >= (int)planet.settlements.size()) continue;
|
||||||
@ -632,20 +639,22 @@ void Viewer::exportAtlasImage() {
|
|||||||
int prio = nat.tier == NationTier::Empire ? 0 : 1;
|
int prio = nat.tier == NationTier::Empire ? 0 : 1;
|
||||||
double lon, lat; dirToLonLat(planet.cells[cell].unit, lon, lat);
|
double lon, lat; dirToLonLat(planet.cells[cell].unit, lon, lat);
|
||||||
Vector2 lp = projLonLat(lon, lat, mapLon, er);
|
Vector2 lp = projLonLat(lon, lat, mapLon, er);
|
||||||
lp.y -= font * 0.9f;
|
float cultureFont = std::max(8.0f, std::round(font * 0.72f));
|
||||||
labels.push_back({ lp, nat.name, font, Color{245, 235, 210, 255}, prio, (float)nat.totalPop, false });
|
bool hasCulture = nat.cultureId >= 0 && nat.cultureId < (int)planet.cultureList().size()
|
||||||
// The realm's dominant culture, as a smaller "(the Velmar)" label anchored just below the
|
&& !planet.cultureList()[nat.cultureId].name.empty();
|
||||||
// realm name (still above the raw capital point) -- a lower-priority candidate in the same
|
float stackTop = lp.y - settleFontMax * 0.5f - pad; // top edge of the settlement's own box
|
||||||
// greedy pass, so on a dense world it simply drops out on its own if it doesn't fit,
|
float cultureCenterY = stackTop - pad - cultureFont * 0.5f;
|
||||||
// without any special-case logic.
|
float realmCenterY = (hasCulture ? cultureCenterY - cultureFont * 0.5f - pad : stackTop - pad)
|
||||||
if (nat.cultureId >= 0 && nat.cultureId < (int)planet.cultureList().size()) {
|
- pad - font * 0.5f;
|
||||||
|
labels.push_back({ Vector2{lp.x, realmCenterY}, nat.name, font, Color{245, 235, 210, 255},
|
||||||
|
prio, (float)nat.totalPop, false });
|
||||||
|
// The realm's dominant culture, as a smaller "(the Velmar)" label right above the realm
|
||||||
|
// name -- a lower-priority candidate in the same greedy pass, so on a dense world it
|
||||||
|
// simply drops out on its own if it doesn't fit, without any special-case logic.
|
||||||
|
if (hasCulture) {
|
||||||
const std::string& cname = planet.cultureList()[nat.cultureId].name;
|
const std::string& cname = planet.cultureList()[nat.cultureId].name;
|
||||||
if (!cname.empty()) {
|
labels.push_back({ Vector2{lp.x, cultureCenterY}, "(" + cname + ")", (int)cultureFont,
|
||||||
int cfont = std::max(8, (int)std::round(font * 0.72f));
|
Color{215, 205, 180, 235}, prio + 1, (float)nat.totalPop, false });
|
||||||
Vector2 clp = lp; clp.y += font * 0.62f;
|
|
||||||
labels.push_back({ clp, "(" + cname + ")", cfont, Color{215, 205, 180, 235},
|
|
||||||
prio + 1, (float)nat.totalPop, false });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user