A new patch for crimson ! AI sucks with transport ! It currently only use transport when no other way to reach the target is available ; with this patch, the AI check if a transport allow to reach the target quicker. The unit stay in the transport as long it give an advantage instead of moving to the target by its own. There is a little level test wich show the problem. -- Sébastien
diff -urNp crimson-0.5.3_orig/src/cf/ai.cpp crimson-0.5.3_patch/src/cf/ai.cpp --- crimson-0.5.3_orig/src/cf/ai.cpp 2007-01-20 11:19:26.000000000 +0100 +++ crimson-0.5.3_patch/src/cf/ai.cpp 2014-04-13 17:27:49.000000000 +0200 @@ -1059,39 +1059,77 @@ bool AI::UnitGoTo( Unit *u, const Point Path p( map ); Point end; - if ( p.Find( u, u->Position(), dest, PATH_BEST, dist ) != -1 ) { - end = FollowPath( u, p ); - Gam->MoveUnit( u, end ); - } else { + const bool sheltered = u->IsSheltered(); + + u->UnsetFlags( U_SHELTERED ); + short distance = p.Find( u, u->Position(), dest, PATH_BEST, dist ); + if (sheltered) u->SetFlags( U_SHELTERED ); + + Transport *t = FindTransport( u, dest, dist, true ); + + if ( distance == -1 ) { // try to find a way using a transporter - short turns; - Transport *t = FindTransport( u, dest, dist, true ); - if ( t ) { - turns = p.Find( u, u->Position(), t->Position() ); - if ( (turns != 1) && (t->UnitCount() == 0) ) { - // get the transport closer first (only if it's empty) - TransPath tp( map, t ); - if ( tp.Find( u, t->Position(), u->Position() ) != -1 ) { - Gam->SelectUnit( t ); - end = FollowPath( t, tp, 1 ); - Gam->MoveUnit( t, end ); - Gam->SelectUnit( u ); - - turns = p.Find( u, u->Position(), end ); - if ( turns != -1 ) { - end = FollowPath( u, p ); - Gam->MoveUnit( u, end ); - } else { - tp.Reverse(); - end = FollowPath( u, tp ); - Gam->MoveUnit( u, end ); - } + if ( !t ) { + return false; + } + short turns = p.Find( u, u->Position(), t->Position() ); + if ( (turns != 1) && (t->UnitCount() == 0) ) { + // get the transport closer first (only if it's empty) + TransPath tp( map, t ); + if ( tp.Find( u, t->Position(), u->Position() ) != -1 ) { + Gam->SelectUnit( t ); + end = FollowPath( t, tp, 1 ); + Gam->MoveUnit( t, end ); + Gam->SelectUnit( u ); + + turns = p.Find( u, u->Position(), end ); + if ( turns != -1 ) { + end = FollowPath( u, p ); + Gam->MoveUnit( u, end ); + } else { + tp.Reverse(); + end = FollowPath( u, tp ); + Gam->MoveUnit( u, end ); } - } else if ( turns >= 0 ) { - end = FollowPath( u, p ); + } + } else if ( turns >= 0 ) { + end = FollowPath( u, p ); + Gam->MoveUnit( u, end ); + } + } else { + // The unit could get this point by is own, but we check if it could be + // better by using a transport + if ( !t || distance <= 2 + || !t->Allow( u )) { + end = FollowPath( u, p ); + Gam->MoveUnit( u, end ); + return true; + } + TransPath tp( map, t ); + Path p2( map ); + short turnsToTarget = tp.Find( t, dest, t->Position() ); + short turnsToTransport = p2.Find( u, u->Position(), t->Position() ); + if ( turnsToTransport != -1 && turnsToTarget != -1 + && turnsToTransport + turnsToTarget < distance) { + Gam->SelectUnit( t ); + end = FollowPath( t, tp, 1 ); + Gam->MoveUnit( t, end ); + Gam->SelectUnit( u ); + + short turns = p2.Find( u, u->Position(), end ); + if ( turns != -1 ) { + end = FollowPath( u, p2 ); + Gam->MoveUnit( u, end ); + } else { + tp.Reverse(); + end = FollowPath( u, tp ); Gam->MoveUnit( u, end ); } - } else rc = false; + } else { + end = FollowPath( u, p ); + Gam->MoveUnit( u, end ); + return true; + } } return rc; }
Attachment:
test_02.lev
Description: Binary data