From 946290f82374d60570665b5ef25a31f3189238ea Mon Sep 17 00:00:00 2001
From: n0body <>
Date: Thu, 21 Aug 2003 06:12:04 +0000
Subject: [PATCH] Show entire path while pressing shift. Tweak code in
 mouse.c(better when clicking on a moving unit). Adding building methods.
 Other minor tweaks.

---
 doc/ChangeLog.html             |  31 ++--
 src/action/action_attack.cpp   |  18 +-
 src/action/action_board.cpp    |   2 +
 src/action/action_build.cpp    | 154 ++++++++++-------
 src/action/action_follow.cpp   |  33 +++-
 src/action/action_move.cpp     |   3 +-
 src/action/action_resource.cpp |  13 +-
 src/action/action_still.cpp    |  21 +--
 src/action/actions.cpp         |   4 +-
 src/action/command.cpp         |   6 +
 src/include/iolib.h            |   6 +-
 src/include/unit.h             |  24 +--
 src/include/unittype.h         |   3 +
 src/sound/flac.cpp             |   4 +-
 src/ui/mainscr.cpp             |   7 +-
 src/ui/mouse.cpp               | 268 +++++++++++++-----------------
 src/unit/script_unittype.cpp   |   7 +
 src/unit/unit_draw.cpp         | 290 ++++++++++++++-------------------
 src/unit/unit_find.cpp         |   2 +
 src/unit/unittype.cpp          |  14 +-
 20 files changed, 445 insertions(+), 465 deletions(-)

diff --git a/doc/ChangeLog.html b/doc/ChangeLog.html
index 562901de2..3926a2799 100644
--- a/doc/ChangeLog.html
+++ b/doc/ChangeLog.html
@@ -36,16 +36,17 @@
 <li>Future 1.19 Release<p>
     <ul>
     <li>++
-    <li>You can now save in gz format (from Russel Smith and Crestez Leonard).
-    <li>Fixed drawing order for units on the same level (from Russel Smith).
+    <li>Added flags for different building methods (from Crestez Leonard).
+    <li>Pressing shift will now show all waypoints, including building outlines (from Crestez Leonard)
+    <li>You can now save in gz format (from Russell Smith and Crestez Leonard).
+    <li>Fixed drawing order for units on the same level (from Russell Smith).
     <li>Remove *ScreenMapPositon bloat (from Crestez Leonard).
     <li>Fixed MacOS X compilation problems (from Duncan McQueen).
     <li>Fixed middle-mouse scrolling, speed now configurable (from Martin Renold).
-    <li>Removed global unit types for tankers, generalized gold mining (from Crestez Dan Leonard).
-    <li>Removed unit-attack-peon and unit-attack-peasant (from Crestez Dan Leonard).
+    <li>Removed global unit types for tankers, generalized gold mining (from Crestez Leonard).
+    <li>Removed unit-attack-peon and unit-attack-peasant (from Crestez Leonard).
     <li>Fixed minor mac compilation bug (from zratchet).
     <li>Fixed small bugs from NEW_UI (from Martin Renold).
-    <li>A lot of progress in resource configurability (from Crestez Dan Leonard).
     <li>Minimap panel can have its own palette now (from Martin Renold).
     <li>NEW_UI: Dropped of displaying the current unit action with the buttons (from Martin Renold).
     <li>NEW_UI: Dropped Alt-Buttons support (did anybody use this?) (from Martin Renold).
@@ -54,21 +55,21 @@
     <li>Added guile support as an alternative scheme interpretor (Fron Ingo Ruhnke).
     <li>Fixed loading games saved with different resolutions (from Martin Renold).
     <li>Removed spaces from data files (from Martin Renold).
-    <li>Changed the handling of contained units to a circular linked list (from Crestez Dan Leonard).
-    <li>Compacted Unit::Rescued and Unit::Rescued from (from Crestez Dan Leonard).
-    <li>Change Unit::Colors to a pointer(saves memory) (from Crestez Dan Leonard).
+    <li>Changed the handling of contained units to a circular linked list (from Crestez Leonard).
+    <li>Compacted Unit::Rescued and Unit::Rescued from (from Crestez Leonard).
+    <li>Change Unit::Colors to a pointer(saves memory) (from Crestez Leonard).
     <li>Renamed project to Stratagus and fixed most internal references to the Freecraft name (From Ingo Ruhnke).
     </ul>
 <p><li>Freecraft renamed to Stratagus.<p>
     <ul>
-    <li>You can select two units on different land masses and they will both board (from Crestez Dan Leonard).
-    <li>Set Harvest with right-click from a building (from Crestez Dan Leonard).
-    <li>Fixed bug where transporter and unit follow each other (from Crestez Dan Leonard).
-    <li>Transporter will find another place to unload if it didn't unload completely (from Crestez Dan Leonard).
-    <li>Fixed bug #700283: Rescued Units don't retain their color after save/load (from Crestez Dan Leonard).
+    <li>You can select two units on different land masses and they will both board (from Crestez Leonard).
+    <li>Set Harvest with right-click from a building (from Crestez Leonard).
+    <li>Fixed bug where transporter and unit follow each other (from Crestez Leonard).
+    <li>Transporter will find another place to unload if it didn't unload completely (from Crestez Leonard).
+    <li>Fixed bug #700283: Rescued Units don't retain their color after save/load (from Crestez Leonard).
     <li>Fixed bug #743369:'Raise Dead' spell bug (from Russell Smith).
     <li>Fixed bug #747212: segfault on loading (from Russell Smith).
-    <li>Fixed bug where rescued flag wasn't saved (from Crestez Dan Leonard).
+    <li>Fixed bug where rescued flag wasn't saved (from Crestez Leonard).
     <li>Fixed bug #206908: A* bug. (from Russell Smith).
     <li>A* turned on, More realistic pathfinding allowed (from Russell Smith).
     <li>Adjustment of pathfinders to give better performance (from Russell Smith).
@@ -109,7 +110,7 @@
     <ul>
     <li>+++
     <li>Fixed bug #749944: UI clipping problems on right panel (from Jimmy Salmon).
-    <li>Fixed bug where rescued flag wasn't saved (from Crestez Dan Leonard).
+    <li>Fixed bug where rescued flag wasn't saved (from Crestez Leonard).
     <li>Fixed bug #697744: cannot cancel patrol when mixed units selected (from Jimmy Salmon).
     <li>Fixed bug #703143: Can't give orders to units (from Russell Smith).
     <li>Fixed bug #697741: tileset not drawn when loading saved game (from Jimmy Salmon).
diff --git a/src/action/action_attack.cpp b/src/action/action_attack.cpp
index 3b1bb745a..8f4874c99 100644
--- a/src/action/action_attack.cpp
+++ b/src/action/action_attack.cpp
@@ -353,15 +353,17 @@ local void MoveToTarget(Unit* unit)
 	    unit->State=unit->SubAction=0;
 	    // Return to old task?
 	    if( err==PF_UNREACHABLE ) {
-		DebugLevel0Fn("Target not reachable, unit: %d" _C_ UnitNumber(unit));
+		DebugLevel3Fn("Target not reachable, unit: %d" _C_ UnitNumber(unit));
 		if( goal ) {
-		    DebugLevel0(", target %d\n" _C_ UnitNumber(goal));
+		    DebugLevel3(", target %d range %d\n" _C_ UnitNumber(goal) _C_ unit->Orders[0].RangeX);
 		} else {
-		    DebugLevel0(", (%d,%d) Tring with more range...\n" _C_ unit->Orders[0].X _C_ unit->Orders[0].Y);
+		    DebugLevel3(", (%d,%d) Tring with more range...\n" _C_ unit->Orders[0].X _C_ unit->Orders[0].Y);
 		}
 		if( unit->Orders[0].RangeX < TheMap.Width 
 		    || unit->Orders[0].RangeY < TheMap.Height ) {
-		    // Try again with more range
+		    // Try again later and with a bigger range.
+		    // FIXME: does the range ever decrease?
+		    unit->Wait=10;
 		    unit->Orders[0].RangeX++;
 		    unit->Orders[0].RangeY++;
 		    return;
@@ -605,16 +607,16 @@ global void HandleActionAttack(Unit* unit)
 	//
 	//	Move near to the target.
 	//
-	case 4:
-	case 4+WEAK_TARGET:
+	case MOVE_TO_TARGET:
+	case MOVE_TO_TARGET+WEAK_TARGET:
 	    MoveToTarget(unit);
 	    break;
 
 	//
 	//	Attack the target.
 	//
-	case 5:
-	case 5+WEAK_TARGET:
+	case ATTACK_TARGET:
+	case ATTACK_TARGET+WEAK_TARGET:
 	    AttackTarget(unit);
 	    break;
 
diff --git a/src/action/action_board.cpp b/src/action/action_board.cpp
index 195d8553a..35b8faa7d 100644
--- a/src/action/action_board.cpp
+++ b/src/action/action_board.cpp
@@ -66,6 +66,8 @@ local int MoveToTransporter(Unit* unit)
     i=DoActionMove(unit);
     // We have to reset a lot, or else they will circle each other and stuff.
     if (x!=unit->X||y!=unit->Y) {
+	unit->Orders[0].RangeX=1;
+	unit->Orders[0].RangeY=1;
         NewResetPath(unit);
     }
     // New code has this as default.
diff --git a/src/action/action_build.cpp b/src/action/action_build.cpp
index 171b2d31e..4a9864353 100644
--- a/src/action/action_build.cpp
+++ b/src/action/action_build.cpp
@@ -151,9 +151,9 @@ global void HandleActionBuild(Unit* unit)
 	//	Some tries to build the building.
 	//
 	if( unit->SubAction++<10 ) {
-	    //	To keep the load low, retry each 1/4 second.
+	    //	To keep the load low, retry each 10 cycles
 	    // NOTE: we can already inform the AI about this problem?
-	    unit->Wait=CYCLES_PER_SECOND/4+unit->SubAction;
+	    unit->Wait=10;
 	    return;
 	}
 
@@ -256,6 +256,7 @@ global void HandleActionBuild(Unit* unit)
 
     build->Orders[0].Action=UnitActionBuilded;
     build->Data.Builded.Sum=0;  // FIXME: Is it necessary?
+    build->Data.Builded.Cancel=0; // FIXME: Is it necessary?
     build->Data.Builded.Val=stats->HitPoints;
     n=(stats->Costs[TimeCost]*CYCLES_PER_SECOND/6)/(SpeedBuild*5);
     if( n ) {
@@ -266,22 +267,37 @@ global void HandleActionBuild(Unit* unit)
 	DebugCheck( build->Data.Builded.Add!=stats->HitPoints );
     }
     build->Data.Builded.Sub=n;
-    build->Data.Builded.Cancel=0; // FIXME: Is it necessary?
-    build->Data.Builded.Worker=unit;
-    DebugLevel3Fn("Build Sum %d, Add %d, Val %d, Sub %d\n"
-	_C_ build->Data.Builded.Sum _C_ build->Data.Builded.Add
-	_C_ build->Data.Builded.Val _C_ build->Data.Builded.Sub);
     build->Wait=CYCLES_PER_SECOND/6;
     UpdateConstructionFrame(build);
 
-    unit->Value=build->Value;		// worker holding value while building
-
-    RemoveUnit(unit,build);		// automaticly: CheckUnitToBeDrawn(unit)
-    build->CurrentSightRange=0;
-    unit->X=x;
-    unit->Y=y;
-    unit->Orders[0].Action=UnitActionStill;
-    unit->SubAction=0;
+    if (type->BuilderInside) {
+	//  Place the builder inside the building
+    	build->Data.Builded.Worker=unit;
+	RemoveUnit(unit,build);
+	build->CurrentSightRange=0;
+	unit->X=x;
+	unit->Y=y;
+	unit->Orders[0].Action=UnitActionStill;
+	unit->SubAction=0;
+    } else {
+	//  Make the builder repair the newly spawned building.
+	unit->Orders[0].Action=UnitActionRepair;
+	unit->Orders[0].Goal=build;
+	unit->Orders[0].X=unit->Orders[0].Y=-1;
+	unit->Orders[0].RangeX=unit->Orders[0].RangeY=REPAIR_RANGE;
+	//unit->Orders[0].Type=unit->Orders[0].Arg1=NULL;
+	unit->SubAction=0;
+	unit->Wait=1;
+//	unit->Reset=1;
+	RefsDebugCheck( !build->Refs );
+	build->Refs++;
+	UnitMarkSeen(unit);
+	// We need somebody to work on it.
+	build->Data.Builded.Sub=build->Data.Builded.Add=0;
+	build->HP=1;
+    }
+    build->Wait=CYCLES_PER_SECOND/6;
+    UpdateConstructionFrame(build);
     UnitMarkSeen(build);
 }
 
@@ -303,14 +319,13 @@ global void HandleActionBuilded(Unit* unit)
     //
     if( unit->Data.Builded.Cancel ) {
 	// Drop out unit
-	worker=unit->Data.Builded.Worker;
-	worker->Orders[0].Action=UnitActionStill;
-	unit->Data.Builded.Worker=NoUnitP;
-	worker->Reset=worker->Wait=1;
-	worker->SubAction=0;
-
-	unit->Value=worker->Value;	// worker holding value while building
-	DropOutOnSide(worker,LookingW,type->TileWidth,type->TileHeight);
+	if ((worker=unit->Data.Builded.Worker)) {
+	    worker->Orders[0].Action=UnitActionStill;
+	    unit->Data.Builded.Worker=NoUnitP;
+	    worker->Reset=worker->Wait=1;
+	    worker->SubAction=0;
+	    DropOutOnSide(worker,LookingW,type->TileWidth,type->TileHeight);
+	}
 
 	// Player gets back 75% of the original cost for a building.
 	PlayerAddCostsFactor(unit->Player,unit->Stats->Costs,
@@ -320,23 +335,26 @@ global void HandleActionBuilded(Unit* unit)
 	return;
     }
 
-    //
-    //	Fixed point HP calculation
-    //
-    unit->Data.Builded.Val-=unit->Data.Builded.Sub;
-    if( unit->Data.Builded.Val<0 ) {
-	unit->Data.Builded.Val+=unit->Stats->HitPoints;
-	unit->HP++;
-	unit->Data.Builded.Sum++;
-    }
+    if (type->BuilderInside) {
+	//
+	//	Fixed point HP calculation
+	//
+	unit->Data.Builded.Val-=unit->Data.Builded.Sub;
+	if( unit->Data.Builded.Val<0 ) {
+	    unit->Data.Builded.Val+=unit->Stats->HitPoints;
+	    unit->HP++;
+	    unit->Data.Builded.Sum++;
+	}
 
-    n=(unit->Stats->Costs[TimeCost]*CYCLES_PER_SECOND/6)/(SpeedBuild*5);
-    if( unit->Data.Builded.Add!=unit->Stats->HitPoints/(n?n:1) ) {
-	unit->Data.Builded.Add=unit->Stats->HitPoints/(n?n:1);
-    }
+	
+	n=(unit->Stats->Costs[TimeCost]*CYCLES_PER_SECOND/6)/(SpeedBuild*5);
+	if( unit->Data.Builded.Add!=unit->Stats->HitPoints/(n?n:1) ) {
+	    unit->Data.Builded.Add=unit->Stats->HitPoints/(n?n:1);
+	}
 
-    unit->HP+=unit->Data.Builded.Add;
-    unit->Data.Builded.Sum+=unit->Data.Builded.Add;
+	unit->HP+=unit->Data.Builded.Add;
+	unit->Data.Builded.Sum+=unit->Data.Builded.Add;
+    }
 
     //
     //	Check if building ready. Note we can build and repair.
@@ -352,37 +370,49 @@ global void HandleActionBuilded(Unit* unit)
 	unit->Constructed=0;
 	unit->Frame=0;
 	unit->Reset=unit->Wait=1;
-	worker=unit->Data.Builded.Worker;
-	worker->Orders[0].Action=UnitActionStill;
-	worker->SubAction=0;
-	worker->Reset=worker->Wait=1;
-	DropOutOnSide(worker,LookingW,type->TileWidth,type->TileHeight);
-	//
-	//	Whe
-	//
-	if( type->MustBuildOnTop ) {
+
+	if ((worker=unit->Data.Builded.Worker)) {
+	    // Bye bye worker.
+	    if (type->BuilderLost) {
+		// FIXME: enough?
+		LetUnitDie(worker);
+	    // Drop out the worker.
+	    } else {
+		worker->Orders[0].Action=UnitActionStill;
+		worker->SubAction=0;
+		worker->Reset=worker->Wait=1;
+		DropOutOnSide(worker,LookingW,type->TileWidth,type->TileHeight);
+		//
+		//	If we can harvest from the new building, do it.
+		//
+		if (worker->Type->Harvester&&worker->Type->ResourceHarvested==type->GivesResource) {
+		    CommandResource(worker,unit,0);
+		}
+		//
+		//	Building lumber mill, let worker automatic chopping wood.
+		//
+		if( type->CanStore[WoodCost] ) {
+		    CommandHarvest(worker,unit->X+unit->Type->TileWidth/2,
+			    unit->Y+unit->Type->TileHeight/2,0);
+		}
+	    }
+	}
+	
+	if( type->GivesResource ) {
 	    // FIXME: nobody: shouldn't this be already 0?
-	    // It holds the number of units inside a resource.
+	    // FIXME: wierd condition.
+	    // FIXME: It holds the number of units inside a resource.
 	    unit->Data.Resource.Active=0;
 	}
-	//
-	//	If we can harvest from the new building, do it.
-	//
-	if (worker->Type->Harvester&&worker->Type->ResourceHarvested==type->GivesResource) {
-	    CommandResource(worker,unit,0);
-	}
-	//
-	//	Building lumber mill, let worker automatic chopping wood.
-	//
-	if( type->CanStore[WoodCost] ) {
-	    CommandHarvest(worker,unit->X+unit->Type->TileWidth/2,
-		    unit->Y+unit->Type->TileHeight/2,0);
-	}
 
 	NotifyPlayer(unit->Player,NotifyGreen,unit->X,unit->Y,
 	    "New %s done", type->Name);
 	if( unit->Player==ThisPlayer ) {
-	    PlayUnitSound(worker,VoiceWorkCompleted);
+	    if (worker) {
+	    	PlayUnitSound(worker,VoiceWorkCompleted);
+	    } else {
+		PlayUnitSound(unit,VoiceBuilding);
+	    }
 	} else if( unit->Player->Ai ) {
 	    AiWorkComplete(worker,unit);
 	}
diff --git a/src/action/action_follow.cpp b/src/action/action_follow.cpp
index 7f266c217..c24b273f2 100644
--- a/src/action/action_follow.cpp
+++ b/src/action/action_follow.cpp
@@ -61,10 +61,6 @@ global void HandleActionFollow(Unit* unit)
 {
     Unit* goal;
 
-    DebugLevel3Fn("%d: %d %d,%d \n" _C_ UnitNumber(unit) _C_
-	    unit->Orders[0].Goal ? UnitNumber(unit->Orders[0].Goal) : -1 _C_
-	    unit->Orders[0].X _C_ unit->Orders[0].Y);
-
     //
     //	Reached target
     //
@@ -88,11 +84,32 @@ global void HandleActionFollow(Unit* unit)
 	    }
 	    return;
 	}
-	if( goal->X==unit->Orders[0].X && goal->Y==unit->Orders[0].Y ) {
-	    unit->Reset=1;
-	    unit->Wait=10;
+
+	// Two posibilities, both broken. maybe we should change the animation system?
+	// FIXME: Unit doesn't decrease range
+#if 0
+	if( (goal->X==unit->Orders[0].X && goal->Y==unit->Orders[0].Y)||unit->State ) {
+	    UnitShowAnimation(unit,unit->Type->Animations->Still);
+	    //
+	    //	Sea and air units are floating up/down.
+	    //	
+	    if( unit->Type->SeaUnit||unit->Type->AirUnit ) {
+		unit->IY=(MyRand()>>15)&1;
+	    }
 	    return;
 	}
+#else
+	// FIXME:Unit doesn't animate.
+	if( (goal->X==unit->Orders[0].X && goal->Y==unit->Orders[0].Y) ) {
+	    unit->Reset=1;
+	    unit->Wait=10;
+	    if ((unit->Orders[0].RangeX>1)||(unit->Orders[0].RangeY>1)) {
+	        unit->Orders[0].RangeX=unit->Orders[0].RangeY=1;
+		unit->SubAction=0;
+	    }
+	    return;
+	}
+#endif
 	unit->SubAction=0;
     }
 
@@ -189,7 +206,7 @@ global void HandleActionFollow(Unit* unit)
 		}
 		return;
 	    }
-	
+
 	    if( !(goal=unit->Orders[0].Goal) ) {// goal has died
 		unit->Wait=1;
 		unit->SubAction=0;
diff --git a/src/action/action_move.cpp b/src/action/action_move.cpp
index 056baba0d..90fd291ca 100644
--- a/src/action/action_move.cpp
+++ b/src/action/action_move.cpp
@@ -115,6 +115,7 @@ local int ActionMoveGeneric(Unit* unit,const Animation* anim)
 	//
 	//	Transporter (un)docking?
 	//
+	//	FIXME: This is an ugly hack
 	if( unit->Type->Transporter
 		&& ( (WaterOnMap(unit->X,unit->Y)
 		    && CoastOnMap(unit->X+xd,unit->Y+yd))
@@ -282,7 +283,7 @@ global void HandleActionMove(Unit* unit)
 	DebugCheck( unit->State!=0 );
     }
 
-    // FIXME: (mr-russ) Make a reachable goal here with GoalReachable...
+    // FIXME: (mr-russ) Make a reachable goal here with GoalReachable ...
 
     switch( DoActionMove(unit) ) {	// reached end-point?
 	case PF_UNREACHABLE:
diff --git a/src/action/action_resource.cpp b/src/action/action_resource.cpp
index f4a7531dc..18e173e40 100644
--- a/src/action/action_resource.cpp
+++ b/src/action/action_resource.cpp
@@ -10,7 +10,7 @@
 //
 /**@name action_resource.c -	The generic resource action. */
 //
-//	(c) Copyright 2001-2003 by Lutz Sammer
+//	(c) Copyright 2001-2003 by Lutz Sammer and Crestez Leonard
 //
 //      This program is free software; you can redistribute it and/or modify
 //      it under the terms of the GNU General Public License as published by
@@ -136,12 +136,7 @@ local int MoveToResource(Unit* unit)
     //	Activate the resource
     //
     goal->Data.Resource.Active++;
-    DebugLevel3Fn("+%d\n" _C_ goal->Data.Resource.Active);
 
-    if( !goal->Frame ) {		// show resource working
-	goal->Frame=1;
-	CheckUnitToBeDrawn(goal);
-    }
     UnitMarkSeen(goal);
     //
     //	Place unit inside the resource
@@ -191,10 +186,8 @@ local int WaitInResource(Unit* unit)
 	source->Value-=unit->Type->ResourceCapacity;
     }
     
-    if( !--source->Data.Resource.Active ) {
-	source->Frame=0;
-	CheckUnitToBeDrawn(source);
-    }
+    source->Data.Resource.Active--;
+    DebugCheck(source->Data.Resource.Active<0);
     
     UnitMarkSeen(source);
     if( IsOnlySelected(source) ) {
diff --git a/src/action/action_still.cpp b/src/action/action_still.cpp
index f6b8ea233..38a8bfc04 100644
--- a/src/action/action_still.cpp
+++ b/src/action/action_still.cpp
@@ -91,12 +91,12 @@ global void ActionStillGeneric(Unit* unit,int ground)
 	UnitShowAnimation(unit,type->Animations->Still);
 
 	//
-	//	FIXME: this a workaround of a bad code.
+	//	FIXME: this a workaround for some bad code.
 	//		UnitShowAnimation resets frame.
 	//	FIXME: the frames are hardcoded they should be configurable
 	//
 	if( unit->State==1 && type->GivesResource==GoldCost ) {
-	    unit->Frame=!!unit->Data.Resource.Active;
+	    unit->Frame=unit->Data.Resource.Active ? 1 : 0;
 	}
 	if( unit->State==1 && type->GivesResource==OilCost ) {
 	    unit->Frame=unit->Data.Resource.Active ? 2 : 0;
@@ -242,7 +242,7 @@ global void ActionStillGeneric(Unit* unit,int ground)
     }
 
     //
-    //	Land units:	are turning left/right.
+    //	Land units are turning left/right.
     //
     if( type->LandUnit ) {
 	switch( (MyRand()>>8)&0x0FF ) {
@@ -263,19 +263,10 @@ global void ActionStillGeneric(Unit* unit,int ground)
     }
 
     //
-    //	Sea units:	are floating up/down.
-    //
-    if( type->SeaUnit ) {
+    //	Sea and air units are floating up/down.
+    //	
+    if( unit->Type->SeaUnit||unit->Type->AirUnit ) {
 	unit->IY=(MyRand()>>15)&1;
-	return;
-    }
-
-    //
-    //	Air units:	are floating up/down.
-    //
-    if( type->AirUnit ) {
-	unit->IY=(MyRand()>>15)&1;
-	return;
     }
 }
 
diff --git a/src/action/actions.cpp b/src/action/actions.cpp
index 919f9a8f2..bf3ba5c16 100644
--- a/src/action/actions.cpp
+++ b/src/action/actions.cpp
@@ -88,7 +88,7 @@ global int UnitShowAnimation(Unit* unit,const Animation* animation)
 	    _C_ animation[state].Flags _C_ animation[state].Pixel
 	    _C_ animation[state].Frame _C_ animation[state].Sleep);
     DebugLevel3("Heading %d +%d,%d\n" _C_ unit->Direction _C_ unit->IX _C_ unit->IY);
-
+    
     if( unit->Frame<0 ) {
 	unit->Frame+=-animation[state].Frame;
     } else {
@@ -398,7 +398,7 @@ global void UnitActions(void)
 	HandleUnitAction(unit);
 	DebugCheck( *tpos!=unit );	// Removed is evil.
 
-#ifdef DEBUG
+#ifdef DEBUG_wastes_disk_space
 	//
 	//	Dump the unit to find the network unsyncron bug.
 	//
diff --git a/src/action/command.cpp b/src/action/command.cpp
index 3d0d2ab69..c65004eec 100644
--- a/src/action/command.cpp
+++ b/src/action/command.cpp
@@ -678,6 +678,12 @@ global void CommandBuildBuilding(Unit* unit,int x,int y
 	    order->X=x;
 	    order->Y=y;
 	}
+	if(!what->BuilderInside) {
+	    // FIXME: n0body: brain damage. Walk around buggy moving to
+	    // FIXME: the building position.
+	    order->RangeX=what->TileWidth+10;
+	    order->RangeY=what->TileWidth+10;
+	}
 	order->Type=what;
 	order->Arg1=NULL;
     }
diff --git a/src/include/iolib.h b/src/include/iolib.h
index bb58d1a00..8521378f7 100644
--- a/src/include/iolib.h
+++ b/src/include/iolib.h
@@ -67,12 +67,14 @@ typedef struct _filelist_ {
 } FileList;
 
 
-#if !defined(USE_ZLIB) && !defined(USE_BZ2LIB) && !defined(USE_ZZIPLIB)
+#if 0 && !defined(USE_ZLIB) && !defined(USE_BZ2LIB) && !defined(USE_ZZIPLIB)
 
+// FIXME: This is broken, should write a CLopen for plain files
+// FIXME: but we can avoid it anyway.
 // use plain file routines directly
 
 #define CLFile				FILE
-#define CLopen(file)			fopen(file,"rb")
+#define CLopen(file,whatever)		fopen(file,"rwb")
 #define CLread(file,buf,len)		fread(buf,1,len,file)
 #define CLseek(file,offset,whence)	fseek(file,offset,whence)
 #define CLclose(file)			fclose(file)
diff --git a/src/include/unit.h b/src/include/unit.h
index a7667d080..273878459 100644
--- a/src/include/unit.h
+++ b/src/include/unit.h
@@ -716,13 +716,13 @@ extern int ShowAttackRange;		/// Flag: show attack range
 extern int ShowOrders;			/// Flag: show orders of unit on map
 extern unsigned long ShowOrdersCount;	/// Show orders for some time
 extern int HitPointRegeneration;	/// Hit point regeneration for all units
-extern int XpDamage;				/// unit XP adds more damage to attacks
+extern int XpDamage;			/// unit XP adds more damage to attacks
 extern char EnableTrainingQueue;	/// Config: training queues enabled
 extern char EnableBuildingCapture;	/// Config: building capture enabled
 extern char RevealAttacker;		/// Config: reveal attacker enabled
 extern const Viewport* CurrentViewport; /// CurrentViewport
-   /// Draw the selection
-extern void (*DrawSelection)(const Unit*,const UnitType*,int,int);
+extern void DrawUnitSelection(const Unit*);
+extern void (*DrawSelection)(int,int,int,int,int);
 
 //	in selection.c
 extern Unit* Selected[MaxSelectable];	/// currently selected units
@@ -909,23 +909,17 @@ extern void DeadCacheRemove(Unit* unit,Unit** List );
 //	in unit_draw.c
 //--------------------
     /// Draw nothing around unit
-extern void DrawSelectionNone(const Unit* unit,const UnitType* type
-	,int x,int y);
+extern void DrawSelectionNone(int,int,int,int,int);
     /// Draw circle around unit
-extern void DrawSelectionCircle(const Unit* unit,const UnitType* type
-	,int x,int y);
+extern void DrawSelectionCircle(int,int,int,int,int);
     /// Draw circle filled with alpha around unit
-extern void DrawSelectionCircleWithTrans(const Unit* unit,const UnitType* type
-	,int x,int y);
+extern void DrawSelectionCircleWithTrans(int,int,int,int,int);
     /// Draw rectangle around unit
-extern void DrawSelectionRectangle(const Unit* unit,const UnitType* type
-	,int x,int y);
+extern void DrawSelectionRectangle(int,int,int,int,int);
     /// Draw rectangle filled with alpha around unit
-extern void DrawSelectionRectangleWithTrans(const Unit* unit
-	,const UnitType* type,int x,int y);
+extern void DrawSelectionRectangleWithTrans(int,int,int,int,int);
     /// Draw corners around unit
-extern void DrawSelectionCorners(const Unit* unit,const UnitType* type
-	,int x,int y);
+extern void DrawSelectionCorners(int,int,int,int,int);
 
     /// Register CCL decorations features
 extern void DecorationCclRegister(void);
diff --git a/src/include/unittype.h b/src/include/unittype.h
index e82928174..4ae244e6f 100644
--- a/src/include/unittype.h
+++ b/src/include/unittype.h
@@ -583,6 +583,9 @@ struct _unit_type_ {
     unsigned CanCastSpell : 1;		/// Unit is able to use spells.
     unsigned CanAttack : 1;		/// Unit can attack.
     unsigned CanRepair : 1;		/// Unit can repair .
+    unsigned BuilderInside : 1;		/// The builder goes inside during the build.
+    unsigned BuilderLost : 1;		/// The builder is lost after the build.
+    unsigned AutoBuildRate;		/// The rate at which the building builds itself
     unsigned Tower : 1;			/// Unit can attack, but not move.
     unsigned Hero : 1;			/// Is hero only used for triggers .
     unsigned Volatile : 1;		/// Invisiblity/unholy armor kills unit.
diff --git a/src/sound/flac.cpp b/src/sound/flac.cpp
index 63fd4e79f..86b22e44a 100644
--- a/src/sound/flac.cpp
+++ b/src/sound/flac.cpp
@@ -360,7 +360,7 @@ global Sample* LoadFlac(const char* name, int flags)
     FLAC__StreamDecoder* stream;
     FlacData *data;
 
-    if (!(f = CLopen(name))) {
+    if (!(f = CLopen(name,CL_OPEN_READ))) {
 	fprintf(stderr, "Can't open file `%s'\n", name);
 	return NULL;
     }
@@ -374,7 +374,7 @@ global Sample* LoadFlac(const char* name, int flags)
 
     // FIXME: ugly way to seek to start of file
     CLclose(f);
-    if (!(f = CLopen(name))) {
+    if (!(f = CLopen(name,CL_OPEN_READ))) {
 	fprintf(stderr, "Can't open file `%s'\n", name);
 	return NULL;
     }
diff --git a/src/ui/mainscr.cpp b/src/ui/mainscr.cpp
index d36ffeadf..6749c05bb 100644
--- a/src/ui/mainscr.cpp
+++ b/src/ui/mainscr.cpp
@@ -187,11 +187,12 @@ global void DrawUnitInfo(const Unit* unit)
 
     type=unit->Type;
     stats=unit->Stats;
-    IfDebug(
+#ifdef DEBUG
 	if( !type ) {
 	    DebugLevel1Fn(" FIXME: free unit selected\n");
 	    return;
-	} );
+	}
+#endif
 
     //
     //	Draw icon in upper left corner
@@ -293,7 +294,7 @@ global void DrawUnitInfo(const Unit* unit)
 	//	Building under constuction.
 	//
 	if( unit->Orders[0].Action==UnitActionBuilded ) {
-	    if( !OriginalBuilding ) {
+	    if( !OriginalBuilding && unit->Data.Builded.Worker ) {
 		// FIXME: Position must be configured!
 		DrawUnitIcon(unit->Data.Builded.Worker->Player
 			,unit->Data.Builded.Worker->Type->Icon.Icon
diff --git a/src/ui/mouse.cpp b/src/ui/mouse.cpp
index fb4797aa3..e40995fd1 100644
--- a/src/ui/mouse.cpp
+++ b/src/ui/mouse.cpp
@@ -134,8 +134,10 @@ global void DoRightButton(int sx,int sy)
     //	Right mouse with SHIFT appends command to old commands.
     //
     flush=!(KeyModifiers&ModifierShift);
+
+    dest=UnitUnderCursor;
     
-    if( UnitUnderCursor && (dest=TransporterOnMapTile(x,y))) {
+    if( dest && dest->Type->Transporter ) {
         // n0b0dy: So we are clicking on a transporter. We have to:
         // 1) Flush the transporters orders.
         // 2) Tell the transporter to follow the units. We have to queue all
@@ -153,7 +155,7 @@ global void DoRightButton(int sx,int sy)
     acknowledged=0;
     for( i=0; i<NumSelected; ++i ) {
 	unit=Selected[i];
-        // If we are telling units to board a tranasporter,
+        // If we are telling units to board a transporter,
         // don't give the transport extra orders.
         if (unit==desttransporter) {
             continue;
@@ -170,41 +172,34 @@ global void DoRightButton(int sx,int sy)
 	//
 	//	Control + right click on unit is follow anything.
 	//
-	if( KeyModifiers&ModifierControl && UnitUnderCursor ) {
-	    // FIXME: what todo if more than one unit on that tile?
-	    dest=UnitOnMapTile(x,y);
-	    if( dest ) {
-		if( dest!=unit ) {
-		    dest->Blink=4;
-		    SendCommandFollow(unit,dest,flush);
-		    continue;
-		}
-	    }
+	if( KeyModifiers&ModifierControl && dest && dest!=unit) {
+	    dest->Blink=4;
+	    SendCommandFollow(unit,dest,flush);
+	    continue;
 	}
 
 	//
 	//	Enter transporters?
 	//
-	if( UnitUnderCursor && (dest=TransporterOnMapTile(x,y))) {
-	    if( dest->Player==unit->Player
-		    && unit->Type->UnitType==UnitTypeLand ) {
-		dest->Blink=4;
-		DebugLevel0Fn("Board transporter\n");
-		//	Let the transporter move to passenger
-		SendCommandFollow(dest,unit,0);
-		SendCommandBoard(unit,-1,-1,dest,flush);
-		continue;
-	    }
+	if( dest && dest->Type->Transporter &&
+		dest->Player==unit->Player
+		&& unit->Type->UnitType==UnitTypeLand ) {
+	    dest->Blink=4;
+	    DebugLevel0Fn("Board transporter\n");
+	    //  Let the transporter move to the unit. And QUEUE!!!
+	    SendCommandFollow(dest,unit,0);
+	    SendCommandBoard(unit,-1,-1,dest,flush);
+	    continue;
 	}
 
 	//
-	//	Worker of human or orcs
+	//	Handle resource workers.
 	//
 	if( action==MouseActionHarvest ) {
 	    //	Return wood cutter home
 	    if( (type==UnitTypeOrcWorkerWithWood ||
 		    type==UnitTypeHumanWorkerWithWood) &&
-		    (dest=ResourceDepositOnMap(x,y,WoodCost)) &&
+		    dest && dest->Type->CanStore[WoodCost] &&
 		    dest->Player==unit->Player) {
 		DebugLevel3("send to wood deposit.\n");
 		dest->Blink=4;
@@ -218,11 +213,11 @@ global void DoRightButton(int sx,int sy)
 		SendCommandHarvest(unit,x,y,flush);
 		continue;
 	    }
-	    if (unit->Type->Harvester&&UnitUnderCursor) {
+	    if (unit->Type->Harvester && dest) {
 		//  Return a loaded harvester to deposit
-		if( (unit->Value>0) &&
-			(dest=ResourceDepositOnMap(x,y,unit->Type->ResourceHarvested)) &&
-			(dest->Player==unit->Player)) {
+		if( unit->Value>0 &&
+			dest->Type->CanStore[unit->Type->ResourceHarvested] &&
+			dest->Player==unit->Player) {
 		    dest->Blink=4;
 		    DebugLevel3Fn("Return to deposit.\n");
 		    SendCommandReturnGoods(unit,dest,flush);
@@ -230,31 +225,29 @@ global void DoRightButton(int sx,int sy)
 		} 
 		//  Go and harvest
 		if( (unit->Value<unit->Type->ResourceCapacity) &&
-			(dest=ResourceOnMap(x,y,unit->Type->ResourceHarvested)) &&
-			((dest->Player==unit->Player) ||
-			 (dest->Player->Player==PlayerMax-1))) {
+			dest->Type->GivesResource==unit->Type->ResourceHarvested &&
+			(dest->Player==unit->Player ||
+			 dest->Player->Player==PlayerMax-1)) {
 		    dest->Blink=4;
 		    SendCommandResource(unit,dest,flush);
 		    continue;
 		}
 	    }
 	    //  Go and repair
-	    if ( (unit->Type->CanRepair) &&
-		    (UnitUnderCursor) &&
-		    (dest=RepairableOnMapTile(x,y)) &&
-		    ((dest->Player==unit->Player) || (IsAllied(dest->Player,dest)))) {
+	    if ( (unit->Type->CanRepair) && dest &&
+		    (dest->Type->Building || dest->Type->Transporter) &&
+		    dest->HP < dest->Stats->HitPoints  &&
+		    (dest->Player==unit->Player || IsAllied(dest->Player,dest)) ) {
 		dest->Blink=4;
 		SendCommandRepair(unit,x,y,dest,flush);
 		continue;
 	    }
 	    //  Follow another unit
-	    if( UnitUnderCursor && (dest=UnitOnMapTile(x,y)) ) {
-		if( (dest->Player==unit->Player || IsAllied(unit->Player,dest))
-			&& dest!=unit ) {
-		    dest->Blink=4;
-		    SendCommandFollow(unit,dest,flush);
-		    continue;
-		}
+	    if( UnitUnderCursor && dest && dest!=unit &&
+		    (dest->Player==unit->Player || IsAllied(unit->Player,dest)) ) {
+		dest->Blink=4;
+		SendCommandFollow(unit,dest,flush);
+		continue;
 	    }
 	    //  Move 
 	    SendCommandMove(unit,x,y,flush);
@@ -265,19 +258,16 @@ global void DoRightButton(int sx,int sy)
 	//	Fighters
 	//
 	if( action==MouseActionDemolish || action==MouseActionAttack ) {
-	    if( UnitUnderCursor ) {
-		// Picks the enemy with highest priority and can be attacked
-		dest=TargetOnMapTile(unit, x, y);
-		if( dest ) {
-		    if( IsEnemy(unit->Player,dest) ) {
-			dest->Blink=4;
-			if( action==MouseActionDemolish ) {
-			    SendCommandDemolish(unit,x,y,dest,flush);
-			} else {
-			    SendCommandAttack(unit,x,y,dest,flush);
-			}
-			continue;
+	    if( dest ) {
+		if( IsEnemy(unit->Player,dest) ) {
+		    dest->Blink=4;
+		    if( action==MouseActionDemolish ) {
+			// This is for demolition squads and such
+			SendCommandDemolish(unit,x,y,dest,flush);
+		    } else {
+			SendCommandAttack(unit,x,y,dest,flush);
 		    }
+		    continue;
 		}
 
 		if( WallOnMap(x,y) ) {
@@ -296,14 +286,11 @@ global void DoRightButton(int sx,int sy)
 		    }
 		}
 
-		dest=UnitOnMapTile(x,y);
-		if( dest ) {
-		    if( (dest->Player==unit->Player
-			    || IsAllied(unit->Player,dest)) && dest!=unit ) {
-			dest->Blink=4;
-			SendCommandFollow(unit,dest,flush);
-			continue;
-		    }
+		if( (dest->Player==unit->Player||IsAllied(unit->Player,dest))
+			&& dest!=unit ) {
+		    dest->Blink=4;
+		    SendCommandFollow(unit,dest,flush);
+		    continue;
 		}
 
 #ifdef NEW_SHIPS
@@ -334,16 +321,12 @@ global void DoRightButton(int sx,int sy)
 	}
 
 	// FIXME: attack/follow/board ...
-	if( action==MouseActionMove || action==MouseActionSail ) {
-	    if( UnitUnderCursor && (dest=UnitOnMapTile(x,y)) ) {
-		// Follow allied units, but not self.
-		if( (dest->Player==unit->Player
-			|| IsAllied(unit->Player,dest)) && dest!=unit ) {
-		    dest->Blink=4;
-		    SendCommandFollow(unit,dest,flush);
-		    continue;
-		}
-	    }
+	if( (action==MouseActionMove || action==MouseActionSail) &&
+		(dest && dest!=unit) &&
+		(dest->Player==unit->Player|| IsAllied(unit->Player,dest))) {
+	    dest->Blink=4;
+	    SendCommandFollow(unit,dest,flush);
+	    continue;
 	}
 
 	//
@@ -361,13 +344,13 @@ global void DoRightButton(int sx,int sy)
 #endif
 
         if (type->Building) {
-	    if( UnitUnderCursor && (dest=ResourceOnMap(x,y,OilCost)) ) {
+	    if( dest && dest->Type->GivesResource==OilCost ) {
                 dest->Blink=4;
 	        DebugLevel3("RALY POINT TO PLATFORM\n");
                 SendCommandResource(Selected[i],dest,!(KeyModifiers&ModifierShift));
 	        continue;
             }
-            if( UnitUnderCursor && (dest=ResourceOnMap(x,y,GoldCost)) ) {
+	    if( dest && dest->Type->GivesResource==GoldCost ) {
 	        dest->Blink=4;
                 DebugLevel3("RALY POINT TO GOLD-MINE\n");
 	        SendCommandResource(Selected[i],dest,!(KeyModifiers&ModifierShift));
@@ -788,23 +771,17 @@ local void SendRepair(int sx,int sy)
     x=sx/TileSizeX;
     y=sy/TileSizeY;
 
-    if( UnitUnderCursor ) {
-	dest=RepairableOnMapTile(x,y);
-    } else {
-	dest=NoUnitP;
-    }
-    for( i=0; i<NumSelected; ++i ) {
-	unit=Selected[i];
-	if( unit->Type->CanRepair ) {
-	    // FIXME: Should move test in repairable
-	    if( dest && dest->Type && (dest->Player==unit->Player
-		    || IsAllied(unit->Player,dest)) ) {
+    // Check if the dest is repairable!
+    if( (dest=UnitUnderCursor) && (dest->HP<dest->Stats->HitPoints) &&
+	    (dest->Type->Building || dest->Type->Transporter) &&
+	    (dest->Player==ThisPlayer||IsAllied(ThisPlayer,dest))) {
+	for( i=0; i<NumSelected; ++i ) {
+	    unit=Selected[i];
+	    if( unit->Type->CanRepair ) {
 		SendCommandRepair(unit,x,y,dest,!(KeyModifiers&ModifierShift));
 	    } else {
-		SendCommandRepair(unit,x,y,NoUnitP,!(KeyModifiers&ModifierShift));
+		DebugLevel0Fn("Non-worker repairs\n");
 	    }
-	} else {
-	    DebugLevel0Fn("Non-worker repairs\n");
 	}
     }
 }
@@ -812,45 +789,39 @@ local void SendRepair(int sx,int sy)
 /**
 **	Send selected units to point.
 **
-**	@param x	X map tile position.
-**	@param y	Y map tile position.
+**	@param sx	X screen tile position.
+**	@param sy	Y screen tile position.
 **
 **	@todo	To reduce the CPU load for pathfinder, we should check if
 **		the destination is reachable and handle nice group movements.
 */
-local void SendMove(int x,int y)
+local void SendMove(int sx,int sy)
 {
     int i;
     int flush;
     Unit* unit;
     Unit* transporter;
 
-    if( UnitUnderCursor ) {
-	transporter=TransporterOnMapTile(x,y);
+    //  Move to a transporter.
+    if( (transporter=UnitUnderCursor) &&
+	    (transporter->Type->Transporter) &&
+	    (transporter->Player==ThisPlayer)){
+	SendCommandStopUnit(transporter);
     } else {
-	transporter=NoUnitP;
+	transporter=NULL;
     }
+
     flush=!(KeyModifiers&ModifierShift);
 
     for( i=0; i<NumSelected; ++i ) {
 	unit=Selected[i];
-	if( transporter && transporter->Player==unit->Player
-		&& unit->Type->UnitType==UnitTypeLand ) {
+	if( transporter && unit->Type->UnitType==UnitTypeLand ) {
 	    transporter->Blink=4;
 	    DebugLevel3Fn("Board transporter\n");
-	    //	Let the transporter move to passenger
-	    //		It should do nothing and not already on coast.
-	    //		FIXME: perhaps force move if not reachable.
-	    if( transporter->Orders[0].Action==UnitActionStill
-		    && transporter->OrderCount==1
-		    && !CoastOnMap(transporter->X,transporter->Y) ) {
-		SendCommandFollow(transporter,unit,FlushCommands);
-	    }
+	    SendCommandFollow(transporter,unit,0);
 	    SendCommandBoard(unit,-1,-1,transporter,flush);
 	} else {
-//	    if( !unit->Type->Building ) {
-		SendCommandMove(unit,x,y,flush);
-//	    }
+	    SendCommandMove(unit,sx/TileSizeX,sy/TileSizeY,flush);
 	}
     }
 }
@@ -882,8 +853,7 @@ local void SendAttack(int sx,int sy)
     for( i=0; i<NumSelected; i++ ) {
 	unit=Selected[i];
 	if( unit->Type->CanAttack || unit->Type->Building ) {
-	    if( UnitUnderCursor
-		    && (dest=TargetOnMapTile(unit,x,y)) ) {
+	    if( (dest=UnitUnderCursor) && CanTarget(unit->Type,dest->Type)) {
 		DebugLevel3Fn("Attacking %p\n" _C_ dest);
 		dest->Blink=4;
 	    } else {
@@ -901,10 +871,10 @@ local void SendAttack(int sx,int sy)
 /**
 **	Send the current selected group ground attacking.
 **
-**	@param x	X map tile position.
-**	@param y	Y map tile position.
+**	@param sx	X screen map position.
+**	@param sy	Y screen map position.
 */
-local void SendAttackGround(int x,int y)
+local void SendAttackGround(int sx,int sy)
 {
     int i;
     Unit* unit;
@@ -912,25 +882,26 @@ local void SendAttackGround(int x,int y)
     for( i=0; i<NumSelected; ++i ) {
 	unit=Selected[i];
 	if( unit->Type->CanAttack ) {
-	    SendCommandAttackGround(unit,x,y,!(KeyModifiers&ModifierShift));
+	    SendCommandAttackGround(unit,sx/TileSizeX,sy/TileSizeY,!(KeyModifiers&ModifierShift));
 	} else {
-	    SendCommandMove(unit,x,y,!(KeyModifiers&ModifierShift));
+	    SendCommandMove(unit,sx/TileSizeX,sy/TileSizeY,!(KeyModifiers&ModifierShift));
 	}
     }
 }
 
 /**
 **	Let units patrol between current postion and the selected.
+**	@param sx	X screen map position.
+**	@param sy	Y screen map position.
 */
-local void SendPatrol(int x,int y)
+local void SendPatrol(int sx,int sy)
 {
     int i;
     Unit* unit;
 
     for( i=0; i<NumSelected; i++ ) {
 	unit=Selected[i];
-	// FIXME: Can the unit patrol ?
-	SendCommandPatrol(unit,x,y,!(KeyModifiers&ModifierShift));
+	SendCommandPatrol(unit,sx/TileSizeX,sy/TileSizeY,!(KeyModifiers&ModifierShift));
     }
 }
 
@@ -954,15 +925,12 @@ local void SendDemolish(int sx,int sy)
 	unit=Selected[i];
 	if( unit->Type->Volatile ) {
 	    // FIXME: choose correct unit no flying ...
-	    if( UnitUnderCursor ) {
-		dest=TargetOnMapTile(unit,x,y);
-		if( dest==unit ) {	// don't let a unit self destruct
-		    dest=NoUnitP;
-		}
+	    if( (dest=UnitUnderCursor) && CanTarget(unit->Type,dest->Type)) {
+		dest->Blink=4;
 	    } else {
 		dest=NoUnitP;
 	    }
-	    SendCommandDemolish(unit,x,y,dest,!(KeyModifiers&ModifierShift));
+	    SendCommandDemolish(unit,sx/TileSizeX,sy/TileSizeY,dest,!(KeyModifiers&ModifierShift));
 	} else {
 	    DebugLevel0Fn("can't demolish %p\n" _C_ unit);
 	}
@@ -972,46 +940,45 @@ local void SendDemolish(int sx,int sy)
 /**
 **	Let units harvest wood/mine gold/haul oil
 **
-**	@param x	X map coordinate of the destination
-**	@param y	Y map coordinate of the destination
+**	@param sx	X screen map position
+**	@param sy	Y screen map position 
 **
 **	@see Selected
 */
-local void SendHarvest(int x,int y)
+local void SendHarvest(int sx,int sy)
 {
     int i;
     Unit* dest;
 
     for( i=0; i<NumSelected; ++i ) {
-	if( UnitUnderCursor && (dest=ResourceOnMap(x,y,OilCost)) ) {
+	DebugCheck(!Selected[i]->Type->Harvester);
+	if ((dest=UnitUnderCursor) &&
+		(Selected[i]->Type->ResourceHarvested==dest->Type->GivesResource)) {
 	    dest->Blink=4;
-	    DebugLevel3("PLATFORM\n");
+	    DebugLevel3("RESOURCE\n");
 	    SendCommandResource(Selected[i],dest,!(KeyModifiers&ModifierShift));
 	    continue;
 	}
-	if( UnitUnderCursor && (dest=ResourceOnMap(x,y,GoldCost)) ) {
-	    dest->Blink=4;
-	    DebugLevel3("GOLD-MINE\n");
-	    SendCommandResource(Selected[i],dest,!(KeyModifiers&ModifierShift));
-	    continue;
+	if( IsMapFieldExplored(Selected[i]->Player,sx/TileSizeX,sy/TileSizeY) &&
+		ForestOnMap(sx/TileSizeX,sy/TileSizeY) ) {
+	    SendCommandHarvest(Selected[i],sx/TileSizeY,sy/TileSizeY,!(KeyModifiers&ModifierShift));
 	}
-	SendCommandHarvest(Selected[i],x,y,!(KeyModifiers&ModifierShift));
     }
 }
 
 /**
 **	Send selected units to unload passengers.
 **
-**	@param x	X map tile position.
-**	@param y	Y map tile position.
+**	@param sx	X screen map position.
+**	@param sy	Y screen map position.
 */
-local void SendUnload(int x,int y)
+local void SendUnload(int sx,int sy)
 {
     int i;
 
     for( i=0; i<NumSelected; i++ ) {
 	// FIXME: not only transporter selected?
-	SendCommandUnload(Selected[i],x,y,NoUnitP
+	SendCommandUnload(Selected[i],sx/TileSizeX,sy/TileSizeY,NoUnitP
 		,!(KeyModifiers&ModifierShift));
     }
 }
@@ -1038,11 +1005,9 @@ local void SendSpellCast(int sx, int sy)
 
     x=sx/TileSizeX;
     y=sy/TileSizeY;
-    if( UnitUnderCursor ) {
-	dest=UnitOnMapTile(x, y);
-    } else {
-	dest=NoUnitP;
-    }
+    
+    dest=UnitUnderCursor;
+    
     DebugLevel3Fn("SpellCast on: %p (%d,%d)\n" _C_ dest _C_ x _C_ y);
     /*	NOTE: Vladi:
        This is a high-level function, it sends target spot and unit
@@ -1056,6 +1021,7 @@ local void SendSpellCast(int sx, int sy)
 	}
 	if( dest && unit==dest ) {
 	    continue;			// no unit can cast spell on himself
+	    // n0b0dy: why not?
 	}
 #ifndef NEW_UI
 	// CursorValue here holds the spell type id
@@ -1072,10 +1038,8 @@ local void SendSpellCast(int sx, int sy)
 /**
 **	Send a command to selected units.
 **
-**	@param sx	X screen map position in pixels.
-**	@param sy	Y screen map position in pixels.
-**
-**	@todo pure chaos the arguments of the Send... functions are no equal.
+**	@param sx	X screen map position
+**	@param sy	Y screen map position
 */
 local void SendCommand(int sx, int sy)
 {
@@ -1091,7 +1055,7 @@ local void SendCommand(int sx, int sy)
 #endif
     switch( CursorAction ) {
 	case ButtonMove:
-	    SendMove(x,y);
+	    SendMove(sx,sy);
 	    break;
 	case ButtonRepair:
 	    SendRepair(sx,sy);
@@ -1100,16 +1064,16 @@ local void SendCommand(int sx, int sy)
 	    SendAttack(sx,sy);
 	    break;
 	case ButtonAttackGround:
-	    SendAttackGround(x,y);
+	    SendAttackGround(sx,sy);
 	    break;
 	case ButtonPatrol:
-	    SendPatrol(x,y);
+	    SendPatrol(sx,sy);
 	    break;
 	case ButtonHarvest:
-	    SendHarvest(x,y);
+	    SendHarvest(sx,sy);
 	    break;
 	case ButtonUnload:
-	    SendUnload(x,y);
+	    SendUnload(sx,sy);
 	    break;
 	case ButtonDemolish:
 	    SendDemolish(sx,sy);
diff --git a/src/unit/script_unittype.cpp b/src/unit/script_unittype.cpp
index 166c5b12c..025696ac6 100644
--- a/src/unit/script_unittype.cpp
+++ b/src/unit/script_unittype.cpp
@@ -377,6 +377,13 @@ local SCM CclDefineUnitType(SCM list)
 
 	} else if( gh_eq_p(value,gh_symbol2scm("building")) ) {
 	    type->Building=1;
+	} else if( gh_eq_p(value,gh_symbol2scm("builder-inside")) ) {
+	    type->BuilderInside=1;
+	} else if( gh_eq_p(value,gh_symbol2scm("builder-lost")) ) {
+	    type->BuilderLost=1;
+	} else if( gh_eq_p(value,gh_symbol2scm("auto-build-rate")) ) {
+	    type->AutoBuildRate=gh_scm2int(gh_car(list));
+	    list=gh_cdr(list);
 	} else if( gh_eq_p(value,gh_symbol2scm("shore-building")) ) {
 	    type->ShoreBuilding=1;
 	} else if( gh_eq_p(value,gh_symbol2scm("land-unit")) ) {
diff --git a/src/unit/unit_draw.cpp b/src/unit/unit_draw.cpp
index f8f0f1c74..558645db6 100644
--- a/src/unit/unit_draw.cpp
+++ b/src/unit/unit_draw.cpp
@@ -87,13 +87,12 @@ global int ShowManaBackgroundLong;
 /**
 **	Show that units are selected.
 **
-**	@param unit	Pointer to the unit.
-**	@param type	Type of the unit.
-**	@param x	Screen X position of the unit.
-**	@param y	Screen Y position of the unit.
+**	@param color
+**	@param x1,y1	Coordinates of the top left corner. 
+**	@param x2,y2	Coordinates of the bottom right corner. 
 */
-global void (*DrawSelection)(const Unit* unit,const UnitType* type,int x,int y)
-	=DrawSelectionNone;
+global void (*DrawSelection)(int color,int x1,int y1,int x2,int y2)
+    =DrawSelectionNone;
 
 /*----------------------------------------------------------------------------
 --	Functions
@@ -110,11 +109,10 @@ global const Viewport* CurrentViewport;	/// FIXME: quick hack for split screen
 **	Choose color for selection.
 **
 **	@param unit	Pointer to the unit.
-**	@param type	Type of the unit.
 **
 **	@return		Color for selection, or -1 if not selected.
 */
-local int SelectionColor(const Unit* unit,const UnitType* type)
+local int SelectionColor(const Unit* unit)
 {
     if( unit->Selected || (unit->Blink&1) ) {
 	if( unit->Player->Player==PlayerNumNeutral ) {
@@ -131,205 +129,130 @@ local int SelectionColor(const Unit* unit,const UnitType* type)
     }
 
     // If building mark all own buildings
-    if( CursorBuilding && type->Building && unit->Player==ThisPlayer ) {
+    if( CursorBuilding && unit->Type->Building && unit->Player==ThisPlayer ) {
 	return ColorGray;
     }
     return -1;
 }
 
+/**
+**	Show selection marker around an unit.
+**
+**	@param unit	Pointer to unit.
+*/
+global void DrawUnitSelection(const Unit* unit)
+{
+    int color;
+    int x;
+    int y;
+    
+    color=SelectionColor(unit);
+    if (color<0) {
+	return;
+    }
+    x=Map2ViewportX(CurrentViewport,unit->X)+unit->IX
+	+unit->Type->TileWidth*TileSizeX/2-unit->Type->BoxWidth/2;
+    y=Map2ViewportY(CurrentViewport,unit->Y)+unit->IY
+	+unit->Type->TileHeight*TileSizeY/2-unit->Type->BoxHeight/2;
+    DrawSelection(color,x,y,x+unit->Type->BoxWidth,y+unit->Type->BoxHeight);
+}
+
 /**
 **	Don't show selected units.
 **
-**	@param unit	Pointer to the unit.
-**	@param type	Type of the unit.
-**	@param x	Screen X position of the unit.
-**	@param y	Screen Y position of the unit.
+**	@param color
+**	@param x1,y1	Coordinates of the top left corner. 
+**	@param x2,y2	Coordinates of the bottom right corner. 
 */
-global void DrawSelectionNone(const Unit* unit __attribute__((unused)),
-	const UnitType* type __attribute__((unused)),
-	int x __attribute__((unused)),int y __attribute__((unused)))
+global void DrawSelectionNone(int color,int x1,int y1,int x2,int y2)
+/*global void DrawSelectionNone(int color __attribute__((unused)),
+	int x1 __attribute__((unused)),int y1 __attribute__((unused)),
+	int x2 __attribute__((unused)),int y2 __attribute__((unused)))*/
 {
 }
 
 /**
 **	Show selected units with circle.
 **
-**	@param unit	Pointer to the unit.
-**	@param type	Type of the unit.
-**	@param x	Screen X position of the unit.
-**	@param y	Screen Y position of the unit.
+**	@param color
+**	@param x1,y1	Coordinates of the top left corner. 
+**	@param x2,y2	Coordinates of the bottom right corner. 
 */
-global void DrawSelectionCircle(const Unit* unit,const UnitType* type
-	,int x,int y)
+global void DrawSelectionCircle(int color,int x1,int x2,int y1,int y2)
 {
-    int color;
-
-    //
-    //	Select color for the circle.
-    //
-    if( (color=SelectionColor(unit,type))<0 ) {
-	return;
-    }
-    VideoDrawCircleClip(color
-	    ,x+type->TileWidth*TileSizeX/2
-	    ,y+type->TileHeight*TileSizeY/2
-	    ,min(type->BoxWidth,type->BoxHeight)/2);
-
-    VideoDrawCircleClip(color
-	    ,x+type->TileWidth*TileSizeX/2
-	    ,y+type->TileHeight*TileSizeY/2
-	    ,min(type->BoxWidth+2,type->BoxHeight+2)/2);
+    DebugCheck(color<0);
+    VideoDrawCircleClip(color,(x1+x2)/2,(y1+y2)/2,
+	    min((x2-x1)/2,(y2-y1)/2));
+    VideoDrawCircleClip(color,(x1+x2)/2,(y1+y2)/2,
+	    min((x2-x1)/2,(y2-y1)/2)+2);
 }
 
 /**
 **	Show selected units with circle.
 **
-**	@param unit	Pointer to the unit.
-**	@param type	Type of the unit.
-**	@param x	Screen X position of the unit.
-**	@param y	Screen Y position of the unit.
+**	@param color
+**	@param x1,y1	Coordinates of the top left corner. 
+**	@param x2,y2	Coordinates of the bottom right corner. 
 */
-global void DrawSelectionCircleWithTrans(const Unit* unit,const UnitType* type
-	,int x,int y)
-{
-    int color;
-
-    //
-    //	Select color for the circle.
-    //
-    if( (color=SelectionColor(unit,type))<0 ) {
-	return;
-    }
-    VideoDrawCircleClip(color
-	    ,x+type->TileWidth*TileSizeX/2
-	    ,y+type->TileHeight*TileSizeY/2
-	    ,min(type->BoxWidth,type->BoxHeight)/2);
-
-    VideoFill75TransCircleClip(color
-	    ,x+type->TileWidth*TileSizeX/2
-	    ,y+type->TileHeight*TileSizeY/2
-	    ,min(type->BoxWidth-2,type->BoxHeight-2)/2);
+global void DrawSelectionCircleWithTrans(int color,int x1,int y1,int x2,int y2)
+{   
+    DebugCheck(color<0);
+    VideoFill75TransCircleClip(color,(x1+x2)/2,(y1+y2)/2,
+	    min((x2-x1)/2,(y2-y1)/2)-2);
+    VideoDrawCircleClip(color,(x1+x2)/2,(y1+y2)/2,
+	    min((x2-x1)/2,(y2-y1)/2));
 }
 
 /**
 **	Draw selected rectangle around the unit.
 **
-**	@param unit	Pointer to the unit.
-**	@param type	Type of the unit.
-**	@param x	Screen X position of the unit.
-**	@param y	Screen Y position of the unit.
+**	@param color
+**	@param x1,y1	Coordinates of the top left corner. 
+**	@param x2,y2	Coordinates of the bottom right corner. 
 */
-global void DrawSelectionRectangle(const Unit* unit,const UnitType* type
-	,int x,int y)
+global void DrawSelectionRectangle(int color,int x1,int y1,int x2,int y2)
 {
-    int color;
-
-    //
-    //	Select color for the rectangle
-    //
-    if( (color=SelectionColor(unit,type))<0 ) {
-	return;
-    }
-
-    VideoDrawRectangleClip(color
-	    ,x+(type->TileWidth*TileSizeX-type->BoxWidth)/2
-	    ,y+(type->TileHeight*TileSizeY-type->BoxHeight)/2
-	    ,type->BoxWidth
-	    ,type->BoxHeight);
+    DebugCheck(color<0);
+    VideoDrawRectangleClip(color,x1,y1,x2-x1,y2-y1);
 }
 
 /**
 **	Draw selected rectangle around the unit.
 **
-**	@param unit	Pointer to the unit.
-**	@param type	Type of the unit.
-**	@param x	Screen X position of the unit.
-**	@param y	Screen Y position of the unit.
+**	@param color
+**	@param x1,y1	Coordinates of the top left corner. 
+**	@param x2,y2	Coordinates of the bottom right corner. 
 */
-global void DrawSelectionRectangleWithTrans(const Unit* unit
-	,const UnitType* type,int x,int y)
+global void DrawSelectionRectangleWithTrans(int color,int x1,int y1,int x2,int y2)
 {
-    int color;
-
-    //
-    //	Select color for the rectangle
-    //
-    if( (color=SelectionColor(unit,type))<0 ) {
-	return;
-    }
-
-    VideoDrawRectangleClip(color
-	    ,x+(type->TileWidth*TileSizeX-type->BoxWidth)/2
-	    ,y+(type->TileHeight*TileSizeY-type->BoxHeight)/2
-	    ,type->BoxWidth
-	    ,type->BoxHeight);
-    VideoFill75TransRectangleClip(color
-	    ,x+1+(type->TileWidth*TileSizeX-type->BoxWidth)/2
-	    ,y+1+(type->TileHeight*TileSizeY-type->BoxHeight)/2
-	    ,type->BoxWidth-2
-	    ,type->BoxHeight-2);
+    DebugCheck(color<0);
+    VideoDrawRectangleClip(color,x1,y1,x2-x1,y2-y1);
+    VideoFill75TransRectangleClip(color,x1+1,y1+1,x2-x1-2,y2-y1-2);
 }
 
 /**
 **	Draw selected corners around the unit.
 **
-**	@param unit	Pointer to the unit.
-**	@param type	Type of the unit.
-**	@param x	Screen X position of the unit.
-**	@param y	Screen Y position of the unit.
+**	@param color
+**	@param x1,y1	Coordinates of the top left corner. 
+**	@param x2,y2	Coordinates of the bottom right corner. 
 */
-global void DrawSelectionCorners(const Unit* unit,const UnitType* type
-	,int x,int y)
+global void DrawSelectionCorners(int color,int x1,int y1,int x2,int y2)
 {
-    int color;
+    DebugCheck(color<0);
 #define CORNER_PIXELS 6
 
-    //
-    //	Select color for the rectangle
-    //
-    if( (color=SelectionColor(unit,type))<0 ) {
-	return;
-    }
+    VideoDrawVLineClip(color,x1,y1,CORNER_PIXELS);
+    VideoDrawHLineClip(color,x1+1,y1,CORNER_PIXELS-1);
 
-    VideoDrawVLineClip(color
-	    ,x+(type->TileWidth*TileSizeX-type->BoxWidth)/2
-	    ,y+(type->TileHeight*TileSizeY-type->BoxHeight)/2
-	    ,CORNER_PIXELS);
-    VideoDrawHLineClip(color
-	    ,x+(type->TileWidth*TileSizeX-type->BoxWidth)/2+1
-	    ,y+(type->TileHeight*TileSizeY-type->BoxHeight)/2
-	    ,CORNER_PIXELS-1);
+    VideoDrawVLineClip(color,x2,y1,CORNER_PIXELS);
+    VideoDrawHLineClip(color,x2-CORNER_PIXELS+1,y1,CORNER_PIXELS-1);
 
-    VideoDrawVLineClip(color
-	    ,x+(type->TileWidth*TileSizeX-type->BoxWidth)/2+type->BoxWidth
-	    ,y+(type->TileHeight*TileSizeY-type->BoxHeight)/2
-	    ,CORNER_PIXELS);
-    VideoDrawHLineClip(color
-	    ,x+(type->TileWidth*TileSizeX-type->BoxWidth)/2+type->BoxWidth
-		-CORNER_PIXELS+1
-	    ,y+(type->TileHeight*TileSizeY-type->BoxHeight)/2
-	    ,CORNER_PIXELS-1);
+    VideoDrawVLineClip(color,x1,y2-CORNER_PIXELS+1,CORNER_PIXELS);
+    VideoDrawHLineClip(color,x1,y2,CORNER_PIXELS-1);
 
-    VideoDrawVLineClip(color
-	    ,x+(type->TileWidth*TileSizeX-type->BoxWidth)/2
-	    ,y+(type->TileHeight*TileSizeY-type->BoxHeight)/2+type->BoxHeight
-		-CORNER_PIXELS+1
-	    ,CORNER_PIXELS);
-    VideoDrawHLineClip(color
-	    ,x+(type->TileWidth*TileSizeX-type->BoxWidth)/2+1
-	    ,y+(type->TileHeight*TileSizeY-type->BoxHeight)/2+type->BoxHeight
-	    ,CORNER_PIXELS-1);
-
-    VideoDrawVLineClip(color
-	    ,x+(type->TileWidth*TileSizeX-type->BoxWidth)/2+type->BoxWidth
-	    ,y+(type->TileHeight*TileSizeY-type->BoxHeight)/2+type->BoxHeight
-		-CORNER_PIXELS+1
-	    ,CORNER_PIXELS);
-    VideoDrawHLineClip(color
-	    ,x+(type->TileWidth*TileSizeX-type->BoxWidth)/2+type->BoxWidth
-		-CORNER_PIXELS+1
-	    ,y+(type->TileHeight*TileSizeY-type->BoxHeight)/2+type->BoxHeight
-	    ,CORNER_PIXELS-1);
+    VideoDrawVLineClip(color,x2,y2-CORNER_PIXELS+1,CORNER_PIXELS);
+    VideoDrawHLineClip(color,x2-CORNER_PIXELS+1,y2,CORNER_PIXELS-1);
 }
 
 /**
@@ -1406,6 +1329,31 @@ global void DrawPath(const Unit* unit)
     }
 }
 
+/**
+**	Get the location of an order.
+**	
+**	@param order	Pointer to order.
+**	@param x	Resulting screen X cordinate.
+**	@param x	Resulting screen Y cordinate.
+*/
+local void GetOrderPosition(const Order* order,int* x,int* y)
+{
+    Unit* goal;
+    // FIXME: n0body: Check for goal gone?
+    if ((goal=order->Goal)&&(!goal->Removed)) {
+	*x = Map2ViewportX(CurrentViewport,goal->X)+goal->IX+goal->Type->TileWidth*TileSizeX/2;
+	*y = Map2ViewportY(CurrentViewport,goal->Y)+goal->IY+goal->Type->TileHeight*TileSizeY/2;
+    } else {
+	*x = Map2ViewportX(CurrentViewport,order->X)+TileSizeX/2;
+	*y = Map2ViewportY(CurrentViewport,order->Y)+TileSizeY/2;
+	if (order->Action==UnitActionBuild) {
+	    // The -1 is because of what we have above.
+	    *x += (order->Type->TileWidth-1)*TileSizeX/2;
+	    *y += (order->Type->TileHeight-1)*TileSizeY/2;
+	}
+    }
+}
+
 /**
 **	Show the order on map.
 **
@@ -1423,15 +1371,8 @@ local void ShowSingleOrder(const Unit* unit, int x1, int y1, const Order* order)
     int dest;
     const Unit* goal;
 
-    if ((goal = order->Goal) && goal->Type) {
-	x2 = Map2ViewportX(CurrentViewport,
-	    goal->X) + goal->IX + goal->Type->TileWidth * TileSizeX / 2;
-	y2 = Map2ViewportY(CurrentViewport,
-	    goal->Y) + goal->IY + goal->Type->TileHeight * TileSizeY / 2;
-    } else {
-	x2 = Map2ViewportX(CurrentViewport, order->X ) + TileSizeX / 2;
-	y2 = Map2ViewportY(CurrentViewport, order->Y ) + TileSizeY / 2;
-    }
+    GetOrderPosition(order,&x2,&y2);
+    
     dest = 0;
     switch (order->Action) {
 	case UnitActionNone:
@@ -1513,6 +1454,8 @@ local void ShowSingleOrder(const Unit* unit, int x1, int y1, const Order* order)
 	    break;
 
 	case UnitActionBuild:
+	    DrawSelection(ColorGray,x2-order->Type->BoxWidth/2,y2-order->Type->BoxHeight/2,
+		    x2+order->Type->BoxWidth/2,y2+order->Type->BoxHeight/2);
 	    e_color = color = ColorGreen;
 	    dest = 1;
 	    break;
@@ -1563,16 +1506,25 @@ local void ShowOrder(const Unit* unit)
 {
     int x1;
     int y1;
+    int i;
+    Unit *goal;
 
     if (unit->Destroyed) {
 	return;
     }
+    
     x1 = Map2ViewportX(CurrentViewport,
 	unit->X) + unit->IX + unit->Type->TileWidth * TileSizeX / 2;
     y1 = Map2ViewportY(CurrentViewport,
 	unit->Y) + unit->IY + unit->Type->TileHeight * TileSizeY / 2;
 
     ShowSingleOrder(unit, x1, y1, unit->Orders);
+#if 1
+    for (i=1;i<unit->OrderCount;i++) {
+	GetOrderPosition(unit->Orders+i-1,&x1,&y1);
+	ShowSingleOrder(unit,x1,y1,unit->Orders+i);
+    }
+#endif
     if (unit->Type->Building) {
 	ShowSingleOrder(unit, x1, y1, &unit->NewOrder);
     }
@@ -1815,7 +1767,7 @@ global void DrawBuilding(const Unit* unit)
     //
     //	Show that the unit is selected
     //
-    DrawSelection(unit,type,x,y);
+    DrawUnitSelection(unit);
 
     //
     //	Buildings under construction/upgrade/ready.
@@ -1876,7 +1828,7 @@ global void DrawUnit(const Unit* unit)
     //
     //	Show that the unit is selected
     //
-    DrawSelection(unit,type,x,y);
+    DrawUnitSelection(unit);
 
     GraphicUnitPixels(unit,type->Sprite);
     DrawUnitType(type,unit->Frame,x,y);
diff --git a/src/unit/unit_find.cpp b/src/unit/unit_find.cpp
index 1f3561dad..69b9b22b0 100644
--- a/src/unit/unit_find.cpp
+++ b/src/unit/unit_find.cpp
@@ -245,6 +245,8 @@ global Unit* TargetOnMapTile(const Unit* source,int tx,int ty)
 	type=unit->Type;
 	if( tx<unit->X || tx>=unit->X+type->TileWidth
 		|| ty<unit->Y || ty>=unit->Y+type->TileHeight ) {
+	    // When does that happen???
+	    DebugLevel0("This is a wierd world");
 	    continue;
 	}
 	if( !CanTarget(source->Type,unit->Type) ) {
diff --git a/src/unit/unittype.cpp b/src/unit/unittype.cpp
index f8eda76b6..02bd9f0d5 100644
--- a/src/unit/unittype.cpp
+++ b/src/unit/unittype.cpp
@@ -840,7 +840,16 @@ local void SaveUnitType(CLFile* file,const UnitType* type,int all)
     }
 
     if( type->Building ) {
-	CLprintf(file,"  'building\n");
+	CLprintf(file,"  'building");
+    }
+    if( type->BuilderInside ) {
+	CLprintf(file,"  'builder-inside");
+    }
+    if( type->BuilderLost ) {
+	CLprintf(file,"  'builder-lost");
+    }
+    if( type->AutoBuildRate ) {
+	CLprintf(file,"  'auto-build-rate");
     }
     if( type->ShoreBuilding ) {
 	CLprintf(file,"  'shore-building\n");
@@ -870,6 +879,9 @@ local void SaveUnitType(CLFile* file,const UnitType* type,int all)
     if( type->Transporter ) {
 	CLprintf(file,"  'transporter\n");
     }
+    if( type->Transporter ) {
+	CLprintf(file,"  'max-on-board %d\n",type->MaxOnBoard);
+    }
 
     if( type->CowerWorker ) {
 	CLprintf(file,"  'cower-worker\n");