It turns out that trying to just give a peep a pathfinding goal and then let them loose doesn't work, because every time they reach a junction, the pathfinder has them walk 'aimlessly' instead of pursuing their target. That's why we were seeing some very large step counts in previous tests - they were (eventually) walking onto the target square, but only after lots of wandering around in circles.
This commit reworks the test data to contain an actual ride for each test scenario, where the peep will path to the tile in front of the ride entrance. A nice side benefit of this is that the ride names must match the test names, so you can now tell from looking at the rides in the test data which one is used for which test instance.
The 'yellow marker' tiles for goal positions are also removed here, as we're deriving goal positions from the ride entrances instead.
To make it a little clearer what the parameter is for, rename FindPath::maxSteps to FindPath::expectedSteps, and extend the comment to describe what happens in negative test scenarios.
There exists a helper function map_get_surface_element_at which already searches a tile's element list for the surface element, so we can just use that.
Introduce some basic scenario-style tests for the pathfinding AI. There
are two tests:
* Test that a peep can get from a given start position to a given end
position, and that it takes them an expected number of ticks to do so.
Also test that they did not walk on any 'forbidden' tiles in the process,
e.g. tiles that are completely the wrong direction from the goal etc.
* Test that a peep can *not* get from a given start position to a given
end position after a given number of ticks.
Each test is parametric, and instantiated for multiple different
start/end positions within the provided test park. If we find a new
situation that needs a test, it should just be a matter of building
that situation in the saved game and then adding a line to the code to
set it up.
Indicating 'forbidden' tiles is done using terrain surface type IDs:
tiles that the pathfinder should never send the peep into should be
painted with the red neon surface type (index 8). This means we have
no way to forbid some path elements on a tile while allowing others,
but we don't need that right now.
Similarly, to help ensure that the test data and code are kept in
sync, the tests also require that peep start tiles are painted with
the green neon surface type (index 11) and that goal tiles are
painted with the yellow neon surface type (index 9).
Previously untitled 'PEEP_ACTION_SPRITE_TYPE7' is actually a single-frame animation for sitting on benches, from looking at the sprite. Makes sense with the way the value is used in the code too.
Use the PEEP_ACTION_SPRITE_TYPE enum for rct_peep::action_sprite_type and ::next_action_sprite_type, as well as other code that deals with action sprite types.
Use the PEEP_ACTION_EVENTS enum for the rct_peep::action field explicitly, so that we get type safety on it from the compiler and debugger. In the process, force PEEP_ACTION_EVENTS to be of size uint8_t, and use named constants for NONE actions instead of magic numbers in a few places.
Explicitly declare the PEEP_STATE enum as being uint8_t width, then use it instead of uint8_t in the rct_peep struct. This has a few benefits:
* It makes it clearer which values we expect to be assigned to that variable. If you hadn't already seen PEEP_STATE existed, it wouldn't be obvious.
* It lets the compiler catch assignment of non-PEEP_STATE values for us
* It lets the debugger show us symbolic constants when looking at a peep, instead of raw values.
The only downside is that we no longer see directly in the rct_peep struct that the field is 1 byte wide, but I think that the benefits outweigh the costs in this case...