Fix defensive bounds checks found in review: plate indexing, war/diplomacy load, map zoom reset
- PlanetDrift.cpp: guard cells[i].plateId before indexing plates[] in advect(), matching the bounds-checking convention used elsewhere in plate lifecycle code. - Panels.cpp: same guard in cellInfo() for the cell-info panel's plate lookup. - PlanetIO.cpp: range-check War.attacker/.defender and DiploTie.a/.b against settlements.size() on load, matching the validation already done for sSettleAllegiance. - Viewer.cpp: reset mapZoom/mapPanX/mapPanY in regenWorld() so a zoomed 2D map doesn't strand the view on reseed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
cdf4319b31
commit
99f4a925a1
@ -34,7 +34,8 @@ static int drawWrapped(const std::string& text, int x, int y, int font, Color co
|
||||
static std::vector<std::string> cellInfo(const Planet& p, int i, double elev, double age) {
|
||||
const Cell& c = p.cells[i];
|
||||
double lon, lat; dirToLonLat(c.unit, lon, lat);
|
||||
const Plate& pl = p.plates[c.plateId];
|
||||
static const Plate kUnknownPlate{}; // defensive: a cell should always own a valid plate
|
||||
const Plate& pl = (c.plateId >= 0 && c.plateId < (int)p.plates.size()) ? p.plates[c.plateId] : kUnknownPlate;
|
||||
const int n = (int)p.cells.size();
|
||||
auto sized = [&](const std::vector<double>& v) { return (int)v.size() == n; };
|
||||
std::vector<std::string> L;
|
||||
|
||||
@ -284,6 +284,7 @@ void Viewer::regenWorld() { // after generate(): geometry change
|
||||
buildDriftArrows(planet, driftR, driftArrows, plateLabels);
|
||||
buildMap2D(planet, mapRect, map2D);
|
||||
selectedCell = -1; subgrids.clear();
|
||||
mapZoom = 1.0; mapPanX = 0.0; mapPanY = 0.0; // drop any 2D-map zoom/pan from the old world
|
||||
settled = false; settleRun = 0; formAccum = 0.0; stepCount = 0; paused = false;
|
||||
liveWorld = false; followId = 0; wxUndo.clear(); events.clear(); nextEventId = 1; // reseed/regen drops back to World Creation
|
||||
liveInfoTab = 0; eventRowRects.clear(); eventRowIndices.clear();
|
||||
|
||||
@ -34,8 +34,12 @@ void Planet::advect(double dtMy) {
|
||||
std::vector<Vec3> vel(n);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
oP[i] = cells[i].plateId; oE[i] = cells[i].elevation; oA[i] = cells[i].geoAge; oO[i] = cells[i].oceanic;
|
||||
const Plate& p = plates[cells[i].plateId];
|
||||
vel[i] = (p.driftAxis * p.angSpeed).cross(cells[i].unit) * R;
|
||||
if (cells[i].plateId >= 0 && cells[i].plateId < (int)plates.size()) {
|
||||
const Plate& p = plates[cells[i].plateId];
|
||||
vel[i] = (p.driftAxis * p.angSpeed).cross(cells[i].unit) * R;
|
||||
} else {
|
||||
vel[i] = Vec3(); // defensive: a cell should always own a valid plate
|
||||
}
|
||||
}
|
||||
|
||||
for (int c = 0; c < n; ++c) {
|
||||
|
||||
@ -756,6 +756,8 @@ bool Planet::readState(std::istream& is, bool hasBiome, bool hasBiota, bool hasM
|
||||
readPod(is, w.id); readPod(is, w.attacker); readPod(is, w.defender);
|
||||
readPod(is, w.startYear); readPod(is, w.warscore); readPod(is, w.battles);
|
||||
if (!is || !std::isfinite(w.warscore)) return false;
|
||||
if (w.attacker < 0 || w.attacker >= (int)settlements.size()
|
||||
|| w.defender < 0 || w.defender >= (int)settlements.size()) return false;
|
||||
}
|
||||
readPod(is, sWarRng); readPod(is, sWarNextId);
|
||||
if (!sWarRng) sWarRng = cfg.seed ? (cfg.seed ^ 0x5A7B0A11u) : 0x5A7B0A11u;
|
||||
@ -771,6 +773,8 @@ bool Planet::readState(std::istream& is, bool hasBiome, bool hasBiota, bool hasM
|
||||
readPod(is, t.truceUntil); uint8_t k = 0; readPod(is, k);
|
||||
t.kind = (k <= (uint8_t)DiploKind::Rival) ? (DiploKind)k : DiploKind::Neutral;
|
||||
if (!is || !std::isfinite(t.attitude)) return false;
|
||||
if (t.a < 0 || t.a >= (int)settlements.size()
|
||||
|| t.b < 0 || t.b >= (int)settlements.size()) return false;
|
||||
}
|
||||
}
|
||||
computeBiotaDensity(); // derived density scalars for the colour views
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user