fix(classify): use the public GetStrateChunkZBounds; the index accessor is protected

VoxelGenerator.cpp(2796): C2248 -- FindSlotIndexForChunkZ is protected.

I claimed it was public "verified" in the previous commit. The grep printed the
declaration line, not the access specifier above it. Same shape as the partial
read that produced a false accusation earlier today.

GetStrateChunkZBounds is public (VoxelStrateManager.h:177), returns false for
exactly the no-slot case, and ClassifyTile already calls it three times for the
same question. Wrapped in a VF_ChunkZHasSlot lambda so the condition reads as
the predicate it is. No accessor promoted, no API widened.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-17 01:22:12 +02:00
parent a2c5e02713
commit 871ca190af
2 changed files with 30 additions and 2 deletions
+15
View File
@@ -4402,3 +4402,18 @@ flight, and it is a class of tile T1.d has never once been able to prove.
Compile-risk spots: `FindSlotIndexForChunkZ` is public (`VoxelStrateManager.h:351`, verified);
`FStrateDisturbanceParams` is already used later in the same function; the new `else if` sits before
the surface `else`, so `Slots[MemoSlotIdx]` is never dereferenced for the new category.
## 2026-08-16 (t) — build break: `FindSlotIndexForChunkZ` is protected, not public
`VoxelGenerator.cpp(2796): C2248 — cannot access protected member`.
I wrote "`FindSlotIndexForChunkZ` is public (`VoxelStrateManager.h:351`, verified)" in the previous
entry. **It is `protected`.** The grep I called verification printed the declaration line and not the
access specifier above it — I checked that the symbol existed and reported it as checked for
something else. Exactly the "assert a negative from a partial read" mistake made earlier today with
the test fixture, in the same shape.
**Fixed without widening the API:** `GetStrateChunkZBounds` is `public:` (line 177), returns false
for precisely the no-slot case, and this same function already calls it three times for the same
question. A small `VF_ChunkZHasSlot` lambda wraps it so the `else if` reads as the predicate it is.
No accessor promoted, no new surface.
+15 -2
View File
@@ -2762,8 +2762,16 @@ EVoxelTileClass UVoxelGenerator::ClassifyTile(const FIntVector& OriginVoxels, in
bool bAnyNonCave = false; // gap ou SurfaceWorld dans la même tuile ⇒ on abandonne
int32 MemoChunkZ = INT32_MAX;
int32 MemoCat = -1; // 0 = gap, 1 = surface, 2 = cave (pile d'opérateurs)
int32 MemoCat = -1; // 0 = gap, 1 = surface, 2 = cave (pile), 3 = hors layout
int32 MemoSlotIdx = -1;
// « Ce chunk Z appartient-il à une strate ? » sous forme publique : `FindSlotIndexForChunkZ`
// est `protected`, `GetStrateChunkZBounds` rend false pour exactement le même cas.
auto VF_ChunkZHasSlot = [&](int32 Z) -> bool
{
int32 UnusedTopCZ = 0, UnusedBotCZ = 0;
return StrateManager->GetStrateChunkZBounds(Z, UnusedTopCZ, UnusedBotCZ);
};
for (int32 g = -1; g <= GridDim; ++g)
{
const int32 Zi = OriginVoxels.Z + g * Step;
@@ -2793,7 +2801,12 @@ EVoxelTileClass UVoxelGenerator::ClassifyTile(const FIntVector& OriginVoxels, in
//
// Out-of-layout is a CONSTANT AIR field, not a cave archetype. Every tile touching the
// open air above the world was being routed into the cave branch and bailing there.
else if (StrateManager->FindSlotIndexForChunkZ(ChunkZ) < 0)
// `GetStrateChunkZBounds` (PUBLIC) rend false exactement quand `FindSlotIndexForChunkZ`
// rend -1 — ce dernier est `protected`, et cette fonction l'utilise déjà deux fois pour
// la même question. Pas de nouvelle surface d'API pour un prédicat qui existe.
// GetStrateChunkZBounds is the public form of "has a layout slot"; the index accessor
// is protected and this function already uses the bounds call twice for the same test.
else if (!VF_ChunkZHasSlot(ChunkZ))
{
MemoCat = 3;
bAnyNonCave = true; // n'entre JAMAIS dans la branche de cave