tron@2186: /* $Id$ */ tron@2186: truelight@0: #include "stdafx.h" Darkvater@1891: #include "openttd.h" tron@507: #include "table/strings.h" celestar@2148: #include "table/sprites.h" Darkvater@1784: #include "table/tree_land.h" tron@2163: #include "functions.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" tron@2153: #include "variables.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@2088: case 0: return (seed >> 6) + 28; tron@2088: case 1: return (seed > 12) ? -1 : 27; tron@2088: default: 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: { tron@2088: int tree = GetRandomTreeType(tile, GB(r, 24, 8)); truelight@0: byte m5; truelight@0: truelight@0: if (tree >= 0) { tron@2088: SetTileType(tile, MP_TREES); tron@2088: tron@2088: m5 = GB(r, 16, 8); tron@2088: if (GB(m5, 0, 3) == 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@2088: _m[tile].m2 |= GB(r, 24, 3); // randomize counter tron@2088: } else { tron@2088: _m[tile].m2 = GB(r, 24, 5); // randomize counter and ground truelight@0: } truelight@0: } truelight@0: } truelight@0: tron@1977: static void DoPlaceMoreTrees(TileIndex tile) truelight@0: { tron@2088: uint i; truelight@0: tron@2088: for (i = 0; i < 1000; i++) { truelight@0: uint32 r = Random(); tron@2088: int x = GB(r, 0, 5) - 16; tron@2088: int y = GB(r, 8, 5) - 16; tron@2088: uint dist = myabs(x) + myabs(y); tron@2088: TileIndex 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: } tron@2088: } truelight@0: } truelight@0: tron@1093: static void PlaceMoreTrees(void) truelight@0: { tron@2243: uint i = ScaleByMapSize(GB(Random(), 0, 5) + 25); truelight@0: do { ludde@2051: DoPlaceMoreTrees(RandomTile()); truelight@0: } while (--i); truelight@0: } truelight@0: tron@1093: void PlaceTreesRandomly(void) truelight@0: { tron@2088: uint i; truelight@0: tron@1202: i = ScaleByMapSize(1000); truelight@0: do { tron@2088: uint32 r = Random(); tron@2088: TileIndex 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 { tron@2088: uint32 r = Random(); tron@2088: TileIndex 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: { tron@2088: uint i; truelight@0: tron@2088: if (_opt.landscape != LT_CANDY) PlaceMoreTrees(); tron@2088: tron@2088: for (i = _opt.landscape == LT_HILLY ? 15 : 6; i != 0; i--) { tron@2088: PlaceTreesRandomly(); truelight@0: } 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; Darkvater@2118: int sx, sy, x, 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 Darkvater@2118: sx = TileX(p2); Darkvater@2118: sy = TileY(p2); Darkvater@2118: ex /= 16; ey /= 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: Darkvater@2118: for (x = sx; x <= ex; x++) { Darkvater@2118: for (y = sy; y <= ey; y++) { tron@2088: TileIndex tile = TileXY(x, y); tron@1286: tron@2088: if (!EnsureNoVehicle(tile)) continue; truelight@0: tron@2088: switch (GetTileType(tile)) { tron@1286: case MP_TREES: tron@1286: // no more space for trees? tron@2088: if (_game_mode != GM_EDITOR && (_m[tile].m5 & 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@2088: _m[tile].m5 += 0x40; tron@2088: MarkTileDirtyByTile(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@2088: if (!IsTileOwner(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@2088: if ((_m[tile].m5 & 0x1F) == 0xF) tron@1286: cost += _price.clear_3; tron@2088: else if ((_m[tile].m5 & 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@2088: Town *t = ClosestTownFromTile(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@2088: switch (_m[tile].m5 & 0x1C) { tron@1286: case 0x04: tron@1286: m2 = 16; tron@1286: break; tron@1286: tron@1286: case 0x10: tron@2088: m2 = ((_m[tile].m5 & 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@2088: treetype = GetRandomTreeType(tile, Random() >> 24); tron@1286: if (treetype == -1) treetype = 27; tron@1286: } tron@1286: tron@2088: ModifyTile(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@2088: SetMapExtraBits(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: tron@2049: m2 = _m[ti->tile].m2; truelight@0: tron@2088: if ((m2 & 0x30) == 0) { truelight@0: DrawClearLandTile(ti, 3); tron@2088: } 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@2220: DrawClearLandFence(ti); truelight@0: truelight@0: z = ti->z; truelight@0: if (ti->tileh != 0) { truelight@0: z += 4; celestar@2085: if (IsSteepTileh(ti->tileh)) truelight@0: z += 4; truelight@0: } truelight@0: truelight@0: { truelight@0: uint16 tmp = ti->x; tron@959: uint index; truelight@0: tron@2088: tmp = ROR(tmp, 2); truelight@0: tmp -= ti->y; tron@2088: tmp = ROR(tmp, 3); truelight@0: tmp -= ti->x; tron@2088: tmp = ROR(tmp, 1); truelight@0: tmp += ti->y; truelight@0: tron@2088: d = _tree_layout_xy[GB(tmp, 4, 2)]; truelight@0: tron@2088: index = GB(tmp, 6, 2) + (_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@2088: if (!(_display_opt & DO_TRANS_BUILDINGS) || !_patches.invisible_trees) { tron@2088: TreeListEnt te[4]; tron@2088: uint i; truelight@0: truelight@0: /* put the trees to draw in a list */ truelight@0: i = (ti->map5 >> 6) + 1; truelight@0: do { tron@2243: uint32 image = s[0] + (--i == 0 ? GB(ti->map5, 0, 3) : 3); tron@497: if (_display_opt & DO_TRANS_BUILDINGS) celestar@2148: MAKE_TRANSPARENT(image); truelight@0: te[i].image = image; truelight@0: te[i].x = d[0]; truelight@0: te[i].y = d[1]; truelight@0: s++; tron@2088: 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 { tron@2088: 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: tron@2088: if (tep == NULL) 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: tron@2537: static uint GetSlopeZ_Trees(const TileInfo* ti) tron@2537: { tron@2243: return GetPartialZ(ti->x & 0xF, ti->y & 0xF, ti->tileh) + ti->z; truelight@0: } truelight@0: Darkvater@2436: static uint GetSlopeTileh_Trees(const TileInfo *ti) { dominik@39: return ti->tileh; dominik@39: } dominik@39: tron@1977: static int32 ClearTile_Trees(TileIndex tile, byte flags) tron@1977: { tron@2243: uint 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@2243: num = GB(_m[tile].m5, 6, 2) + 1; tron@2243: if (IS_INT_INSIDE(_m[tile].m3, 20, 26 + 1)) num *= 4; truelight@0: tron@2243: if (flags & DC_EXEC) 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@1977: static void TileLoopTreesDesert(TileIndex tile) truelight@0: { tron@2243: static const SoundFx forest_sounds[] = { tron@2243: SND_42_LOON_BIRD, tron@2243: SND_43_LION, tron@2243: SND_44_MONKEYS, tron@2243: SND_48_DISTANT_BIRD tron@2243: }; truelight@0: tron@2243: byte b = GetMapExtraBits(tile); tron@2243: tron@2088: if (b == 2) { tron@2088: uint32 r = Random(); truelight@0: tron@2243: if (CHANCE16I(1, 200, r)) SndPlayTileFx(forest_sounds[GB(r, 16, 2)], tile); truelight@0: } else if (b == 1) { tron@2243: if (GB(_m[tile].m2, 4, 2) != 2) { tron@2243: SB(_m[tile].m2, 4, 2, 2); tron@2243: SB(_m[tile].m2, 6, 2, 3); 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@2230: tmp = _m[tile].m2 & 0xF0; truelight@0: truelight@0: if (k < -8) { tron@2088: if ((tmp & 0x30) != 0x20) return; tron@2243: m2 = 0; // no snow truelight@0: } else if (k == -8) { tron@2243: m2 = 0x20; // 1/4 snow tron@2088: if (tmp == m2) return; tron@2243: } else if (k == 0) { tron@2243: m2 = 0x60;// 1/2 snow tron@2088: if (tmp == m2) return; truelight@0: } else if (k == 8) { tron@2243: m2 = 0xA0; // 3/4 snow tron@2088: if (tmp == m2) return; truelight@0: } else { tron@2230: if (tmp == 0xE0) { tron@2088: uint32 r = Random(); tron@2243: if (CHANCE16I(1, 200, r)) { tron@541: SndPlayTileFx((r & 0x80000000) ? SND_39_HEAVY_WIND : SND_34_WIND, tile); truelight@0: } truelight@0: return; truelight@0: } else { tron@2243: m2 = 0xE0; // full snow 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 */ tron@2238: AB(_m[tile].m2, 0, 4, 1); tron@2238: if (GB(_m[tile].m2, 0, 4) != 0) return; truelight@0: tron@2049: m5 = _m[tile].m5; tron@2088: if (GB(m5, 0, 3) == 3) { truelight@0: /* regular sized tree */ tron@2088: 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@2088: if (!IsTileType(tile, MP_CLEAR)) 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@2088: if ((_m[tile].m5 & 0x1F) != 3) 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: } tron@2088: } else if (GB(m5, 0, 3) == 6) { truelight@0: /* final stage of tree destruction */ tron@2088: if (GB(m5, 6, 2) != 0) { 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; tron@2088: if ((m2 & 0x30) != 0) { // on snow/desert or rough land truelight@0: m5 = (m2 >> 6) | 0x10; tron@2088: 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 && tron@2088: (r = Random(), tile = RandomTileSeed(r), GetMapExtraBits(tile) == 2) && tron@1035: IsTileType(tile, MP_CLEAR) && tron@2088: (m = _m[tile].m5 & 0x1C, m <= 4) && tron@2088: (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 tron@2088: if (--_trees_tick_ctr != 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@2088: (m = _m[tile].m5 & 0x1C, m == 0 || m == 4 || m == 0x10) && tron@2088: (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: Darkvater@2436: static void ChangeTileOwner_Trees(TileIndex tile, PlayerID old_player, PlayerID 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: };