(svn r10226) -Codechange: Add support for newindustry tiles drawing.
authorbelugas
Tue, 19 Jun 2007 17:33:12 +0000
changeset 6970 b489d8ec5d4a
parent 6969 3d6722f0e3bd
child 6971 6dd4632b7c1d
(svn r10226) -Codechange: Add support for newindustry tiles drawing.
Heavily based on Maedhros's newhouses implementation
src/industry_cmd.cpp
src/newgrf_industrytiles.cpp
src/newgrf_industrytiles.h
--- a/src/industry_cmd.cpp	Tue Jun 19 17:32:01 2007 +0000
+++ b/src/industry_cmd.cpp	Tue Jun 19 17:33:12 2007 +0000
@@ -30,6 +30,8 @@
 #include "water_map.h"
 #include "tree_map.h"
 #include "cargotype.h"
+#include "newgrf_industrytiles.h"
+#include "newgrf_callbacks.h"
 
 void ShowIndustryViewWindow(int industry);
 void BuildOilRig(TileIndex tile);
@@ -241,18 +243,32 @@
 
 static void DrawTile_Industry(TileInfo *ti)
 {
-	const IndustryGfx gfx = GetIndustryGfx(ti->tile);
-	const Industry *ind;
+	IndustryGfx gfx = GetIndustryGfx(ti->tile);
+	Industry *ind = GetIndustryByTile(ti->tile);
+	const IndustryTileSpec *indts = GetIndustryTileSpec(gfx);
 	const DrawBuildingsTileStruct *dits;
 	byte z;
 	SpriteID image;
 	SpriteID pal;
 
-	/* Pointer to industry */
-	ind = GetIndustryByTile(ti->tile);
+	/* Retrieve pointer to the draw industry tile struct */
+	if (gfx >= NEW_INDUSTRYTILEOFFSET) {
+		/* Draw the tile using the specialized method of newgrf industrytile.
+		 * DrawNewIndustry will return false if ever the resolver could not
+		 * find any sprite to display.  So in this case, we will jump on the
+		 * substitute gfx instead. */
+		if (indts->grf_prop.spritegroup != NULL && DrawNewIndustryTile(ti, ind, gfx, indts)) {
+			return;
+		} else {
+			/* No sprite group (or no valid one) found, meaning no graphics associated.
+			 * Use the substitute one instead */
+			gfx = indts->grf_prop.subst_id;
+			/* And point the industrytile spec accordingly */
+			indts = GetIndustryTileSpec(indts->grf_prop.subst_id);
+		}
+	}
 
-	/* Retrieve pointer to the draw industry tile struct */
-	dits = &_industry_draw_tile_data[gfx << 2 | (GetIndustryTileSpec(gfx)->anim_state ?
+	dits = &_industry_draw_tile_data[gfx << 2 | (indts->anim_state ?
 			GetIndustryAnimationState(ti->tile) & 3 :
 			GetIndustryConstructionStage(ti->tile))];
 
--- a/src/newgrf_industrytiles.cpp	Tue Jun 19 17:32:01 2007 +0000
+++ b/src/newgrf_industrytiles.cpp	Tue Jun 19 17:33:12 2007 +0000
@@ -143,6 +143,44 @@
 	res->reseed          = 0;
 }
 
+void IndustryDrawTileLayout(const TileInfo *ti, const SpriteGroup *group, byte rnd_color, byte stage, IndustryGfx gfx)
+{
+	const DrawTileSprites *dts = group->g.layout.dts;
+	const DrawTileSeqStruct *dtss;
+
+	SpriteID image = dts->ground_sprite;
+	SpriteID pal   = dts->ground_pal;
+
+	if (GB(image, 0, SPRITE_WIDTH) != 0) DrawGroundSprite(image, pal);
+
+	foreach_draw_tile_seq(dtss, dts->seq) {
+		if (GB(dtss->image, 0, SPRITE_WIDTH) == 0) continue;
+
+		image = dtss->image + stage;
+		pal   = dtss->pal;
+
+		if (!HASBIT(image, SPRITE_MODIFIER_OPAQUE) && HASBIT(_transparent_opt, TO_INDUSTRIES)) {
+			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+			pal = PALETTE_TO_TRANSPARENT;
+		} else if (HASBIT(image, PALETTE_MODIFIER_COLOR)) {
+			pal = GENERAL_SPRITE_COLOR(rnd_color);
+		} else {
+			pal = PAL_NONE;
+		}
+
+		if ((byte)dtss->delta_z != 0x80) {
+			AddSortableSpriteToDraw(
+				image, pal,
+				ti->x + dtss->delta_x, ti->y + dtss->delta_y,
+				dtss->size_x, dtss->size_y,
+				dtss->size_z, ti->z + dtss->delta_z
+			);
+		} else {
+			AddChildSpriteScreen(image, pal, dtss->delta_x, dtss->delta_y);
+		}
+	}
+}
+
 uint16 GetIndustryTileCallback(uint16 callback, uint32 param1, uint32 param2, IndustryGfx gfx_id, Industry *industry, TileIndex tile)
 {
 	ResolverObject object;
@@ -158,3 +196,33 @@
 
 	return group->g.callback.result;
 }
+
+bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const IndustryTileSpec *inds)
+{
+	const SpriteGroup *group;
+	ResolverObject object;
+
+	if (ti->tileh != SLOPE_FLAT) {
+		bool draw_old_one = true;
+		if (HASBIT(inds->callback_flags, CBM_INDT_DRAW_FOUNDATIONS)) {
+			/* Called to determine the type (if any) of foundation to draw for industry tile */
+			uint32 callback_res = GetIndustryTileCallback(CBID_INDUSTRY_DRAW_FOUNDATIONS, 0, 0, gfx, i, ti->tile);
+			draw_old_one = callback_res == 0 || callback_res == CALLBACK_FAILED;
+		}
+
+		if (draw_old_one) DrawFoundation(ti, ti->tileh);
+	}
+
+	NewIndustryTileResolver(&object, gfx, ti->tile, i);
+
+	group = Resolve(inds->grf_prop.spritegroup, &object);
+	if (group == NULL || group->type != SGT_TILELAYOUT) {
+		return false;
+	} else {
+		/* Limit the building stage to the number of stages supplied. */
+		byte stage = GetIndustryConstructionStage(ti->tile);
+		stage = clamp(stage - 4 + group->g.layout.num_sprites, 0, group->g.layout.num_sprites - 1);
+		IndustryDrawTileLayout(ti, group, i->random_color, stage, gfx);
+		return true;
+	}
+}
--- a/src/newgrf_industrytiles.h	Tue Jun 19 17:32:01 2007 +0000
+++ b/src/newgrf_industrytiles.h	Tue Jun 19 17:33:12 2007 +0000
@@ -5,7 +5,7 @@
 #ifndef NEWGRF_INDUSTRYTILES_H
 #define NEWGRF_INDUSTRYTILES_H
 
-void DrawNewIndustryTile(TileInfo *ti, IndustryGfx gfx);
+bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const IndustryTileSpec *inds);
 uint16 GetIndustryTileCallback(uint16 callback, uint32 param1, uint32 param2, IndustryGfx gfx_id, Industry *industry, TileIndex tile);
 
 #endif /* NEWGRF_INDUSTRYTILES_H */