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