fix(grid): correct Dijkstra path order and layer-setter cache invalidation
Two real engine bugs, both surfaced by unrotting tests that had been silently scored as passing for months, and both independently reproduced before fixing. #375 -- DijkstraMap.path_from() returned the path REVERSED, and step_from() inherited the error, returning a cell that is not adjacent to the query position. libtcod builds its list as [pos, ..., root_adjacent] and TCOD_dijkstra_path_walk() pops from the BACK, so the collecting loop produced [root_adjacent, ..., pos]. On an open grid with root (5,5): path_from((9,5)) -> [(6,5),(7,5),(8,5),(9,5)] # marched AWAY from the root step_from((9,5)) -> (6,5) # a three-cell teleport That contradicted path_from's own docstring, AStarPath.origin/.destination, and find_path()'s convention. step_from was the dangerous one: an entity chasing a Dijkstra root would jump next to the root on its first step. The path is now emitted origin->destination, excluding the origin and including the root (found via descentStep, so multi-root lands on the right root), and step_from returns its first element -- provably adjacent. The behavior system was never affected: PathProvider (SEEK/FLEE) uses descentStep, which was already correct. getPathFrom/stepFrom had no internal C++ callers. #376 -- ColorLayer/TileLayer .visible and .z_index setters never called markDirty(), so they did not bump content_generation, which is the key the #351 render early-out uses. Hiding a layer left the rendered image byte-identical (sha256 unchanged) until some unrelated mutation happened to dirty it; re-showing it did not restore it. z_index carried an explicit "TODO: Trigger re-sort in parent grid" and had the same defect. Both setters now invalidate on change. (Only observable after #351 stopped redrawing unconditionally -- the same masking story as the entity set_position bug.) Neither was caught because no test asserted path ORDER (test_astar checks only length and wall-avoidance, both invariant under reversal), and because issue_148_layer_dirty_flags.py -- the test literally named for this defect class -- had rotted and was exiting 0 without running. closes #375 closes #376
This commit is contained in:
parent
bd0b913d7d
commit
48eef0b095
3 changed files with 47 additions and 15 deletions
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue