diff --git a/doc/scripts/ai.html b/doc/scripts/ai.html
index cc08b2d01..549eebf5c 100644
--- a/doc/scripts/ai.html
+++ b/doc/scripts/ai.html
@@ -54,7 +54,6 @@
 <a href="#define-ai-player">define-ai-player</a>
 <a href="pud.html#define-ai-wc-names">define-ai-wc-names</a>
 <a href="#ai:adhoc-force">ai:adhoc-force</a>
-<a href="#ai:attack-with-force">ai:attack-with-force</a>
 <a href="#ai:check-force">ai:check-force</a>
 <a href="#ai:clear-force">ai:clear-force</a>
 <a href="#ai:compute-gauges">ai:compute-gauges</a>
@@ -113,9 +112,8 @@ There are two kinds of scripts :
 Scripts can arrange and control units using forces : <br>
 A script can ask for some type of unit in a force (using <a href="#ai:force">ai:force</a>), 
 and then wait for them to be ready (using <a href="#ai:wait-force">ai:wait-force</a>).<br>
-Then it can send them to attack ( <a href="#ai:attack-with-force">ai:attack-with-force</a>, 
-<a href="#ai:hotspot-attack-with-force">ai:hotspot-attack-with-force</a> ) or back home 
-( <a href="#ai:force-go-home">ai:force-go-home</a> ).
+Then it can send them to attack ( <a href="#ai:hotspot-attack-with-force">ai:hotspot-attack-with-force</a> ) 
+or back home ( <a href="#ai:force-go-home">ai:force-go-home</a> ).
 <br>
 Each action/reaction script has a specific force which keeps all its units. ( see <a href="#ai:own-force">ai:own-force</a> )<br>
 <br>
@@ -436,45 +434,6 @@ its representation in the resulting force.
       (writes nil "Can't defend with grunts and trolls!"))
 </pre>
 
-<h4>Used</h4>
-
-<a href="../../data/ccl/ai.ccl"> $LIBARYPATH/ccl/ai.ccl </a>
-
-<a name="ai:attack-with-force"></a>
-<h3>(ai:attack-with-force force)</h3>
-
-Attack the opponent with a force. The place is choosen by the AI. If there
-are flyers, ships and land units in the force they could attack different
-goals.
-
-
-<dl>
-<dt>force</dt>
-<dd>Number of the force to which the units should belong. 0 - 9 is currently
-supported.22
-</dd>
-</dl>
-
-<i>The force isn't moved as unit, faster units attacks first, than later the
-slower units will attack.</i>
-
-<h4>Example</h4>
-
-<pre>
-    ;; Force 0 is built with one footman. The script continues processing, if the
-    ;; footman is ready trained. Now attack the opponent with force 0.
-    (ai:force 0 'unit-footman 1)
-    (ai:wait-force 0)
-    (ai:attack-with-force 0)
-</pre>
-
-<h4>See also</h4>
-
-<a href="#ai:hotspot-attack-with-force">ai:hotspot-attack-with-force</a>
-
-<a href="#ai:force-go-home">ai:force-go-home</a>
-
-
 <h4>Used</h4>
 
 <a href="../../data/ccl/ai.ccl"> $LIBARYPATH/ccl/ai.ccl </a>
diff --git a/src/ai/ai_force.cpp b/src/ai/ai_force.cpp
index cb4e02302..5a62c1293 100644
--- a/src/ai/ai_force.cpp
+++ b/src/ai/ai_force.cpp
@@ -838,62 +838,6 @@ global void AiAttackWithForceAt(int force, int x, int y)
     }
 }
 
-/**
-**	Attack opponent with force.
-**
-**	@param force	Force number to attack with.
-*/
-global void AiAttackWithForce(int force)
-{
-    const AiUnit *aiunit;
-    const Unit *enemy;
-    int x;
-    int y;
-
-    AiCleanForce(force);
-
-    AiPlayer->Force[force].Attacking = 0;
-    if ((aiunit = AiPlayer->Force[force].Units)) {
-	AiPlayer->Force[force].Attacking = 1;
-	DebugLevel3Fn("FORCE %d started ( AiAttackWithForce )\n" _C_ force);
-
-	enemy = NoUnitP;
-	while (aiunit && !enemy) {	// Use an unit that can attack
-	    if (aiunit->Unit->Type->CanAttack) {
-		enemy = AttackUnitsInDistance(aiunit->Unit, MaxMapWidth);
-	    }
-	    aiunit = aiunit->Next;
-	}
-
-	if (!enemy) {
-	    DebugLevel0Fn("Need to plan an attack with transporter\n");
-	    if (!AiPlayer->Force[force].State && !AiPlanAttack(&AiPlayer->Force[force])) {
-		DebugLevel0Fn("Can't transport, look for walls\n");
-		if (!AiFindWall(&AiPlayer->Force[force])) {
-		    AiPlayer->Force[force].Attacking = 0;
-		}
-	    }
-	    return;
-	}
-	AiPlayer->Force[force].State = 0;
-	x = enemy->X;
-	y = enemy->Y;
-
-	//
-	//      Send all units in the force to enemy.
-	//
-	aiunit = AiPlayer->Force[force].Units;
-	while (aiunit) {
-	    if (aiunit->Unit->Type->CanAttack) {
-		CommandAttack(aiunit->Unit, x, y, NULL, FlushCommands);
-	    } else {
-		CommandMove(aiunit->Unit, x, y, FlushCommands);
-	    }
-	    aiunit = aiunit->Next;
-	}
-    }
-}
-
 /**
 **	Try to group units in a force. Units are grouped arround the closest units of the hotspot. 
 **
@@ -995,189 +939,6 @@ global void AiSendForceHome(int force)
     }
 }
 
-//----------------------------------------------------------------------------
-//      Handle attack of force with transporter.
-//----------------------------------------------------------------------------
-
-/**
-**	Step 1)
-**	Load force on transporters.
-**
-**	@param force	Force pointer.
-**
-**	@todo	If an unit can't reach the transporter the code hangs.
-**		We must the transporter land on a new position.
-**		Or the board action will be better written.
-*/
-local void AiLoadForce(AiForce * force)
-{
-    AiUnit *aiunit;
-    Unit *table[UnitMax];
-    int n;
-    int i;
-    int o;
-    int f;
-
-    //
-    //  Find all transporters.
-    //
-    n = 0;
-    aiunit = force->Units;
-    while (aiunit) {
-	if (aiunit->Unit->Type->Transporter) {
-	    table[n++] = aiunit->Unit;
-	}
-	aiunit = aiunit->Next;
-    }
-
-    if (!n) {
-	DebugLevel0Fn("No transporter, lost or error in code?\n");
-	force->MustTransport = 0;
-	force->State = 0;
-	return;
-    }
-    //
-    //  Load all on transporter.
-    //
-    f = o = i = 0;
-    aiunit = force->Units;
-    while (aiunit) {
-	Unit *unit;
-
-	unit = aiunit->Unit;
-	if (!unit->Type->Transporter && unit->Type->UnitType == UnitTypeLand) {
-	    if (!unit->Removed) {
-		f = 1;
-		if (unit->Orders[0].Action != UnitActionBoard) {
-		    if (UnitIdle(table[i])) {
-			DebugLevel0Fn("Send transporter %d\n" _C_ i);
-			CommandFollow(table[i], unit, FlushCommands);
-		    }
-		    CommandBoard(unit, table[i], FlushCommands);
-		    ++o;
-		    // FIXME
-		    if (o == table[i]->Type->MaxOnBoard) {
-			DebugLevel0Fn("FIXME: next transporter for AI boarding\n");
-			return;
-		    }
-		}
-	    }
-	}
-	aiunit = aiunit->Next;
-    }
-
-    if (!f) {
-	DebugLevel0Fn("All are loaded\n");
-	++force->State;
-    }
-}
-
-/**
-**	Step 2)
-**	Send force awaay in transporters, to unload at target position.
-**
-**	@param force	Force pointer.
-**
-**	@todo	The transporter should avoid enemy contact and should land
-**		at an unfortified coast. If we send more transporters they
-**		should land on different positions.
-*/
-local void AiSendTransporter(AiForce * force)
-{
-    AiUnit *aiunit;
-
-    //
-    //  Find all transporters.
-    //
-    aiunit = force->Units;
-    while (aiunit) {
-	//      Transporter to unload units
-	if (aiunit->Unit->Type->Transporter) {
-	    CommandUnload(aiunit->Unit, force->GoalX, force->GoalY, NoUnitP,
-		FlushCommands);
-	    //      Ships to defend transporter
-	} else if (aiunit->Unit->Type->UnitType == UnitTypeNaval) {
-	    CommandAttack(aiunit->Unit, force->GoalX, force->GoalY, NoUnitP,
-		FlushCommands);
-	}
-	aiunit = aiunit->Next;
-    }
-    ++force->State;
-}
-
-/**
-**	Step 3)
-**	Wait for transporters landed.
-**
-**	@param force	Force pointer.
-**
-*/
-local void AiWaitLanded(AiForce * force)
-{
-    AiUnit *aiunit;
-    int i;
-
-    DebugLevel0Fn("Waiting\n");
-    //
-    //  Find all transporters.
-    //
-    i = 1;
-    aiunit = force->Units;
-    while (aiunit) {
-	if (aiunit->Unit->Type->Transporter) {
-	    if (UnitIdle(aiunit->Unit)) {
-		DebugLevel0Fn("Unloading\n");
-		// Don't tell empty transporters to unload.
-		if (aiunit->Unit->InsideCount) {
-		    CommandUnload(aiunit->Unit, force->GoalX, force->GoalY,
-			NoUnitP, FlushCommands);
-		    i = 0;
-		}
-	    } else {
-		i = 0;
-	    }
-	}
-	aiunit = aiunit->Next;
-    }
-    if (i) {
-	++force->State;			// all unloaded
-    }
-}
-
-/**
-**	Step 4)
-**	Force on attack ride. We attack until there is no unit or enemy left.
-**
-**	@param force	Force pointer.
-*/
-local void AiForceAttacks(AiForce * force)
-{
-    const AiUnit *aiunit;
-
-    if ((aiunit = force->Units)) {
-	while (aiunit) {
-	    // Still some action
-	    if (!UnitIdle(aiunit->Unit)) {
-		break;
-	    }
-	    aiunit = aiunit->Next;
-	}
-	// Must mark the attack as terminated 
-	if (!aiunit) {
-	    DebugLevel3Fn("FORCE stopped ( AiForceAttacks, unitactionstill )\n");
-	    DebugLevel3Fn("force target was %d %d\n" _C_ force->GoalX _C_ force->GoalY);
-	    DebugLevel3Fn("unit pos was %d %d\n" _C_ force->Units->Unit->X _C_ force->
-		Units->Unit->Y);
-
-	    force->Attacking = 0;
-	    // AiAttackWithForce(force-AiPlayer->Force);
-	}
-    } else {
-	DebugLevel3Fn("FORCE stopped ( AiAttackWithForce, no unit )\n");
-	force->Attacking = 0;
-    }
-}
-
 global void AiForceHelpMe(int force, const Unit * attacker, Unit * defender)
 {
     AiForce *aiForce;
@@ -1223,58 +984,12 @@ global void AiForceHelpMe(int force, const Unit * attacker, Unit * defender)
     }
 }
 
-/**
-**	Handle an attack force.
-**
-**	@param force	Force pointer.
-*/
-local void AiGuideAttackForce(AiForce * force)
-{
-    enum { StartState = 1, TransporterLoaded, WaitLanded, AttackNow };
-
-    switch (force->State) {
-	    //
-	    //  Load units on transporters.
-	    //
-	case StartState:
-	    AiLoadForce(force);
-	    break;
-	case TransporterLoaded:
-	    AiSendTransporter(force);
-	    break;
-	case WaitLanded:
-	    AiWaitLanded(force);
-	    break;
-	case AttackNow:
-	    force->State = 0;
-	    AiAttackWithForce(force - AiPlayer->Force);
-	    break;
-
-	    //
-	    //  Attacking!
-	    //
-	case 0:
-	    AiForceAttacks(force);
-	    break;
-    }
-}
-
 /**
 **	Entry point of force manager, perodic called.
 */
 global void AiForceManager(void)
 {
-    int force;
-
-    //
-    //  Look if our defenders still have enemies in range.
-    //
-    for (force = 0; force < AI_MAX_FORCES; ++force) {
-	if (AiPlayer->Force[force].Attacking) {
-	    AiCleanForce(force);
-	    AiGuideAttackForce(&AiPlayer->Force[force]);
-	}
-    }
+    // FIXME : is this really needed anymore
     AiAssignFreeUnitsToForce();
 }
 
diff --git a/src/ai/ai_plan.cpp b/src/ai/ai_plan.cpp
index a7bfa3e49..ed38b7bcb 100644
--- a/src/ai/ai_plan.cpp
+++ b/src/ai/ai_plan.cpp
@@ -50,552 +50,6 @@
 --	Variables
 ----------------------------------------------------------------------------*/
 
-/*----------------------------------------------------------------------------
---	Functions
-----------------------------------------------------------------------------*/
-
-/**
-**	Choose enemy on map tile.
-**
-**	@param source	Unit which want to attack.
-**	@param tx	X position on map, tile-based.
-**	@param ty	Y position on map, tile-based.
-**
-**	@return		Returns ideal target on map tile.
-*/
-local Unit *EnemyOnMapTile(const Unit * source, int tx, int ty)
-{
-    Unit *table[UnitMax];
-    Unit *unit;
-    Unit *best;
-    const UnitType *type;
-    int n;
-    int i;
-
-    n = SelectUnitsOnTile(tx, ty, table);
-    best = NoUnitP;
-    for (i = 0; i < n; ++i) {
-	unit = table[i];
-	// unusable unit ?
-	// if( UnitUnusable(unit) ) can't attack constructions
-	// FIXME: did SelectUnitsOnTile already filter this?
-	// Invisible and not Visible
-	if (unit->Removed || unit->Invisible || !unit->HP
-	    || !(unit->Visible & (1 << source->Player->Player))
-	    || unit->Orders[0].Action == UnitActionDie) {
-	    continue;
-	}
-	type = unit->Type;
-	if (tx < unit->X || tx >= unit->X + type->TileWidth
-	    || ty < unit->Y || ty >= unit->Y + type->TileHeight) {
-	    continue;
-	}
-	if (!CanTarget(source->Type, unit->Type)) {
-	    continue;
-	}
-	if (!IsEnemy(source->Player, unit)) {	// a friend or neutral
-	    continue;
-	}
-	//
-	//      Choose the best target.
-	//
-	if (!best || best->Type->Priority < unit->Type->Priority) {
-	    best = unit;
-	}
-    }
-    return best;
-}
-
-/**
-**	Mark all by transporter reachable water tiles.
-**
-**	@param unit	Transporter
-**	@param matrix	Water matrix.
-**
-**	@note only works for water transporters!
-*/
-local void AiMarkWaterTransporter(const Unit * unit, unsigned char *matrix)
-{
-    static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 };
-    static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 };
-    struct {
-	unsigned short X;
-	unsigned short Y;
-    }     *points;
-    int size;
-    int x;
-    int y;
-    int rx;
-    int ry;
-    int mask;
-    int wp;
-    int rp;
-    int ep;
-    int i;
-    int w;
-    unsigned char *m;
-
-    x = unit->X;
-    y = unit->Y;
-    w = TheMap.Width + 2;
-    matrix += w + w + 2;
-    if (matrix[x + y * w]) {		// already marked
-	DebugLevel0("Done\n");
-	return;
-    }
-
-    points = malloc(TheMap.Width * TheMap.Height);
-    size = TheMap.Width * TheMap.Height / sizeof (*points);
-
-    //
-    //  Make movement matrix.
-    //
-    mask = UnitMovementMask(unit);
-    // Ignore all possible mobile units.
-    mask &= ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit);
-
-    points[0].X = x;
-    points[0].Y = y;
-    rp = 0;
-    matrix[x + y * w] = 66;		// mark start point
-    ep = wp = 1;			// start with one point
-
-    //
-    //  Pop a point from stack, push all neightbors which could be entered.
-    //
-    for (;;) {
-	while (rp != ep) {
-	    rx = points[rp].X;
-	    ry = points[rp].Y;
-	    for (i = 0; i < 8; ++i) {	// mark all neighbors
-		x = rx + xoffset[i];
-		y = ry + yoffset[i];
-		m = matrix + x + y * w;
-		if (*m) {		// already checked
-		    continue;
-		}
-
-		if (CanMoveToMask(x, y, mask)) {	// reachable
-
-		    *m = 66;
-		    points[wp].X = x;	// push the point
-		    points[wp].Y = y;
-		    if (++wp >= size) {	// round about
-			wp = 0;
-		    }
-		    /*      Must be checked multiple
-		       } else {                     // unreachable
-		       *m=99;
-		     */
-		}
-	    }
-
-	    if (++rp >= size) {		// round about
-		rp = 0;
-	    }
-	}
-
-	//
-	//      Continue with next frame.
-	//
-	if (rp == wp) {			// unreachable, no more points available
-	    break;
-	}
-	ep = wp;
-    }
-
-    free(points);
-}
-
-/**
-**	Find possible targets.
-**
-**	@param unit	Attack.
-**	@param matrix	Water matrix.
-**	@param dx	Attack point X.
-**	@param dy	Attack point Y.
-**	@param ds	Attack state.
-**
-**	@return 	True if target found.
-*/
-local int AiFindTarget(const Unit * unit, unsigned char *matrix, int *dx, int *dy,
-    int *ds)
-{
-    static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 };
-    static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 };
-    struct {
-	unsigned short X;
-	unsigned short Y;
-	unsigned char State;
-    }     *points;
-    int size;
-    int x;
-    int y;
-    int rx;
-    int ry;
-    int mask;
-    int wp;
-    int rp;
-    int ep;
-    int i;
-    int w;
-    enum { OnWater, OnLand, OnIsle } state;
-    unsigned char *m;
-
-    size = TheMap.Width * TheMap.Height / 2;
-    points = malloc(size * sizeof (*points));
-
-    x = unit->X;
-    y = unit->Y;
-
-    w = TheMap.Width + 2;
-    mask = UnitMovementMask(unit);
-    // Ignore all possible mobile units.
-    mask &= ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit);
-
-    points[0].X = x;
-    points[0].Y = y;
-    points[0].State = OnLand;
-    matrix += w + w + 2;
-    rp = 0;
-    matrix[x + y * w] = 1;		// mark start point
-    ep = wp = 1;			// start with one point
-
-    //
-    //  Pop a point from stack, push all neightbors which could be entered.
-    //
-    for (;;) {
-	while (rp != ep) {
-	    rx = points[rp].X;
-	    ry = points[rp].Y;
-	    state = points[rp].State;
-	    for (i = 0; i < 8; ++i) {	// mark all neighbors
-		x = rx + xoffset[i];
-		y = ry + yoffset[i];
-		m = matrix + x + y * w;
-
-		if (state != OnWater) {
-		    if (*m) {		// already checked
-			if (state == OnLand && *m == 66) {	// tansporter?
-			    DebugLevel0Fn("->Water\n");
-			    *m = 6;
-			    points[wp].X = x;	// push the point
-			    points[wp].Y = y;
-			    points[wp].State = OnWater;
-			    if (++wp >= size) {	// round about
-				wp = 0;
-			    }
-			}
-			continue;
-		    }
-		    // Check targets on tile?
-		    // FIXME: the move code didn't likes a shore building as
-		    //          target
-		    if (EnemyOnMapTile(unit, x, y)) {
-			DebugLevel0Fn("Target found %d,%d-%d\n" _C_ x _C_ y _C_ state);
-			*dx = x;
-			*dy = y;
-			*ds = state;
-			free(points);
-			return 1;
-		    }
-
-		    if (CanMoveToMask(x, y, mask)) {	// reachable
-
-			*m = 1;
-			points[wp].X = x;	// push the point
-			points[wp].Y = y;
-			points[wp].State = state;
-			if (++wp >= size) {	// round about
-			    wp = 0;
-			}
-		    } else {		// unreachable
-			*m = 99;
-		    }
-		} else {		// On water
-		    if (*m) {		// already checked 
-			if (*m == 66) {	// tansporter?
-			    *m = 6;
-			    points[wp].X = x;	// push the point
-			    points[wp].Y = y;
-			    points[wp].State = OnWater;
-			    if (++wp >= size) {	// round about
-				wp = 0;
-			    }
-			}
-			continue;
-		    }
-		    if (CanMoveToMask(x, y, mask)) {	// reachable
-			DebugLevel0Fn("->Land\n");
-			*m = 1;
-			points[wp].X = x;	// push the point
-			points[wp].Y = y;
-			points[wp].State = OnIsle;
-			if (++wp >= size) {	// round about
-			    wp = 0;
-			}
-		    } else {		// unreachable
-			*m = 99;
-		    }
-		}
-	    }
-
-	    if (++rp >= size) {		// round about
-		rp = 0;
-	    }
-	}
-
-	//
-	//      Continue with next frame.
-	//
-	if (rp == wp) {			// unreachable, no more points available
-	    break;
-	}
-	ep = wp;
-    }
-    free(points);
-    return 0;
-}
-
-/**
-**	Find possible walls to target.
-**
-**	@param force	Attack force.
-**
-**	@return 	True if wall found.
-*/
-global int AiFindWall(AiForce * force)
-{
-    static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 };
-    static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 };
-    struct {
-	unsigned short X;
-	unsigned short Y;
-    }     *points;
-    int size;
-    int x;
-    int y;
-    int rx;
-    int ry;
-    int mask;
-    int wp;
-    int rp;
-    int ep;
-    int i;
-    int w;
-    unsigned char *m;
-    unsigned char *matrix;
-    int destx;
-    int desty;
-    AiUnit *aiunit;
-    Unit *unit;
-
-    // Find a unit to use.  Best choice is a land unit with range 1.
-    // Next best choice is any land unit.  Otherwise just use the first.
-    aiunit = force->Units;
-    unit = aiunit->Unit;
-    while (aiunit) {
-	if (aiunit->Unit->Type->UnitType == UnitTypeLand) {
-	    unit = aiunit->Unit;
-	    if (aiunit->Unit->Type->Missile.Missile->Range == 1) {
-		break;
-	    }
-	}
-	aiunit = aiunit->Next;
-    }
-
-    x = unit->X;
-    y = unit->Y;
-    size = TheMap.Width * TheMap.Height / 4;
-    points = malloc(size * sizeof (*points));
-
-    destx = -1;
-    desty = -1;
-
-    matrix = CreateMatrix();
-    w = TheMap.Width + 2;
-    matrix += w + w + 2;
-
-    points[0].X = x;
-    points[0].Y = y;
-    rp = 0;
-    matrix[x + y * w] = 1;		// mark start point
-    ep = wp = 1;			// start with one point
-
-    mask = UnitMovementMask(unit);
-
-    //
-    //  Pop a point from stack, push all neighbors which could be entered.
-    //
-    for (; destx == -1;) {
-	while (rp != ep && destx == -1) {
-	    rx = points[rp].X;
-	    ry = points[rp].Y;
-	    for (i = 0; i < 8; ++i) {	// mark all neighbors
-		x = rx + xoffset[i];
-		y = ry + yoffset[i];
-		m = matrix + x + y * w;
-		if (*m) {
-		    continue;
-		}
-		// 
-		//      Check for a wall
-		//
-		if (WallOnMap(x, y)) {
-		    DebugLevel0Fn("Wall found %d,%d\n" _C_ x _C_ y);
-		    destx = x;
-		    desty = y;
-		    break;
-		}
-
-		if (CanMoveToMask(x, y, mask)) {	// reachable
-		    *m = 1;
-		    points[wp].X = x;	// push the point
-		    points[wp].Y = y;
-		    if (++wp >= size) {	// round about
-			wp = 0;
-		    }
-		} else {		// unreachable
-		    *m = 99;
-		}
-	    }
-	    if (++rp >= size) {		// round about
-		rp = 0;
-	    }
-	}
-
-	//
-	//      Continue with next frame.
-	//
-	if (rp == wp) {			// unreachable, no more points available
-	    break;
-	}
-	ep = wp;
-    }
-    free(points);
-
-    if (destx != -1) {
-	force->State = 0;
-	aiunit = force->Units;
-	while (aiunit) {
-	    if (aiunit->Unit->Type->CanAttack) {
-		CommandAttack(aiunit->Unit, destx, desty, NULL, FlushCommands);
-	    } else {
-		CommandMove(aiunit->Unit, destx, desty, FlushCommands);
-	    }
-	    aiunit = aiunit->Next;
-	}
-	return 1;
-    }
-
-    return 0;
-}
-
-/**
-**	Plan an attack with a force.
-**	We know, that we must use a transporter.
-**
-**	@param force	Pointer on the force.
-**
-**	@return		True if target found, false otherwise.
-**
-**	@todo	Perfect planning.
-**		Only works for water transporter!
-*/
-global int AiPlanAttack(AiForce * force)
-{
-    char *watermatrix;
-    const AiUnit *aiunit;
-    int x;
-    int y;
-    int i;
-    int state;
-    Unit *transporter;
-
-    DebugLevel0Fn("Planning for force #%d of player #%d\n"
-	_C_ force - AiPlayer->Force _C_ AiPlayer->Player->Player);
-
-    watermatrix = CreateMatrix();
-
-    //
-    //  Transporter must be already assigned to the force.
-    //  NOTE: finding free transportes was too much work for me.
-    //
-    aiunit = force->Units;
-    state = 1;
-    while (aiunit) {
-	if (aiunit->Unit->Type->Transporter) {
-	    DebugLevel0Fn("Transporter #%d\n" _C_ UnitNumber(aiunit->Unit));
-	    AiMarkWaterTransporter(aiunit->Unit, watermatrix);
-	    state = 0;
-	}
-	aiunit = aiunit->Next;
-    }
-
-    //
-    //  No transport that belongs to the force.
-    //
-    transporter = NULL;
-    if (state) {
-	for (i = 0; i < AiPlayer->Player->TotalNumUnits; ++i) {
-	    Unit *unit;
-
-	    unit = AiPlayer->Player->Units[i];
-	    if (unit->Type->Transporter && UnitIdle(unit)) {
-		DebugLevel0Fn("Assign any transporter\n");
-		AiMarkWaterTransporter(unit, watermatrix);
-		// FIXME: can be the wrong transporter.
-		transporter = unit;
-		state = 0;
-	    }
-	}
-    }
-
-    if (state) {			// Absolute no transporter
-	DebugLevel0Fn("No transporter available\n");
-	// FIXME: should tell the resource manager we need a transporter!
-	return 0;
-    }
-    //
-    //  Find a land unit of the force.
-    //          FIXME: if force is split over different places -> broken
-    //
-    aiunit = force->Units;
-    while (aiunit) {
-	if (aiunit->Unit->Type->UnitType == UnitTypeLand) {
-	    DebugLevel0Fn("Landunit %d\n" _C_ UnitNumber(aiunit->Unit));
-	    break;
-	}
-	aiunit = aiunit->Next;
-    }
-
-    if (!aiunit) {
-	DebugLevel0Fn("No land unit in force\n");
-	return 0;
-    }
-
-    if (AiFindTarget(aiunit->Unit, watermatrix, &x, &y, &state)) {
-	AiUnit *aiunit;
-
-	if (transporter) {
-	    aiunit = malloc(sizeof (*aiunit));
-	    aiunit->Next = force->Units;
-	    force->Units = aiunit;
-	    aiunit->Unit = transporter;
-	    RefsIncrease(transporter);
-	}
-
-	DebugLevel0Fn("Can attack\n");
-	force->GoalX = x;
-	force->GoalY = y;
-	force->MustTransport = state == 2;
-
-	force->State = 1;
-	return 1;
-    }
-    return 0;
-}
-
 /**
 **	Respond to ExplorationRequests
 */
diff --git a/src/ai/script_ai.cpp b/src/ai/script_ai.cpp
index 26c186038..8f2fe0df0 100644
--- a/src/ai/script_ai.cpp
+++ b/src/ai/script_ai.cpp
@@ -1528,25 +1528,6 @@ local SCM CclAiWaitForce(SCM value)
     return SCM_BOOL_T;
 }
 
-/**
-**	Attack with force.
-**
-**	@param value	Force number.
-*/
-local SCM CclAiAttackWithForce(SCM value)
-{
-    int force;
-
-    force = gh_scm2int(value);
-    if (force < 0 || force >= AI_MAX_FORCES) {
-	errl("Force out of range", value);
-    }
-
-    AiAttackWithForce(force);
-
-    return SCM_BOOL_F;
-}
-
 /**
 **	Attack with force, on the current script hotspot.
 **
@@ -2110,7 +2091,6 @@ global void AiCclRegister(void)
 
     gh_new_procedure0_0("ai:idle", CclAiIdle);
     gh_new_procedure2_0("ai:timed-wait-force", CclAiTimedWaitForce);
-    gh_new_procedure1_0("ai:attack-with-force", CclAiAttackWithForce);
     gh_new_procedure1_0("ai:hotspot-attack-with-force", CclAiHotSpotAttackWithForce);
     gh_new_procedure1_0("ai:force-go-home", CclAiForceHome);
     gh_new_procedure1_0("ai:sleep", CclAiSleep);