truelight@0: #include "stdafx.h" truelight@0: #include "ttd.h" tron@679: #include "map.h" tron@1209: #include "tile.h" truelight@0: #include truelight@0: #include "gfx.h" truelight@0: #include "viewport.h" truelight@0: #include "command.h" truelight@0: #include "vehicle.h" truelight@0: truelight@183: extern const TileTypeProcs truelight@0: _tile_type_clear_procs, truelight@0: _tile_type_rail_procs, truelight@0: _tile_type_road_procs, truelight@0: _tile_type_town_procs, truelight@0: _tile_type_trees_procs, truelight@0: _tile_type_station_procs, truelight@0: _tile_type_water_procs, truelight@0: _tile_type_dummy_procs, truelight@0: _tile_type_industry_procs, truelight@0: _tile_type_tunnelbridge_procs, truelight@0: _tile_type_unmovable_procs; truelight@0: truelight@0: const TileTypeProcs * const _tile_type_procs[16] = { truelight@0: &_tile_type_clear_procs, truelight@0: &_tile_type_rail_procs, truelight@0: &_tile_type_road_procs, truelight@0: &_tile_type_town_procs, truelight@0: &_tile_type_trees_procs, truelight@0: &_tile_type_station_procs, truelight@0: &_tile_type_water_procs, truelight@0: &_tile_type_dummy_procs, truelight@0: &_tile_type_industry_procs, truelight@0: &_tile_type_tunnelbridge_procs, truelight@0: &_tile_type_unmovable_procs, truelight@0: }; truelight@0: truelight@0: /* landscape slope => sprite */ truelight@0: const byte _tileh_to_sprite[32] = { truelight@0: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,0, truelight@0: 0,0,0,0,0,0,0,16,0,0,0,17,0,15,18,0, truelight@0: }; truelight@0: truelight@0: uint GetTileSlope(uint tile, int *h) truelight@0: { truelight@0: uint a,b,c,d,min; truelight@0: int r; truelight@0: tron@1222: assert(tile < MapSize()); tron@1222: tron@926: if (TileX(tile) == MapMaxX() || TileY(tile) == MapMaxY()) { truelight@0: if (h) truelight@0: *h = 0; truelight@0: return 0; truelight@0: } truelight@0: tron@1044: min = a = TileHeight(tile); tron@1044: b = TileHeight(tile + TILE_XY(1,0)); truelight@0: if (min >= b) min = b; tron@1044: c = TileHeight(tile + TILE_XY(0,1)); truelight@0: if (min >= c) min = c; tron@1044: d = TileHeight(tile + TILE_XY(1,1)); truelight@0: if (min >= d) min = d; truelight@183: truelight@0: r = 0; truelight@0: if ((a-=min)!=0) { r += (--a << 4) + 8; } truelight@0: if ((c-=min)!=0) { r += (--c << 4) + 4; } truelight@0: if ((d-=min)!=0) { r += (--d << 4) + 2; } truelight@0: if ((b-=min)!=0) { r += (--b << 4) + 1; } truelight@0: truelight@0: if (h != 0) truelight@0: *h = min * 8; truelight@0: truelight@0: return r; truelight@0: } truelight@0: truelight@0: int GetTileZ(uint tile) truelight@0: { truelight@0: int h; truelight@0: GetTileSlope(tile, &h); truelight@0: return h; truelight@0: } truelight@0: tron@1193: void FindLandscapeHeightByTile(TileInfo *ti, TileIndex tile) truelight@0: { tron@1193: assert(tile < MapSize()); truelight@0: truelight@0: ti->tile = tile; truelight@0: ti->map5 = _map5[tile]; tron@1214: ti->type = GetTileType(tile); truelight@0: ti->tileh = GetTileSlope(tile, &ti->z); truelight@0: } truelight@0: truelight@0: /* find the landscape height for the coordinates x y */ truelight@0: void FindLandscapeHeight(TileInfo *ti, uint x, uint y) truelight@0: { truelight@0: int tile; truelight@0: truelight@0: ti->x = x; truelight@0: ti->y = y; truelight@0: tron@856: if (x >= MapMaxX() * 16 - 1 || y >= MapMaxY() * 16 - 1) { truelight@0: ti->tileh = 0; dominik@925: ti->type = MP_VOID; truelight@0: ti->tile = 0; truelight@0: ti->map5 = 0; truelight@0: ti->z = 0; truelight@0: return; truelight@0: } truelight@0: truelight@0: tile = TILE_FROM_XY(x,y); truelight@0: FindLandscapeHeightByTile(ti, tile); truelight@0: } truelight@0: truelight@0: uint GetPartialZ(int x, int y, int corners) truelight@0: { truelight@0: int z = 0; truelight@0: truelight@0: switch(corners) { truelight@0: case 1: truelight@0: if (x - y >= 0) truelight@0: z = (x - y) >> 1; truelight@0: break; truelight@183: truelight@0: case 2: truelight@0: y^=0xF; truelight@0: if ( (x - y) >= 0) truelight@0: z = (x - y) >> 1; truelight@0: break; truelight@0: truelight@0: case 3: truelight@0: z = (x>>1) + 1; truelight@0: break; truelight@0: truelight@0: case 4: truelight@0: if (y - x >= 0) truelight@0: z = (y - x) >> 1; truelight@0: break; truelight@0: truelight@0: case 5: truelight@0: case 10: truelight@0: case 15: truelight@0: z = 4; truelight@0: break; truelight@0: truelight@0: case 6: truelight@0: z = (y>>1) + 1; truelight@0: break; truelight@0: truelight@0: case 7: truelight@0: z = 8; truelight@0: y^=0xF; truelight@0: if (x - y < 0) truelight@0: z += (x - y) >> 1; truelight@0: break; truelight@0: truelight@0: case 8: truelight@0: y ^= 0xF; truelight@0: if (y - x >= 0) truelight@0: z = (y - x) >> 1; truelight@0: break; truelight@0: truelight@0: case 9: truelight@0: z = (y^0xF)>>1; truelight@0: break; truelight@0: truelight@0: case 11: truelight@0: z = 8; truelight@0: if (x - y < 0) truelight@0: z += (x - y) >> 1; truelight@0: break; truelight@0: truelight@0: case 12: truelight@0: z = (x^0xF)>>1; truelight@0: break; truelight@0: truelight@0: case 13: truelight@0: z = 8; truelight@0: y ^= 0xF; truelight@0: if (y - x < 0) truelight@0: z += (y - x) >> 1; truelight@0: break; truelight@0: truelight@0: case 14: truelight@0: z = 8; truelight@0: if (y - x < 0) truelight@0: z += (y - x) >> 1; truelight@0: break; truelight@0: truelight@0: case 23: truelight@0: z = 1 + ((x+y)>>1); truelight@0: break; truelight@0: truelight@0: case 27: truelight@0: z = 1 + ((x+(y^0xF))>>1); truelight@0: break; truelight@0: truelight@0: case 29: truelight@0: z = 1 + (((x^0xF)+(y^0xF))>>1); truelight@0: break; truelight@183: truelight@0: case 30: truelight@0: z = 1 + (((x^0xF)+(y^0xF))>>1); truelight@0: break; truelight@0: } truelight@0: truelight@0: return z; truelight@0: } truelight@0: truelight@0: uint GetSlopeZ(int x, int y) truelight@0: { truelight@0: TileInfo ti; truelight@0: // int z; truelight@0: truelight@0: FindLandscapeHeight(&ti, x, y); truelight@0: truelight@0: /* truelight@0: z = ti.z; truelight@0: x &= 0xF; truelight@0: y &= 0xF; truelight@0: truelight@0: truelight@0: assert(z < 256); truelight@0: */ truelight@0: return _tile_type_procs[ti.type]->get_slope_z_proc(&ti); truelight@0: } truelight@0: dominik@39: // direction=true: check for foundation in east and south corner dominik@39: // direction=false: check for foundation in west and south corner tron@1095: static bool hasFoundation(TileInfo *ti, bool direction) dominik@37: { dominik@39: bool south, other; // southern corner and east/west corner dominik@39: uint slope = _tile_type_procs[ti->type]->get_slope_tileh_proc(ti); dominik@50: uint tileh = ti->tileh; dominik@50: dominik@50: if(slope==0 && slope!=tileh) tileh=15; dominik@50: south = (tileh & 2) != (slope & 2); dominik@39: dominik@39: if(direction) dominik@50: other = (tileh & 4) != (slope & 4); dominik@39: else dominik@50: other = (tileh & 1) != (slope & 1); dominik@50: return south || other; dominik@39: dominik@37: } dominik@37: truelight@0: void DrawFoundation(TileInfo *ti, uint f) truelight@0: { dominik@37: uint32 sprite_base = SPR_SLOPES_BASE-14; dominik@39: dominik@39: TileInfo ti2; dominik@39: FindLandscapeHeight(&ti2, ti->x, ti->y-1); dominik@39: if(hasFoundation( &ti2, true )) sprite_base += 22; // foundation in NW direction dominik@39: FindLandscapeHeight(&ti2, ti->x-1, ti->y); dominik@39: if(hasFoundation( &ti2, false )) sprite_base += 22*2; // foundation in NE direction dominik@37: truelight@0: if (f < 15) { truelight@183: // leveled foundation dominik@37: if( sprite_base < SPR_SLOPES_BASE ) sprite_base = 990; // use original slope sprites dominik@37: dominik@37: AddSortableSpriteToDraw(f-1 + sprite_base, ti->x, ti->y, 16, 16, 7, ti->z); truelight@0: ti->z += 8; truelight@0: ti->tileh = 0; truelight@0: OffsetGroundSprite(31, 1); truelight@0: } else { truelight@0: // inclined foundation dominik@37: sprite_base += 14; truelight@183: truelight@0: AddSortableSpriteToDraw( dominik@37: HASBIT( (1<<1) | (1<<2) | (1<<4) | (1<<8), ti->tileh) ? sprite_base + (f - 15) : ti->tileh + 0x3DE - 1, truelight@0: ti->x, ti->y, 1, 1, 1, ti->z truelight@0: ); truelight@183: truelight@0: ti->tileh = _inclined_tileh[f - 15]; truelight@0: OffsetGroundSprite(31, 9); truelight@0: } truelight@0: } truelight@0: truelight@0: void DoClearSquare(uint tile) truelight@0: { truelight@0: ModifyTile(tile, truelight@0: MP_SETTYPE(MP_CLEAR) | truelight@0: MP_MAP2_CLEAR | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR | MP_MAPOWNER | MP_MAP5, truelight@0: OWNER_NONE, /* map_owner */ truelight@0: _generating_world ? 3 : 0 /* map5 */ truelight@0: ); truelight@0: } truelight@0: truelight@159: uint32 GetTileTrackStatus(uint tile, TransportType mode) truelight@0: { tron@1214: return _tile_type_procs[GetTileType(tile)]->get_tile_track_status_proc(tile, mode); truelight@0: } truelight@0: truelight@0: void ChangeTileOwner(uint tile, byte old_player, byte new_player) truelight@0: { tron@1214: _tile_type_procs[GetTileType(tile)]->change_tile_owner_proc(tile, old_player, new_player); truelight@0: } truelight@0: tron@473: void GetAcceptedCargo(uint tile, AcceptedCargo ac) truelight@0: { truelight@0: memset(ac, 0, sizeof(AcceptedCargo)); tron@1214: _tile_type_procs[GetTileType(tile)]->get_accepted_cargo_proc(tile, ac); truelight@0: } truelight@0: truelight@0: void AnimateTile(uint tile) truelight@0: { tron@1214: _tile_type_procs[GetTileType(tile)]->animate_tile_proc(tile); truelight@0: } truelight@0: truelight@0: void ClickTile(uint tile) truelight@0: { tron@1214: _tile_type_procs[GetTileType(tile)]->click_tile_proc(tile); truelight@0: } truelight@0: truelight@0: void DrawTile(TileInfo *ti) truelight@0: { truelight@0: _tile_type_procs[ti->type]->draw_tile_proc(ti); truelight@0: } truelight@0: truelight@0: void GetTileDesc(uint tile, TileDesc *td) truelight@0: { tron@1214: _tile_type_procs[GetTileType(tile)]->get_tile_desc_proc(tile, td); truelight@0: } truelight@0: truelight@0: /* Clear a piece of landscape truelight@0: * p1 = 0, truelight@0: * p2 = 0 truelight@0: */ truelight@0: truelight@0: int32 CmdLandscapeClear(int x, int y, uint32 flags, uint32 p1, uint32 p2) truelight@0: { truelight@0: uint tile; truelight@0: SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); truelight@0: truelight@0: tile = TILE_FROM_XY(x,y); tron@1214: return _tile_type_procs[GetTileType(tile)]->clear_tile_proc(tile, flags); truelight@0: } truelight@0: truelight@0: // p1 = end tile truelight@0: int32 CmdClearArea(int ex, int ey, uint32 flags, uint32 p1, uint32 p2) truelight@0: { truelight@0: int32 cost,ret, money; truelight@0: int sx,sy; truelight@0: int x,y; truelight@0: bool success = false; truelight@0: darkvater@889: SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); darkvater@889: truelight@0: // make sure sx,sy are smaller than ex,ey tron@926: sx = TileX(p1) * 16; tron@926: sy = TileY(p1) * 16; truelight@0: if (ex < sx) intswap(ex, sx); truelight@0: if (ey < sy) intswap(ey, sy); truelight@0: truelight@0: money = GetAvailableMoneyForCommand(); truelight@0: cost = 0; truelight@0: truelight@0: for(x=sx; x<=ex; x+=16) { truelight@0: for(y=sy; y<=ey; y+=16) { truelight@0: ret = DoCommandByTile(TILE_FROM_XY(x,y), 0, 0, flags &~DC_EXEC, CMD_LANDSCAPE_CLEAR); truelight@0: if (ret == CMD_ERROR) continue; truelight@0: cost += ret; truelight@0: success = true; truelight@0: truelight@0: if (flags & DC_EXEC) { truelight@0: if ( ret>0 && (money -= ret) < 0) { truelight@0: _additional_cash_required = ret; truelight@0: return cost - ret; truelight@0: } truelight@183: DoCommandByTile(TILE_FROM_XY(x,y), 0, 0, flags, CMD_LANDSCAPE_CLEAR); truelight@0: truelight@0: // draw explosion animation... truelight@0: if ((x==sx || x==ex) && (y==sy || y==ey)) { truelight@0: // big explosion in each corner, or small explosion for single tiles truelight@0: CreateEffectVehicleAbove(x + 8,y + 8, 2, sy==ey && sx==ex ? EV_DEMOLISH : EV_CRASHED_SMOKE); truelight@0: } truelight@0: } truelight@0: } truelight@0: } truelight@0: truelight@0: if (!success) truelight@0: cost = CMD_ERROR; truelight@0: return cost; truelight@0: } truelight@0: truelight@0: truelight@0: /* utility function used to modify a tile */ truelight@0: void CDECL ModifyTile(uint tile, uint flags, ...) truelight@0: { truelight@0: va_list va; truelight@0: int i; truelight@0: truelight@0: va_start(va, flags); truelight@0: truelight@0: if ((i = (flags >> 8) & 0xF) != 0) { tron@1059: SetTileType(tile, i - 1); truelight@0: } truelight@0: truelight@0: if (flags & (MP_MAP2_CLEAR | MP_MAP2)) { truelight@0: int x = 0; truelight@0: if (flags & MP_MAP2) x = va_arg(va, int); truelight@0: _map2[tile] = x; truelight@0: } truelight@0: truelight@0: if (flags & (MP_MAP3LO_CLEAR | MP_MAP3LO)) { truelight@0: int x = 0; truelight@0: if (flags & MP_MAP3LO) x = va_arg(va, int); truelight@0: _map3_lo[tile] = x; truelight@0: } truelight@0: truelight@0: if (flags & (MP_MAP3HI_CLEAR | MP_MAP3HI)) { truelight@0: int x = 0; truelight@0: if (flags & MP_MAP3HI) x = va_arg(va, int); truelight@0: _map3_hi[tile] = x; truelight@0: } truelight@0: truelight@0: if (flags & (MP_MAPOWNER|MP_MAPOWNER_CURRENT)) { truelight@0: byte x = _current_player; truelight@0: if (flags & MP_MAPOWNER) x = va_arg(va, int); truelight@0: _map_owner[tile] = x; truelight@0: } truelight@0: truelight@0: if (flags & MP_MAP5) { truelight@0: _map5[tile] = va_arg(va, int); truelight@0: } truelight@0: truelight@0: va_end(va); truelight@0: truelight@0: if (!(flags & MP_NODIRTY)) truelight@0: MarkTileDirtyByTile(tile); truelight@0: } truelight@0: truelight@0: truelight@0: #define TILELOOP_BITS 4 truelight@0: #define TILELOOP_SIZE (1 << TILELOOP_BITS) tron@927: #define TILELOOP_ASSERTMASK ((TILELOOP_SIZE-1) + ((TILELOOP_SIZE-1) << MapLogX())) tron@927: #define TILELOOP_CHKMASK (((1 << (MapLogX() - TILELOOP_BITS))-1) << TILELOOP_BITS) truelight@0: tron@1093: void RunTileLoop(void) truelight@0: { truelight@0: uint tile; truelight@0: uint count; truelight@0: truelight@0: tile = _cur_tileloop_tile; truelight@0: truelight@0: assert( (tile & ~TILELOOP_ASSERTMASK) == 0); tron@863: count = (MapSizeX() / TILELOOP_SIZE) * (MapSizeY() / TILELOOP_SIZE); truelight@0: do { tron@1214: _tile_type_procs[GetTileType(tile)]->tile_loop_proc(tile); truelight@0: tron@926: if (TileX(tile) < MapSizeX() - TILELOOP_SIZE) { truelight@0: tile += TILELOOP_SIZE; /* no overflow */ truelight@0: } else { tron@863: tile = TILE_MASK(tile - TILELOOP_SIZE * (MapSizeX() / TILELOOP_SIZE-1) + TILE_XY(0, TILELOOP_SIZE)); /* x would overflow, also increase y */ truelight@0: } truelight@0: } while (--count); truelight@0: assert( (tile & ~TILELOOP_ASSERTMASK) == 0); truelight@0: truelight@0: tile += 9; truelight@0: if (tile & TILELOOP_CHKMASK) tron@863: tile = (tile + MapSizeX()) & TILELOOP_ASSERTMASK; truelight@0: _cur_tileloop_tile = tile; truelight@0: } truelight@0: tron@1218: void InitializeLandscape(uint log_x, uint log_y) truelight@0: { tron@1218: uint map_size; tron@959: uint i; truelight@0: tron@1218: InitMap(log_x, log_y); tron@1218: map_size = MapSize(); tron@1218: truelight@840: memset(_map_type_and_height, MP_CLEAR << 4, map_size); tron@1218: memset(_map_owner, OWNER_NONE, map_size); tron@1218: memset(_map2, 0, map_size * sizeof(_map2[0])); tron@1218: memset(_map3_lo, 0, map_size); tron@1218: memset(_map3_hi, 0, map_size); tron@1218: memset(_map5, 3, map_size); tron@1218: memset(_map_extra_bits, 0, map_size / 4); truelight@0: tron@1181: // create void tiles at the border tron@1181: for (i = 0; i < MapMaxY(); ++i) tron@1181: SetTileType(i * MapSizeX() + MapMaxX(), MP_VOID); tron@1181: for (i = 0; i < MapSizeX(); ++i) tron@1181: SetTileType(MapSizeX() * MapMaxY() + i, MP_VOID); truelight@0: } truelight@0: tron@1093: void ConvertGroundTilesIntoWaterTiles(void) truelight@0: { truelight@0: uint tile = 0; truelight@0: int h; truelight@0: truelight@0: while(true) { tron@1035: if (IsTileType(tile, MP_CLEAR) && GetTileSlope(tile, &h) == 0 && h == 0) { tron@1059: SetTileType(tile, MP_WATER); truelight@0: _map5[tile] = 0; truelight@0: _map_owner[tile] = OWNER_WATER; truelight@0: } truelight@0: tile++; tron@926: if (TileX(tile) == MapMaxX()) { darkvater@857: tile += TILE_XY(-(int)MapMaxX(), 1); tron@926: if (TileY(tile) == MapMaxY()) truelight@0: break; truelight@0: } truelight@0: } truelight@0: } truelight@0: truelight@0: static const byte _genterrain_tbl_1[5] = { 10, 22, 33, 37, 4 }; truelight@0: static const byte _genterrain_tbl_2[5] = { 0, 0, 0, 0, 33 }; truelight@0: truelight@0: static void GenerateTerrain(int type, int flag) truelight@0: { truelight@0: uint32 r; darkvater@857: uint x,y; truelight@0: int w,h; truelight@0: byte *p,*tile; truelight@0: byte direction; truelight@0: truelight@0: r = Random(); truelight@0: p = GetSpritePtr((((r >> 24) * _genterrain_tbl_1[type]) >> 8) + _genterrain_tbl_2[type] + 4845); truelight@0: tron@856: x = r & MapMaxX(); tron@927: y = (r >> MapLogX()) & MapMaxY(); truelight@0: truelight@0: truelight@0: if (x < 2 || y < 2) truelight@0: return; truelight@0: truelight@0: direction = (byte)(r >> 22) & 3; truelight@0: w = p[2]; truelight@0: h = p[1]; truelight@0: if (direction & 1) { w = p[1]; h = p[2]; } truelight@183: p += 8; truelight@0: truelight@0: if (flag & 4) { truelight@0: if (!(flag & 2)) { truelight@0: if (!(flag & 1)) { truelight@0: if (x + y > 190) truelight@0: return; truelight@0: } else { truelight@0: if (y < 30 + x) truelight@0: return; truelight@0: } truelight@0: } else { truelight@0: if (!(flag & 1)) { truelight@0: if (x + y < 256) truelight@0: return; truelight@0: } else { truelight@0: if (x < 30 + y) truelight@0: return; truelight@0: } truelight@0: } truelight@0: } truelight@0: tron@856: if (x + w >= MapMaxX() - 1) truelight@0: return; truelight@0: tron@856: if (y + h >= MapMaxY() - 1) truelight@0: return; truelight@0: truelight@0: tile = &_map_type_and_height[TILE_XY(x,y)]; truelight@0: truelight@0: if (direction == 0) { truelight@0: do { truelight@0: int w_cur = w; truelight@0: byte *tile_cur = tile; truelight@0: do { truelight@0: if (*p >= *tile_cur) *tile_cur = *p; truelight@0: p++; truelight@0: tile_cur++; truelight@0: } while (--w_cur != 0); truelight@0: tile += TILE_XY(0,1); truelight@0: } while (--h != 0); truelight@0: } else if (direction == 1) { truelight@0: do { truelight@0: int h_cur = h; truelight@0: byte *tile_cur = tile; truelight@0: do { truelight@0: if (*p >= *tile_cur) *tile_cur = *p; truelight@0: p++; truelight@0: tile_cur+=TILE_XY(0,1); truelight@0: } while (--h_cur != 0); truelight@0: tile++; truelight@0: } while (--w != 0); truelight@0: } else if (direction == 2) { truelight@0: tile += w - 1; truelight@0: do { truelight@0: int w_cur = w; truelight@0: byte *tile_cur = tile; truelight@0: do { truelight@0: if (*p >= *tile_cur) *tile_cur = *p; truelight@0: p++; truelight@0: tile_cur--; truelight@0: } while (--w_cur != 0); truelight@0: tile += TILE_XY(0,1); truelight@0: } while (--h != 0); truelight@0: } else { truelight@0: tile += (h - 1) * TILE_XY(0,1); truelight@0: do { truelight@0: int h_cur = h; truelight@0: byte *tile_cur = tile; truelight@0: do { truelight@0: if (*p >= *tile_cur) *tile_cur = *p; truelight@0: p++; truelight@0: tile_cur-=TILE_XY(0,1); truelight@0: } while (--h_cur != 0); truelight@0: tile++; truelight@0: } while (--w != 0); truelight@0: } truelight@0: } truelight@0: truelight@0: truelight@0: #include "table/genland.h" truelight@0: tron@1093: static void CreateDesertOrRainForest(void) truelight@0: { truelight@0: uint tile; tron@909: const TileIndexDiffC *data; truelight@0: int i; truelight@0: tron@909: for (tile = 0; tile != MapSize(); ++tile) { tron@909: for (data = _make_desert_or_rainforest_data; tron@909: data != endof(_make_desert_or_rainforest_data); ++data) { tron@1184: TileIndex t = TILE_MASK(tile + ToTileIndexDiff(*data)); tron@1044: if (TileHeight(t) >= 4 || IsTileType(t, MP_WATER)) break; tron@909: } tron@909: if (data == endof(_make_desert_or_rainforest_data)) tron@909: SetMapExtraBits(tile, 1); tron@909: } truelight@183: truelight@0: for(i=0; i!=256; i++) truelight@0: RunTileLoop(); truelight@0: tron@909: for (tile = 0; tile != MapSize(); ++tile) { tron@909: for (data = _make_desert_or_rainforest_data; tron@909: data != endof(_make_desert_or_rainforest_data); ++data) { tron@909: TileIndex t = TILE_MASK(tile + ToTileIndexDiff(*data)); tron@1035: if (IsTileType(t, MP_CLEAR) && (_map5[t] & 0x1c) == 0x14) break; tron@909: } tron@909: if (data == endof(_make_desert_or_rainforest_data)) tron@909: SetMapExtraBits(tile, 2); tron@909: } truelight@0: } truelight@0: tron@1093: void GenerateLandscape(void) truelight@0: { truelight@0: int i,flag; truelight@0: uint32 r; truelight@183: truelight@0: if (_opt.landscape == LT_HILLY) { tron@1202: i = ScaleByMapSize((Random() & 0x7F) + 950); truelight@0: do { truelight@0: GenerateTerrain(2, 0); truelight@0: } while (--i); truelight@183: truelight@0: r = Random(); truelight@0: flag = (r & 3) | 4; tron@1202: i = ScaleByMapSize(((r >> 16) & 0x7F) + 450); truelight@0: do { truelight@0: GenerateTerrain(4, flag); truelight@0: } while (--i); truelight@0: } else if (_opt.landscape == LT_DESERT) { tron@1202: i = ScaleByMapSize((Random()&0x7F) + 170); truelight@0: do { truelight@0: GenerateTerrain(0, 0); truelight@0: } while (--i); truelight@183: truelight@0: r = Random(); truelight@0: flag = (r & 3) | 4; tron@1202: i = ScaleByMapSize(((r >> 16) & 0xFF) + 1700); truelight@0: do { truelight@0: GenerateTerrain(0, flag); truelight@0: } while (--i); truelight@0: truelight@0: flag ^= 2; truelight@0: tron@1202: i = ScaleByMapSize((Random() & 0x7F) + 410); truelight@0: do { truelight@183: GenerateTerrain(3, flag); truelight@0: } while (--i); truelight@0: } else { tron@1202: i = ScaleByMapSize((Random() & 0x7F) + (3 - _opt.diff.quantity_sea_lakes) * 256 + 100); truelight@0: do { truelight@0: GenerateTerrain(_opt.diff.terrain_type, 0); truelight@0: } while (--i); truelight@0: } truelight@0: truelight@0: ConvertGroundTilesIntoWaterTiles(); truelight@0: truelight@0: if (_opt.landscape == LT_DESERT) truelight@0: CreateDesertOrRainForest(); truelight@0: } truelight@0: tron@1093: void OnTick_Town(void); tron@1093: void OnTick_Trees(void); tron@1093: void OnTick_Station(void); tron@1093: void OnTick_Industry(void); truelight@0: tron@1093: void OnTick_Players(void); tron@1093: void OnTick_Train(void); truelight@0: tron@1093: void CallLandscapeTick(void) truelight@0: { truelight@0: OnTick_Town(); truelight@0: OnTick_Trees(); truelight@0: OnTick_Station(); truelight@0: OnTick_Industry(); truelight@0: truelight@0: OnTick_Players(); truelight@0: OnTick_Train(); truelight@0: } truelight@0: truelight@0: TileIndex AdjustTileCoordRandomly(TileIndex a, byte rng) truelight@0: { truelight@0: int rn = rng; truelight@0: uint32 r = Random(); truelight@0: tron@1174: return TILE_MASK(TILE_XY( tron@926: TileX(a) + ((byte)r * rn * 2 >> 8) - rn, tron@926: TileY(a) + ((byte)(r >> 8) * rn * 2 >> 8) - rn tron@1174: )); truelight@0: } truelight@0: truelight@0: bool IsValidTile(uint tile) truelight@0: { tron@926: return (tile < MapSizeX() * MapMaxY() && TileX(tile) != MapMaxX()); truelight@0: }