From 542cb5a5d477968b50625ed0e38d7e5fb4b9fef8 Mon Sep 17 00:00:00 2001
From: cybermind <iddqd_mail@mail.ru>
Date: Sun, 17 Mar 2013 12:02:27 +0600
Subject: [PATCH] [-] Fixed crash when handlind action for unit killed by TTL
 [-] Fixed crash for pience missiles which are gone outside of map [-] Fixed
 crash when saving invalid order [-] Fixed crash when changing owner for dead
 unit [-] Don't help to summoned units for AI

---
 src/action/actions.cpp  |  4 ++++
 src/ai/ai.cpp           |  7 +++++--
 src/missile/missile.cpp | 16 ++++++++++++----
 src/unit/unit.cpp       |  7 ++++++-
 4 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/src/action/actions.cpp b/src/action/actions.cpp
index 532b6611d..15918fd54 100644
--- a/src/action/actions.cpp
+++ b/src/action/actions.cpp
@@ -470,6 +470,10 @@ static void UnitActionsEachCycle(UNITP_ITERATOR begin, UNITP_ITERATOR end)
 
 		// Handle each cycle buffs
 		HandleBuffsEachCycle(unit);
+		// Unit could be dead after TTL kill
+		if (unit.Destroyed) {
+			continue;
+		}
 
 		try {
 			HandleUnitAction(unit);
diff --git a/src/ai/ai.cpp b/src/ai/ai.cpp
index e494ee41c..7e6508d2c 100644
--- a/src/ai/ai.cpp
+++ b/src/ai/ai.cpp
@@ -655,7 +655,7 @@ void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type)
 */
 void AiHelpMe(const CUnit *attacker, CUnit &defender)
 {
-	/* Freandly Fire - typical splash */
+	/* Friendly Fire - typical splash */
 	if (!attacker || attacker->Player->Index == defender.Player->Index) {
 		//FIXME - try react somehow
 		return;
@@ -669,11 +669,14 @@ void AiHelpMe(const CUnit *attacker, CUnit &defender)
 	if (!defender.Type->CanAttack && defender.Type->UnitType == UnitTypeFly) {
 		return;
 	}
+	// Summoned unit, don't help
+	if (defender.GroupId == -1) {
+		return;
+	}
 
 	PlayerAi &pai = *defender.Player->Ai;
 	AiPlayer = &pai;
 
-
 	//  If unit belongs to an attacking force, check if force members can help.
 	if (defender.GroupId) {
 		AiForce &aiForce = pai.Force[defender.GroupId - 1];
diff --git a/src/missile/missile.cpp b/src/missile/missile.cpp
index 96289e574..a4b2ae0de 100644
--- a/src/missile/missile.cpp
+++ b/src/missile/missile.cpp
@@ -647,10 +647,18 @@ bool MissileInitMove(Missile &missile)
 
 void MissileHandlePierce(Missile &missile, const Vec2i &pos)
 {
-	CUnit *unit = UnitOnMapTile(pos, -1);
-	if (unit && unit->IsAliveOnMap()
-		&& (missile.Type->FriendlyFire || unit->IsEnemy(*missile.SourceUnit->Player))) {
-		missile.MissileHit(unit);
+	if (Map.Info.IsPointOnMap(pos) == false) {
+		return;
+	}
+	std::vector<CUnit *> units;
+	Select(pos, pos, units);
+	for (std::vector<CUnit *>::iterator it = units.begin(); it != units.end(); ++it) {
+		CUnit &unit = **it;
+
+		if (unit.IsAliveOnMap()
+			&& (missile.Type->FriendlyFire || unit.IsEnemy(*missile.SourceUnit->Player))) {
+			missile.MissileHit(&unit);
+		}
 	}
 }
 
diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp
index 3ed4a287d..b23010076 100644
--- a/src/unit/unit.cpp
+++ b/src/unit/unit.cpp
@@ -665,7 +665,7 @@ bool CUnit::CanStoreOrder(COrder *order)
 {
 	Assert(order);
 
-	if (order && order->Finished == true && order->IsValid() == false) {
+	if ((order && order->Finished == true) || order->IsValid() == false) {
 		return false;
 	}
 	if (this->SavedOrder != NULL) {
@@ -1664,6 +1664,11 @@ void CUnit::ChangeOwner(CPlayer &newplayer)
 		return;
 	}
 
+	// Can't change owner for dead units
+	if (this->IsAlive() == false) {
+		return;
+	}
+
 	// Rescue all units in buildings/transporters.
 	CUnit *uins = UnitInside;
 	for (int i = InsideCount; i; --i, uins = uins->NextContained) {