Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 16 additions & 30 deletions simconvoi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2666,9 +2666,10 @@ void convoi_t::vorfahren()
}

// is driving direction not change?
ribi_t::ribi neue_richtung_rwr = ribi_t::backward(fahr[0]->calc_direction(route.front(), route.at(min(2, route.get_count() - 1))));
ribi_t::ribi neue_richtung_rwr = ribi_t::backward(front()->calc_direction(route.front(), route.at(min(1, route.get_count() - 1))));

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

route.at(min(2, route.get_count() - 1))min(1, route.get_count() - 1) に変更されました。
Simutransのルーティングにおいて進行方向を確認する際、とくに次のタイルが対角線のステップであったり極端に短い区間である場合、正確な方角を得るために「次の次のタイル (at(2))」を参照する必要があります。これを at(1) に変更すると、カーブやポイントなどで neue_richtung_rwr が誤って計算される可能性があります。
古いコードの min(2, ...) は方向計算のために意図的に2タイル先まで見る設計だったと思われますが、この変更は意図的なものでしょうか?

(Antigravity による自動レビュー)

bool const go_same_direction = (neue_richtung_rwr&alte_richtung)==0;
uint8 const start_step = front()->get_steps();
vehicle_t *last_car=find_most_child_convoi()->back();
uint8 const start_step = last_car->get_steps();
koord3d const start_pos = front()->get_pos();


Expand All @@ -2680,6 +2681,14 @@ void convoi_t::vorfahren()
// add the position which vehicles on to reset the position.
insert_route_convoy_on();

// using last car's steps value? we also can use this value when coupling at this point.
bool using_last_car_steps = go_same_direction;
if( last_car->get_pos()==route.front() ) {
// last car is on the front of the route->we need to check last car's direction
ribi_t::ribi neue_richtung_rwr_back = ribi_t::backward(front()->calc_direction(route.front(), route.at(min(1, route.get_count() - 1))));
using_last_car_steps |= ((neue_richtung_rwr_back&last_car->get_direction())==0);
}

// this is the position for recalculating route when reversing only image direction (not driving direction).
c = self;
while( c.is_bound() ) {
Expand Down Expand Up @@ -2811,6 +2820,10 @@ void convoi_t::vorfahren()
fahr[0]->set_leading(false); // switches off signal checks ...
uint32 dist = VEHICLE_STEPS_PER_CARUNIT*train_length<<YARDS_PER_VEHICLE_STEP_SHIFT;
inspecting = self;
if( using_last_car_steps ) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

新しいコードでは、最初から diststart_step が足され、すべての距離調整が set_leading(false) (シグナルチェック無効)の状態のまま最初の do_drive ループで行われるようになっています。
以前のコードでは、シグナルチェックを無効にして初期配置を行った後、set_leading(true) でシグナルチェックを有効に戻してから、2回目のループで start_step までの微調整を行っていました。
この正確な配置調整時にシグナルチェックが行われなくなったため、自動テスト test_priority_signal_reserve が失敗しています(シグナルの状態評価が誤る、または予約ブロックの確保に失敗するなどの問題が生じています)。初期ステップへの進行時には適切にシグナルチェックが有効になるよう修正をお願いします。

(Antigravity による自動レビュー)

// we know the exact step of back vehicle.
dist += start_step<<YARDS_PER_VEHICLE_STEP_SHIFT;
}
while( inspecting.is_bound() ) {
for(unsigned i=0; i<inspecting->get_vehicle_count(); i++) {
vehicle_t* v = inspecting->get_vehikel(i);
Expand All @@ -2832,34 +2845,7 @@ void convoi_t::vorfahren()
}
inspecting = inspecting->get_coupling_convoi();
}
// if this convoy go to the same direction, we need to advance them to the initial step.
if( go_same_direction ) {
inspecting = self;
// if front vehicle is not on the same position, we need to advance more.
uint16 const current_route_index = front()->get_route_index();
dist = 0;
if( current_route_index<route.get_count()-1 && route.at(current_route_index) == start_pos ) {
// the next tile is the forst pos, advance.
dist += (uint32)(ribi_t::is_bend(front()->get_direction())?start_step+(vehicle_base_t::diagonal_vehicle_steps_per_tile-front()->get_steps()):start_step+(VEHICLE_STEPS_PER_TILE-front()->get_steps()))<<YARDS_PER_VEHICLE_STEP_SHIFT;
} else {
// it already on the first tile, or invalid tile. advance a bit.
dist += (uint32)(start_step>=front()->get_steps()?start_step-front()->get_steps():0)<<YARDS_PER_VEHICLE_STEP_SHIFT;
}
if(dist>0) {
while( inspecting.is_bound() ) {
for(unsigned i=0; i<inspecting->get_vehicle_count(); i++) {
vehicle_t* v = inspecting->get_vehikel(i);

v->get_smoke(false);
uint32 const driven = v->do_drive( dist );
// this gives the length in carunits, 1/CARUNITS_PER_TILE of a full tile => all cars closely coupled!
v->get_smoke(true);
}
inspecting = inspecting->get_coupling_convoi();
}
}
}
else if( !get_coupling_convoi().is_bound() && get_vehicle_count()==1 ) {
if( !go_same_direction && !get_coupling_convoi().is_bound() && get_vehicle_count()==1 ) {
// In case that single car bus or truck is turning around...
if( road_vehicle_t* rv = dynamic_cast<road_vehicle_t*>(self->front()) ) {
rv->set_sideways_image();
Expand Down
Loading