summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2007-07-09 18:53:43 +0000
committerrubidium <rubidium@openttd.org>2007-07-09 18:53:43 +0000
commitf183f465612b10ba67ca7a896a40a991749b81b5 (patch)
tree21dc250e63653de67cd14413a726db70f11a25d6
parentb1b26ddb79df38f22bd56724521b94e06b894e4d (diff)
downloadopenttd-f183f465612b10ba67ca7a896a40a991749b81b5.tar.xz
(svn r10490) -Codechange: add support for industries on non-flat surfaces.
-rw-r--r--src/industry_cmd.cpp90
-rw-r--r--src/newgrf_callbacks.h2
-rw-r--r--src/newgrf_industrytiles.cpp21
-rw-r--r--src/newgrf_industrytiles.h1
4 files changed, 71 insertions, 43 deletions
diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp
index 60e55a0a6..9fa957d03 100644
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -1165,7 +1165,7 @@ static const Town *CheckMultipleIndustryInTown(TileIndex tile, int type)
return t;
}
-static bool CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable *it, int type)
+static bool CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable *it, int type, bool *custom_shape_check = NULL)
{
_error_message = STR_0239_SITE_UNSUITABLE;
@@ -1186,55 +1186,60 @@ static bool CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable
if (!EnsureNoVehicle(cur_tile)) return false;
if (MayHaveBridgeAbove(cur_tile) && IsBridgeAbove(cur_tile)) return false;
+ const IndustryTileSpec *its = GetIndustryTileSpec(it->gfx);
IndustyBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
- if (ind_behav & INDUSTRYBEH_BUILT_ONWATER) {
- /* As soon as the tile is not water, bail out.
- * But that does not mean the search is over. You have
- * to make sure every tile of the industry will be only water*/
- if (!IsClearWaterTile(cur_tile)) return false;
+ if (HASBIT(its->callback_flags, CBM_INDT_SHAPE_CHECK)) {
+ if (custom_shape_check != NULL) *custom_shape_check = true;
+ if (!PerformIndustryTileSlopeCheck(cur_tile, its, it->gfx)) return false;
} else {
- Slope tileh;
+ if (ind_behav & INDUSTRYBEH_BUILT_ONWATER) {
+ /* As soon as the tile is not water, bail out.
+ * But that does not mean the search is over. You have
+ * to make sure every tile of the industry will be only water*/
+ if (!IsClearWaterTile(cur_tile)) return false;
+ } else {
+ Slope tileh;
- if (IsClearWaterTile(cur_tile)) return false;
+ if (IsClearWaterTile(cur_tile)) return false;
- tileh = GetTileSlope(cur_tile, NULL);
- if (IsSteepSlope(tileh)) return false;
+ tileh = GetTileSlope(cur_tile, NULL);
+ if (IsSteepSlope(tileh)) return false;
- if (_patches.land_generator != LG_TERRAGENESIS || !_generating_world) {
- /* It is almost impossible to have a fully flat land in TG, so what we
- * do is that we check if we can make the land flat later on. See
- * CheckIfCanLevelIndustryPlatform(). */
- if (tileh != SLOPE_FLAT) {
- Slope t;
- byte bits = GetIndustryTileSpec(it->gfx)->slopes_refused;
+ if (_patches.land_generator != LG_TERRAGENESIS || !_generating_world) {
+ /* It is almost impossible to have a fully flat land in TG, so what we
+ * do is that we check if we can make the land flat later on. See
+ * CheckIfCanLevelIndustryPlatform(). */
+ if (tileh != SLOPE_FLAT) {
+ Slope t;
+ byte bits = its->slopes_refused;
- if (bits & 0x10) return false;
+ if (bits & 0x10) return false;
- t = ComplementSlope(tileh);
+ t = ComplementSlope(tileh);
- if (bits & 1 && (t & SLOPE_NW)) return false;
- if (bits & 2 && (t & SLOPE_NE)) return false;
- if (bits & 4 && (t & SLOPE_SW)) return false;
- if (bits & 8 && (t & SLOPE_SE)) return false;
+ if (bits & 1 && (t & SLOPE_NW)) return false;
+ if (bits & 2 && (t & SLOPE_NE)) return false;
+ if (bits & 4 && (t & SLOPE_SW)) return false;
+ if (bits & 8 && (t & SLOPE_SE)) return false;
+ }
}
}
+ }
- if (ind_behav & INDUSTRYBEH_ONLY_INTOWN) {
- if (!IsTileType(cur_tile, MP_HOUSE)) {
- _error_message = STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS;
- return false;
- }
- } else {
- if (ind_behav & INDUSTRYBEH_ONLY_NEARTOWN) {
- if (!IsTileType(cur_tile, MP_HOUSE)) goto do_clear;
- } else {
-do_clear:
- if (CmdFailed(DoCommand(cur_tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR)))
- return false;
- }
+ if (ind_behav & INDUSTRYBEH_ONLY_INTOWN) {
+ if (!IsTileType(cur_tile, MP_HOUSE)) {
+ _error_message = STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS;
+ return false;
}
}
+ if (ind_behav & INDUSTRYBEH_ONLY_NEARTOWN) {
+ if (!IsTileType(cur_tile, MP_HOUSE)) goto do_clear;
+ } else {
+do_clear:
+ if (CmdFailed(DoCommand(cur_tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR)))
+ return false;
+ }
}
} while ((++it)->ti.x != -0x80);
@@ -1496,14 +1501,17 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, int type, const Ind
static Industry *CreateNewIndustryHelper(TileIndex tile, IndustryType type, uint32 flags, const IndustrySpec *indspec, uint itspec_index)
{
const IndustryTileTable *it = indspec->table[itspec_index];
+ bool custom_shape_check = false;
+
+ if (!CheckIfIndustryTilesAreFree(tile, it, type, &custom_shape_check)) return NULL;
+
if (HASBIT(GetIndustrySpec(type)->callback_flags, CBM_IND_LOCATION)) {
if (!CheckIfCallBackAllowsCreation(tile, type, itspec_index)) return NULL;
- /* TODO: what with things like quarries and other stuff that must not be on level ground? */
+ } else {
+ if (!_check_new_industry_procs[indspec->check_proc](tile)) return NULL;
}
- if (!CheckIfIndustryTilesAreFree(tile, it, type)) return NULL;
- if (_patches.land_generator == LG_TERRAGENESIS && _generating_world && !CheckIfCanLevelIndustryPlatform(tile, 0, it, type)) return NULL;
- if (!_check_new_industry_procs[indspec->check_proc](tile)) return NULL;
+ if (!custom_shape_check && _patches.land_generator == LG_TERRAGENESIS && _generating_world && !CheckIfCanLevelIndustryPlatform(tile, 0, it, type)) return NULL;
if (!CheckIfTooCloseToIndustry(tile, type)) return NULL;
const Town *t = CheckMultipleIndustryInTown(tile, type);
@@ -1516,7 +1524,7 @@ static Industry *CreateNewIndustryHelper(TileIndex tile, IndustryType type, uint
if (i == NULL) return NULL;
if (flags & DC_EXEC) {
- CheckIfCanLevelIndustryPlatform(tile, DC_EXEC, it, type);
+ if (!custom_shape_check) CheckIfCanLevelIndustryPlatform(tile, DC_EXEC, it, type);
DoCreateNewIndustry(i, tile, type, it, t, OWNER_NONE);
}
diff --git a/src/newgrf_callbacks.h b/src/newgrf_callbacks.h
index 27d468c66..25e5fb80d 100644
--- a/src/newgrf_callbacks.h
+++ b/src/newgrf_callbacks.h
@@ -121,7 +121,7 @@ enum CallbackID {
CBID_HOUSE_PRODUCE_CARGO = 0x2E, // not yet implemented
/* Called to determine if the given industry tile can be built on specific tile */
- CBID_INDTILE_SHAPE_CHECK = 0x2F, // not yet implemented
+ CBID_INDTILE_SHAPE_CHECK = 0x2F,
/* Called to determine the type (if any) of foundation to draw for industry tile */
CBID_INDUSTRY_DRAW_FOUNDATIONS = 0x30,
diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp
index a3f07242c..75e61f6ba 100644
--- a/src/newgrf_industrytiles.cpp
+++ b/src/newgrf_industrytiles.cpp
@@ -15,9 +15,11 @@
#include "newgrf_spritegroup.h"
#include "newgrf_callbacks.h"
#include "newgrf_industries.h"
+#include "newgrf_text.h"
#include "industry_map.h"
#include "clear_map.h"
#include "table/sprites.h"
+#include "table/strings.h"
#include "sprite.h"
/**
@@ -82,7 +84,7 @@ static uint32 IndustryTileGetVariable(const ResolverObject *object, byte variabl
case 0x44 : return (IsTileType(tile, MP_INDUSTRY)) ? GetIndustryAnimationState(tile) : 0;
/* Land info of nearby tiles */
- case 0x60 : return GetNearbyIndustryTileInformation(parameter, tile, inds->index);
+ case 0x60 : return GetNearbyIndustryTileInformation(parameter, tile, inds == NULL ? (IndustryID)INVALID_INDUSTRY : inds->index);
case 0x61 : {/* Animation stage of nearby tiles */
tile = GetNearbyTile(parameter, tile);
@@ -226,3 +228,20 @@ bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const Indus
return true;
}
}
+
+bool PerformIndustryTileSlopeCheck(TileIndex tile, const IndustryTileSpec *its, IndustryGfx gfx)
+{
+ uint16 callback_res = GetIndustryTileCallback(CBID_INDTILE_SHAPE_CHECK, 0, 0, gfx, NULL, tile);
+ if (its->grf_prop.grffile->grf_version < 7) {
+ return callback_res != 0;
+ }
+ if (callback_res != CALLBACK_FAILED) return true;
+
+ switch (callback_res) {
+ case 0x400: return true;
+ case 0x401: _error_message = STR_0239_SITE_UNSUITABLE; return false;
+ case 0x402: _error_message = STR_0317_CAN_ONLY_BE_BUILT_IN_RAINFOREST; return false;
+ case 0x403: _error_message = STR_0318_CAN_ONLY_BE_BUILT_IN_DESERT; return false;
+ default: _error_message = GetGRFStringID(its->grf_prop.grffile->grfid, 0xD000 + callback_res); return false;
+ }
+}
diff --git a/src/newgrf_industrytiles.h b/src/newgrf_industrytiles.h
index 648c165e1..9495aa202 100644
--- a/src/newgrf_industrytiles.h
+++ b/src/newgrf_industrytiles.h
@@ -7,5 +7,6 @@
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);
+bool PerformIndustryTileSlopeCheck(TileIndex tile, const IndustryTileSpec *its, IndustryGfx gfx);
#endif /* NEWGRF_INDUSTRYTILES_H */