src/unmovable_cmd.cpp
changeset 10357 5c767b7ef1af
parent 10229 fba3f9fa44d7
child 10429 1b99254f9607
equal deleted inserted replaced
10356:46ad3ed53a41 10357:5c767b7ef1af
    39  * @param flags docommand flags of calling function
    39  * @param flags docommand flags of calling function
    40  * @return cost of the operation
    40  * @return cost of the operation
    41  */
    41  */
    42 static CommandCost DestroyCompanyHQ(PlayerID pid, uint32 flags)
    42 static CommandCost DestroyCompanyHQ(PlayerID pid, uint32 flags)
    43 {
    43 {
    44 	Player* p = GetPlayer(pid);
    44 	Player *p = GetPlayer(pid);
    45 
    45 
    46 	if (flags & DC_EXEC) {
    46 	if (flags & DC_EXEC) {
    47 		TileIndex t = p->location_of_house;
    47 		TileIndex t = p->location_of_house;
    48 
    48 
    49 		DoClearSquare(t + TileDiffXY(0, 0));
    49 		DoClearSquare(t + TileDiffXY(0, 0));
   151 CommandCost CmdSellLandArea(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   151 CommandCost CmdSellLandArea(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   152 {
   152 {
   153 	if (!IsOwnedLandTile(tile)) return CMD_ERROR;
   153 	if (!IsOwnedLandTile(tile)) return CMD_ERROR;
   154 	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER) return CMD_ERROR;
   154 	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER) return CMD_ERROR;
   155 
   155 
   156 
       
   157 	if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
   156 	if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
   158 
   157 
   159 	if (flags & DC_EXEC) DoClearSquare(tile);
   158 	if (flags & DC_EXEC) DoClearSquare(tile);
   160 
   159 
   161 	return CommandCost(EXPENSES_CONSTRUCTION, - _price.clear_roughland * 2);
   160 	return CommandCost(EXPENSES_CONSTRUCTION, - _price.clear_roughland * 2);
   167 {
   166 {
   168 
   167 
   169 	switch (GetUnmovableType(ti->tile)) {
   168 	switch (GetUnmovableType(ti->tile)) {
   170 		case UNMOVABLE_TRANSMITTER:
   169 		case UNMOVABLE_TRANSMITTER:
   171 		case UNMOVABLE_LIGHTHOUSE: {
   170 		case UNMOVABLE_LIGHTHOUSE: {
   172 			const DrawTileSeqStruct* dtu = &_draw_tile_transmitterlighthouse_data[GetUnmovableType(ti->tile)];
   171 			const DrawTileSeqStruct *dtu = &_draw_tile_transmitterlighthouse_data[GetUnmovableType(ti->tile)];
   173 
   172 
   174 			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
   173 			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
   175 			DrawClearLandTile(ti, 2);
   174 			DrawClearLandTile(ti, 2);
   176 
   175 
   177 			if (IsInvisibilitySet(TO_STRUCTURES)) break;
   176 			if (IsInvisibilitySet(TO_STRUCTURES)) break;
   204 			);
   203 			);
   205 			DrawBridgeMiddle(ti);
   204 			DrawBridgeMiddle(ti);
   206 			break;
   205 			break;
   207 
   206 
   208 		default: {
   207 		default: {
   209 			const DrawTileSeqStruct* dtss;
       
   210 			const DrawTileSprites* t;
       
   211 			SpriteID palette;
       
   212 
       
   213 			assert(IsCompanyHQ(ti->tile));
   208 			assert(IsCompanyHQ(ti->tile));
   214 			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
   209 			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
   215 
   210 
   216 			palette = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
   211 			SpriteID palette = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
   217 
   212 
   218 			t = &_unmovable_display_datas[GetCompanyHQSection(ti->tile)];
   213 			const DrawTileSprites *t = &_unmovable_display_datas[GetCompanyHQSection(ti->tile)];
   219 			DrawGroundSprite(t->ground.sprite, palette);
   214 			DrawGroundSprite(t->ground.sprite, palette);
   220 
   215 
   221 			if (IsInvisibilitySet(TO_STRUCTURES)) break;
   216 			if (IsInvisibilitySet(TO_STRUCTURES)) break;
   222 
   217 
       
   218 			const DrawTileSeqStruct *dtss;
   223 			foreach_draw_tile_seq(dtss, t->seq) {
   219 			foreach_draw_tile_seq(dtss, t->seq) {
   224 				AddSortableSpriteToDraw(
   220 				AddSortableSpriteToDraw(
   225 					dtss->image.sprite, palette,
   221 					dtss->image.sprite, palette,
   226 					ti->x + dtss->delta_x, ti->y + dtss->delta_y,
   222 					ti->x + dtss->delta_x, ti->y + dtss->delta_y,
   227 					dtss->size_x, dtss->size_y,
   223 					dtss->size_x, dtss->size_y,
   284 	return CommandCost();
   280 	return CommandCost();
   285 }
   281 }
   286 
   282 
   287 static void GetAcceptedCargo_Unmovable(TileIndex tile, AcceptedCargo ac)
   283 static void GetAcceptedCargo_Unmovable(TileIndex tile, AcceptedCargo ac)
   288 {
   284 {
   289 	uint level; // HQ level (depends on company performance) in the range 1..5.
       
   290 
       
   291 	if (!IsCompanyHQ(tile)) return;
   285 	if (!IsCompanyHQ(tile)) return;
   292 
   286 
   293 	/* HQ accepts passenger and mail; but we have to divide the values
   287 	/* HQ accepts passenger and mail; but we have to divide the values
   294 	 * between 4 tiles it occupies! */
   288 	 * between 4 tiles it occupies! */
   295 
   289 
   296 	level = GetCompanyHQSize(tile) + 1;
   290 	/* HQ level (depends on company performance) in the range 1..5. */
       
   291 	uint level = GetCompanyHQSize(tile) + 1;
   297 
   292 
   298 	/* Top town building generates 10, so to make HQ interesting, the top
   293 	/* Top town building generates 10, so to make HQ interesting, the top
   299 	 * type makes 20. */
   294 	 * type makes 20. */
   300 	ac[CT_PASSENGERS] = max(1U, level);
   295 	ac[CT_PASSENGERS] = max(1U, level);
   301 
   296 
   324 	/* not used */
   319 	/* not used */
   325 }
   320 }
   326 
   321 
   327 static void TileLoop_Unmovable(TileIndex tile)
   322 static void TileLoop_Unmovable(TileIndex tile)
   328 {
   323 {
   329 	uint level; // HQ level (depends on company performance) in the range 1..5.
       
   330 	uint32 r;
       
   331 
       
   332 	if (!IsCompanyHQ(tile)) return;
   324 	if (!IsCompanyHQ(tile)) return;
   333 
   325 
   334 	/* HQ accepts passenger and mail; but we have to divide the values
   326 	/* HQ accepts passenger and mail; but we have to divide the values
   335 	 * between 4 tiles it occupies! */
   327 	 * between 4 tiles it occupies! */
   336 
   328 
   337 	level = GetCompanyHQSize(tile) + 1;
   329 	/* HQ level (depends on company performance) in the range 1..5. */
       
   330 	uint level = GetCompanyHQSize(tile) + 1;
   338 	assert(level < 6);
   331 	assert(level < 6);
   339 
   332 
   340 	r = Random();
   333 	uint r = Random();
   341 	/* Top town buildings generate 250, so the top HQ type makes 256. */
   334 	/* Top town buildings generate 250, so the top HQ type makes 256. */
   342 	if (GB(r, 0, 8) < (256 / 4 / (6 - level))) {
   335 	if (GB(r, 0, 8) < (256 / 4 / (6 - level))) {
   343 		uint amt = GB(r, 0, 8) / 8 / 4 + 1;
   336 		uint amt = GB(r, 0, 8) / 8 / 4 + 1;
   344 		if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
   337 		if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
   345 		MoveGoodsToStation(tile, 2, 2, CT_PASSENGERS, amt);
   338 		MoveGoodsToStation(tile, 2, 2, CT_PASSENGERS, amt);
   379 	return false;
   372 	return false;
   380 }
   373 }
   381 
   374 
   382 void GenerateUnmovables()
   375 void GenerateUnmovables()
   383 {
   376 {
   384 	int i, li, j, loop_count;
       
   385 	TileIndex tile;
       
   386 	uint h;
       
   387 	uint maxx;
       
   388 	uint maxy;
       
   389 
       
   390 	if (_opt.landscape == LT_TOYLAND) return;
   377 	if (_opt.landscape == LT_TOYLAND) return;
   391 
   378 
   392 	/* add radio tower */
   379 	/* add radio tower */
   393 	i = ScaleByMapSize(1000);
   380 	int radiotowser_to_build = ScaleByMapSize(15); // maximum number of radio towers on the map
   394 	j = ScaleByMapSize(15); // maximum number of radio towers on the map
   381 	int lighthouses_to_build = _opt.landscape == LT_TROPIC ? 0 : ScaleByMapSize1D((Random() & 3) + 7);
   395 	li = ScaleByMapSize1D((Random() & 3) + 7);
   382 	SetGeneratingWorldProgress(GWP_UNMOVABLE, radiotowser_to_build + lighthouses_to_build);
   396 	SetGeneratingWorldProgress(GWP_UNMOVABLE, j + li);
   383 
   397 
   384 	for (uint i = ScaleByMapSize(1000); i != 0; i--) {
   398 	do {
   385 		TileIndex tile = RandomTile();
   399 		tile = RandomTile();
   386 
       
   387 		uint h;
   400 		if (IsTileType(tile, MP_CLEAR) && GetTileSlope(tile, &h) == SLOPE_FLAT && h >= TILE_HEIGHT * 4 && !IsBridgeAbove(tile)) {
   388 		if (IsTileType(tile, MP_CLEAR) && GetTileSlope(tile, &h) == SLOPE_FLAT && h >= TILE_HEIGHT * 4 && !IsBridgeAbove(tile)) {
   401 			if (IsRadioTowerNearby(tile)) continue;
   389 			if (IsRadioTowerNearby(tile)) continue;
       
   390 
   402 			MakeTransmitter(tile);
   391 			MakeTransmitter(tile);
   403 			IncreaseGeneratingWorldProgress(GWP_UNMOVABLE);
   392 			IncreaseGeneratingWorldProgress(GWP_UNMOVABLE);
   404 			if (--j == 0) break;
   393 			if (--radiotowser_to_build == 0) break;
   405 		}
   394 		}
   406 	} while (--i);
   395 	}
   407 
   396 
   408 	if (_opt.landscape == LT_TROPIC) return;
   397 	if (_opt.landscape == LT_TROPIC) return;
   409 
   398 
   410 	/* add lighthouses */
   399 	/* add lighthouses */
   411 	i = li;
   400 	uint maxx = MapMaxX();
   412 	maxx = MapMaxX();
   401 	uint maxy = MapMaxY();
   413 	maxy = MapMaxY();
   402 	for (int loop_count = 0; loop_count < 1000 && lighthouses_to_build != 0; loop_count++) {
   414 	loop_count = 0;
   403 		uint r = Random();
   415 	do {
   404 
   416 		uint32 r;
   405 		/* Scatter the lighthouses more evenly around the perimeter */
       
   406 		int perimeter = (GB(r, 16, 16) % (2 * (maxx + maxy))) - maxy;
   417 		DiagDirection dir;
   407 		DiagDirection dir;
   418 		int perimeter;
       
   419 
       
   420 restart:
       
   421 		/* Avoid infinite loops */
       
   422 		if (++loop_count > 1000) break;
       
   423 
       
   424 		r = Random();
       
   425 
       
   426 		/* Scatter the lighthouses more evenly around the perimeter */
       
   427 		perimeter = (GB(r, 16, 16) % (2 * (maxx + maxy))) - maxy;
       
   428 		for (dir = DIAGDIR_NE; perimeter > 0; dir++) {
   408 		for (dir = DIAGDIR_NE; perimeter > 0; dir++) {
   429 			perimeter -= (DiagDirToAxis(dir) == AXIS_X) ? maxx : maxy;
   409 			perimeter -= (DiagDirToAxis(dir) == AXIS_X) ? maxx : maxy;
   430 		}
   410 		}
   431 
   411 
       
   412 		TileIndex tile;
   432 		switch (dir) {
   413 		switch (dir) {
   433 			default:
   414 			default:
   434 			case DIAGDIR_NE: tile = TileXY(maxx,     r % maxy); break;
   415 			case DIAGDIR_NE: tile = TileXY(maxx,     r % maxy); break;
   435 			case DIAGDIR_SE: tile = TileXY(r % maxx, 0);        break;
   416 			case DIAGDIR_SE: tile = TileXY(r % maxx, 0);        break;
   436 			case DIAGDIR_SW: tile = TileXY(0,        r % maxy); break;
   417 			case DIAGDIR_SW: tile = TileXY(0,        r % maxy); break;
   437 			case DIAGDIR_NW: tile = TileXY(r % maxx, maxy);     break;
   418 			case DIAGDIR_NW: tile = TileXY(r % maxx, maxy);     break;
   438 		}
   419 		}
   439 		j = 20;
   420 
   440 		do {
   421 		for (int j = 0; j < 20; j++) {
   441 			if (--j == 0) goto restart;
   422 			uint h;
       
   423 			if (IsTileType(tile, MP_CLEAR) && GetTileSlope(tile, &h) == SLOPE_FLAT && h <= TILE_HEIGHT * 2 && !IsBridgeAbove(tile)) {
       
   424 				MakeLighthouse(tile);
       
   425 				IncreaseGeneratingWorldProgress(GWP_UNMOVABLE);
       
   426 				lighthouses_to_build--;
       
   427 				assert(tile == TILE_MASK(tile));
       
   428 				break;
       
   429 			}
   442 			tile = TILE_MASK(tile + TileOffsByDiagDir(dir));
   430 			tile = TILE_MASK(tile + TileOffsByDiagDir(dir));
   443 		} while (!(IsTileType(tile, MP_CLEAR) && GetTileSlope(tile, &h) == SLOPE_FLAT && h <= TILE_HEIGHT * 2 && !IsBridgeAbove(tile)));
   431 		}
   444 
   432 	}
   445 		assert(tile == TILE_MASK(tile));
       
   446 
       
   447 		MakeLighthouse(tile);
       
   448 		IncreaseGeneratingWorldProgress(GWP_UNMOVABLE);
       
   449 	} while (--i);
       
   450 }
   433 }
   451 
   434 
   452 static void ChangeTileOwner_Unmovable(TileIndex tile, PlayerID old_player, PlayerID new_player)
   435 static void ChangeTileOwner_Unmovable(TileIndex tile, PlayerID old_player, PlayerID new_player)
   453 {
   436 {
   454 	if (!IsTileOwner(tile, old_player)) return;
   437 	if (!IsTileOwner(tile, old_player)) return;