@@ -1176,13 +1176,29 @@ static const Town *CheckMultipleIndustry
}
return t;
static bool CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable *it, int type, bool *custom_shape_check = NULL)
bool IsSlopeRefused(Slope current, Slope refused)
{
if (current != SLOPE_FLAT) {
if (refused & SLOPE_STEEP) return true;
Slope t = ComplementSlope(current);
if (refused & 1 && (t & SLOPE_NW)) return false;
if (refused & 2 && (t & SLOPE_NE)) return false;
if (refused & 4 && (t & SLOPE_SW)) return false;
if (refused & 8 && (t & SLOPE_SE)) return false;
return false;
static bool CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable *it, uint itspec_index, int type, bool *custom_shape_check = NULL)
_error_message = STR_0239_SITE_UNSUITABLE;
do {
IndustryGfx gfx = GetTranslatedIndustryTileID(it->gfx);
TileIndex cur_tile = tile + ToTileIndexDiff(it->ti);
@@ -1204,13 +1220,13 @@ static bool CheckIfIndustryTilesAreFree(
const IndustryTileSpec *its = GetIndustryTileSpec(gfx);
IndustyBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
if (HASBIT(its->callback_flags, CBM_INDT_SHAPE_CHECK)) {
if (custom_shape_check != NULL) *custom_shape_check = true;
if (!PerformIndustryTileSlopeCheck(cur_tile, its, type, gfx)) return false;
if (!PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, itspec_index)) return false;
} else {
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;
@@ -1223,25 +1239,13 @@ static bool CheckIfIndustryTilesAreFree(
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 = its->slopes_refused;
if (bits & 0x10) return false;
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 (IsSlopeRefused(tileh, its->slopes_refused)) return false;
if (ind_behav & INDUSTRYBEH_ONLY_INTOWN) {
if (!IsTileType(cur_tile, MP_HOUSE)) {
@@ -1538,13 +1542,13 @@ static void DoCreateNewIndustry(Industry
*/
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 (!CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, &custom_shape_check)) return NULL;
if (HASBIT(GetIndustrySpec(type)->callback_flags, CBM_IND_LOCATION)) {
if (!CheckIfCallBackAllowsCreation(tile, type, itspec_index)) return NULL;
if (!_check_new_industry_procs[indspec->check_proc](tile)) return NULL;
@@ -1579,13 +1583,12 @@ static Industry *CreateNewIndustryHelper
* @return index of the newly create industry, or CMD_ERROR if it failed
CommandCost CmdBuildIndustry(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
int num;
const IndustryTileTable * const *itt;
const IndustryTileTable *it;
const IndustrySpec *indspec;
SET_EXPENSES_TYPE(EXPENSES_OTHER);
indspec = GetIndustrySpec(p1);
@@ -1623,13 +1626,13 @@ CommandCost CmdBuildIndustry(TileIndex t
num = indspec->num_table;
itt = indspec->table;
if (--num < 0) return_cmd_error(STR_0239_SITE_UNSUITABLE);
} while (!CheckIfIndustryTilesAreFree(tile, it = itt[num], p1));
} while (!CheckIfIndustryTilesAreFree(tile, itt[num], num, p1));
if (CreateNewIndustryHelper(tile, p1, flags, indspec, num) == NULL) return CMD_ERROR;
return CommandCost(indspec->GetConstructionCost());
@@ -244,24 +244,29 @@ bool DrawNewIndustryTile(TileInfo *ti, I
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;
bool PerformIndustryTileSlopeCheck(TileIndex tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx)
extern bool IsSlopeRefused(Slope current, Slope refused);
bool PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, uint itspec_index)
Industry ind;
ind.xy = 0;
ind.index = INVALID_INDUSTRY;
ind.xy = ind_base_tile;
ind.width = 0;
ind.type = type;
uint16 callback_res = GetIndustryTileCallback(CBID_INDTILE_SHAPE_CHECK, 0, 0, gfx, &ind, tile);
uint16 callback_res = GetIndustryTileCallback(CBID_INDTILE_SHAPE_CHECK, 0, itspec_index, gfx, &ind, ind_tile);
if (callback_res == CALLBACK_FAILED) {
return !IsSlopeRefused(GetTileSlope(ind_tile, NULL), its->slopes_refused);
if (its->grf_prop.grffile->grf_version < 7) {
return callback_res != 0;
if (callback_res == CALLBACK_FAILED) return false;
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;
@@ -12,13 +12,13 @@ enum IndustryAnimationTrigger {
IAT_INDUSTRY_RECEIVED_CARGO,
IAT_INDUSTRY_DISTRIBUTES_CARGO,
};
bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const IndustryTileSpec *inds);
uint16 GetIndustryTileCallback(CallbackID callback, uint32 param1, uint32 param2, IndustryGfx gfx_id, Industry *industry, TileIndex tile);
bool PerformIndustryTileSlopeCheck(TileIndex tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx);
bool PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, uint itspec_index);
void AnimateNewIndustryTile(TileIndex tile);
bool StartStopIndustryTileAnimation(TileIndex tile, IndustryAnimationTrigger iat, uint32 random = Random());
bool StartStopIndustryTileAnimation(const Industry *ind, IndustryAnimationTrigger iat);
#endif /* NEWGRF_INDUSTRYTILES_H */
Status change: