From c8d9a9f20c993f5ad1b1d14710b16f517ad9a376 Mon Sep 17 00:00:00 2001
From: joris <joris.dauphin@gmail.com>
Date: Fri, 24 Feb 2012 09:42:36 +0100
Subject: [PATCH] Move CUnit::OrderFlush into COrder::Finished some clean up

---
 src/action/action_board.cpp     | 60 ++++++++++++------------
 src/action/action_build.cpp     | 70 +++++++++-------------------
 src/action/action_die.cpp       | 28 ++++-------
 src/action/action_follow.cpp    | 67 +++++++++++++++------------
 src/action/action_move.cpp      | 24 +++++-----
 src/action/action_patrol.cpp    | 30 +++---------
 src/action/action_repair.cpp    | 24 +++++-----
 src/action/action_research.cpp  | 28 ++++-------
 src/action/action_spellcast.cpp | 41 ++++++-----------
 src/action/action_stand.cpp     | 15 ------
 src/action/action_still.cpp     | 46 +++++-------------
 src/action/action_train.cpp     | 28 +++++------
 src/action/action_unload.cpp    | 36 ++++++---------
 src/action/action_upgradeto.cpp | 43 ++++++-----------
 src/action/actions.cpp          | 75 +++++++++++++++---------------
 src/action/command.cpp          |  2 +-
 src/include/actions.h           | 82 ++++++++++-----------------------
 src/include/unit.h              |  8 +---
 src/unit/script_unit.cpp        |  6 ++-
 src/unit/unit.cpp               | 12 ++---
 src/unit/unit_draw.cpp          |  5 +-
 src/unit/unit_save.cpp          |  6 ++-
 22 files changed, 278 insertions(+), 458 deletions(-)

diff --git a/src/action/action_board.cpp b/src/action/action_board.cpp
index 0b9120e2a..4983fbe0a 100644
--- a/src/action/action_board.cpp
+++ b/src/action/action_board.cpp
@@ -47,6 +47,15 @@
 #include "iolib.h"
 #include "script.h"
 
+
+
+enum {
+	State_Init = 0,
+	State_MoveToTransporterMax = 200, // Range from previous
+	State_WaitForTransporter = 201,
+	State_EnterTransporter = 202
+};
+
 /*----------------------------------------------------------------------------
 --  Functions
 ----------------------------------------------------------------------------*/
@@ -55,6 +64,9 @@
 {
 	file.printf("{\"action-board\",");
 
+	if (this->Finished) {
+		file.printf(" \"finished\", ");
+	}
 	file.printf(" \"range\", %d,", this->Range);
 	if (this->HasGoal()) {
 		CUnit &goal = *this->GetGoal();
@@ -152,7 +164,7 @@ bool COrder_Board::WaitForTransporter(CUnit &unit)
 	// is not there. The unit searches with a big range, so it thinks
 	// it's there. This is why we reset the search. The transporter
 	// should be a lot closer now, so it's not as bad as it seems.
-	this->State = 0;
+	this->State = State_Init;
 	this->Range = 1;
 	// Uhh wait a bit.
 	unit.Wait = 10;
@@ -194,39 +206,40 @@ static void EnterTransporter(CUnit &unit, COrder_Board &order)
 	DebugPrint("No free slot in transporter\n");
 }
 
-/* virtual */ bool COrder_Board::Execute(CUnit &unit)
+/* virtual */ void COrder_Board::Execute(CUnit &unit)
 {
 	switch (this->State) {
 		// Wait for transporter
-		case 201:
+		case State_WaitForTransporter:
 			if (this->WaitForTransporter(unit)) {
-				this->State = 202;
+				this->State = State_EnterTransporter;
 			} else {
 				UnitShowAnimation(unit, unit.Type->Animations->Still);
 			}
 			break;
-		// Enter transporter
-		case 202:
+
+		case State_EnterTransporter: {
 			EnterTransporter(unit, *this);
-			return true;
-			break;
-		// Move to transporter
-		case 0:
+			this->Finished = true;
+			return ;
+		}
+		case State_Init:
 			if (unit.Wait) {
 				unit.Wait--;
-				return false;
+				return;
 			}
 			this->NewResetPath();
 			this->State = 1;
 			// FALL THROUGH
-		default:
-			if (this->State <= 200) {
+		default: { // Move to transporter
+			if (this->State <= State_MoveToTransporterMax) {
 				const int pathRet = MoveToTransporter(unit);
 				// FIXME: if near transporter wait for enter
 				if (pathRet) {
 					if (pathRet == PF_UNREACHABLE) {
-						if (++this->State == 200) {
-							return true;
+						if (++this->State == State_MoveToTransporterMax) {
+							this->Finished = true;
+							return;
 						} else {
 							// Try with a bigger range.
 							if (this->CheckRange()) {
@@ -235,27 +248,14 @@ static void EnterTransporter(CUnit &unit, COrder_Board &order)
 							}
 						}
 					} else if (pathRet == PF_REACHED) {
-						this->State = 201;
+						this->State = State_WaitForTransporter;
 					}
 				}
 			}
 			break;
+		}
 	}
-	return false;
 }
 
-/**
-**  The unit boards a transporter.
-**
-**  @todo FIXME: While waiting for the transporter the units must defend themselves.
-**
-**  @param unit  Pointer to unit.
-*/
-void HandleActionBoard(COrder& order, CUnit &unit)
-{
-	if (order.Execute(unit)) {
-		unit.ClearAction();
-	}
-}
 
 //@}
diff --git a/src/action/action_build.cpp b/src/action/action_build.cpp
index 084afe6b1..dc6152d71 100644
--- a/src/action/action_build.cpp
+++ b/src/action/action_build.cpp
@@ -74,6 +74,10 @@ enum
 /* virtual */ void COrder_Build::Save(CFile &file, const CUnit &unit) const
 {
 	file.printf("{\"action-build\",");
+
+	if (this->Finished) {
+		file.printf(" \"finished\", ");
+	}
 	file.printf(" \"range\", %d,", this->Range);
 #if 1 // Fixed with Type
 	file.printf(" \"width\", %d,", this->Width);
@@ -371,22 +375,24 @@ bool COrder_Build::BuildFromOutside(CUnit &unit) const
 }
 
 
-/* virtual */ bool COrder_Build::Execute(CUnit &unit)
+/* virtual */ void COrder_Build::Execute(CUnit &unit)
 {
 	if (unit.Wait) {
 		unit.Wait--;
-		return false;
+		return ;
 	}
 	if (this->State <= State_MoveToLocationMax) {
 		if (this->MoveToLocation(unit)) {
-			return true;
+			this->Finished = true;
+			return ;
 		}
 	}
 	const CUnitType &type = this->GetUnitType();
 
 	if (State_NearOfLocation <= this->State && this->State < State_StartBuilding_Failed) {
 		if (CheckLimit(unit, type) == false) {
-			return true;
+			this->Finished = true;
+			return ;
 		}
 		CUnit *ontop = this->CheckCanBuild(unit);
 
@@ -400,31 +406,14 @@ bool COrder_Build::BuildFromOutside(CUnit &unit) const
 		if (unit.Player->AiEnabled) {
 			AiCanNotBuild(unit, type);
 		}
-		return true;
+		this->Finished = true;
+		return ;
 	}
 	if (this->State == State_BuildFromOutside) {
 		this->BuildFromOutside(unit);
 	}
-
-	return false;
 }
 
-/**
-**  Unit builds a building.
-**
-**  @param unit  Unit that builds a building
-*/
-void HandleActionBuild(COrder& order, CUnit &unit)
-{
-	Assert(order.Action == UnitActionBuild);
-
-	if (order.Execute(unit)) {
-		unit.ClearAction();
-	}
-}
-
-
-
 
 ///////////////////////////
 // Action_built
@@ -433,7 +422,9 @@ void HandleActionBuild(COrder& order, CUnit &unit)
 /* virtual */ void COrder_Built::Save(CFile &file, const CUnit &unit) const
 {
 	file.printf("{\"action-built\", ");
-
+	if (this->Finished) {
+		file.printf(" \"finished\", ");
+	}
 	CConstructionFrame *cframe = unit.Type->Construction->Frames;
 	int frame = 0;
 	while (cframe != this->Frame) {
@@ -501,7 +492,7 @@ static void CancelBuilt(COrder_Built &order, CUnit &unit)
 	LetUnitDie(unit);
 }
 
-static bool Finish(COrder_Built &order, CUnit& unit)
+static void Finish(COrder_Built &order, CUnit& unit)
 {
 	const CUnitType &type = *unit.Type;
 	CPlayer &player = *unit.Player;
@@ -565,7 +556,7 @@ static bool Finish(COrder_Built &order, CUnit& unit)
 		UnitLost(unit);
 		UnitClearOrders(unit);
 		unit.Release();
-		return false;
+		return ;
 	}
 
 	UpdateForNewUnit(unit, 0);
@@ -587,11 +578,11 @@ static bool Finish(COrder_Built &order, CUnit& unit)
 	MapUnmarkUnitSight(unit);
 	unit.CurrentSightRange = unit.Stats->Variables[SIGHTRANGE_INDEX].Max;
 	MapMarkUnitSight(unit);
-	return true;
+	order.Finished = true;
 }
 
 
-/* virtual */ bool COrder_Built::Execute(CUnit &unit)
+/* virtual */ void COrder_Built::Execute(CUnit &unit)
 {
 	const CUnitType &type = *unit.Type;
 
@@ -610,16 +601,16 @@ static bool Finish(COrder_Built &order, CUnit& unit)
 		DebugPrint("%d: %s canceled.\n" _C_ unit.Player->Index _C_ unit.Type->Name.c_str());
 
 		CancelBuilt(*this, unit);
-		return false;
+		this->Finished = true;
+		return ;
 	}
 
 	const int maxProgress = type.Stats[unit.Player->Index].Costs[TimeCost] * 600;
 
 	// Check if building ready. Note we can both build and repair.
 	if (!unit.Anim.Unbreakable && this->ProgressCounter >= maxProgress) {
-		return Finish(*this, unit);
+		Finish(*this, unit);
 	}
-	return false;
 }
 
 /* virtual */ void COrder_Built::Cancel(CUnit &unit)
@@ -734,21 +725,4 @@ void COrder_Built::Boost(CUnit &building, int amount, int varIndex) const
 	currentValue = std::min(currentValue, maxValue);
 }
 
-
-
-/**
-**  Unit under Construction
-**
-**  @param unit  Unit that is being built
-*/
-void HandleActionBuilt(COrder& order, CUnit &unit)
-{
-	Assert(order.Action == UnitActionBuilt);
-
-	if (order.Execute(unit)) {
-		order.ClearGoal();
-		unit.ClearAction();
-	}
-}
-
 //@}
diff --git a/src/action/action_die.cpp b/src/action/action_die.cpp
index 389fc9a73..3375acdcd 100644
--- a/src/action/action_die.cpp
+++ b/src/action/action_die.cpp
@@ -49,7 +49,11 @@
 
 /* virtual */ void COrder_Die::Save(CFile &file, const CUnit &unit) const
 {
-	file.printf("{\"action-die\"}");
+	file.printf("{\"action-die\"");
+	if (this->Finished) {
+		file.printf(", \"finished\"");
+	}
+	file.printf("}");
 }
 
 /* virtual */ bool COrder_Die::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit)
@@ -75,7 +79,7 @@ static bool AnimateActionDie(CUnit &unit)
 }
 
 
-/* virtual */ bool COrder_Die::Execute(CUnit &unit)
+/* virtual */ void COrder_Die::Execute(CUnit &unit)
 {
 	// Show death animation
 	if (AnimateActionDie(unit) == false) {
@@ -83,7 +87,7 @@ static bool AnimateActionDie(CUnit &unit)
 		unit.Anim.Unbreakable = 0;
 	}
 	if (unit.Anim.Unbreakable) {
-		return false;
+		return ;
 	}
 	CUnitType &type = *unit.Type;
 
@@ -91,7 +95,7 @@ static bool AnimateActionDie(CUnit &unit)
 	if (type.CorpseType == NULL) {
 		unit.Remove(NULL);
 		unit.Release();
-		return false;
+		return ;
 	}
 
 	CUnitType &corpseType = *type.CorpseType;
@@ -109,22 +113,6 @@ static bool AnimateActionDie(CUnit &unit)
 	unit.Frame = 0;
 	UnitUpdateHeading(unit);
 	AnimateActionDie(unit); // with new corpse.
-	return false;
-}
-
-
-/**
-**  Unit dies!
-**
-**  @param unit  The unit which dies.
-*/
-void HandleActionDie(COrder& order, CUnit &unit)
-{
-	Assert(order.Action == UnitActionDie);
-
-	if (order.Execute(unit)) {
-		unit.ClearAction();
-	}
 }
 
 //@}
diff --git a/src/action/action_follow.cpp b/src/action/action_follow.cpp
index 629499b9a..1d43cf8ea 100644
--- a/src/action/action_follow.cpp
+++ b/src/action/action_follow.cpp
@@ -45,6 +45,15 @@
 #include "iolib.h"
 #include "script.h"
 
+enum {
+	State_Init = 0,
+	State_Initialized = 1,
+
+	State_TargetReached = 128,
+};
+
+
+
 /*----------------------------------------------------------------------------
 --  Functions
 ----------------------------------------------------------------------------*/
@@ -54,6 +63,9 @@
 {
 	file.printf("{\"action-follow\",");
 
+	if (this->Finished) {
+		file.printf(" \"finished\", ");
+	}
 	file.printf(" \"range\", %d,", this->Range);
 	if (this->HasGoal()) {
 		CUnit &goal = *this->GetGoal();
@@ -87,26 +99,28 @@
 	return true;
 }
 
-/* virtual */ bool COrder_Follow::Execute(CUnit &unit)
+/* virtual */ void COrder_Follow::Execute(CUnit &unit)
 {
 	if (unit.Wait) {
 		unit.Wait--;
-		return false;
+		return ;
 	}
 	CUnit *goal = this->GetGoal();
 
 	// Reached target
-	if (this->State == 128) {
+	if (this->State == State_TargetReached) {
 
 		if (!goal || !goal->IsVisibleAsGoal(*unit.Player)) {
 			DebugPrint("Goal gone\n");
-			return true;
+			this->Finished = true;
+			return ;
 		}
 
 		if (goal->tilePos == this->goalPos) {
 			// Move to the next order
 			if (unit.Orders.size() > 1) {
-				return true;
+				this->Finished = true;
+				return ;
 			}
 
 			// Reset frame to still frame while we wait
@@ -116,14 +130,14 @@
 			unit.Wait = 10;
 			if (this->Range > 1) {
 				this->Range = 1;
-				this->State = 0;
+				this->State = State_Init;
 			}
-			return false;
+			return ;
 		}
-		this->State = 0;
+		this->State = State_Init;
 	}
-	if (!this->State) { // first entry
-		this->State = 1;
+	if (this->State == State_Init) { // first entry
+		this->State = State_Initialized;
 		this->NewResetPath();
 	}
 	switch (DoActionMove(unit)) { // reached end-point?
@@ -137,7 +151,8 @@
 		case PF_REACHED:
 		{
 			if (!goal) { // goal has died
-				return true;
+				this->Finished = true;
+				return ;
 			}
 			// Handle Teleporter Units
 			// FIXME: BAD HACK
@@ -163,24 +178,24 @@
 					|| (dest.NewOrder->Action == UnitActionResource && !unit.Type->Harvester)
 					|| (dest.NewOrder->Action == UnitActionAttack && !unit.Type->CanAttack)
 					|| (dest.NewOrder->Action == UnitActionBoard && unit.Type->UnitType != UnitTypeLand)) {
-					return true;
+					this->Finished = true;
+					return ;
 				} else {
 					if (dest.NewOrder->HasGoal()) {
 						if (dest.NewOrder->GetGoal()->Destroyed) {
 							delete dest.NewOrder;
 							dest.NewOrder = NULL;
-							return true;
+							this->Finished = true;
+							return ;
 						}
 					}
-
-					delete unit.CurrentOrder();
-					unit.Orders[0] = dest.NewOrder->Clone();
-					unit.CurrentResource = dest.CurrentResource;
-					return false;
+					unit.Orders.insert(unit.Orders.begin() + 1, dest.NewOrder->Clone());
+					this->Finished = true;
+					return ;
 				}
 			}
 			this->goalPos = goal->tilePos;
-			this->State = 128;
+			this->State = State_TargetReached;
 		}
 			// FALL THROUGH
 		default:
@@ -197,7 +212,7 @@
 	}
 
 	if (unit.Anim.Unbreakable) {
-		return false;
+		return ;
 	}
 	// If our leader is dead or stops or attacks:
 	// Attack any enemy in reaction range.
@@ -210,23 +225,15 @@
 			// Save current command to come back.
 			COrder *savedOrder = this->Clone();
 
-			CommandAttack(unit, target->tilePos, NULL, FlushCommands);
+			this->Finished = true;
+			unit.Orders.insert(unit.Orders.begin() + 1, COrder::NewActionAttack(unit, target->tilePos));
 
 			if (unit.StoreOrder(savedOrder) == false) {
 				delete savedOrder;
 				savedOrder = NULL;
 			}
-			return true;
 		}
 	}
-	return false;
-}
-
-void HandleActionFollow(COrder& order, CUnit &unit)
-{
-	if (order.Execute(unit)) {
-		unit.ClearAction();
-	}
 }
 
 //@}
diff --git a/src/action/action_move.cpp b/src/action/action_move.cpp
index 9c78f2f1e..5070ba12d 100644
--- a/src/action/action_move.cpp
+++ b/src/action/action_move.cpp
@@ -59,6 +59,9 @@
 {
 	file.printf("{\"action-move\",");
 
+	if (this->Finished) {
+		file.printf(" \"finished\", ");
+	}
 	file.printf(" \"range\", %d,", this->Range);
 	file.printf(" \"tile\", {%d, %d},", this->goalPos.x, this->goalPos.y);
 
@@ -178,13 +181,13 @@ int DoActionMove(CUnit &unit)
 }
 
 
-/* virtual */ bool COrder_Move::Execute(CUnit &unit)
+/* virtual */ void COrder_Move::Execute(CUnit &unit)
 {
 	Assert(unit.CanMove());
 
 	if (unit.Wait) {
 		unit.Wait--;
-		return false;
+		return ;
 	}
 	// FIXME: (mr-russ) Make a reachable goal here with GoalReachable ...
 
@@ -193,22 +196,17 @@ int DoActionMove(CUnit &unit)
 			// Some tries to reach the goal
 			if (this->CheckRange()) {
 				this->Range++;
-				break;
+			} else {
+				this->Finished = true;
 			}
-			// FALL THROUGH
+			break;
+
 		case PF_REACHED:
-			return true;
+			this->Finished = true;
+			break;
 		default:
 			break;
 	}
-	return false;
-}
-
-void HandleActionMove(COrder& order, CUnit &unit)
-{
-	if (order.Execute(unit)) {
-		unit.ClearAction();
-	}
 }
 
 //@}
diff --git a/src/action/action_patrol.cpp b/src/action/action_patrol.cpp
index 43ea097cc..a215132dd 100644
--- a/src/action/action_patrol.cpp
+++ b/src/action/action_patrol.cpp
@@ -54,6 +54,9 @@
 {
 	file.printf("{\"action-patrol\",");
 
+	if (this->Finished) {
+		file.printf(" \"finished\", ");
+	}
 	file.printf(" \"tile\", {%d, %d},", this->goalPos.x, this->goalPos.y);
 	file.printf(" \"range\", %d,", this->Range);
 
@@ -85,11 +88,11 @@
 	return true;
 }
 
-/* virtual */ bool COrder_Patrol::Execute(CUnit &unit)
+/* virtual */ void COrder_Patrol::Execute(CUnit &unit)
 {
 	if (unit.Wait) {
 		unit.Wait--;
-		return false;
+		return ;
 	}
 
 	switch (DoActionMove(unit)) {
@@ -130,30 +133,9 @@
 
 	if (!unit.Anim.Unbreakable) {
 		if (AutoAttack(unit) || AutoRepair(unit) || AutoCast(unit)) {
-			return true;
+			this->Finished = true;
 		}
 	}
-	return false;
-}
-
-/**
-**  Unit Patrol:
-**    The unit patrols between two points.
-**    Any enemy unit in reaction range is attacked.
-**  @todo FIXME:
-**    Should do some tries to reach the end-points.
-**    Should support patrol between more points!
-**    Patrol between units.
-**
-**  @param unit  Patroling unit pointer.
-*/
-void HandleActionPatrol(COrder& order, CUnit &unit)
-{
-	Assert(order.Action == UnitActionPatrol);
-
-	if (order.Execute(unit)) {
-		unit.ClearAction();
-	}
 }
 
 //@}
diff --git a/src/action/action_repair.cpp b/src/action/action_repair.cpp
index 170581031..9ba17ed78 100644
--- a/src/action/action_repair.cpp
+++ b/src/action/action_repair.cpp
@@ -59,6 +59,9 @@
 {
 	file.printf("{\"action-repair\",");
 
+	if (this->Finished) {
+		file.printf(" \"finished\", ");
+	}
 	file.printf(" \"range\", %d,", this->Range);
 	if (this->HasGoal()) {
 		CUnit &goal = *this->GetGoal();
@@ -157,7 +160,7 @@ static void AnimateActionRepair(CUnit &unit)
 	UnitShowAnimation(unit, unit.Type->Animations->Repair);
 }
 
-/* virtual */ bool COrder_Repair::Execute(CUnit &unit)
+/* virtual */ void COrder_Repair::Execute(CUnit &unit)
 {
 	switch (this->State) {
 		case 0:
@@ -194,7 +197,8 @@ static void AnimateActionRepair(CUnit &unit)
 					const Vec2i dir = goal->tilePos + goal->Type->GetHalfTileSize() - unit.tilePos;
 					UnitHeadingFromDeltaXY(unit, dir);
 				} else if (err < 0) {
-					return true;
+					this->Finished = true;
+					return ;
 				}
 			}
 			break;
@@ -203,7 +207,7 @@ static void AnimateActionRepair(CUnit &unit)
 			AnimateActionRepair(unit);
 			this->RepairCycle++;
 			if (unit.Anim.Unbreakable) {
-				return false;
+				return ;
 			}
 			CUnit *goal = this->GetGoal();
 
@@ -220,7 +224,8 @@ static void AnimateActionRepair(CUnit &unit)
 
 					if (dist <= unit.Type->RepairRange) {
 						if (RepairUnit(unit, *goal)) {
-							return true;
+							this->Finished = true;
+							return ;
 						}
 					} else if (dist > unit.Type->RepairRange) {
 						// If goal has move, chase after it
@@ -231,21 +236,14 @@ static void AnimateActionRepair(CUnit &unit)
 			}
 			// Target is fine, choose new one.
 			if (!goal || goal->Variable[HP_INDEX].Value >= goal->Variable[HP_INDEX].Max) {
-				return true;
+				this->Finished = true;
+				return ;
 			}
 			// FIXME: automatic repair
 		}
 		break;
 	}
-	return false;
 }
 
 
-void HandleActionRepair(COrder& order, CUnit &unit)
-{
-	if (order.Execute(unit)) {
-		unit.ClearAction();
-	}
-}
-
 //@}
diff --git a/src/action/action_research.cpp b/src/action/action_research.cpp
index 4fa71899b..e0fa66e6e 100644
--- a/src/action/action_research.cpp
+++ b/src/action/action_research.cpp
@@ -58,6 +58,9 @@
 {
 	file.printf("{\"action-research\"");
 
+	if (this->Finished) {
+		file.printf(" \"finished\", ");
+	}
 	if (this->Upgrade) {
 		file.printf(", \"upgrade\", \"%s\"", this->Upgrade->Ident.c_str());
 	}
@@ -89,7 +92,7 @@
 **
 **  @return true when finished.
 */
-/* virtual */ bool COrder_Research::Execute(CUnit &unit)
+/* virtual */ void COrder_Research::Execute(CUnit &unit)
 {
 	const CUpgrade &upgrade = this->GetUpgrade();
 	const CUnitType &type = *unit.Type;
@@ -99,11 +102,11 @@
 		UnitShowAnimation(unit, type.Animations->Still);
 	if (unit.Wait) {
 		unit.Wait--;
-		return false;
+		return ;
 	}
 #if 0
 	if (unit.Anim.Unbreakable) {
-		return false;
+		return ;
 	}
 #endif
 	CPlayer &player = *unit.Player;
@@ -122,10 +125,10 @@
 			AiResearchComplete(unit, &upgrade);
 		}
 		UpgradeAcquire(player, &upgrade);
-		return true;
+		this->Finished = true;
+		return ;
 	}
 	unit.Wait = CYCLES_PER_SECOND / 6;
-	return false;
 }
 
 /* virtual */ void COrder_Research::Cancel(CUnit &unit)
@@ -136,19 +139,4 @@
 	unit.Player->AddCostsFactor(upgrade.Costs, CancelResearchCostsFactor);
 }
 
-
-/**
-**  Unit researches!
-**
-**  @param unit  Pointer of researching unit.
-*/
-void HandleActionResearch(COrder& order, CUnit &unit)
-{
-	Assert(order.Action == UnitActionResearch);
-
-	if (order.Execute(unit)) {
-		unit.ClearAction();
-	}
-}
-
 //@}
diff --git a/src/action/action_spellcast.cpp b/src/action/action_spellcast.cpp
index 2349cd0bb..3a932ba08 100644
--- a/src/action/action_spellcast.cpp
+++ b/src/action/action_spellcast.cpp
@@ -65,6 +65,9 @@
 {
 	file.printf("{\"action-spell-cast\",");
 
+	if (this->Finished) {
+		file.printf(" \"finished\", ");
+	}
 	file.printf(" \"range\", %d,", this->Range);
 	file.printf(" \"width\", %d,", this->Width);
 	file.printf(" \"height\", %d,", this->Height);
@@ -185,13 +188,13 @@ bool COrder_SpellCast::SpellMoveToTarget(CUnit &unit)
 }
 
 
-/* virtual */ bool COrder_SpellCast::Execute(CUnit &unit)
+/* virtual */ void COrder_SpellCast::Execute(CUnit &unit)
 {
 	COrder_SpellCast &order = *this;
 
 	if (unit.Wait) {
 		unit.Wait--;
-		return false;
+		return ;
 	}
 	const SpellType &spell = order.GetSpell();
 	switch (this->State) {
@@ -212,7 +215,8 @@ bool COrder_SpellCast::SpellMoveToTarget(CUnit &unit)
 				if (unit.Player->AiEnabled) {
 					DebugPrint("FIXME: do we need an AI callback?\n");
 				}
-				return true;
+				this->Finished = true;
+				return ;
 			}
 			// FIXME FIXME FIXME: Check if already in range and skip straight to 2(casting)
 			if (!spell.IsCasterOnly()) {
@@ -224,9 +228,10 @@ bool COrder_SpellCast::SpellMoveToTarget(CUnit &unit)
 		case 1:                         // Move to the target.
 			if (spell.Range && spell.Range != INFINITE_RANGE) {
 				if (SpellMoveToTarget(unit) == true) {
-					return true;
+					this->Finished = true;
+					return ;
 				}
-				return false;
+				return ;
 			} else {
 				this->State = 2;
 			}
@@ -235,7 +240,7 @@ bool COrder_SpellCast::SpellMoveToTarget(CUnit &unit)
 			if (!spell.IsCasterOnly()) {
 				AnimateActionSpellCast(unit, *this);
 				if (unit.Anim.Unbreakable) {
-					return false;
+					return ;
 				}
 			} else {
 				// FIXME: what todo, if unit/goal is removed?
@@ -247,7 +252,8 @@ bool COrder_SpellCast::SpellMoveToTarget(CUnit &unit)
 				}
 			}
 			if (!unit.ReCast && unit.CurrentAction() != UnitActionDie) {
-				return true;
+				this->Finished = true;
+				return ;
 			}
 			break;
 
@@ -255,27 +261,6 @@ bool COrder_SpellCast::SpellMoveToTarget(CUnit &unit)
 			this->State = 0; // Reset path, than move to target
 			break;
 	}
-	return false;
-}
-
-/* virtual */ void COrder_SpellCast::Cancel(CUnit&)
-{
-}
-
-
-/**
-**  Unit casts a spell!
-**
-**  @param unit  Unit, for that the spell cast is handled.
-*/
-void HandleActionSpellCast(COrder& order, CUnit &unit)
-{
-	Assert(order.Action == UnitActionSpellCast);
-
-	if (order.Execute(unit)) {
-		order.ClearGoal();
-		unit.ClearAction();
-	}
 }
 
 //@}
diff --git a/src/action/action_stand.cpp b/src/action/action_stand.cpp
index cb41d2071..4211bdbcf 100644
--- a/src/action/action_stand.cpp
+++ b/src/action/action_stand.cpp
@@ -36,25 +36,10 @@
 #include <stdio.h>
 
 #include "stratagus.h"
-#include "unit.h"
-#include "actions.h"
 
 /*----------------------------------------------------------------------------
 --  Functions
 ----------------------------------------------------------------------------*/
 
-/**
-**  Unit stands ground!
-**
-**  @param unit  Action handled for this unit pointer.
-*/
-void HandleActionStandGround(COrder& order, CUnit &unit)
-{
-	Assert(order.Action == UnitActionStandGround);
-
-	if (order.Execute(unit)) {
-		unit.ClearAction();
-	}
-}
 
 //@}
diff --git a/src/action/action_still.cpp b/src/action/action_still.cpp
index 889535c24..ec386d3e9 100644
--- a/src/action/action_still.cpp
+++ b/src/action/action_still.cpp
@@ -63,6 +63,9 @@ enum {
 	} else {
 		file.printf("{\"action-stand-ground\",");
 	}
+	if (this->Finished) {
+		file.printf(" \"finished\", ");
+	}
 	if (this->HasGoal()) {
 		CUnit &goal = *this->GetGoal();
 		if (goal.Destroyed) {
@@ -241,19 +244,9 @@ bool COrder_Still::AutoAttackStand(CUnit &unit)
 	if (goal == NULL) {
 		return false;
 	}
-
-	CUnit *oldGoal =this->GetGoal();
-	if (oldGoal && oldGoal->CurrentAction() == UnitActionDie) {
-		this->ClearGoal();
-		oldGoal = NULL;
-	}
-	if (this->State < SUB_STILL_ATTACK || oldGoal != goal) {
-		// New target.
-		this->SetGoal(goal);
-		unit.State = 0;
-		this->State = SUB_STILL_ATTACK; // Mark attacking.
-		UnitHeadingFromDeltaXY(unit, goal->tilePos + goal->Type->GetHalfTileSize() - unit.tilePos);
-	}
+	this->SetGoal(goal);
+	this->State = SUB_STILL_ATTACK; // Mark attacking.
+	UnitHeadingFromDeltaXY(unit, goal->tilePos + goal->Type->GetHalfTileSize() - unit.tilePos);
 	return true;
 }
 
@@ -291,13 +284,14 @@ bool AutoAttack(CUnit &unit)
 }
 
 
-/* virtual */ bool COrder_Still::Execute(CUnit &unit)
+/* virtual */ void COrder_Still::Execute(CUnit &unit)
 {
 	// If unit is not bunkered and removed, wait
 	if (unit.Removed
 		&& (unit.Container == NULL || unit.Container->Type->AttackFromTransporter == false)) {
-		return false;
+		return ;
 	}
+	this->Finished = false;
 
 	switch (this->State) {
 		case SUB_STILL_INIT: //first entry
@@ -311,38 +305,22 @@ bool AutoAttack(CUnit &unit)
 		break;
 	}
 	if (unit.Anim.Unbreakable) { // animation can't be aborted here
-		return false;
+		return ;
 	}
+	this->State = SUB_STILL_STANDBY;
+	this->Finished = (this->Action == UnitActionStill);
 	if (this->Action == UnitActionStandGround || unit.Removed || unit.CanMove() == false) {
 		if (unit.IsAgressive()) {
 			this->AutoAttackStand(unit);
-			return false;
 		}
 	} else {
 		if ((unit.IsAgressive() && AutoAttack(unit))
 			|| AutoCast(unit)
 			|| AutoRepair(unit)
 			|| MoveRandomly(unit)) {
-			return true;
 		}
 	}
-	return false;
 }
 
-/**
-**  Unit stands still!
-**
-**  @param unit  Unit pointer for still action.
-*/
-void HandleActionStill(COrder& order, CUnit &unit)
-{
-	Assert(order.Action == UnitActionStill);
-
-	if (order.Execute(unit)) {
-		unit.ClearAction();
-	}
-}
-
-
 
 //@}
diff --git a/src/action/action_train.cpp b/src/action/action_train.cpp
index 822ea8cd7..ac39c912e 100644
--- a/src/action/action_train.cpp
+++ b/src/action/action_train.cpp
@@ -58,6 +58,9 @@
 /* virtual */ void COrder_Train::Save(CFile &file, const CUnit &unit) const
 {
 	file.printf("{\"action-train\",");
+	if (this->Finished) {
+		file.printf(" \"finished\", ");
+	}
 	file.printf("\"type\", \"%s\",", this->Type->Ident.c_str());
 	file.printf("\"ticks\", %d", this->Ticks);
 	file.printf("}");
@@ -152,12 +155,12 @@ static void AnimateActionTrain(CUnit &unit)
 	}
 }
 
-/* virtual */ bool COrder_Train::Execute(CUnit &unit)
+/* virtual */ void COrder_Train::Execute(CUnit &unit)
 {
 	AnimateActionTrain(unit);
 	if (unit.Wait) {
 		unit.Wait--;
-		return false;
+		return ;
 	}
 	CPlayer &player = *unit.Player;
 	CUnitType &nType = *this->Type;
@@ -166,14 +169,14 @@ static void AnimateActionTrain(CUnit &unit)
 
 	if (this->Ticks < cost) {
 		unit.Wait = CYCLES_PER_SECOND / 6;
-		return false;
+		return ;
 	}
 	this->Ticks = std::min(this->Ticks, cost);
 
 	// Check if there are still unit slots.
 	if (NumUnits >= UnitMax) {
 		unit.Wait = CYCLES_PER_SECOND / 6;
-		return false;
+		return ;
 	}
 
 	// Check if enough supply available.
@@ -183,7 +186,7 @@ static void AnimateActionTrain(CUnit &unit)
 			AiNeedMoreSupply(*unit.Player);
 		}
 		unit.Wait = CYCLES_PER_SECOND / 6;
-		return false;
+		return ;
 	}
 
 	CUnit *newUnit = MakeUnit(nType, &player);
@@ -192,7 +195,7 @@ static void AnimateActionTrain(CUnit &unit)
 		player.Notify(NotifyYellow, unit.tilePos.x, unit.tilePos.y,
 				_("Unable to train %s"), nType.Name.c_str());
 		unit.Wait = CYCLES_PER_SECOND / 6;
-		return false;
+		return ;
 	}
 
 	// New unit might supply food
@@ -228,27 +231,18 @@ static void AnimateActionTrain(CUnit &unit)
 	}
 
 	if (CanHandleOrder(*newUnit, unit.NewOrder) == true) {
-		delete newUnit->CurrentOrder();
+		delete newUnit->Orders[0];
 		newUnit->Orders[0] = unit.NewOrder->Clone();
 	} else {
 #if 0
 		// Tell the unit to rigth-click ?
 #endif
 	}
+	this->Finished = true;
 	if (IsOnlySelected(unit)) {
 		UI.ButtonPanel.Update();
 	}
-	return true;
-}
 
-void HandleActionTrain(COrder& order, CUnit &unit)
-{
-	Assert(order.Action == UnitActionTrain);
-
-	if (order.Execute(unit)) {
-
-		unit.ClearAction();
-	}
 }
 
 //@}
diff --git a/src/action/action_unload.cpp b/src/action/action_unload.cpp
index 611181ea1..f36bb86d5 100644
--- a/src/action/action_unload.cpp
+++ b/src/action/action_unload.cpp
@@ -53,6 +53,9 @@
 /* virtual */ void COrder_Unload::Save(CFile &file, const CUnit &unit) const
 {
 	file.printf("{\"action-unload\",");
+	if (this->Finished) {
+		file.printf(" \"finished\", ");
+	}
 	if (this->HasGoal()) {
 		CUnit &goal = *this->GetGoal();
 		if (goal.Destroyed) {
@@ -352,7 +355,7 @@ bool COrder_Unload::LeaveTransporter(CUnit &transporter)
 	}
 }
 
-/* virtual */ bool COrder_Unload::Execute(CUnit &unit)
+/* virtual */ void COrder_Unload::Execute(CUnit &unit)
 {
 	const int maxSearchRange = 20;
 
@@ -365,7 +368,8 @@ bool COrder_Unload::LeaveTransporter(CUnit &transporter)
 				Vec2i pos;
 
 				if (!ClosestFreeDropZone(unit, this->goalPos, maxSearchRange, &pos)) {
-					return true;
+					this->Finished = true;
+					return ;
 				}
 				this->goalPos = pos;
 			}
@@ -382,40 +386,26 @@ bool COrder_Unload::LeaveTransporter(CUnit &transporter)
 				if (moveResult) {
 					if (moveResult == PF_REACHED) {
 						if (++this->State == 1) {
-							return true;
+							this->Finished = true;
+							return ;
 						}
 					} else {
 						this->State = 2;
 					}
 				}
-				return false;
+				return ;
 			}
 		case 2: { // Leave the transporter
 			// FIXME: show still animations ?
 			if (LeaveTransporter(unit)) {
-				return true;
+				this->Finished = true;
+				return ;
 			}
-			return false;
+			return ;
 		}
 		default:
-			return false;
+			return ;
 	}
 }
 
-
-/**
-**  The transporter unloads a unit.
-**
-**  @param unit  Pointer to unit.
-*/
-void HandleActionUnload(COrder& order, CUnit &unit)
-{
-	Assert(order.Action == UnitActionUnload);
-
-	if (order.Execute(unit)) {
-		unit.ClearAction();
-	}
-}
-
-
 //@}
diff --git a/src/action/action_upgradeto.cpp b/src/action/action_upgradeto.cpp
index 1452e4cad..eed5b293b 100644
--- a/src/action/action_upgradeto.cpp
+++ b/src/action/action_upgradeto.cpp
@@ -145,6 +145,9 @@ static int TransformUnitIntoType(CUnit &unit, const CUnitType &newtype)
 /* virtual */ void COrder_TransformInto::Save(CFile &file, const CUnit &unit) const
 {
 	file.printf("{\"action-transform-into\",");
+	if (this->Finished) {
+		file.printf(" \"finished\", ");
+	}
 	file.printf(" \"type\", \"%s\"", this->Type->Ident.c_str());
 	file.printf("}");
 }
@@ -162,19 +165,10 @@ static int TransformUnitIntoType(CUnit &unit, const CUnitType &newtype)
 	return true;
 }
 
-/* virtual */ bool COrder_TransformInto::Execute(CUnit &unit)
+/* virtual */ void COrder_TransformInto::Execute(CUnit &unit)
 {
 	TransformUnitIntoType(unit, *this->Type);
-	return true;
-}
-
-void HandleActionTransformInto(COrder& order, CUnit &unit)
-{
-	Assert(order.Action == UnitActionTransformInto);
-
-	if (order.Execute(unit)) {
-//		unit.ClearAction();
-	}
+	this->Finished = true;
 }
 
 #endif
@@ -184,6 +178,9 @@ void HandleActionTransformInto(COrder& order, CUnit &unit)
 /* virtual */ void COrder_UpgradeTo::Save(CFile &file, const CUnit &unit) const
 {
 	file.printf("{\"action-upgrade-to\",");
+	if (this->Finished) {
+		file.printf(" \"finished\", ");
+	}
 	file.printf(" \"type\", \"%s\",", this->Type->Ident.c_str());
 	file.printf(" \"ticks\", %d", this->Ticks);
 	file.printf("}");
@@ -215,12 +212,12 @@ static void AnimateActionUpgradeTo(CUnit &unit)
 		UnitShowAnimation(unit, unit.Type->Animations->Still);
 }
 
-/* virtual */ bool COrder_UpgradeTo::Execute(CUnit &unit)
+/* virtual */ void COrder_UpgradeTo::Execute(CUnit &unit)
 {
 	AnimateActionUpgradeTo(unit);
 	if (unit.Wait) {
 		unit.Wait--;
-		return false;
+		return ;
 	}
 	CPlayer &player = *unit.Player;
 	const CUnitType &newtype = *this->Type;
@@ -229,18 +226,19 @@ static void AnimateActionUpgradeTo(CUnit &unit)
 	this->Ticks += SpeedUpgrade;
 	if (this->Ticks < newstats.Costs[TimeCost]) {
 		unit.Wait = CYCLES_PER_SECOND / 6;
-		return false;
+		return ;
 	}
 
 	if (unit.Anim.Unbreakable) {
 		this->Ticks = newstats.Costs[TimeCost];
-		return false;
+		return ;
 	}
 
 	if (TransformUnitIntoType(unit, newtype) == 0) {
 		player.Notify(NotifyGreen, unit.tilePos.x, unit.tilePos.y,
 			_("Upgrade to %s canceled"), newtype.Name.c_str());
-		return true;
+		this->Finished = true;
+		return ;
 	}
 	player.Notify(NotifyGreen, unit.tilePos.x, unit.tilePos.y,
 		_("Upgrade to %s complete"), unit.Type->Name.c_str());
@@ -249,7 +247,7 @@ static void AnimateActionUpgradeTo(CUnit &unit)
 	if (player.AiEnabled) {
 		AiUpgradeToComplete(unit, newtype);
 	}
-	return true;
+	this->Finished = true;
 }
 
 /* virtual */ void COrder_UpgradeTo::Cancel(CUnit &unit)
@@ -267,16 +265,5 @@ static void AnimateActionUpgradeTo(CUnit &unit)
 	unit.Variable[UPGRADINGTO_INDEX].Max = this->Type->Stats[unit.Player->Index].Costs[TimeCost];
 }
 
-
-
-void HandleActionUpgradeTo(COrder& order, CUnit &unit)
-{
-	Assert(order.Action == UnitActionUpgradeTo);
-
-	if (order.Execute(unit)) {
-		unit.ClearAction();
-	}
-}
-
 #endif
 //@}
diff --git a/src/action/actions.cpp b/src/action/actions.cpp
index a66f221a4..752eaa2c0 100644
--- a/src/action/actions.cpp
+++ b/src/action/actions.cpp
@@ -168,8 +168,6 @@ unsigned SyncHash; /// Hash calculated to find sync failures
 {
 	COrder_Built* order = new COrder_Built();
 
-	order->Action = UnitActionBuilt;
-
 	// Make sure the bulding doesn't cancel itself out right away.
 
 	unit.Variable[HP_INDEX].Value = 1;
@@ -261,8 +259,6 @@ unsigned SyncHash; /// Hash calculated to find sync failures
 {
 	COrder_Research *order = new COrder_Research();
 
-	order->Action = UnitActionResearch;
-
 	// FIXME: if you give quick an other order, the resources are lost!
 	unit.Player->SubCosts(upgrade.Costs);
 
@@ -324,8 +320,6 @@ unsigned SyncHash; /// Hash calculated to find sync failures
 {
 	COrder_SpellCast *order = new COrder_SpellCast;
 
-	order->Action = UnitActionSpellCast;
-
 	order->Range = spell.Range;
 	if (target) {
 		// Destination could be killed.
@@ -457,7 +451,7 @@ void COrder::ReleaseRefs(CUnit &unit)
 			}
 		}
 		// Still shouldn't have a reference unless attacking
-		Assert(!(this->Action == UnitActionStill && !SubAction.Attack));
+		Assert(this->Action != UnitActionStill);
 		this->ClearGoal();
 	}
 #ifdef DEBUG
@@ -1339,26 +1333,26 @@ static void HandleActionNotWritten(COrder&, CUnit &unit)
 */
 static void (*HandleActionTable[256])(COrder&, CUnit &) = {
 	HandleActionNone,
-	HandleActionStill,
-	HandleActionStandGround,
-	HandleActionFollow,
-	HandleActionMove,
+	HandleActionNone, // HandleActionStill,
+	HandleActionNone, // HandleActionStandGround,
+	HandleActionNone, // HandleActionFollow,
+	HandleActionNone, // HandleActionMove,
 	HandleActionAttack,
 	HandleActionAttack, // HandleActionAttackGround,
-	HandleActionDie,
-	HandleActionSpellCast,
-	HandleActionTrain,
-	HandleActionUpgradeTo,
-	HandleActionResearch,
-	HandleActionBuilt,
-	HandleActionBoard,
-	HandleActionUnload,
-	HandleActionPatrol,
-	HandleActionBuild,
-	HandleActionRepair,
+	HandleActionNone, // HandleActionDie,
+	HandleActionNone, // HandleActionSpellCast,
+	HandleActionNone, // HandleActionTrain,
+	HandleActionNone, // HandleActionUpgradeTo,
+	HandleActionNone, // HandleActionResearch,
+	HandleActionNone, // HandleActionBuilt,
+	HandleActionNone, // HandleActionBoard,
+	HandleActionNone, // HandleActionUnload,
+	HandleActionNone, // HandleActionPatrol,
+	HandleActionNone, // HandleActionBuild,
+	HandleActionNone, // HandleActionRepair,
 	HandleActionResource,
 	HandleActionReturnGoods,
-	HandleActionTransformInto,
+	HandleActionNone, // HandleActionTransformInto,
 	HandleActionNotWritten,
 
 	// Enough for the future ?
@@ -1522,9 +1516,12 @@ static void HandleBuffs(CUnit &unit, int amount)
 	}
 }
 
-static void RunAction(COrder &order, CUnit &unit)
+
+
+
+void COrder::Execute(CUnit &unit)
 {
-	HandleActionTable[order.Action](order, unit);
+	HandleActionTable[Action](*this, unit);
 }
 
 
@@ -1538,40 +1535,44 @@ static void HandleUnitAction(CUnit &unit)
 	// If current action is breakable proceed with next one.
 	if (!unit.Anim.Unbreakable) {
 		if (unit.CriticalOrder != NULL) {
-			RunAction(*unit.CriticalOrder, unit);
+			unit.CriticalOrder->Execute(unit);
 			delete unit.CriticalOrder;
 			unit.CriticalOrder = NULL;
 		}
 
+		if (unit.Orders[0]->Finished && unit.Orders[0]->Action != UnitActionStill
+			&& unit.Orders.size() == 1) {
+			unit.Orders[0]->ReleaseRefs(unit);
+
+			delete unit.Orders[0];
+			unit.Orders[0] = new COrder_Still(false);
+			unit.State = 0;
+			if (IsOnlySelected(unit)) { // update display for new action
+				SelectedUnitChanged();
+			}
+		}
+
 		// o Look if we have a new order and old finished.
 		// o Or the order queue should be flushed.
-		if (unit.Orders.size() > 1
-			&& (unit.CurrentAction() == UnitActionStill || unit.OrderFlush)) {
-
+		if (unit.Orders[0]->Finished && unit.Orders.size() > 1) {
 			if (unit.Removed) { // FIXME: johns I see this as an error
 				DebugPrint("Flushing removed unit\n");
 				// This happens, if building with ALT+SHIFT.
 				return;
 			}
-			COrderPtr order = unit.CurrentOrder();
+			unit.Orders[0]->ReleaseRefs(unit);
 
-			order->ReleaseRefs(unit);
-
-			unit.OrderFlush = 0;
 			delete unit.Orders[0];
 			unit.Orders.erase(unit.Orders.begin());
 
 			unit.State = 0;
 			unit.Wait = 0;
-
 			if (IsOnlySelected(unit)) { // update display for new action
 				SelectedUnitChanged();
 			}
 		}
 	}
-
-	// Select action.
-	RunAction(*unit.CurrentOrder(), unit);
+	unit.Orders[0]->Execute(unit);
 }
 
 /**
diff --git a/src/action/command.cpp b/src/action/command.cpp
index 18c28e678..47ef0f163 100644
--- a/src/action/command.cpp
+++ b/src/action/command.cpp
@@ -67,7 +67,7 @@ static void ReleaseOrders(CUnit &unit)
 		delete unit.Orders[i];
 	}
 	unit.Orders.resize(1);
-	unit.OrderFlush = 1;
+	unit.Orders[0]->Finished = true;
 }
 
 /**
diff --git a/src/include/actions.h b/src/include/actions.h
index 3c793a224..0786948b6 100644
--- a/src/include/actions.h
+++ b/src/include/actions.h
@@ -101,9 +101,10 @@ struct lua_State;
 */
 class COrder
 {
+
 public:
 	COrder(int action) : Goal(NULL), Range(0), MinRange(0), Width(0),
-		Height(0), Action(action), CurrentResource(0)
+		Height(0), Action(action), Finished(false), CurrentResource(0)
 	{
 		goalPos.x = -1;
 		goalPos.y = -1;
@@ -114,7 +115,7 @@ public:
 	virtual ~COrder();
 
 	virtual COrder *Clone() const;
-	virtual bool Execute(CUnit &unit) { return false; }
+	virtual void Execute(CUnit &unit);
 	virtual void Cancel(CUnit &unit) {}
 	virtual void OnAnimationAttack(CUnit &unit);
 
@@ -184,6 +185,7 @@ public:
 	unsigned char Width;    /// Goal Width (used when Goal is not)
 	unsigned char Height;   /// Goal Height (used when Goal is not)
 	unsigned char Action;   /// global action
+	bool Finished; /// true when order is finish
 	unsigned char CurrentResource; ///used in UnitActionResource and UnitActionReturnGoods
 
 	Vec2i goalPos;          /// or tile coordinate of destination
@@ -227,7 +229,7 @@ public:
 	virtual void Save(CFile &file, const CUnit &unit) const;
 	virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
 
-	virtual bool Execute(CUnit &unit);
+	virtual void Execute(CUnit &unit);
 
 private:
 	bool WaitForTransporter(CUnit &unit);
@@ -247,7 +249,7 @@ public:
 	virtual void Save(CFile &file, const CUnit &unit) const;
 	virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
 
-	virtual bool Execute(CUnit &unit);
+	virtual void Execute(CUnit &unit);
 
 	virtual void AiUnitKilled(CUnit &unit);
 
@@ -276,7 +278,7 @@ public:
 	virtual void Save(CFile &file, const CUnit &unit) const;
 	virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
 
-	virtual bool Execute(CUnit &unit);
+	virtual void Execute(CUnit &unit);
 	virtual void Cancel(CUnit &unit);
 
 	virtual void UpdateUnitVariables(CUnit &unit) const;
@@ -312,7 +314,7 @@ public:
 	virtual void Save(CFile &file, const CUnit &unit) const;
 	virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
 
-	virtual bool Execute(CUnit &unit);
+	virtual void Execute(CUnit &unit);
 };
 
 class COrder_Follow : public COrder
@@ -325,7 +327,7 @@ public:
 	virtual void Save(CFile &file, const CUnit &unit) const;
 	virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
 
-	virtual bool Execute(CUnit &unit);
+	virtual void Execute(CUnit &unit);
 private:
 	unsigned int State;
 };
@@ -340,7 +342,7 @@ public:
 	virtual void Save(CFile &file, const CUnit &unit) const;
 	virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
 
-	virtual bool Execute(CUnit &unit);
+	virtual void Execute(CUnit &unit);
 };
 
 
@@ -356,7 +358,7 @@ public:
 	virtual void Save(CFile &file, const CUnit &unit) const;
 	virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
 
-	virtual bool Execute(CUnit &unit);
+	virtual void Execute(CUnit &unit);
 
 	const Vec2i& GetWayPoint() const { return WayPoint; }
 private:
@@ -376,7 +378,7 @@ public:
 	virtual void Save(CFile &file, const CUnit &unit) const;
 	virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
 
-	virtual bool Execute(CUnit &unit);
+	virtual void Execute(CUnit &unit);
 private:
 	bool RepairUnit(const CUnit &unit, CUnit &goal);
 private:
@@ -396,7 +398,7 @@ public:
 	virtual void Save(CFile &file, const CUnit &unit) const;
 	virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
 
-	virtual bool Execute(CUnit &unit);
+	virtual void Execute(CUnit &unit);
 	virtual void Cancel(CUnit &unit);
 
 	virtual void UpdateUnitVariables(CUnit &unit) const;
@@ -417,8 +419,7 @@ public:
 	virtual void Save(CFile &file, const CUnit &unit) const;
 	virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
 
-	virtual bool Execute(CUnit &unit);
-	virtual void Cancel(CUnit &unit);
+	virtual void Execute(CUnit &unit);
 	virtual void OnAnimationAttack(CUnit &unit);
 
 	const SpellType& GetSpell() const { return *Spell; }
@@ -440,7 +441,7 @@ public:
 	virtual void Save(CFile &file, const CUnit &unit) const;
 	virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
 
-	virtual bool Execute(CUnit &unit);
+	virtual void Execute(CUnit &unit);
 private:
 	bool AutoAttackStand(CUnit &unit);
 private:
@@ -459,7 +460,7 @@ public:
 	virtual void Save(CFile &file, const CUnit &unit) const;
 	virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
 
-	virtual bool Execute(CUnit &unit);
+	virtual void Execute(CUnit &unit);
 	virtual void Cancel(CUnit &unit);
 
 	virtual void UpdateUnitVariables(CUnit &unit) const;
@@ -483,7 +484,7 @@ public:
 	virtual void Save(CFile &file, const CUnit &unit) const;
 	virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
 
-	virtual bool Execute(CUnit &unit);
+	virtual void Execute(CUnit &unit);
 
 private:
 	CUnitType *Type; /// Transform unit into this unit-type
@@ -502,7 +503,7 @@ public:
 	virtual void Save(CFile &file, const CUnit &unit) const;
 	virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
 
-	virtual bool Execute(CUnit &unit);
+	virtual void Execute(CUnit &unit);
 
 private:
 	bool LeaveTransporter(CUnit &transporter);
@@ -522,7 +523,7 @@ public:
 	virtual void Save(CFile &file, const CUnit &unit) const;
 	virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
 
-	virtual bool Execute(CUnit &unit);
+	virtual void Execute(CUnit &unit);
 	virtual void Cancel(CUnit &unit);
 
 	virtual void UpdateUnitVariables(CUnit &unit) const;
@@ -619,55 +620,22 @@ extern int GetNumWaitingWorkers(const CUnit &mine);
 extern bool AutoAttack(CUnit &unit);
 extern bool AutoRepair(CUnit &unit);
 extern bool AutoCast(CUnit &unit);
-
 extern void UnHideUnit(CUnit &unit);
 
+	/// Generic move action
+extern int DoActionMove(CUnit &unit);
+	/// Show attack animation
+extern void AnimateActionAttack(CUnit &unit);
+
+
 typedef void HandleActionFunc(COrder& order, CUnit &unit);
 
-	/// Handle command still
-extern HandleActionFunc HandleActionStill;
-	/// Handle command stand ground
-extern HandleActionFunc HandleActionStandGround;
-	/// Handle command follow
-extern HandleActionFunc HandleActionFollow;
-	/// Generic move action
-extern int DoActionMove(CUnit &unit);
-	/// Handle command move
-extern HandleActionFunc HandleActionMove;
-	/// Handle command repair
-extern HandleActionFunc HandleActionRepair;
-	/// Handle command patrol
-extern HandleActionFunc HandleActionPatrol;
-	/// Show attack animation
-extern void AnimateActionAttack(CUnit &unit);
 	/// Handle command attack
 extern HandleActionFunc HandleActionAttack;
-	/// Handle command board
-extern HandleActionFunc HandleActionBoard;
-	/// Handle command unload
-extern HandleActionFunc HandleActionUnload;
 	/// Handle command resource
 extern HandleActionFunc HandleActionResource;
 	/// Handle command return
 extern HandleActionFunc HandleActionReturnGoods;
-	/// Handle command die
-extern HandleActionFunc HandleActionDie;
-	/// Handle command build
-extern HandleActionFunc HandleActionBuild;
-	/// Handle command built
-extern HandleActionFunc HandleActionBuilt;
-	/// Handle command train
-extern HandleActionFunc HandleActionTrain;
-	/// Handle command upgrade to
-extern HandleActionFunc HandleActionUpgradeTo;
-	/// Handle command transform into
-extern HandleActionFunc HandleActionTransformInto;
-	/// Handle command upgrade
-extern HandleActionFunc HandleActionUpgrade;
-	/// Handle command research
-extern HandleActionFunc HandleActionResearch;
-	/// Handle command spellcast
-extern HandleActionFunc HandleActionSpellCast;
 
 /*----------------------------------------------------------------------------
 --  Actions: actions.c
diff --git a/src/include/unit.h b/src/include/unit.h
index 1cf8597c2..fe50ffac6 100644
--- a/src/include/unit.h
+++ b/src/include/unit.h
@@ -295,12 +295,6 @@
 **  Pointer to the original owner of a unit. It will be NULL if
 **  the unit was not rescued.
 **
-**
-**  CUnit::OrderFlush
-**
-**  A flag, which tells the unit to stop with the current order
-**  and immediately start with the next order.
-**
 **  CUnit::Orders
 **
 **  Contains all orders of the unit. Slot 0 is always used.
@@ -566,11 +560,11 @@ public:
 	} Anim;
 
 
-	char OrderFlush;            /// cancel current order, take next
 	std::vector<COrder *> Orders; /// orders to process
 	COrder *SavedOrder;         /// order to continue after current
 	COrder *NewOrder;           /// order for new trained units
 	COrder *CriticalOrder;      /// order to do as possible in breakable animation.
+
 	char *AutoCastSpell;        /// spells to auto cast
 
 	CUnit *Goal; /// Generic/Teleporter goal pointer
diff --git a/src/unit/script_unit.cpp b/src/unit/script_unit.cpp
index c5202b91a..f1dc82a17 100644
--- a/src/unit/script_unit.cpp
+++ b/src/unit/script_unit.cpp
@@ -188,6 +188,10 @@ bool COrder::ParseGenericData(lua_State *l, int &j, const char *value)
 		lua_rawgeti(l, -1, j + 1);
 		this->Height = LuaToNumber(l, -1);
 		lua_pop(l, 1);
+	} else if (!strcmp(value, "finished")) {
+		lua_rawgeti(l, -1, j + 1);
+		this->Finished = true;
+		lua_pop(l, 1);
 	} else if (!strcmp(value, "goal")) {
 		++j;
 		lua_rawgeti(l, -1, j + 1);
@@ -656,8 +660,6 @@ static int CclUnit(lua_State *l)
 				lua_pop(l, 1);
 				u->AddInContainer(*unit);
 			}
-		} else if (!strcmp(value, "order-flush")) {
-			unit->OrderFlush = LuaToNumber(l, j + 1);
 		} else if (!strcmp(value, "orders")) {
 			lua_pushvalue(l, j + 1);
 			CclParseOrders(l, *unit);
diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp
index 01a9f92ac..6163199b0 100644
--- a/src/unit/unit.cpp
+++ b/src/unit/unit.cpp
@@ -178,7 +178,6 @@ void CUnit::Init()
 	CacheLock = 0;
 	memset(&Anim, 0, sizeof(Anim));
 	CurrentResource = 0;
-	OrderFlush = 0;
 	Orders.clear();
 	delete SavedOrder;
 	SavedOrder = NULL;
@@ -264,8 +263,7 @@ unsigned int CUnit::CurrentAction() const
 
 void CUnit::ClearAction()
 {
-	delete CurrentOrder();
-	Orders[0] = COrder::NewActionStill();
+	Orders[0]->Finished = true;
 
 	if (Selected) {
 		SelectedUnitChanged();
@@ -373,13 +371,13 @@ bool CUnit::RestoreOrder()
 
 	// Cannot delete this->Orders[0] since it is generally that order
 	// which call this method.
+	this->Orders[0]->Finished = true;
+
 
 	//copy
-	this->Orders[0] = this->SavedOrder;
+	this->Orders.insert(this->Orders.begin() + 1, this->SavedOrder);
 	this->CurrentResource = this->SavedOrder->CurrentResource;
 
-	this->CurrentOrder()->NewResetPath();
-
 	this->SavedOrder = NULL;
 	return true;
 }
@@ -2131,8 +2129,6 @@ void DropOutAll(const CUnit &source)
 
 	for (int i = source.InsideCount; i; --i, unit = unit->NextContained) {
 		DropOutOnSide(*unit, LookingW, &source);
-		Assert(!unit->CurrentOrder()->HasGoal());
-		unit->CurrentOrder()->Action = UnitActionStill;
 	}
 }
 
diff --git a/src/unit/unit_draw.cpp b/src/unit/unit_draw.cpp
index f5e272091..f6673c774 100644
--- a/src/unit/unit_draw.cpp
+++ b/src/unit/unit_draw.cpp
@@ -854,9 +854,10 @@ void ShowOrder(const CUnit &unit)
 	const PixelPos mapPos = unit.GetMapPixelPosCenter();
 	PixelPos screenStartPos = CurrentViewport->MapToScreenPixelPos(mapPos);
 	COrderPtr order;
+	const bool flushed = unit.Orders[0]->Finished;
 
 	// If the current order is cancelled show the next one
-	if (unit.Orders.size() > 1 && unit.OrderFlush) {
+	if (unit.Orders.size() > 1 && flushed) {
 		order = unit.Orders[1];
 	} else {
 		order = unit.Orders[0];
@@ -864,7 +865,7 @@ void ShowOrder(const CUnit &unit)
 	ShowSingleOrder(unit, screenStartPos, *order);
 
 	// Show the rest of the orders
-	for (size_t i = 1 + (unit.OrderFlush ? 1 : 0); i < unit.Orders.size(); ++i) {
+	for (size_t i = 1 + (flushed ? 1 : 0); i < unit.Orders.size(); ++i) {
 		PixelPos screenPos;
 		GetOrderPosition(unit, *unit.Orders[i - 1], &screenPos);
 		ShowSingleOrder(unit, screenPos, *unit.Orders[i]);
diff --git a/src/unit/unit_save.cpp b/src/unit/unit_save.cpp
index 5dee3daa6..d8c5dc0a3 100644
--- a/src/unit/unit_save.cpp
+++ b/src/unit/unit_save.cpp
@@ -116,6 +116,11 @@ void SaveOrder(const COrder &order, const CUnit &unit, CFile *file)
 	file.printf(" \"width\", %d,", order.Width);
 	file.printf(" \"height\", %d,", order.Height);
 	file.printf(" \"min-range\", %d,", order.MinRange);
+
+	if (order.Finished) {
+		file.printf(" \"finished\", ");
+	}
+
 	if (order.HasGoal()) {
 		CUnit &goal = *order.GetGoal();
 		if (goal.Destroyed) {
@@ -382,7 +387,6 @@ void SaveUnit(const CUnit &unit, CFile *file)
 		}
 		file->printf("},\n  ");
 	}
-	file->printf("\"order-flush\", %d,\n  ", unit.OrderFlush);
 	file->printf("\"orders\", {\n");
 	Assert(unit.Orders.empty() == false);
 	SaveOrder(*unit.Orders[0], unit, file);