From b5c35acaae4978217e8410c2bc4e4d328bbf676f Mon Sep 17 00:00:00 2001
From: n0body <>
Date: Sun, 9 Nov 2003 02:42:05 +0000
Subject: [PATCH] Removed DrawBuilding, merged it with DrawUnit. This was long
 overdue.

---
 doc/scripts/unittype.html    |   4 ++
 src/include/unit.h           |   1 -
 src/include/unittype.h       |   7 +-
 src/stratagus/mainloop.cpp   |  12 +---
 src/unit/script_unittype.cpp |   2 +
 src/unit/unit.cpp            |   2 +-
 src/unit/unit_draw.cpp       | 129 ++++++++++++-----------------------
 src/unit/unittype.cpp        |   9 ++-
 src/video/cursor.cpp         |   2 +-
 9 files changed, 66 insertions(+), 102 deletions(-)

diff --git a/doc/scripts/unittype.html b/doc/scripts/unittype.html
index b12ce3c63..9aa667f92 100644
--- a/doc/scripts/unittype.html
+++ b/doc/scripts/unittype.html
@@ -417,6 +417,10 @@ It's followed by a list of accepted resource identifiers. F.E. can-store '(stone
 <dt>building</dt>
 <dd>Unit is a building, and imobile. Available as a spell target check.
 </dd>
+<dt>visible-under-fow</dt>
+<dd>Unit remains visible under fog of war. In most games this is true for and only for
+buildings.
+</dd>
 <dt>shore-building</dt>
 <dd>Unit is a shore building, and imobile. This is used for those unique buildings
 that have to be build on sea and have at least one point on coast.
diff --git a/src/include/unit.h b/src/include/unit.h
index 9c6d9b4d3..86af6d1fe 100644
--- a/src/include/unit.h
+++ b/src/include/unit.h
@@ -923,7 +923,6 @@ extern void DrawShadow(const Unit* unit, const UnitType* type, int frame,
     int x, int y);
     /// Draw A single Unit
 extern void DrawUnit(const Unit* unit);
-extern void DrawBuilding(const Unit* unit);
     /// Draw all units visible on map in viewport
 extern int FindAndSortUnits(const Viewport* vp, Unit** table);
     /// Show an unit's orders.
diff --git a/src/include/unittype.h b/src/include/unittype.h
index 2c2875c92..bfdf98e14 100644
--- a/src/include/unittype.h
+++ b/src/include/unittype.h
@@ -306,6 +306,10 @@
 **
 **		Unit is a Building
 **
+**	UnitType::VisibileUnderFog
+**
+**		Unit is visible under fog of war.
+**
 **	UnitType::PermanentCloak
 **
 **		Unit is permanently cloaked.
@@ -725,6 +729,7 @@ struct _unit_type_ {
     unsigned SeaUnit : 1;		/// Sea animated
     unsigned ExplodeWhenKilled : 1;	/// Death explosion animated
     unsigned Building : 1;		/// Building
+    unsigned VisibleUnderFog : 1;	/// Unit is visible under fog of war.
     unsigned PermanentCloak : 1;	/// Is only visible by CloakDetectors.
     unsigned DetectCloak : 1;		/// Can see Cloaked units.
     unsigned Coward : 1;		/// Unit will only attack if instructed.
@@ -820,7 +825,7 @@ extern void SaveUnitTypeDefs(CLFile* file);		/// Declare the unit-type table fir
 extern void SaveUnitTypes(CLFile* file);		/// Save the unit-type table
 extern UnitType* NewUnitTypeSlot(char*);		/// Allocate an empty unit-type slot
     /// Draw the sprite frame of unit-type
-extern void DrawUnitType(const UnitType* type,int frame,int x,int y);
+extern void DrawUnitType(const UnitType* type, Graphic* sprite, int frame, int x, int y);
 
 extern void InitUnitTypes(int reset_player_stats);	/// Init unit-type table
 extern void LoadUnitTypes(void);			/// Load the unit-type data
diff --git a/src/stratagus/mainloop.cpp b/src/stratagus/mainloop.cpp
index 8570235a4..4b5e7e771 100644
--- a/src/stratagus/mainloop.cpp
+++ b/src/stratagus/mainloop.cpp
@@ -423,11 +423,7 @@ local void DrawMapViewport(Viewport* vp)
 	while (i < nunits && j < nmissiles) {
 	    if (table[i]->Type->DrawLevel <= missiletable[j]->Type->DrawLevel) {
 		if (UnitVisibleInViewport(vp, table[i])) {
-		    if (table[i]->Type->Building) {
-			DrawBuilding(table[i]);
-		    } else {
-			DrawUnit(table[i]);
-		    }
+		    DrawUnit(table[i]);
 		}
 		++i;
 	    } else {
@@ -452,11 +448,7 @@ local void DrawMapViewport(Viewport* vp)
 	}
 	for (; i < nunits; ++i) {
 	    if (UnitVisibleInViewport(vp, table[i])) {
-		if (table[i]->Type->Building) {
-		    DrawBuilding(table[i]);
-		} else {
-		    DrawUnit(table[i]);
-		}
+		DrawUnit(table[i]);
 	    }
 	}
 	for (; j < nmissiles; ++j) {
diff --git a/src/unit/script_unittype.cpp b/src/unit/script_unittype.cpp
index 276315094..2cefd2e21 100644
--- a/src/unit/script_unittype.cpp
+++ b/src/unit/script_unittype.cpp
@@ -423,6 +423,8 @@ 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("visible-under-fog"))) {
+	    type->VisibleUnderFog = 1;
 	} else if (gh_eq_p(value, gh_symbol2scm("builder-outside"))) {
 	    type->BuilderOutside = 1;
 	} else if (gh_eq_p(value, gh_symbol2scm("builder-lost"))) {
diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp
index 4582e2c7d..ca9d942ce 100644
--- a/src/unit/unit.cpp
+++ b/src/unit/unit.cpp
@@ -1215,7 +1215,7 @@ global int UnitVisibleInViewport(const Viewport* vp, const Unit* unit)
     for (; h-- > 0;) {
 	for (w = w0; w-- > 0;) {
 	    if (IsMapFieldVisible(ThisPlayer, x + w, y + h) || ReplayRevealMap ||
-		    (unit->Type->Building && unit->SeenFrame != UnitNotSeen &&
+		    (unit->Type->VisibleUnderFog && unit->SeenFrame != UnitNotSeen &&
 			IsMapFieldExplored(ThisPlayer, x + w, y + h))) {
 		return 1;
 	    }
diff --git a/src/unit/unit_draw.cpp b/src/unit/unit_draw.cpp
index dc78c26fb..a7e5e93a0 100644
--- a/src/unit/unit_draw.cpp
+++ b/src/unit/unit_draw.cpp
@@ -1742,7 +1742,7 @@ local void DrawConstruction(const Unit* unit, int frame, int x, int y)
 	x -= unit->Type->TileWidth * TileSizeX / 2;
 	y -= unit->Type->TileHeight * TileSizeY / 2;
 	GraphicUnitPixels(unit, unit->Type->Sprite);
-	DrawUnitType(unit->Type, frame, x, y);
+	DrawUnitType(unit->Type, unit->Type->Sprite, frame, x, y);
 #ifdef USE_OPENGL
 	DrawUnitPlayerColor(unit->Type, unit->Player->Player, frame, x, y);
 #endif
@@ -1762,23 +1762,27 @@ local void DrawConstruction(const Unit* unit, int frame, int x, int y)
 */
 
 /**
-**	Draw building on map.
+**	Draw unit on map.
 **
-**	@param unit	Pointer to the building
+**	@param unit	Pointer to the unit.
 */
-global void DrawBuilding(const Unit* unit)
+global void DrawUnit(const Unit* unit)
 {
     int x;
     int y;
-    const UnitType* type;
     int frame;
-    int visible;
     int state;
     int constructed;
+    Graphic* sprite;
+    ResourceInfo* resinfo;
+    const UnitType* type;
 
-    visible = BuildingVisibleOnMap(unit);
+    if (unit->Type->Revealer) {		// Revealers are not drawn
+	DebugLevel3Fn("Drawing revealer %d\n" _C_ UnitNumber(unit));
+	return;
+    }
 
-    if (ReplayRevealMap) {
+    if (ReplayRevealMap || !unit->Type->VisibleUnderFog) {
 	type = unit->Type;
 	frame = unit->Frame;
 	y = unit->IY;
@@ -1795,15 +1799,20 @@ global void DrawBuilding(const Unit* unit)
 	state = unit->SeenState;
     }
 
-    x += Map2ViewportX(CurrentViewport, unit->X);
-    y += Map2ViewportY(CurrentViewport, unit->Y);
-
     if (frame == UnitNotSeen) {
-	DebugLevel0Fn("FIXME: Something is wrong, unit %d not seen time %lu?.\n" _C_
+	DebugLevel0Fn("FIXME: Something is wrong, unit %d not seen but drawn time %lu?.\n" _C_
 	    unit->Slot _C_ GameCycle);
 	return;
     }
 
+#ifdef NEW_DECODRAW
+    if (!CurrentViewport) {
+	CurrentViewport = TheUI.SelectedViewport;
+    }
+#endif
+    x += Map2ViewportX(CurrentViewport, unit->X);
+    y += Map2ViewportY(CurrentViewport, unit->Y);
+
     if (state == 1 && constructed) {
 	DrawConstructionShadow(unit, frame, x, y);
     } else {
@@ -1815,7 +1824,27 @@ global void DrawBuilding(const Unit* unit)
     //
     DrawUnitSelection(unit);
 
+    GraphicUnitPixels(unit, type->Sprite);
+
     //
+    //	Adjust sprite for Harvesters.
+    //
+    sprite = type->Sprite;
+    if (type->Harvester && unit->CurrentResource) {
+	resinfo = type->ResInfo[unit->CurrentResource];
+	if (unit->Value) {
+	    if (resinfo->SpriteWhenLoaded) {
+		sprite = resinfo->SpriteWhenLoaded;
+	    }
+	} else {
+	    if (resinfo->SpriteWhenEmpty) {
+		sprite = resinfo->SpriteWhenEmpty;
+	    }
+	}
+    }
+
+    //
+    //	Now draw!
     //	Buildings under construction/upgrade/ready.
     //
     if (state == 1) {
@@ -1830,90 +1859,20 @@ global void DrawBuilding(const Unit* unit)
     } else if (state == 2) {
 	// FIXME: this frame is hardcoded!!!
 	GraphicUnitPixels(unit, type->Sprite);
-	DrawUnitType(type, frame < 0 ? -1 : 1, x, y);
+	DrawUnitType(type, sprite, frame < 0 ? -1 : 1, x, y);
 #ifdef USE_OPENGL
 	DrawUnitPlayerColor(type, unit->Player->Player,
 	    frame < 0 ? -1 : 1, x, y);
 #endif
     } else {
-	GraphicUnitPixels(unit, type->Sprite);
-	DrawUnitType(type, frame, x, y);
+	DrawUnitType(type, sprite, frame, x, y);
 #ifdef USE_OPENGL
 	DrawUnitPlayerColor(type, unit->Player->Player, frame, x, y);
 #endif
     }
 
-    // FIXME: johns: ugly check here, should be removed!
-    if (visible || ReplayRevealMap) {
-	DrawInformations(unit, type, x, y);
-    }
-}
-
-/**
-**	Draw unit on map.
-**
-**	@param unit	Pointer to the unit.
-*/
-global void DrawUnit(const Unit* unit)
-{
-    int x;
-    int y;
-    Graphic* sprite;
-    ResourceInfo* resinfo;
-    const UnitType* type;
-
-    if (unit->Type->Revealer) {		// Revealers are not drawn
-	DebugLevel3Fn("Drawing revealer %d\n" _C_ UnitNumber(unit));
-	return;
-    }
-
-#ifdef NEW_DECODRAW
-    if (!CurrentViewport) {
-	CurrentViewport = TheUI.SelectedViewport;
-    }
-#endif
-    x = Map2ViewportX(CurrentViewport, unit->X) + unit->IX;
-    y = Map2ViewportY(CurrentViewport, unit->Y) + unit->IY;
-
-    type = unit->Type;
-
-    DrawShadow(unit, NULL, unit->Frame, x, y);
-
-    //
-    //	Show that the unit is selected
-    //
-    DrawUnitSelection(unit);
-
-    GraphicUnitPixels(unit, type->Sprite);
-
-    sprite = type->Sprite;
-    if (type->Harvester && unit->CurrentResource) {
-	resinfo = type->ResInfo[unit->CurrentResource];
-	if (unit->Value) {
-	    if (resinfo->SpriteWhenLoaded) {
-		sprite = resinfo->SpriteWhenLoaded;
-	    }
-	} else {
-	    if (resinfo->SpriteWhenEmpty) {
-		sprite = resinfo->SpriteWhenEmpty;
-	    }
-	}
-    }
-    if (unit->Frame < 0) {
-	VideoDrawClipX(sprite, -unit->Frame,
-	    x - (type->Width - type->TileWidth * TileSizeX) / 2,
-	    y - (type->Height - type->TileHeight * TileSizeY) / 2);
-    } else {
-	VideoDrawClip(sprite, unit->Frame,
-	    x - (type->Width - type->TileWidth * TileSizeX) / 2,
-	    y - (type->Height - type->TileHeight * TileSizeY) / 2);
-    }
-#ifdef USE_OPENGL
-    DrawUnitPlayerColor(type, unit->Player->Player, unit->Frame, x, y);
-#endif
-
 #ifndef NEW_DECODRAW
-// Unit's extras not fully supported.. need to be decorations themselves.
+    // Unit's extras not fully supported.. need to be decorations themselves.
     DrawInformations(unit, type, x, y);
 #endif
 }
diff --git a/src/unit/unittype.cpp b/src/unit/unittype.cpp
index fbc46cb04..6121073c6 100644
--- a/src/unit/unittype.cpp
+++ b/src/unit/unittype.cpp
@@ -917,6 +917,9 @@ local void SaveUnitType(CLFile* file, const UnitType* type, int all)
     if (type->Building) {
 	CLprintf(file, "  'building");
     }
+    if (type->VisibleUnderFog) {
+	CLprintf(file, "  'visible-under-fog");
+    }
     if (type->BuilderOutside) {
 	CLprintf(file, "  'builder-outside");
     }
@@ -1300,7 +1303,7 @@ global UnitType* NewUnitTypeSlot(char* ident)
 **	@todo	Do screen position caculation in high level.
 **		Better way to handle in x mirrored sprites.
 */
-global void DrawUnitType(const UnitType* type, int frame, int x, int y)
+global void DrawUnitType(const UnitType* type, Graphic* sprite, int frame, int x, int y)
 {
     // FIXME: move this calculation to high level.
     x -= (type->Width - type->TileWidth * TileSizeX) / 2;
@@ -1308,9 +1311,9 @@ global void DrawUnitType(const UnitType* type, int frame, int x, int y)
 
     // FIXME: This is a hack for mirrored sprites
     if (frame < 0) {
-	VideoDrawClipX(type->Sprite, -frame, x, y);
+	VideoDrawClipX(sprite, -frame, x, y);
     } else {
-	VideoDrawClip(type->Sprite, frame, x, y);
+	VideoDrawClip(sprite, frame, x, y);
     }
 }
 
diff --git a/src/video/cursor.cpp b/src/video/cursor.cpp
index b9e0118be..6f26ca557 100644
--- a/src/video/cursor.cpp
+++ b/src/video/cursor.cpp
@@ -727,7 +727,7 @@ local void DrawBuildingCursor(void)
     SetClipping(vp->X, vp->Y, vp->EndX, vp->EndY);
     DrawShadow(NULL, CursorBuilding, frame, x, y);
     GraphicPlayerPixels(ThisPlayer, CursorBuilding->Sprite);
-    DrawUnitType(CursorBuilding, frame, x, y);
+    DrawUnitType(CursorBuilding, CursorBuilding->Sprite, frame, x, y);
     PopClipping();
 
     //