truelight@0: #include "stdafx.h" Darkvater@1891: #include "openttd.h" tron@507: #include "table/strings.h" Darkvater@1784: #include "table/tree_land.h" tron@679: #include "map.h" tron@1209: #include "tile.h" truelight@0: #include "viewport.h" truelight@0: #include "command.h" truelight@0: #include "town.h" tron@337: #include "sound.h" truelight@0: tron@1286: static int GetRandomTreeType(TileIndex tile, uint seed) truelight@0: { tron@1286: switch (_opt.landscape) { tron@1286: case LT_NORMAL: tron@1286: return seed * 12 >> 8; truelight@0: tron@1286: case LT_HILLY: tron@1286: return (seed >> 5) + 12; tron@1286: tron@1286: case LT_DESERT: tron@1286: switch (GetMapExtraBits(tile)) { tron@1286: case 0: tron@1286: return (seed >> 6) + 28; tron@1286: tron@1286: case 1: tron@1286: return (seed > 12) ? -1 : 27; tron@1286: tron@1286: default: tron@1286: return (seed * 7 >> 8) + 20; tron@1286: } tron@1286: tron@1286: default: tron@1286: return (seed * 9 >> 8) + 32; truelight@0: } truelight@0: } truelight@0: tron@1977: static void PlaceTree(TileIndex tile, uint32 r, byte m5_or) truelight@0: { truelight@0: int tree = GetRandomTreeType(tile, (r >> 24)); truelight@0: byte m5; truelight@0: truelight@0: if (tree >= 0) { truelight@0: m5 = (byte)(r >> 16); tron@407: if ((m5 & 0x7) == 7) m5--; // there is no growth state 7 truelight@0: tron@2049: _m[tile].m5 = m5 & 0x07; // growth state; tron@2049: _m[tile].m5 |= m5 & 0xC0; // amount of trees truelight@0: tron@2049: _m[tile].m3 = tree; // set type of tree tron@2049: _m[tile].m4 = 0; // no hedge truelight@0: truelight@0: // above snowline? tron@1370: if (_opt.landscape == LT_HILLY && GetTileZ(tile) > _opt.snow_line) { tron@2049: _m[tile].m2 = 0xE0; // set land type to snow tron@2049: _m[tile].m2 |= (byte)(r >> 24)&0x07; // randomize counter truelight@0: } truelight@0: else truelight@0: { tron@2049: _m[tile].m2 = (byte)(r >> 24)&0x1F; // randomize counter and ground truelight@0: } truelight@0: truelight@0: truelight@0: // make it tree class tron@1059: SetTileType(tile, MP_TREES); truelight@0: } truelight@0: } truelight@0: tron@1977: static void DoPlaceMoreTrees(TileIndex tile) truelight@0: { truelight@0: int i = 1000; truelight@0: int x,y; truelight@0: int dist; truelight@0: truelight@0: do { truelight@0: uint32 r = Random(); tron@1977: TileIndex cur_tile; tron@1977: truelight@0: x = (r & 0x1F) - 16; truelight@0: y = ((r>>8) & 0x1F) - 16; truelight@0: truelight@0: dist = myabs(x) + myabs(y); truelight@0: tron@1981: cur_tile = TILE_MASK(tile + TileDiffXY(x, y)); truelight@0: truelight@828: /* Only on tiles within 13 squares from tile, darkvater@874: on clear tiles, and NOT on farm-tiles or rocks */ tron@1035: if (dist <= 13 && IsTileType(cur_tile, MP_CLEAR) && tron@2049: (_m[cur_tile].m5 & 0x1F) != 0x0F && (_m[cur_tile].m5 & 0x1C) != 8) { truelight@0: PlaceTree(cur_tile, r, dist <= 6 ? 0xC0 : 0); truelight@0: } truelight@0: } while (--i); truelight@0: } truelight@0: tron@1093: static void PlaceMoreTrees(void) truelight@0: { tron@1202: int i = ScaleByMapSize((Random() & 0x1F) + 25); truelight@0: do { ludde@2051: DoPlaceMoreTrees(RandomTile()); truelight@0: } while (--i); truelight@0: } truelight@0: tron@1093: void PlaceTreesRandomly(void) truelight@0: { truelight@0: int i; truelight@0: uint32 r; tron@1977: TileIndex tile; truelight@0: tron@1202: i = ScaleByMapSize(1000); truelight@0: do { truelight@0: r = Random(); ludde@2051: tile = RandomTileSeed(r); darkvater@874: /* Only on clear tiles, and NOT on farm-tiles or rocks */ tron@2049: if (IsTileType(tile, MP_CLEAR) && (_m[tile].m5 & 0x1F) != 0x0F && (_m[tile].m5 & 0x1C) != 8) { truelight@0: PlaceTree(tile, r, 0); truelight@0: } truelight@0: } while (--i); truelight@0: truelight@0: /* place extra trees at rainforest area */ truelight@0: if (_opt.landscape == LT_DESERT) { tron@1202: i = ScaleByMapSize(15000); truelight@0: truelight@0: do { truelight@0: r = Random(); ludde@2051: tile = RandomTileSeed(r); tron@1035: if (IsTileType(tile, MP_CLEAR) && GetMapExtraBits(tile) == 2) { truelight@0: PlaceTree(tile, r, 0); truelight@0: } truelight@0: } while (--i); truelight@0: } truelight@0: } truelight@0: tron@1093: void GenerateTrees(void) truelight@0: { truelight@0: int i; truelight@0: truelight@0: if (_opt.landscape != LT_CANDY) { truelight@0: PlaceMoreTrees(); truelight@0: } truelight@0: truelight@0: i = _opt.landscape == LT_HILLY ? 15 : 6; truelight@0: do { truelight@0: PlaceTreesRandomly(); truelight@0: } while (--i); truelight@0: } truelight@0: Darkvater@1784: /** Plant a tree. Darkvater@1784: * @param x,y start tile of area-drag of tree plantation Darkvater@1784: * @param p1 tree type, -1 means random. Darkvater@1784: * @param p2 end tile of area-drag truelight@0: */ truelight@0: int32 CmdPlantTree(int ex, int ey, uint32 flags, uint32 p1, uint32 p2) truelight@0: { truelight@0: int32 cost; tron@1286: int sx; tron@1286: int sy; tron@1286: int x; tron@1286: int y; tron@1286: Darkvater@1784: if (p2 > MapSize()) return CMD_ERROR; Darkvater@1784: /* Check the tree type. It can be random or some valid value within the current climate */ Darkvater@1784: if (p1 != (uint)-1 && p1 - _tree_base_by_landscape[_opt.landscape] >= _tree_count_by_landscape[_opt.landscape]) return CMD_ERROR; truelight@193: truelight@0: SET_EXPENSES_TYPE(EXPENSES_OTHER); truelight@0: truelight@0: // make sure sx,sy are smaller than ex,ey tron@926: sx = TileX(p2) * 16; tron@926: sy = TileY(p2) * 16; truelight@0: if (ex < sx) intswap(ex, sx); truelight@0: if (ey < sy) intswap(ey, sy); truelight@193: truelight@0: cost = 0; // total cost truelight@0: tron@1286: for (x = sx; x <= ex; x += 16) { tron@1286: for (y = sy; y <= ey; y += 16) { tron@1286: TileInfo ti; tron@1286: truelight@0: FindLandscapeHeight(&ti, x, y); truelight@0: if (!EnsureNoVehicle(ti.tile)) truelight@0: continue; truelight@0: tron@1286: switch (ti.type) { tron@1286: case MP_TREES: tron@1286: // no more space for trees? tron@1286: if (_game_mode != GM_EDITOR && (ti.map5 & 0xC0) == 0xC0) { tron@1286: _error_message = STR_2803_TREE_ALREADY_HERE; tron@1286: continue; truelight@0: } truelight@0: tron@1286: if (flags & DC_EXEC) { tron@2049: _m[ti.tile].m5 = ti.map5 + 0x40; tron@1286: MarkTileDirtyByTile(ti.tile); tron@1286: } tron@1286: // 2x as expensive to add more trees to an existing tile tron@1286: cost += _price.build_trees * 2; tron@1286: break; tron@1286: tron@1286: case MP_CLEAR: tron@1901: if (!IsTileOwner(ti.tile, OWNER_NONE)) { tron@1286: _error_message = STR_2804_SITE_UNSUITABLE; tron@1286: continue; truelight@0: } truelight@193: tron@1286: // it's expensive to clear farmland tron@1286: if ((ti.map5 & 0x1F) == 0xF) tron@1286: cost += _price.clear_3; tron@1286: else if ((ti.map5 & 0x1C) == 8) tron@1286: cost += _price.clear_2; truelight@0: tron@1286: if (flags & DC_EXEC) { tron@1286: int treetype; tron@1286: int m2; tron@1286: tron@1286: if (_game_mode != GM_EDITOR && _current_player < MAX_PLAYERS) { tron@1286: Town *t = ClosestTownFromTile(ti.tile, _patches.dist_local_authority); tron@1286: if (t != NULL) tron@1286: ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM); tron@1286: } tron@1286: tron@1286: switch (ti.map5 & 0x1C) { tron@1286: case 0x04: tron@1286: m2 = 16; tron@1286: break; tron@1286: tron@1286: case 0x10: tron@1286: m2 = ((ti.map5 & 3) << 6) | 0x20; tron@1286: break; tron@1286: tron@1286: default: tron@1286: m2 = 0; tron@1286: break; tron@1286: } tron@1286: tron@1286: treetype = p1; tron@1286: if (treetype == -1) { tron@1286: treetype = GetRandomTreeType(ti.tile, Random() >> 24); tron@1286: if (treetype == -1) treetype = 27; tron@1286: } tron@1286: tron@1286: ModifyTile(ti.tile, tron@1286: MP_SETTYPE(MP_TREES) | tron@1286: MP_MAP2 | MP_MAP3LO | MP_MAP3HI_CLEAR | MP_MAP5, tron@1286: m2, /* map2 */ tron@1286: treetype, /* map3lo */ tron@1286: _game_mode == GM_EDITOR ? 3 : 0 /* map5 */ tron@1286: ); tron@1286: tron@1286: if (_game_mode == GM_EDITOR && IS_BYTE_INSIDE(treetype, 0x14, 0x1B)) tron@1286: SetMapExtraBits(ti.tile, 2); truelight@0: } tron@1286: cost += _price.build_trees; tron@1286: break; tron@1286: tron@1286: default: tron@1286: _error_message = STR_2804_SITE_UNSUITABLE; tron@1286: break; truelight@0: } truelight@0: } truelight@0: } truelight@193: Darkvater@1784: return (cost == 0) ? CMD_ERROR : cost; truelight@0: } truelight@0: truelight@0: typedef struct TreeListEnt { truelight@0: uint32 image; truelight@0: byte x,y; truelight@0: } TreeListEnt; truelight@0: truelight@0: static void DrawTile_Trees(TileInfo *ti) truelight@0: { truelight@817: uint16 m2; truelight@0: const uint32 *s; truelight@0: const byte *d; truelight@0: byte z; truelight@0: TreeListEnt te[4]; truelight@0: tron@2049: m2 = _m[ti->tile].m2; truelight@0: truelight@0: if ( (m2&0x30) == 0) { truelight@0: DrawClearLandTile(ti, 3); truelight@0: } else if ((m2&0x30) == 0x20) { truelight@0: DrawGroundSprite(_tree_sprites_1[m2 >> 6] + _tileh_to_sprite[ti->tileh]); truelight@0: } else { truelight@0: DrawHillyLandTile(ti); truelight@0: } truelight@0: tron@2049: DrawClearLandFence(ti, _m[ti->tile].m4 >> 2); truelight@0: truelight@0: z = ti->z; truelight@0: if (ti->tileh != 0) { truelight@0: z += 4; truelight@0: if (ti->tileh & 0x10) truelight@0: z += 4; truelight@0: } truelight@0: truelight@0: { truelight@0: uint16 tmp = ti->x; tron@959: uint index; truelight@0: truelight@0: tmp = (tmp >> 2) | (tmp << 14); truelight@0: tmp -= ti->y; truelight@0: tmp = (tmp >> 3) | (tmp << 13); truelight@0: tmp -= ti->x; truelight@0: tmp = (tmp >> 1) | (tmp << 15); truelight@0: tmp += ti->y; truelight@0: truelight@0: d = _tree_layout_xy[(tmp & 0x30) >> 4]; truelight@0: tron@2049: index = ((tmp>>6)&3) + (_m[ti->tile].m3<<2); truelight@193: truelight@0: /* different tree styles above one of the grounds */ truelight@0: if ((m2 & 0xB0) == 0xA0 && index >= 48 && index < 80) truelight@0: index += 164 - 48; truelight@193: truelight@193: assert(index < lengthof(_tree_layout_sprite)); truelight@0: s = _tree_layout_sprite[index]; truelight@0: } truelight@0: truelight@0: StartSpriteCombine(); truelight@0: tron@497: if (!(_display_opt & DO_TRANS_BUILDINGS) || !_patches.invisible_trees) truelight@0: { truelight@0: int i; truelight@0: truelight@0: /* put the trees to draw in a list */ truelight@0: i = (ti->map5 >> 6) + 1; truelight@0: do { truelight@0: uint32 image = s[0] + (--i==0 ? (ti->map5 & 7) : 3); tron@497: if (_display_opt & DO_TRANS_BUILDINGS) truelight@0: image = (image & 0x3FFF) | 0x3224000; truelight@0: te[i].image = image; truelight@0: te[i].x = d[0]; truelight@0: te[i].y = d[1]; truelight@0: s++; truelight@0: d+=2; truelight@0: } while (i); truelight@0: truelight@0: /* draw them in a sorted way */ truelight@0: for(;;) { truelight@0: byte min = 0xFF; truelight@0: TreeListEnt *tep = NULL; truelight@0: truelight@0: i = (ti->map5 >> 6) + 1; truelight@0: do { truelight@0: if (te[--i].image!=0 && (byte)(te[i].x + te[i].y) < min) { truelight@0: min = te[i].x + te[i].y; truelight@0: tep = &te[i]; truelight@0: } truelight@0: } while (i); truelight@0: truelight@0: if (tep == NULL) truelight@0: break; truelight@0: truelight@0: AddSortableSpriteToDraw(tep->image, ti->x + tep->x, ti->y + tep->y, 5, 5, 0x10, z); truelight@0: tep->image = 0; truelight@0: } truelight@0: } truelight@0: truelight@0: EndSpriteCombine(); truelight@0: } truelight@0: truelight@0: truelight@0: static uint GetSlopeZ_Trees(TileInfo *ti) { truelight@0: return GetPartialZ(ti->x&0xF, ti->y&0xF, ti->tileh) + ti->z; truelight@0: } truelight@0: dominik@39: static uint GetSlopeTileh_Trees(TileInfo *ti) { dominik@39: return ti->tileh; dominik@39: } dominik@39: tron@1977: static int32 ClearTile_Trees(TileIndex tile, byte flags) tron@1977: { truelight@0: int num; truelight@0: truelight@0: if (flags & DC_EXEC && _current_player < MAX_PLAYERS) { truelight@0: Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority); truelight@193: if (t != NULL) celestar@1005: ChangeTownRating(t, RATING_TREE_DOWN_STEP, RATING_TREE_MINIMUM); truelight@0: } truelight@0: tron@2049: num = (_m[tile].m5 >> 6) + 1; tron@2049: if ( (byte)(_m[tile].m3-0x14) <= (0x1A-0x14)) truelight@0: num <<= 2; truelight@0: truelight@0: if (flags & DC_EXEC) truelight@0: DoClearSquare(tile); truelight@0: truelight@0: return num * _price.remove_trees; truelight@0: } truelight@0: tron@1977: static void GetAcceptedCargo_Trees(TileIndex tile, AcceptedCargo ac) truelight@0: { truelight@0: /* not used */ truelight@0: } truelight@0: tron@1977: static void GetTileDesc_Trees(TileIndex tile, TileDesc *td) truelight@0: { truelight@0: byte b; truelight@0: StringID str; truelight@0: tron@1901: td->owner = GetTileOwner(tile); truelight@0: tron@2049: b = _m[tile].m3; truelight@0: (str=STR_2810_CACTUS_PLANTS, b==0x1B) || truelight@0: (str=STR_280F_RAINFOREST, IS_BYTE_INSIDE(b, 0x14, 0x1A+1)) || truelight@0: (str=STR_280E_TREES, true); truelight@193: td->str = str; truelight@0: } truelight@0: tron@1977: static void AnimateTile_Trees(TileIndex tile) truelight@0: { truelight@0: /* not used */ truelight@0: } truelight@0: tron@541: static SoundFx _desert_sounds[] = { tron@541: SND_42_LOON_BIRD, tron@541: SND_43_LION, tron@541: SND_44_MONKEYS, tron@541: SND_48_DISTANT_BIRD truelight@0: }; truelight@0: tron@1977: static void TileLoopTreesDesert(TileIndex tile) truelight@0: { truelight@0: byte b; truelight@0: truelight@0: if ((b=GetMapExtraBits(tile)) == 2) { truelight@0: uint32 r; truelight@0: truelight@0: if (CHANCE16I(1,200,r=Random())) { truelight@0: SndPlayTileFx(_desert_sounds[(r >> 16) & 3], tile); truelight@0: } truelight@0: } else if (b == 1) { tron@2049: if ((_m[tile].m2 & 0x30) != 0x20) { tron@2049: _m[tile].m2 &= 0xF; tron@2049: _m[tile].m2 |= 0xE0; truelight@0: MarkTileDirtyByTile(tile); truelight@0: } truelight@0: } truelight@0: } truelight@0: tron@1977: static void TileLoopTreesAlps(TileIndex tile) truelight@0: { truelight@0: byte tmp, m2; truelight@0: int k; truelight@0: truelight@0: /* distance from snow line, in steps of 8 */ truelight@0: k = GetTileZ(tile) - _opt.snow_line; truelight@0: tron@2049: tmp = _m[tile].m5 & 0xF0; truelight@0: truelight@0: if (k < -8) { truelight@0: /* snow_m2_down */ truelight@0: if ((tmp&0x30) != 0x20) truelight@0: return; truelight@0: m2 = 0; truelight@0: } else if (k == -8) { truelight@0: /* snow_m1 */ truelight@193: m2 = 0x20; truelight@0: if (tmp == m2) truelight@0: return; truelight@0: } else if (k < 8) { truelight@0: /* snow_0 */ truelight@0: m2 = 0x60; truelight@0: if (tmp == m2) truelight@0: return; truelight@0: } else if (k == 8) { truelight@0: /* snow_p1 */ truelight@0: m2 = 0xA0; truelight@0: if (tmp == m2) truelight@0: return; truelight@0: } else { truelight@0: /* snow_p2_up */ truelight@0: if (tmp == 0xC0) { truelight@0: uint32 r; truelight@0: if (CHANCE16I(1,200,r=Random())) { tron@541: SndPlayTileFx((r & 0x80000000) ? SND_39_HEAVY_WIND : SND_34_WIND, tile); truelight@0: } truelight@0: return; truelight@0: } else { truelight@0: m2 = 0xE0; truelight@0: } truelight@0: } truelight@0: tron@2049: _m[tile].m2 &= 0xF; tron@2049: _m[tile].m2 |= m2; truelight@0: MarkTileDirtyByTile(tile); truelight@0: } truelight@0: tron@1977: static void TileLoop_Trees(TileIndex tile) truelight@0: { truelight@817: byte m5; truelight@817: uint16 m2; truelight@0: tron@909: static const TileIndexDiffC _tileloop_trees_dir[] = { tron@909: {-1, -1}, tron@909: { 0, -1}, tron@909: { 1, -1}, tron@909: {-1, 0}, tron@909: { 1, 0}, tron@909: {-1, 1}, tron@909: { 0, 1}, tron@909: { 1, 1} truelight@0: }; truelight@0: truelight@0: if (_opt.landscape == LT_DESERT) { truelight@0: TileLoopTreesDesert(tile); truelight@0: } else if (_opt.landscape == LT_HILLY) { truelight@0: TileLoopTreesAlps(tile); truelight@0: } truelight@0: truelight@0: TileLoopClearHelper(tile); truelight@0: truelight@0: /* increase counter */ truelight@0: { tron@2049: uint16 m2 = _m[tile].m2; tron@2049: _m[tile].m2 = m2 = (m2 & 0xF0) | ((m2+1)&0xF); truelight@0: if (m2 & 0xF) truelight@0: return; truelight@0: } truelight@0: tron@2049: m5 = _m[tile].m5; truelight@0: if ((m5&7) == 3) { truelight@0: /* regular sized tree */ tron@2049: if (_opt.landscape == LT_DESERT && _m[tile].m3!=0x1B && GetMapExtraBits(tile)==1) { truelight@0: m5++; /* start destructing */ truelight@0: } else { truelight@0: switch(Random() & 0x7) { truelight@0: case 0: /* start destructing */ truelight@0: m5++; truelight@0: break; truelight@193: truelight@0: case 1: /* add a tree */ truelight@0: if (m5 < 0xC0) { truelight@0: m5 = (m5 + 0x40) & ~7; truelight@0: break; truelight@0: } truelight@0: /* fall through */ truelight@0: truelight@0: case 2: { /* add a neighbouring tree */ tron@2049: byte m3 = _m[tile].m3; truelight@193: tron@909: tile += ToTileIndexDiff(_tileloop_trees_dir[Random() & 7]); truelight@0: tron@1035: if (!IsTileType(tile, MP_CLEAR)) truelight@0: return; truelight@0: tron@2049: if ( (_m[tile].m5 & 0x1C) == 4) { tron@2049: _m[tile].m2 = 0x10; tron@2049: } else if ((_m[tile].m5 & 0x1C) == 16) { tron@2049: _m[tile].m2 = ((_m[tile].m5 & 3) << 6) | 0x20; truelight@0: } else { tron@2049: if ((_m[tile].m5 & 0x1F) != 3) truelight@0: return; tron@2049: _m[tile].m2 = 0; truelight@0: } truelight@0: tron@2049: _m[tile].m3 = m3; tron@2049: _m[tile].m4 = 0; tron@1059: SetTileType(tile, MP_TREES); truelight@0: truelight@0: m5 = 0; truelight@0: break; truelight@193: } truelight@0: truelight@0: default: truelight@0: return; truelight@0: } truelight@0: } truelight@0: } else if ((m5&7) == 6) { truelight@0: /* final stage of tree destruction */ truelight@0: if (m5 & 0xC0) { truelight@0: /* more than one tree, delete it? */ truelight@0: m5 = ((m5 - 6) - 0x40) + 3; truelight@0: } else { truelight@0: /* just one tree, change type into MP_CLEAR */ tron@1059: SetTileType(tile, MP_CLEAR); truelight@0: truelight@0: m5 = 3; tron@2049: m2 = _m[tile].m2; darkvater@881: if ((m2&0x30) != 0) { // on snow/desert or rough land truelight@0: m5 = (m2 >> 6) | 0x10; darkvater@881: if ((m2&0x30) != 0x20) // if not on snow/desert, then on rough land truelight@0: m5 = 7; truelight@0: } tron@1902: SetTileOwner(tile, OWNER_NONE); truelight@0: } truelight@0: } else { truelight@0: /* in the middle of a transition, change to next */ truelight@0: m5++; truelight@0: } truelight@0: tron@2049: _m[tile].m5 = m5; truelight@0: MarkTileDirtyByTile(tile); truelight@0: } truelight@0: tron@1093: void OnTick_Trees(void) truelight@0: { truelight@0: uint32 r; tron@1977: TileIndex tile; truelight@0: byte m; truelight@0: int tree; truelight@0: truelight@0: /* place a tree at a random rainforest spot */ truelight@193: if (_opt.landscape == LT_DESERT && ludde@2051: (r=Random(),tile=RandomTileSeed(r),GetMapExtraBits(tile)==2) && tron@1035: IsTileType(tile, MP_CLEAR) && tron@2049: (m=_m[tile].m5&0x1C, m<=4) && truelight@0: (tree=GetRandomTreeType(tile, r>>24)) >= 0) { truelight@193: truelight@0: ModifyTile(tile, truelight@193: MP_SETTYPE(MP_TREES) | truelight@0: MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5, truelight@0: (m == 4 ? 0x10 : 0), truelight@0: tree, tron@2049: _m[tile].m4 & ~3, truelight@0: 0 truelight@0: ); truelight@0: } truelight@0: truelight@0: // byte underflow truelight@0: if (--_trees_tick_ctr) truelight@0: return; truelight@193: truelight@0: /* place a tree at a random spot */ truelight@0: r = Random(); truelight@0: tile = TILE_MASK(r); tron@1035: if (IsTileType(tile, MP_CLEAR) && tron@2049: (m=_m[tile].m5&0x1C, m==0 || m==4 || m==0x10) && truelight@0: (tree=GetRandomTreeType(tile, r>>24)) >= 0) { truelight@0: int m2; truelight@193: truelight@0: if (m == 0) { truelight@0: m2 = 0; truelight@0: } else if (m == 4) { truelight@0: m2 = 0x10; truelight@0: } else { tron@2049: m2 = ((_m[tile].m5 & 3) << 6) | 0x20; truelight@0: } truelight@0: truelight@0: ModifyTile(tile, truelight@193: MP_SETTYPE(MP_TREES) | truelight@0: MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5, truelight@0: m2, truelight@0: tree, tron@2049: _m[tile].m4 & ~3, truelight@0: 0 truelight@0: ); truelight@0: } truelight@0: } truelight@0: tron@1977: static void ClickTile_Trees(TileIndex tile) truelight@0: { truelight@0: /* not used */ truelight@0: } truelight@0: tron@1977: static uint32 GetTileTrackStatus_Trees(TileIndex tile, TransportType mode) truelight@0: { truelight@0: return 0; truelight@0: } truelight@0: tron@1977: static void ChangeTileOwner_Trees(TileIndex tile, byte old_player, byte new_player) truelight@0: { truelight@0: /* not used */ truelight@0: } truelight@0: tron@1093: void InitializeTrees(void) truelight@0: { truelight@0: _trees_tick_ctr = 0; truelight@0: } truelight@0: truelight@0: truelight@0: const TileTypeProcs _tile_type_trees_procs = { truelight@0: DrawTile_Trees, /* draw_tile_proc */ truelight@0: GetSlopeZ_Trees, /* get_slope_z_proc */ truelight@0: ClearTile_Trees, /* clear_tile_proc */ truelight@0: GetAcceptedCargo_Trees, /* get_accepted_cargo_proc */ truelight@0: GetTileDesc_Trees, /* get_tile_desc_proc */ truelight@0: GetTileTrackStatus_Trees, /* get_tile_track_status_proc */ truelight@0: ClickTile_Trees, /* click_tile_proc */ truelight@0: AnimateTile_Trees, /* animate_tile_proc */ truelight@0: TileLoop_Trees, /* tile_loop_clear */ truelight@0: ChangeTileOwner_Trees, /* change_tile_owner_clear */ truelight@0: NULL, /* get_produced_cargo_proc */ truelight@0: NULL, /* vehicle_enter_tile_proc */ truelight@0: NULL, /* vehicle_leave_tile_proc */ dominik@39: GetSlopeTileh_Trees, /* get_slope_tileh_proc */ truelight@0: };