File diff r7649:de7392d40f90 → r7650:d12631d10c9c
src/industry_cmd.cpp
Show inline comments
 
@@ -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;