clear_cmd.c
changeset 2955 24de69e236d2
parent 2952 58522ed8f0f1
child 2956 3e9a354875c5
equal deleted inserted replaced
2954:da67225401cf 2955:24de69e236d2
     1 /* $Id$ */
     1 /* $Id$ */
     2 
     2 
     3 #include "stdafx.h"
     3 #include "stdafx.h"
     4 #include "openttd.h"
     4 #include "openttd.h"
       
     5 #include "clear.h"
     5 #include "table/strings.h"
     6 #include "table/strings.h"
     6 #include "functions.h"
     7 #include "functions.h"
     7 #include "map.h"
     8 #include "map.h"
     8 #include "player.h"
     9 #include "player.h"
     9 #include "tile.h"
    10 #include "tile.h"
   411 }
   412 }
   412 
   413 
   413 
   414 
   414 static int32 ClearTile_Clear(TileIndex tile, byte flags)
   415 static int32 ClearTile_Clear(TileIndex tile, byte flags)
   415 {
   416 {
   416 	static const int32 null = 0;
       
   417 	static const int32* clear_price_table[] = {
   417 	static const int32* clear_price_table[] = {
   418 		&null,
       
   419 		&_price.clear_1,
       
   420 		&_price.clear_1,
       
   421 		&_price.clear_1,
   418 		&_price.clear_1,
   422 		&_price.purchase_land,
   419 		&_price.purchase_land,
   423 		&_price.purchase_land,
       
   424 		&_price.purchase_land,
       
   425 		&_price.purchase_land,
       
   426 		&_price.clear_2,
   420 		&_price.clear_2,
   427 		&_price.clear_2,
       
   428 		&_price.clear_2,
       
   429 		&_price.clear_2,
       
   430 		&_price.clear_3,
       
   431 		&_price.clear_3,
       
   432 		&_price.clear_3,
       
   433 		&_price.clear_3,
   421 		&_price.clear_3,
   434 		&_price.purchase_land,
   422 		&_price.purchase_land,
   435 		&_price.purchase_land,
   423 		&_price.purchase_land,
   436 		&_price.purchase_land,
   424 		&_price.clear_2, // XXX unused?
   437 		&_price.purchase_land,
       
   438 		&_price.purchase_land,
       
   439 		&_price.purchase_land,
       
   440 		&_price.purchase_land,
       
   441 		&_price.purchase_land,
       
   442 		&_price.clear_2,
       
   443 		&_price.clear_2,
       
   444 		&_price.clear_2,
       
   445 		&_price.clear_2,
       
   446 	};
   425 	};
   447 	const int32 *price = clear_price_table[GB(_m[tile].m5, 0, 5)];
   426 	int32 price;
       
   427 
       
   428 	if (IsClearGround(tile, CL_GRASS) && GetClearDensity(tile) == 0) {
       
   429 		price = 0;
       
   430 	} else {
       
   431 		price = *clear_price_table[GetClearGround(tile)];
       
   432 	}
   448 
   433 
   449 	if (flags & DC_EXEC) DoClearSquare(tile);
   434 	if (flags & DC_EXEC) DoClearSquare(tile);
   450 
   435 
   451 	return *price;
   436 	return price;
   452 }
   437 }
   453 
   438 
   454 /** Sell a land area. Actually you only sell one tile, so
   439 /** Sell a land area. Actually you only sell one tile, so
   455  * the name is a bit confusing ;p
   440  * the name is a bit confusing ;p
   456  * @param x,y the tile the player is selling
   441  * @param x,y the tile the player is selling
   515 }
   500 }
   516 
   501 
   517 static void DrawTile_Clear(TileInfo *ti)
   502 static void DrawTile_Clear(TileInfo *ti)
   518 {
   503 {
   519 	switch (GB(ti->map5, 2, 3)) {
   504 	switch (GB(ti->map5, 2, 3)) {
   520 	case 0:
   505 		case CL_GRASS:
   521 		DrawClearLandTile(ti, GB(ti->map5, 0, 2));
   506 			DrawClearLandTile(ti, GB(ti->map5, 0, 2));
   522 		break;
   507 			break;
   523 
   508 
   524 	case 1:
   509 		case CL_ROUGH:
   525 		DrawHillyLandTile(ti);
   510 			DrawHillyLandTile(ti);
   526 		break;
   511 			break;
   527 
   512 
   528 	case 2:
   513 		case CL_ROCKS:
   529 		DrawGroundSprite(SPR_FLAT_ROCKY_LAND_1 + _tileh_to_sprite[ti->tileh]);
   514 			DrawGroundSprite(SPR_FLAT_ROCKY_LAND_1 + _tileh_to_sprite[ti->tileh]);
   530 		break;
   515 			break;
   531 
   516 
   532 	case 3:
   517 		case CL_FIELDS:
   533 		DrawGroundSprite(_clear_land_sprites_1[GB(_m[ti->tile].m3, 0, 4)] + _tileh_to_sprite[ti->tileh]);
   518 			DrawGroundSprite(_clear_land_sprites_1[GB(_m[ti->tile].m3, 0, 4)] + _tileh_to_sprite[ti->tileh]);
   534 		break;
   519 			break;
   535 
   520 
   536 	case 4:
   521 		case CL_SNOW:
   537 		DrawGroundSprite(_clear_land_sprites_2[GB(ti->map5, 0, 2)] + _tileh_to_sprite[ti->tileh]);
   522 			DrawGroundSprite(_clear_land_sprites_2[GB(ti->map5, 0, 2)] + _tileh_to_sprite[ti->tileh]);
   538 		break;
   523 			break;
   539 
   524 
   540 	case 5:
   525 		case CL_DESERT:
   541 		DrawGroundSprite(_clear_land_sprites_3[GB(ti->map5, 0, 2)] + _tileh_to_sprite[ti->tileh]);
   526 			DrawGroundSprite(_clear_land_sprites_3[GB(ti->map5, 0, 2)] + _tileh_to_sprite[ti->tileh]);
   542 		break;
   527 			break;
   543 	}
   528 	}
   544 
   529 
   545 	DrawClearLandFence(ti);
   530 	DrawClearLandFence(ti);
   546 }
   531 }
   547 
   532 
   569 {
   554 {
   570 	byte self;
   555 	byte self;
   571 	byte neighbour;
   556 	byte neighbour;
   572 	TileIndex dirty = INVALID_TILE;
   557 	TileIndex dirty = INVALID_TILE;
   573 
   558 
   574 	switch (GetTileType(tile)) {
   559 	self = (IsTileType(tile, MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 1, 0), CL_FIELDS));
   575 		case MP_CLEAR:
   560 
   576 			self = (GB(_m[tile].m5, 0, 5) == 15);
   561 	neighbour = (IsTileType(TILE_ADDXY(tile, 1, 0), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 1, 0), CL_FIELDS));
   577 			break;
       
   578 
       
   579 		default:
       
   580 			self = 0;
       
   581 			break;
       
   582 	}
       
   583 
       
   584 	switch (GetTileType(TILE_ADDXY(tile, 1, 0))) {
       
   585 		case MP_CLEAR:
       
   586 			neighbour = (GB(_m[TILE_ADDXY(tile, 1, 0)].m5, 0, 5) == 15);
       
   587 			break;
       
   588 
       
   589 		default:
       
   590 			neighbour = 0;
       
   591 			break;
       
   592 	}
       
   593 
       
   594 	if (GB(_m[tile].m4, 5, 3) == 0) {
   562 	if (GB(_m[tile].m4, 5, 3) == 0) {
   595 		if (self != neighbour) {
   563 		if (self != neighbour) {
   596 			SB(_m[tile].m4, 5, 3, 3);
   564 			SB(_m[tile].m4, 5, 3, 3);
   597 			dirty = tile;
   565 			dirty = tile;
   598 		}
   566 		}
   601 			SB(_m[tile].m4, 5, 3, 0);
   569 			SB(_m[tile].m4, 5, 3, 0);
   602 			dirty = tile;
   570 			dirty = tile;
   603 		}
   571 		}
   604 	}
   572 	}
   605 
   573 
   606 	switch (GetTileType(TILE_ADDXY(tile, 0, 1))) {
   574 	neighbour = (IsTileType(TILE_ADDXY(tile, 0, 1), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 0, 1), CL_FIELDS));
   607 		case MP_CLEAR:
       
   608 			neighbour = (GB(_m[TILE_ADDXY(tile, 0, 1)].m5, 0, 5) == 15);
       
   609 			break;
       
   610 
       
   611 		default:
       
   612 			neighbour = 0;
       
   613 			break;
       
   614 	}
       
   615 
       
   616 	if (GB(_m[tile].m4, 2, 3) == 0) {
   575 	if (GB(_m[tile].m4, 2, 3) == 0) {
   617 		if (self != neighbour) {
   576 		if (self != neighbour) {
   618 			SB(_m[tile].m4, 2, 3, 3);
   577 			SB(_m[tile].m4, 2, 3, 3);
   619 			dirty = tile;
   578 			dirty = tile;
   620 		}
   579 		}
   630 
   589 
   631 
   590 
   632 /* convert into snowy tiles */
   591 /* convert into snowy tiles */
   633 static void TileLoopClearAlps(TileIndex tile)
   592 static void TileLoopClearAlps(TileIndex tile)
   634 {
   593 {
   635 	int k;
       
   636 	byte m5,tmp;
       
   637 
       
   638 	/* distance from snow line, in steps of 8 */
   594 	/* distance from snow line, in steps of 8 */
   639 	k = GetTileZ(tile) - _opt.snow_line;
   595 	int k = GetTileZ(tile) - _opt.snow_line;
   640 
   596 
   641 	m5 = _m[tile].m5 & 0x1C;
   597 	if (k < -8) { // well below the snow line
   642 	tmp = _m[tile].m5 & 3;
   598 		if (!IsClearGround(tile, CL_SNOW)) return;
   643 
   599 		if (GetClearDensity(tile) == 0) SetClearGroundDensity(tile, CL_GRASS, 3);
   644 	if (k < -8) {
       
   645 		/* snow_m2_down */
       
   646 		if (m5 != 0x10)
       
   647 			return;
       
   648 		if (tmp == 0)
       
   649 			m5 = 3;
       
   650 	} else if (k == -8) {
       
   651 		/* snow_m1 */
       
   652 		if (m5 != 0x10) {
       
   653 			m5 = 0x10;
       
   654 		} else if (tmp != 0) {
       
   655 			m5 = (tmp - 1) + 0x10;
       
   656 		} else
       
   657 			return;
       
   658 	} else if (k < 8) {
       
   659 		/* snow_0 */
       
   660 		if (m5 != 0x10) {
       
   661 			m5 = 0x10;
       
   662 		} else if (tmp != 1) {
       
   663 			m5 = 1;
       
   664 			if (tmp != 0)
       
   665 				m5 = tmp - 1;
       
   666 			m5 += 0x10;
       
   667 		} else
       
   668 			return;
       
   669 	} else if (k == 8) {
       
   670 		/* snow_p1 */
       
   671 		if (m5 != 0x10) {
       
   672 			m5 = 0x10;
       
   673 		} else if (tmp != 2) {
       
   674 			m5 = 2;
       
   675 			if (tmp <= 2)
       
   676 				m5 = tmp + 1;
       
   677 			m5 += 0x10;
       
   678 		} else
       
   679 			return;
       
   680 	} else {
   600 	} else {
   681 		/* snow_p2_up */
   601 		if (!IsClearGround(tile, CL_SNOW)) {
   682 		if (m5 != 0x10) {
   602 			SetClearGroundDensity(tile, CL_SNOW, 0);
   683 			m5 = 0x10;
   603 		} else {
   684 		} else if (tmp != 3) {
   604 			uint density = min((uint)(k + 8) / 8, 3);
   685 			m5 = tmp + 1 + 0x10;
   605 
   686 		} else
   606 			if (GetClearDensity(tile) < density) {
   687 			return;
   607 				AddClearDensity(tile, 1);
   688 	}
   608 			} else if (GetClearDensity(tile) > density) {
   689 
   609 				AddClearDensity(tile, -1);
   690 	_m[tile].m5 = m5;
   610 			} else {
       
   611 				return;
       
   612 			}
       
   613 		}
       
   614 	}
       
   615 
   691 	MarkTileDirtyByTile(tile);
   616 	MarkTileDirtyByTile(tile);
   692 }
   617 }
   693 
   618 
   694 static void TileLoopClearDesert(TileIndex tile)
   619 static void TileLoopClearDesert(TileIndex tile)
   695 {
   620 {
   696  	if ((_m[tile].m5 & 0x1C) == 0x14) return;
   621 	if (IsClearGround(tile, CL_DESERT)) return;
   697 
   622 
   698 	if (GetMapExtraBits(tile) == 1) {
   623 	if (GetMapExtraBits(tile) == 1) {
   699 		_m[tile].m5 = 0x17;
   624 		SetClearGroundDensity(tile, CL_DESERT, 3);
   700 	} else {
   625 	} else {
   701 		if (GetMapExtraBits(tile + TileDiffXY( 1,  0)) != 1 &&
   626 		if (GetMapExtraBits(tile + TileDiffXY( 1,  0)) != 1 &&
   702 				GetMapExtraBits(tile + TileDiffXY(-1,  0)) != 1 &&
   627 				GetMapExtraBits(tile + TileDiffXY(-1,  0)) != 1 &&
   703 				GetMapExtraBits(tile + TileDiffXY( 0,  1)) != 1 &&
   628 				GetMapExtraBits(tile + TileDiffXY( 0,  1)) != 1 &&
   704 				GetMapExtraBits(tile + TileDiffXY( 0, -1)) != 1)
   629 				GetMapExtraBits(tile + TileDiffXY( 0, -1)) != 1)
   705 			return;
   630 			return;
   706 		_m[tile].m5 = 0x15;
   631 		SetClearGroundDensity(tile, CL_DESERT, 1);
   707 	}
   632 	}
   708 
   633 
   709 	MarkTileDirtyByTile(tile);
   634 	MarkTileDirtyByTile(tile);
   710 }
   635 }
   711 
   636 
   712 static void TileLoop_Clear(TileIndex tile)
   637 static void TileLoop_Clear(TileIndex tile)
   713 {
   638 {
   714 	byte m5,m3;
       
   715 
       
   716 	TileLoopClearHelper(tile);
   639 	TileLoopClearHelper(tile);
   717 
   640 
   718 	if (_opt.landscape == LT_DESERT) {
   641 	if (_opt.landscape == LT_DESERT) {
   719 		TileLoopClearDesert(tile);
   642 		TileLoopClearDesert(tile);
   720 	} else if (_opt.landscape == LT_HILLY) {
   643 	} else if (_opt.landscape == LT_HILLY) {
   721 		TileLoopClearAlps(tile);
   644 		TileLoopClearAlps(tile);
   722 	}
   645 	}
   723 
   646 
   724 	m5 = _m[tile].m5;
   647 	switch (GetClearGround(tile)) {
   725 	if ((m5 & 0x1C) == 0x10 || (m5 & 0x1C) == 0x14) return;
   648 		case CL_GRASS:
   726 
   649 			if (GetClearDensity(tile) == 3) return;
   727 	if ((m5 & 0x1C) != 0xC) {
   650 
   728 		if ((m5 & 3) == 3) return;
   651 			if (_game_mode != GM_EDITOR) {
   729 
   652 				if (GetClearCounter(tile) < 7) {
   730 		if (_game_mode != GM_EDITOR) {
   653 					AddClearCounter(tile, 1);
   731 			m5 += 0x20;
   654 					return;
   732 			if (m5 >= 0x20) {
   655 				} else {
   733 				// Didn't overflow
   656 					SetClearCounter(tile, 0);
   734 				_m[tile].m5 = m5;
   657 					AddClearDensity(tile, 1);
       
   658 				}
       
   659 			} else {
       
   660 				SetClearGroundDensity(tile, GB(Random(), 0, 8) > 21 ? CL_GRASS : CL_ROUGH, 3);
       
   661 			}
       
   662 			break;
       
   663 
       
   664 		case CL_FIELDS: {
       
   665 			uint field_type;
       
   666 
       
   667 			if (_game_mode == GM_EDITOR) return;
       
   668 
       
   669 			if (GetClearCounter(tile) < 7) {
       
   670 				AddClearCounter(tile, 1);
   735 				return;
   671 				return;
   736 			}
   672 			} else {
   737 			/* did overflow, so continue */
   673 				SetClearCounter(tile, 0);
   738 		} else {
   674 			}
   739 			m5 = (GB(Random(), 0, 8) > 21) ? 2 : 6;
   675 
   740 		}
   676 			field_type = GB(_m[tile].m3, 0, 4);
   741 		m5++;
   677 			field_type = (field_type < 8) ? field_type + 1 : 0;
   742 	} else if (_game_mode != GM_EDITOR) {
   678 			SB(_m[tile].m3, 0, 4, field_type);
   743 		/* handle farm field */
   679 			break;
   744 		m5 += 0x20;
   680 		}
   745 		if (m5 >= 0x20) {
   681 
   746 			// Didn't overflow
   682 		default:
   747 			_m[tile].m5 = m5;
       
   748 			return;
   683 			return;
   749 		}
   684 	}
   750 		/* overflowed */
   685 
   751 		m3 = _m[tile].m3 + 1;
       
   752 		assert( (m3 & 0xF) != 0);
       
   753 		if ( (m3 & 0xF) >= 9) /* NOTE: will not work properly if m3&0xF == 0xF */
       
   754 			m3 &= ~0xF;
       
   755 		_m[tile].m3 = m3;
       
   756 	}
       
   757 
       
   758 	_m[tile].m5 = m5;
       
   759 	MarkTileDirtyByTile(tile);
   686 	MarkTileDirtyByTile(tile);
   760 }
   687 }
   761 
   688 
   762 void GenerateClearTile(void)
   689 void GenerateClearTile(void)
   763 {
   690 {
   766 
   693 
   767 	/* add hills */
   694 	/* add hills */
   768 	i = ScaleByMapSize(GB(Random(), 0, 10) + 0x400);
   695 	i = ScaleByMapSize(GB(Random(), 0, 10) + 0x400);
   769 	do {
   696 	do {
   770 		tile = RandomTile();
   697 		tile = RandomTile();
   771 		if (IsTileType(tile, MP_CLEAR)) SB(_m[tile].m5, 2, 2, 1);
   698 		if (IsTileType(tile, MP_CLEAR)) SetClearGroundDensity(tile, CL_ROUGH, 3);
   772 	} while (--i);
   699 	} while (--i);
   773 
   700 
   774 	/* add grey squares */
   701 	/* add grey squares */
   775 	i = ScaleByMapSize(GB(Random(), 0, 7) + 0x80);
   702 	i = ScaleByMapSize(GB(Random(), 0, 7) + 0x80);
   776 	do {
   703 	do {
   779 		if (IsTileType(tile, MP_CLEAR)) {
   706 		if (IsTileType(tile, MP_CLEAR)) {
   780 			uint j = GB(r, 16, 4) + 5;
   707 			uint j = GB(r, 16, 4) + 5;
   781 			for (;;) {
   708 			for (;;) {
   782 				TileIndex tile_new;
   709 				TileIndex tile_new;
   783 
   710 
   784 				SB(_m[tile].m5, 2, 2, 2);
   711 				SetClearGroundDensity(tile, CL_ROCKS, 3);
   785 				do {
   712 				do {
   786 					if (--j == 0) goto get_out;
   713 					if (--j == 0) goto get_out;
   787 					tile_new = tile + TileOffsByDir(GB(Random(), 0, 2));
   714 					tile_new = tile + TileOffsByDir(GB(Random(), 0, 2));
   788 				} while (!IsTileType(tile_new, MP_CLEAR));
   715 				} while (!IsTileType(tile_new, MP_CLEAR));
   789 				tile = tile_new;
   716 				tile = tile_new;
   802 {
   729 {
   803 	return 0;
   730 	return 0;
   804 }
   731 }
   805 
   732 
   806 static const StringID _clear_land_str[] = {
   733 static const StringID _clear_land_str[] = {
       
   734 	STR_080D_GRASS,
   807 	STR_080B_ROUGH_LAND,
   735 	STR_080B_ROUGH_LAND,
   808 	STR_080A_ROCKS,
   736 	STR_080A_ROCKS,
   809 	STR_080E_FIELDS,
   737 	STR_080E_FIELDS,
   810 	STR_080F_SNOW_COVERED_LAND,
   738 	STR_080F_SNOW_COVERED_LAND,
   811 	STR_0810_DESERT,
   739 	STR_0810_DESERT
   812 	0,
       
   813 	0,
       
   814 	STR_080C_BARE_LAND,
       
   815 	STR_080D_GRASS,
       
   816 	STR_080D_GRASS,
       
   817 	STR_080D_GRASS,
       
   818 };
   740 };
   819 
   741 
   820 static void GetTileDesc_Clear(TileIndex tile, TileDesc *td)
   742 static void GetTileDesc_Clear(TileIndex tile, TileDesc *td)
   821 {
   743 {
   822 	uint i = GB(_m[tile].m5, 2, 3);
   744 	if (IsClearGround(tile, CL_GRASS) && GetClearDensity(tile) == 0) {
   823 	if (i == 0) i = GB(_m[tile].m5, 0, 2) + 8;
   745 		td->str = STR_080C_BARE_LAND;
   824 	td->str = _clear_land_str[i - 1];
   746 	} else {
       
   747 		td->str = _clear_land_str[GetClearGround(tile)];
       
   748 	}
   825 	td->owner = GetTileOwner(tile);
   749 	td->owner = GetTileOwner(tile);
   826 }
   750 }
   827 
   751 
   828 static void ChangeTileOwner_Clear(TileIndex tile, PlayerID old_player, PlayerID new_player)
   752 static void ChangeTileOwner_Clear(TileIndex tile, PlayerID old_player, PlayerID new_player)
   829 {
   753 {