|
@@ -1366,192 +1366,197 @@ static bool CheckIfCanLevelIndustryPlatf
|
|
|
while (curh != h) {
|
|
|
/* We give the terraforming for free here, because we can't calculate
|
|
|
* exact cost in the test-round, and as we all know, that will cause
|
|
|
* a nice assert if they don't match ;) */
|
|
|
DoCommand(tile_walk, SLOPE_N, (curh > h) ? 0 : 1, flags, CMD_TERRAFORM_LAND);
|
|
|
curh += (curh > h) ? -1 : 1;
|
|
|
}
|
|
|
} END_TILE_LOOP(tile_walk, size_x, size_y, cur_tile)
|
|
|
}
|
|
|
|
|
|
_current_player = old_player;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
|
|
|
static bool CheckIfTooCloseToIndustry(TileIndex tile, int type)
|
|
|
{
|
|
|
const IndustrySpec *indspec = GetIndustrySpec(type);
|
|
|
const Industry *i;
|
|
|
|
|
|
/* accepting industries won't be close, not even with patch */
|
|
|
if (_patches.same_industry_close && indspec->accepts_cargo[0] == CT_INVALID)
|
|
|
return true;
|
|
|
|
|
|
FOR_ALL_INDUSTRIES(i) {
|
|
|
/* check if an industry that accepts the same goods is nearby */
|
|
|
if (DistanceMax(tile, i->xy) <= 14 &&
|
|
|
indspec->accepts_cargo[0] != CT_INVALID &&
|
|
|
indspec->accepts_cargo[0] == i->accepts_cargo[0] && (
|
|
|
_game_mode != GM_EDITOR ||
|
|
|
!_patches.same_industry_close ||
|
|
|
!_patches.multiple_industry_per_town
|
|
|
)) {
|
|
|
_error_message = STR_INDUSTRY_TOO_CLOSE;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
/* check "not close to" field. */
|
|
|
if ((i->type == indspec->conflicting[0] || i->type == indspec->conflicting[1] || i->type == indspec->conflicting[2]) &&
|
|
|
DistanceMax(tile, i->xy) <= 14) {
|
|
|
_error_message = STR_INDUSTRY_TOO_CLOSE;
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
static void DoCreateNewIndustry(Industry *i, TileIndex tile, int type, const IndustryTileTable *it, byte layout, const Town *t, Owner owner)
|
|
|
{
|
|
|
const IndustrySpec *indspec = GetIndustrySpec(type);
|
|
|
uint32 r;
|
|
|
uint j;
|
|
|
|
|
|
i->xy = tile;
|
|
|
i->width = i->height = 0;
|
|
|
i->type = type;
|
|
|
IncIndustryTypeCount(type);
|
|
|
|
|
|
i->produced_cargo[0] = indspec->produced_cargo[0];
|
|
|
i->produced_cargo[1] = indspec->produced_cargo[1];
|
|
|
i->accepts_cargo[0] = indspec->accepts_cargo[0];
|
|
|
i->accepts_cargo[1] = indspec->accepts_cargo[1];
|
|
|
i->accepts_cargo[2] = indspec->accepts_cargo[2];
|
|
|
i->production_rate[0] = indspec->production_rate[0];
|
|
|
i->production_rate[1] = indspec->production_rate[1];
|
|
|
|
|
|
if (_patches.smooth_economy) {
|
|
|
i->production_rate[0] = min((RandomRange(256) + 128) * i->production_rate[0] >> 8 , 255);
|
|
|
i->production_rate[1] = min((RandomRange(256) + 128) * i->production_rate[1] >> 8 , 255);
|
|
|
}
|
|
|
|
|
|
i->town = t;
|
|
|
i->owner = owner;
|
|
|
|
|
|
r = Random();
|
|
|
i->random_color = GB(r, 8, 4);
|
|
|
i->counter = GB(r, 0, 12);
|
|
|
i->produced_cargo_waiting[0] = 0;
|
|
|
i->produced_cargo_waiting[1] = 0;
|
|
|
i->incoming_cargo_waiting[0] = 0;
|
|
|
i->incoming_cargo_waiting[1] = 0;
|
|
|
i->incoming_cargo_waiting[2] = 0;
|
|
|
i->this_month_production[0] = 0;
|
|
|
i->this_month_production[1] = 0;
|
|
|
i->this_month_transported[0] = 0;
|
|
|
i->this_month_transported[1] = 0;
|
|
|
i->last_month_pct_transported[0] = 0;
|
|
|
i->last_month_pct_transported[1] = 0;
|
|
|
i->last_month_transported[0] = 0;
|
|
|
i->last_month_transported[1] = 0;
|
|
|
i->was_cargo_delivered = false;
|
|
|
i->last_prod_year = _cur_year;
|
|
|
i->last_month_production[0] = i->production_rate[0] * 8;
|
|
|
i->last_month_production[1] = i->production_rate[1] * 8;
|
|
|
i->founder = _current_player;
|
|
|
|
|
|
if (HASBIT(indspec->callback_flags, CBM_IND_DECIDE_COLOUR)) {
|
|
|
uint16 res = GetIndustryCallback(CBID_INDUSTRY_DECIDE_COLOUR, 0, 0, i, type, INVALID_TILE);
|
|
|
if (res != CALLBACK_FAILED) i->random_color = GB(res, 0, 4);
|
|
|
}
|
|
|
|
|
|
if (HASBIT(indspec->callback_flags, CBM_IND_INPUT_CARGO_TYPES)) {
|
|
|
for (j = 0; j < lengthof(i->accepts_cargo); j++) i->accepts_cargo[j] = CT_INVALID;
|
|
|
for (j = 0; j < lengthof(i->accepts_cargo); j++) {
|
|
|
uint16 res = GetIndustryCallback(CBID_INDUSTRY_INPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE);
|
|
|
if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
|
|
|
i->accepts_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (HASBIT(indspec->callback_flags, CBM_IND_OUTPUT_CARGO_TYPES)) {
|
|
|
for (j = 0; j < lengthof(i->produced_cargo); j++) i->produced_cargo[j] = CT_INVALID;
|
|
|
for (j = 0; j < lengthof(i->produced_cargo); j++) {
|
|
|
uint16 res = GetIndustryCallback(CBID_INDUSTRY_OUTPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE);
|
|
|
if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
|
|
|
i->produced_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
i->construction_date = _date;
|
|
|
i->construction_type = (_game_mode == GM_EDITOR) ? ICT_SCENARIO_EDITOR :
|
|
|
(_generating_world ? ICT_MAP_GENERATION : ICT_NORMAL_GAMEPLAY);
|
|
|
|
|
|
/* Adding 1 here makes it conform to specs of var44 of varaction2 for industries
|
|
|
* 0 = created prior of newindustries
|
|
|
* else, chosen layout + 1 */
|
|
|
i->selected_layout = layout + 1;
|
|
|
|
|
|
if (!_generating_world) i->last_month_production[0] = i->last_month_production[1] = 0;
|
|
|
|
|
|
i->prod_level = 0x10;
|
|
|
|
|
|
do {
|
|
|
TileIndex cur_tile = tile + ToTileIndexDiff(it->ti);
|
|
|
|
|
|
if (it->gfx != GFX_WATERTILE_SPECIALCHECK) {
|
|
|
byte size;
|
|
|
|
|
|
size = it->ti.x;
|
|
|
if (size > i->width) i->width = size;
|
|
|
size = it->ti.y;
|
|
|
if (size > i->height)i->height = size;
|
|
|
|
|
|
DoCommand(cur_tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
|
|
|
|
|
|
MakeIndustry(cur_tile, i->index, it->gfx);
|
|
|
if (_generating_world) {
|
|
|
SetIndustryConstructionCounter(cur_tile, 3);
|
|
|
SetIndustryConstructionStage(cur_tile, 2);
|
|
|
}
|
|
|
}
|
|
|
} while ((++it)->ti.x != -0x80);
|
|
|
|
|
|
i->width++;
|
|
|
i->height++;
|
|
|
|
|
|
if (GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_PLANT_ON_BUILT) {
|
|
|
for (j = 0; j != 50; j++) PlantRandomFarmField(i);
|
|
|
}
|
|
|
_industry_sort_dirty = true;
|
|
|
InvalidateWindow(WC_INDUSTRY_DIRECTORY, 0);
|
|
|
}
|
|
|
|
|
|
/** Helper function for Build/Fund an industry
|
|
|
* @param tile tile where industry is built
|
|
|
* @param type of industry to build
|
|
|
* @param flags of operations to conduct
|
|
|
* @param indspec pointer to industry specifications
|
|
|
* @param itspec_index the index of the itsepc to build/fund
|
|
|
* @return the pointer of the newly created industry, or NULL if it failed
|
|
|
*/
|
|
|
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;
|
|
|
} else {
|
|
|
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);
|
|
|
if (t == NULL) return NULL;
|
|
|
|
|
|
if (!CheckIfIndustryIsAllowed(tile, type, t)) return NULL;
|
|
|
if (!CheckSuitableIndustryPos(tile)) return NULL;
|
|
|
|
|
|
Industry *i = new Industry(tile);
|
|
|
if (i == NULL) return NULL;
|
|
|
AutoPtrT<Industry> i_auto_delete = i;
|
|
|
|