From 8d311bd54b5f421afc1e7909f32ffce25f4a4134 Mon Sep 17 00:00:00 2001
From: n0body <>
Date: Sat, 25 Oct 2003 02:12:17 +0000
Subject: [PATCH] Fixed missile orientation. Fixed some leaks. Removed
 DEMOLISH_DAMAGE.

---
 doc/ChangeLog.html               |  1 +
 src/action/action_resource.cpp   |  4 ++--
 src/include/stratagus.h          |  1 -
 src/stratagus/missile.cpp        | 26 ++++++++++++++++----------
 src/stratagus/script_missile.cpp |  2 +-
 src/ui/menus.cpp                 |  4 ++++
 src/ui/script_ui.cpp             |  8 +++++---
 src/ui/ui.cpp                    |  8 ++++++++
 src/unit/unittype.cpp            |  3 +++
 9 files changed, 40 insertions(+), 17 deletions(-)

diff --git a/doc/ChangeLog.html b/doc/ChangeLog.html
index ae2f41fa3..56d53cc1c 100644
--- a/doc/ChangeLog.html
+++ b/doc/ChangeLog.html
@@ -36,6 +36,7 @@
 <li>Future 2.00 Release<p>
     <ul>
     <li>++
+    <li>Applied patch #2116 (correct missile directions) (from Ludovic Jarod Dauphin).
     <li>Added Neutral Minimap Color. (from Russell Smith).
     <li>Removed the demolish action, we now use the demolish spell. (from Crestez Leonard).
     <li>Applied patch #1969 (AI enhancement) (from Ludovic Pollet).
diff --git a/src/action/action_resource.cpp b/src/action/action_resource.cpp
index 672615e6f..91b599cae 100644
--- a/src/action/action_resource.cpp
+++ b/src/action/action_resource.cpp
@@ -84,8 +84,8 @@ local int MoveToResource(Unit* unit)
 	y = unit->Orders->Y;
 	// Wood gone, look somewhere else.
 	if ((!ForestOnMap(x, y)) && (!unit->IX) && (!unit->IY)) {
-	    if (!FindTerrainType(UnitMovementMask(unit), MapFieldForest, 0, 10,
-		    unit->Player, unit->X, unit->Y, &x, &y)) {
+	    if (!FindTerrainType(UnitMovementMask(unit), MapFieldForest, 0, 16,
+		    unit->Player, unit->Orders->X, unit->Orders->Y, &x, &y)) {
 		DebugLevel3Fn("No wood in range\n");
 		return -1;
 	    } else {
diff --git a/src/include/stratagus.h b/src/include/stratagus.h
index c4ad9e743..1b3bb884c 100644
--- a/src/include/stratagus.h
+++ b/src/include/stratagus.h
@@ -326,7 +326,6 @@ extern char NameLine[];
 #endif
 
 #define MAGIC_FOR_NEW_UNITS	33	/// How many percent of max mana for new units
-#define DEMOLISH_DAMAGE		400	/// Damage for demolish attack
 
 /*----------------------------------------------------------------------------
 --	Some limits
diff --git a/src/stratagus/missile.cpp b/src/stratagus/missile.cpp
index 1c4d26245..7030245ca 100644
--- a/src/stratagus/missile.cpp
+++ b/src/stratagus/missile.cpp
@@ -782,6 +782,7 @@ global int FindAndSortMissiles(const Viewport* vp, Missile** table)
 **	@param missile	Missile pointer.
 **	@param dx	Delta in x.
 **	@param dy	Delta in y.
+**	@internal We have : SpriteFrame / (2 * (Numdirection - 1)) == DirectionToHeading / 256.
 */
 local void MissileNewHeadingFromXY(Missile* missile, int dx, int dy)
 {
@@ -790,21 +791,26 @@ local void MissileNewHeadingFromXY(Missile* missile, int dx, int dy)
 
     DebugCheck(missile == NULL);
     DebugCheck(missile->Type == NULL);
+    DebugCheck(!(missile->Type->NumDirections & 1)); // Only support for impair number of directions.
+    if (missile->Type->NumDirections == 1 || (dx == 0 && dy == 0)) {
+        return ;
+    }
+// reinitialise the direction but with skipping Animation step.
     if (missile->SpriteFrame < 0) {
 	missile->SpriteFrame = -missile->SpriteFrame;
     }
     missile->SpriteFrame /= missile->Type->NumDirections / 2 + 1;
     missile->SpriteFrame *= missile->Type->NumDirections / 2 + 1;
 
-    nextdir = 256 / missile->Type->NumDirections;
+    nextdir = 128 / (missile->Type->NumDirections - 1);
     DebugCheck(nextdir == 0);
-    dir = ((DirectionToHeading(dx, dy) + nextdir / 2) & 0xFF) / nextdir;
-    if (dir <= LookingS / nextdir) {	// north->east->south
-	missile->SpriteFrame += dir;
-    } else {
-	missile->SpriteFrame += 256 / nextdir - dir;
-	missile->SpriteFrame = -missile->SpriteFrame;
+    dir = ((DirectionToHeading(10 * dx, 10 * dy) + nextdir / 2) & 0xFF) / nextdir;
+    if (dir >= missile->Type->NumDirections) {
+        dir -= (missile->Type->NumDirections - 1) * 2;
     }
+    DebugCheck(dir >= missile->Type->NumDirections);
+    DebugCheck(dir < -missile->Type->NumDirections + 1);
+    missile->SpriteFrame = dir;
 }
 /**
 **	Init the move.
@@ -817,15 +823,15 @@ local int MissileInitMove(Missile* missile)
     int dy;
 
     DebugCheck(missile == 0);
+    dx = missile->DX - missile->X;
+    dy = missile->DY - missile->Y;
+    MissileNewHeadingFromXY(missile, dx, dy);
     if (!(missile->State & 1)) {
-        dx = missile->DX - missile->X;
-        dy = missile->DY - missile->Y;
         missile->CurrentStep = 0;
         missile->TotalStep = 0;
         if (dx == 0 && dy == 0) {
             return 1;
         }
-        MissileNewHeadingFromXY(missile, dx, dy);
 	// initialize
         missile->TotalStep = MapDistance(missile->SourceX, missile->SourceY, missile->DX, missile->DY);
         missile->State++;
diff --git a/src/stratagus/script_missile.cpp b/src/stratagus/script_missile.cpp
index c54fc5f3f..505627590 100644
--- a/src/stratagus/script_missile.cpp
+++ b/src/stratagus/script_missile.cpp
@@ -88,7 +88,7 @@ local SCM CclDefineMissileType(SCM list)
 	mtype = NewMissileTypeSlot(str);	// str consumed!
     }
 
-    mtype->NumDirections = 8;
+    mtype->NumDirections = 1;
     //
     //	Parse the arguments, already the new tagged format.
     //
diff --git a/src/ui/menus.cpp b/src/ui/menus.cpp
index 2c32b31da..38d124fd7 100644
--- a/src/ui/menus.cpp
+++ b/src/ui/menus.cpp
@@ -7184,6 +7184,10 @@ local void InitPlayerRaces(Menuitem *mi)
 	}
     }
     ++n;
+    //  Reallocate pulldown options.
+    if (mi->d.pulldown.options) {
+	free (mi->d.pulldown.options);
+    }
     mi->d.pulldown.options = (unsigned char **)malloc(n * sizeof(unsigned char *));
     for (i = 0, n = 0; i < PlayerRaces.Count; ++i) {
 	if (PlayerRaces.Visible[i]) {
diff --git a/src/ui/script_ui.cpp b/src/ui/script_ui.cpp
index 67bc927e2..ae9f0fcf1 100644
--- a/src/ui/script_ui.cpp
+++ b/src/ui/script_ui.cpp
@@ -292,6 +292,7 @@ local SCM CclSetTitleScreen(SCM list)
     if (TitleScreen) {
 	for (i = 0; TitleScreen[i]; ++i) {
 	    free(TitleScreen[i]);
+	    TitleScreen[i]=NULL;
 	}
     }
     if (!gh_null_p(list)) {
@@ -2267,6 +2268,9 @@ local SCM CclDefineMenuItem(SCM list)
 			    int i;
 
 			    n = item->d.pulldown.noptions = gh_length(value);
+			    if (item->d.pulldown.options) {
+			    	free(item->d.pulldown.options);
+			    }
 			    item->d.pulldown.options = (unsigned char**)malloc(sizeof(unsigned char*)*n);
 			    for (i = 0; i < n; ++i) {
 				item->d.pulldown.options[i] = gh_scm2newstr(gh_car(value), NULL);
@@ -2802,9 +2806,7 @@ local SCM CclDefineButton(SCM list)
 	    } else if (gh_eq_p(value, gh_symbol2scm("cancel-build"))) {
 		ba.Action = ButtonCancelBuild;
 	    } else {
-		s1 = gh_scm2newstr(value, NULL);
-		fprintf(stderr, "Unsupported action %s\n",s1);
-		free(s1);
+		errl("Unsupported button action ",value);
 	    }
 	} else if (gh_eq_p(value, gh_symbol2scm("value"))) {
 	    value = gh_car(list);
diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp
index be05d7239..065cec260 100644
--- a/src/ui/ui.cpp
+++ b/src/ui/ui.cpp
@@ -808,6 +808,14 @@ global void CleanUserInterface(void)
 	UI_Table = NULL;
     }
 
+    //	Free Title screen.
+    if (TitleScreen) {
+	for (i = 0; TitleScreen[i]; ++i) {
+	    free(TitleScreen[i]);
+	    TitleScreen[i]=NULL;
+	}
+    }
+
     // FIXME: Johns: Implement this correctly or we will lose memory!
     DebugLevel0Fn("FIXME: not completely written\n");
 
diff --git a/src/unit/unittype.cpp b/src/unit/unittype.cpp
index 682d5cfc0..d9cbbb7f9 100644
--- a/src/unit/unittype.cpp
+++ b/src/unit/unittype.cpp
@@ -1506,6 +1506,9 @@ global void CleanUnitTypes(void)
 	if (type->CorpseName) {
 	    free(type->CorpseName);
 	}
+	if (type->CanCastSpell) {
+	    free(type->CanCastSpell);
+	}
 
 	for (res = 0; res < MaxCosts; ++res) {
 	    if (type->ResInfo[res]) {