James, I think I have finally found out why there is such default waiting time problem.
(1) Waiting times are calculated and recorded correctly in the appropriate place
I added some code in hole_ab(), vereinige_waren() and add_ware_to_halt() of haltestelle_t to output relevant data in calculating arrival_time and waiting_time. I sorted and filtered the output and checked for the suspicious cases, but found that they are actually correct.
Even for the cases where waiting time evaluates to zero, they are also correct -- they are just very rare cases where ware_t objects are unloaded/created and loaded in the same step. FYI, around 6.43% of those ~22000 entries generated from hole_ab fall in the range of 0 to 10 (in tenths of min of waiting time), so having waiting time < 10 does not signify any problem.
Since the data are correct, I would suggest removing the "waiting time unknown" message from halt details window to avoid confusion (since it is actually known), and display waiting time in XX.X format instead. As for setting waiting time to 10 when average waiting time is below 10, I would suggest you to try removing this adjustment first and see if you would like to add it back later, after applying the fixes below.
(2) Waiting time lists fail to be re-constructed correctly from save data during game loading
At first I thought that waiting times are not properly calculated and recorded, but as pointed above, this ****umption was wrong.
The problem happens because, halts are reconstructed one by one during game loading. In your code related to saving waiting times, reachable halts are saved as coordinates (koord). When you load a halt koord from the save game (pls see below), you try to look up the halt in the map; if you fail to find a suitable halt at koord, you ****ume that the data is corrupted and discard all waiting time data -- no waiting time list will be constructed for that halt.
for(uint16 k = 0; k < halts_count; k ++)
{
koord halt_position;
halt_position.rdwr(file);
if(halt_position != koord::invalid)
{
halthandle_t current_halt = welt->lookup(halt_position)->get_halt();
if(!current_halt.is_bound())
{
// The halt was not properly saved,
// or was removed at some point.
uint8 waiting_time_count;
file->rdwr_byte(waiting_time_count, "");
for(uint8 j = 0; j < waiting_time_count; j ++)
{
uint16 current_time;
file->rdwr_short(current_time, "");
}
continue;
}
...
However, this creates a problem. ****uming that the map has 3 halts, A, B and C, which are served by a bus line. If A is the first one to be reconstructed from save data, A will not be able to rebuild the waiting time lists for B and C, simply because B and C do not exist on the map yet. After that, when B is reconstructed, it can only rebuild waiting time list for A, but not C, which again does not exist yet. And finally, C can rebuild waiting lists for both A and B upon reconstruction.
(3) base_pathing_counter is properly saved but never loaded from save game
Although waiting times are not loaded for some reachable halts, the lists should nevertheless be rebuilt over time. However, some waiting times are still shown as "unknown" after several months, which is perplexing.
I tried to output some data related to path and connexion staleness checks, and discovered that upon loading a save game, base_pathing_counter (which records the current game month counted from the 1st month at the start of a game) was only 5, while paths_timestamp[c] was 35 (which was correct given the game was tested for ~3 game years). Though seemingly trivial, this problem prevented connexions and paths from being rebuilt for many months (provided that the player didn't change halts or schedules and trigger welt->set_schedule_counter()).
The reason is that, in the following code from haltestelle::get_path_to(),
if(reschedule[category]
|| paths_timestamp[category] < welt->get_base_pathing_counter() - welt->get_einstellungen()->get_max_rerouting_interval_months()
|| welt->get_base_pathing_counter() >= (65535 - welt->get_einstellungen()->get_max_rerouting_interval_months()))
{
// If the paths hashtable is stale, clear it.
// This will mean that all the paths will need to be recalculated.
// Must always recalculate if the schedules change.
paths[category].clear();
search_complete = false;
}
destination_path = paths[category].get(goal);
if(!destination_path.next_transfer.is_bound() && !search_complete)
{
// The pathfinding is incomplete or stale - recalculate
// If the next transfer is not bound even though the search
// is complete, then there is no admissible path to the goal.
calculate_paths(goal, category);
destination_path = paths[category].get(goal);
}
If reschedule[c] is not set, the if condition above will remain false for many months and the stale paths will not be deleted. Even if connexions_timestamp < base_pathing_counter, since old paths are available, calculate_paths() will not be invoked, and connexions are thus not rebuilt, causing the same waiting time to be shown over months.
So what caused this problem? This variable is properly saved to the save game in karte_t::speichern(loadsave_t *file,bool silent). However, I found that this function is not invoked during game loading when I set a breakpoint inside it. Finally, I discovered that there is another function karte_t::laden(loadsave_t *file) which does the loading. Thus, karte_t is different from other cl****es, in that it has separate loading and saving functions, so adding the variable in the saving function alone is not enough -- you have to add counterpart code in the loading function.