James,
I have reviewed the whole of step_p****giere() when I located and fixed the bugs mentioned in the other thread. However, I have some questions with certain portions of your code.
(1)
if(route_good == good)
{
pax.arrival_time = welt->get_zeit_ms();
// All p****engers will use the quickest route.
start_halt = start_halts[best_start_halt];
pax.set_origin(start_halt);
// Now, decide whether p****engers would prefer to use their private cars,
// even though they can travel by public transport.
uint16 distance = accurate_distance(destinations[current_destination].location, pos);
if(has_private_car)
{
//Weighted random.
uint8 private_car_chance = simrand(100);
if(private_car_chance < 1)
{
// If the chances are zero, skip all the rest of this code. This
// will speed up processing, and enable reversion to older behaviour.
goto public_transport;
}
//Check first that car journey is within time tolerance.
// As the crow flies distance. This is very much an approximation - *but*
// we use the standard speedbonus speed (for 'buses), which are generally
// slower than cars, so, very approximately, it should balance correctly.
// TODO: (Long-term) get the accurate road distance between each town
// and have a speedbonus.tab entry for private cars.
const uint16 car_distance = accurate_distance(k, destinations[current_destination].location);
const sint32 car_speed = welt->get_average_speed(road_wt) > 0 ? welt->get_average_speed(road_wt) : 1;
const uint16 car_minutes = (((float)car_distance / car_speed) * welt->get_einstellungen()->get_journey_time_multiplier() * 60.0F);
May I know why in determining the value of the variable distance, pos (position of the city) instead of k (position of the origin building) is used? If this is just a mistake, then the car_distance variable alone is enough.
Besides, isn't it necessary to scale the distances with distance_per_tile? The same issue happens with finde_p****agier_ziel() when determining distance between 2 towns :
for(uint8 i = 0; i < 32; i ++)
{
zielstadt = welt->get_town_at(random);
distance = accurate_distance(this->get_pos(), zielstadt->get_pos());
if(distance <= max_distance && distance >= min_distance)
{
break;
}
(2)
For this portion of code :
// This is the speed bonus calculation, without reference to price.
const ware_besch_t* p****engers = pax.get_besch();
const uint16 average_speed = (60 * distance) / (best_journey_time * (1.0F - welt->get_einstellungen()->get_journey_time_multiplier()));
const sint32 ref_speed = welt->get_average_speed(road_wt) > 0 ? welt->get_average_speed(road_wt) : 1;
const uint16 speed_bonus_rating = convoi_t::calc_adjusted_speed_bonus(p****engers->get_speed_bonus(), distance, welt);
const sint32 speed_base = (100 * average_speed) / ref_speed - 100;
const float base_bonus = (float)speed_base * ((float)speed_bonus_rating / 100.0F);
//base_bonus should be 1 if the average speed is the same as the bonus speed.
In determining average_speed, may I know why best_journey_time is multiplied by (1 - journey_time_multiplier)? And why is distance multiplied by 60, but not 600 as in add_connexion()? It seems to me that your formulas are often different in different places.
(3)
In the following part of code :
// now try to add them to the target halt
uint32 max_ware = ret_halt->get_capacity(wtyp->get_catg_index());
if(!ret_halt->is_overcrowded(wtyp->get_catg_index()))
{
// prissi: not overcrowded and can recieve => add them
if (found)
{
ware_t return_pax(wtyp, ret_halt);
return_pax.menge = pax_left_to_do;
return_pax.set_zielpos(k);
return_pax.set_ziel(start_halt);
if(ret_halt->find_route(return_pax) != 65535)
{
return_pax.arrival_time = welt->get_zeit_ms();
ret_halt->starte_mit_route(return_pax);
ret_halt->add_pax_happy(pax_left_to_do);
}
else
{
ret_halt->add_pax_no_route(pax_left_to_do);
}
}
else
{
// no route back
if(has_private_car)
{
//Must use private car, since there is no route back.
set_private_car_trip(num_pax, destinations[current_destination].town);
}
else
{
ret_halt->add_pax_no_route(pax_left_to_do);
}
}
}
else
{
// return halt crowded
ret_halt->add_pax_unhappy(pax_left_to_do);
if(has_private_car)
{
//Must use private car, since the halt is crowded.
// However, check first that car journey is within time tolerance.
// As the crow flies distance. This is very much an approximation - *but*
// we use the standard speedbonus speed (for 'buses), which are generally
// slower than cars, so, very approximately, it should balance correctly.
// TODO: (Long-term) get the accurate road distance between each town
// and have a speedbonus.tab entry for private cars.
const uint16 car_distance = accurate_distance(k, destinations[current_destination].location);
const sint32 car_speed = welt->get_average_speed(road_wt) > 0 ? welt->get_average_speed(road_wt) : 1;
const uint16 car_minutes = (((float)car_distance / car_speed) * welt->get_einstellungen()->get_journey_time_multiplier() * 60.0F);
if(car_minutes <= destinations[current_destination].tolerance)
{
set_private_car_trip(num_pax, destinations[0].town);
#ifdef DESTINATION_CITYCARS
//citycars with destination
erzeuge_verkehrsteilnehmer(k, step_count, destinations[0].location);
#endif
}
else
{
if(current_destination == 0)
{
// If p****engers cannot get to their destination by private car because the journey is too long,
// they should have a chance of having alternative destinations. This should be re-set on the *first*
// p**** only.
max_destinations = (welt->get_einstellungen()->get_max_alternative_destinations() < 16 ? welt->get_einstellungen()->get_max_alternative_destinations() : 15) + 1;
}
if(!start_halts.empty())
{
if(current_destination + 1 >= destination_count)
{
// Only record too slow if alternative destinations not canv****ed.
start_halts[best_start_halt]->add_pax_too_slow(pax_left_to_do);
}
}
}
}
There are 2 places which check whether to use private car if available. However, the first one does not check for tolerance level and does not create citycars with destination; while the second one does both. I think this is inconsistent.
Besides, for this specific part of code :
if(current_destination == 0)
{
// If p****engers cannot get to their destination by private car because the journey is too long,
// they should have a chance of having alternative destinations. This should be re-set on the *first*
// p**** only.
max_destinations = (welt->get_einstellungen()->get_max_alternative_destinations() < 16 ? welt->get_einstellungen()->get_max_alternative_destinations() : 15) + 1;
}
if(!start_halts.empty())
{
if(current_destination + 1 >= destination_count)
{
// Only record too slow if alternative destinations not canv****ed.
start_halts[best_start_halt]->add_pax_too_slow(pax_left_to_do);
}
}
This is inside the part of code that deals with return trip when a good route has already been found and the current pax packet has already chosen to take public transport or private car to travel from origin to destination. I don't understand why you should allow an alternative destination again, for this will cause the problem of double counting -- so the same pax packet is to go from origin to 2 different places?
Besides, please don't register a case as "Too Slow" on the ground that private car does not meet tolerance level. Otherwise, the figure will be misleading to players -- they don't know how many of such cases are caused by public transport. If origin halt is overcrowded and private car does not meet tolerance level, please register as unhappy; similarly, if there is no route and private car does not meet tolerance level, please register as no route.
Knightly