Mercurial > hg > openttd
changeset 2981:04c4d746d872 draft
(svn r3556) Add accessors for handling tree tiles
See tree.h for details
author | tron <tron@openttd.org> |
---|---|
date | Sun, 05 Feb 2006 14:47:15 +0000 |
parents | 7c5065b1038e |
children | 90ec515d436e |
files | smallmap_gui.c tree.h tree_cmd.c |
diffstat | 3 files changed, 240 insertions(+), 205 deletions(-) [+] |
line wrap: on
line diff
--- a/smallmap_gui.c +++ b/smallmap_gui.c @@ -10,6 +10,7 @@ #include "map.h" #include "tile.h" #include "gui.h" +#include "tree.h" #include "window.h" #include "gfx.h" #include "viewport.h" @@ -489,7 +490,7 @@ break; case MP_TREES: - if ((_m[tile].m2 & 0x30) == 0x20) { + if (GetTreeGround(tile) == TR_SNOW_DESERT) { bits = (_opt.landscape == LT_HILLY) ? MKCOLOR(0x98575798) : MKCOLOR(0xC25757C2); } else { bits = MKCOLOR(0x54575754);
new file mode 100644 --- /dev/null +++ b/tree.h @@ -0,0 +1,59 @@ +/* $Id$ */ + +#ifndef TREE_H +#define TREE_H + +#include "macros.h" + +typedef enum TreeType { + TR_INVALID = -1, + TR_TEMPERATE = 0, + TR_SUB_ARCTIC = 12, + TR_RAINFOREST = 20, + TR_CACTUS = 27, + TR_SUB_TROPICAL = 28, + TR_TOYLAND = 32 +} TreeType; + +enum { + TR_COUNT_TEMPERATE = TR_SUB_ARCTIC - TR_TEMPERATE, + TR_COUNT_SUB_ARCTIC = TR_RAINFOREST - TR_SUB_ARCTIC, + TR_COUNT_RAINFOREST = TR_CACTUS - TR_RAINFOREST, + TR_COUNT_SUB_TROPICAL = TR_SUB_TROPICAL - TR_CACTUS, + TR_COUNT_TOYLAND = 9 +}; + +/* ground type, m2 bits 4...5 + * valid densities (bits 6...7) in comments after the enum */ +typedef enum TreeGround { + TR_GRASS = 0, // 0 + TR_ROUGH = 1, // 0 + TR_SNOW_DESERT = 2 // 0-3 for snow, 3 for desert +} TreeGround; + +static inline TreeType GetTreeType(TileIndex t) { return _m[t].m3; } +static inline void SetTreeType(TileIndex t, TreeType r) { _m[t].m3 = r; } + +static inline TreeGround GetTreeGround(TileIndex t) { return GB(_m[t].m2, 4, 2); } + +static inline uint GetTreeDensity(TileIndex t) { return GB(_m[t].m2, 6, 2); } + +static inline void SetTreeGroundDensity(TileIndex t, TreeGround g, uint d) +{ + SB(_m[t].m2, 4, 2, g); + SB(_m[t].m2, 6, 2, d); +} + +static inline void AddTreeCount(TileIndex t, int c) { _m[t].m5 += c << 6; } +static inline uint GetTreeCount(TileIndex t) { return GB(_m[t].m5, 6, 2); } +static inline void SetTreeCount(TileIndex t, uint c) { SB(_m[t].m5, 6, 2, c); } + +static inline void AddTreeGrowth(TileIndex t, int a) { _m[t].m5 += a; } +static inline uint GetTreeGrowth(TileIndex t) { return GB(_m[t].m5, 0, 3); } +static inline void SetTreeGrowth(TileIndex t, uint g) { SB(_m[t].m5, 0, 3, g); } + +static inline void AddTreeCounter(TileIndex t, int a) { _m[t].m2 += a; } +static inline uint GetTreeCounter(TileIndex t) { return GB(_m[t].m2, 0, 4); } +static inline void SetTreeCounter(TileIndex t, uint c) { SB(_m[t].m2, 0, 4, c); } + +#endif
--- a/tree_cmd.c +++ b/tree_cmd.c @@ -9,56 +9,53 @@ #include "functions.h" #include "map.h" #include "tile.h" +#include "tree.h" #include "viewport.h" #include "command.h" #include "town.h" #include "sound.h" #include "variables.h" -static int GetRandomTreeType(TileIndex tile, uint seed) +static TreeType GetRandomTreeType(TileIndex tile, uint seed) { switch (_opt.landscape) { case LT_NORMAL: - return seed * 12 >> 8; + return seed * TR_COUNT_TEMPERATE / 256 + TR_TEMPERATE; case LT_HILLY: - return (seed >> 5) + 12; + return seed * TR_COUNT_SUB_ARCTIC / 256 + TR_SUB_ARCTIC; case LT_DESERT: switch (GetMapExtraBits(tile)) { - case 0: return (seed >> 6) + 28; - case 1: return (seed > 12) ? -1 : 27; - default: return (seed * 7 >> 8) + 20; + case 0: return seed * TR_COUNT_SUB_TROPICAL / 256 + TR_SUB_TROPICAL; + case 1: return (seed > 12) ? TR_INVALID : TR_CACTUS; + default: return seed * TR_COUNT_RAINFOREST / 256 + TR_RAINFOREST; } default: - return (seed * 9 >> 8) + 32; + return seed * TR_COUNT_TOYLAND / 256 + TR_TOYLAND; } } static void PlaceTree(TileIndex tile, uint32 r) { - int tree = GetRandomTreeType(tile, GB(r, 24, 8)); - byte m5; - - if (tree >= 0) { - SetTileType(tile, MP_TREES); + TreeType tree = GetRandomTreeType(tile, GB(r, 24, 8)); - m5 = GB(r, 16, 8); - if (GB(m5, 0, 3) == 7) m5--; // there is no growth state 7 - - _m[tile].m5 = m5 & 0x07; // growth state; - _m[tile].m5 |= m5 & 0xC0; // amount of trees - - _m[tile].m3 = tree; // set type of tree - _m[tile].m4 = 0; // no hedge + if (tree != TR_INVALID) { + SetTileType(tile, MP_TREES); + SetTreeType(tile, tree); + SetFenceSE(tile, 0); + SetFenceSW(tile, 0); + SetTreeCount(tile, GB(r, 22, 2)); + SetTreeGrowth(tile, min(GB(r, 16, 3), 6)); // above snowline? if (_opt.landscape == LT_HILLY && GetTileZ(tile) > _opt.snow_line) { - _m[tile].m2 = 0xE0; // set land type to snow - _m[tile].m2 |= GB(r, 24, 3); // randomize counter + SetTreeGroundDensity(tile, TR_SNOW_DESERT, 3); + SetTreeCounter(tile, GB(r, 24, 3)); } else { - _m[tile].m2 = GB(r, 24, 5); // randomize counter and ground + SetTreeGroundDensity(tile, GB(r, 28, 1), 0); + SetTreeCounter(tile, GB(r, 24, 4)); } } } @@ -165,13 +162,13 @@ switch (GetTileType(tile)) { case MP_TREES: // no more space for trees? - if (_game_mode != GM_EDITOR && (_m[tile].m5 & 0xC0) == 0xC0) { + if (_game_mode != GM_EDITOR && GetTreeCount(tile) != 3) { _error_message = STR_2803_TREE_ALREADY_HERE; continue; } if (flags & DC_EXEC) { - _m[tile].m5 += 0x40; + AddTreeCount(tile, 1); MarkTileDirtyByTile(tile); } // 2x as expensive to add more trees to an existing tile @@ -191,8 +188,7 @@ } if (flags & DC_EXEC) { - int treetype; - int m2; + TreeType treetype; if (_game_mode != GM_EDITOR && _current_player < MAX_PLAYERS) { Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority); @@ -200,27 +196,27 @@ ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM); } - switch (GetClearGround(tile)) { - case CL_ROUGH: m2 = 16; break; - case CL_SNOW: m2 = GetClearDensity(tile) << 6 | 0x20; break; - default: m2 = 0; break; + treetype = p1; + if (treetype == TR_INVALID) { + treetype = GetRandomTreeType(tile, GB(Random(), 24, 8)); + if (treetype == TR_INVALID) treetype = TR_CACTUS; } - treetype = p1; - if (treetype == -1) { - treetype = GetRandomTreeType(tile, GB(Random(), 24, 8)); - if (treetype == -1) treetype = 27; + switch (GetClearGround(tile)) { + case CL_ROUGH: SetTreeGroundDensity(tile, TR_ROUGH, 0); break; + case CL_SNOW: SetTreeGroundDensity(tile, TR_SNOW_DESERT, GetClearDensity(tile)); break; + default: SetTreeGroundDensity(tile, TR_GRASS, 0); break; } + SetTreeCounter(tile, 0); - ModifyTile(tile, - MP_SETTYPE(MP_TREES) | - MP_MAP2 | MP_MAP3LO | MP_MAP3HI_CLEAR | MP_MAP5, - m2, /* map2 */ - treetype, /* map3lo */ - _game_mode == GM_EDITOR ? 3 : 0 /* map5 */ - ); + SetTileType(tile, MP_TREES); + SetTreeType(tile, treetype); + SetFenceSE(tile, 0); + SetFenceSW(tile, 0); + SetTreeCount(tile, 0); + SetTreeGrowth(tile, _game_mode == GM_EDITOR ? 3 : 0); - if (_game_mode == GM_EDITOR && IS_BYTE_INSIDE(treetype, 0x14, 0x1B)) + if (_game_mode == GM_EDITOR && IS_INT_INSIDE(treetype, TR_RAINFOREST, TR_CACTUS)) SetMapExtraBits(tile, 2); } cost += _price.build_trees; @@ -243,19 +239,14 @@ static void DrawTile_Trees(TileInfo *ti) { - uint16 m2; const uint32 *s; const TreePos* d; byte z; - m2 = _m[ti->tile].m2; - - if ((m2 & 0x30) == 0) { - DrawClearLandTile(ti, 3); - } else if ((m2 & 0x30) == 0x20) { - DrawGroundSprite(_tree_sprites_1[m2 >> 6] + _tileh_to_sprite[ti->tileh]); - } else { - DrawHillyLandTile(ti); + switch (GetTreeGround(ti->tile)) { + case TR_GRASS: DrawClearLandTile(ti, 3); break; + case TR_ROUGH: DrawHillyLandTile(ti); break; + default: DrawGroundSprite(_tree_sprites_1[GetTreeDensity(ti->tile)] + _tileh_to_sprite[ti->tileh]); break; } DrawClearLandFence(ti); @@ -280,11 +271,14 @@ d = _tree_layout_xy[GB(tmp, 4, 2)]; - index = GB(tmp, 6, 2) + (_m[ti->tile].m3 << 2); + index = GB(tmp, 6, 2) + (GetTreeType(ti->tile) << 2); /* different tree styles above one of the grounds */ - if ((m2 & 0xB0) == 0xA0 && index >= 48 && index < 80) - index += 164 - 48; + if (GetTreeGround(ti->tile) == TR_SNOW_DESERT && + GetTreeDensity(ti->tile) >= 2 && + IS_INT_INSIDE(index, TR_SUB_ARCTIC << 2, TR_RAINFOREST << 2)) { + index += 164 - (TR_SUB_ARCTIC << 2); + } assert(index < lengthof(_tree_layout_sprite)); s = _tree_layout_sprite[index]; @@ -352,8 +346,8 @@ ChangeTownRating(t, RATING_TREE_DOWN_STEP, RATING_TREE_MINIMUM); } - num = GB(_m[tile].m5, 6, 2) + 1; - if (IS_INT_INSIDE(_m[tile].m3, 20, 26 + 1)) num *= 4; + num = GetTreeCount(tile) + 1; + if (IS_INT_INSIDE(GetTreeType(tile), TR_RAINFOREST, TR_CACTUS)) num *= 4; if (flags & DC_EXEC) DoClearSquare(tile); @@ -367,16 +361,17 @@ static void GetTileDesc_Trees(TileIndex tile, TileDesc *td) { - byte b; - StringID str; + TreeType tt = GetTreeType(tile); + + if (IS_INT_INSIDE(tt, TR_RAINFOREST, TR_CACTUS)) { + td->str = STR_280F_RAINFOREST; + } else if (tt == TR_CACTUS) { + td->str = STR_2810_CACTUS_PLANTS; + } else { + td->str = STR_280E_TREES; + } td->owner = GetTileOwner(tile); - - b = _m[tile].m3; - (str=STR_2810_CACTUS_PLANTS, b==0x1B) || - (str=STR_280F_RAINFOREST, IS_BYTE_INSIDE(b, 0x14, 0x1A+1)) || - (str=STR_280E_TREES, true); - td->str = str; } static void AnimateTile_Trees(TileIndex tile) @@ -386,71 +381,56 @@ static void TileLoopTreesDesert(TileIndex tile) { - static const SoundFx forest_sounds[] = { - SND_42_LOON_BIRD, - SND_43_LION, - SND_44_MONKEYS, - SND_48_DISTANT_BIRD - }; - - byte b = GetMapExtraBits(tile); + switch (GetMapExtraBits(tile)) { + case 1: + if (GetTreeGround(tile) != TR_SNOW_DESERT) { + SetTreeGroundDensity(tile, TR_SNOW_DESERT, 3); + MarkTileDirtyByTile(tile); + } + break; - if (b == 2) { - uint32 r = Random(); + case 2: { + static const SoundFx forest_sounds[] = { + SND_42_LOON_BIRD, + SND_43_LION, + SND_44_MONKEYS, + SND_48_DISTANT_BIRD + }; + uint32 r = Random(); - if (CHANCE16I(1, 200, r)) SndPlayTileFx(forest_sounds[GB(r, 16, 2)], tile); - } else if (b == 1) { - if (GB(_m[tile].m2, 4, 2) != 2) { - SB(_m[tile].m2, 4, 2, 2); - SB(_m[tile].m2, 6, 2, 3); - MarkTileDirtyByTile(tile); + if (CHANCE16I(1, 200, r)) SndPlayTileFx(forest_sounds[GB(r, 16, 2)], tile); + break; } } } static void TileLoopTreesAlps(TileIndex tile) { - byte tmp, m2; - int k; - - /* distance from snow line, in steps of 8 */ - k = GetTileZ(tile) - _opt.snow_line; - - tmp = _m[tile].m2 & 0xF0; + int k = GetTileZ(tile) - _opt.snow_line; if (k < -8) { - if ((tmp & 0x30) != 0x20) return; - m2 = 0; // no snow - } else if (k == -8) { - m2 = 0x20; // 1/4 snow - if (tmp == m2) return; - } else if (k == 0) { - m2 = 0x60;// 1/2 snow - if (tmp == m2) return; - } else if (k == 8) { - m2 = 0xA0; // 3/4 snow - if (tmp == m2) return; + if (GetTreeGround(tile) != TR_SNOW_DESERT) return; + SetTreeGroundDensity(tile, TR_GRASS, 0); } else { - if (tmp == 0xE0) { - uint32 r = Random(); - if (CHANCE16I(1, 200, r)) { - SndPlayTileFx((r & 0x80000000) ? SND_39_HEAVY_WIND : SND_34_WIND, tile); + uint density = min((uint)(k + 8) / 8, 3); + + if (GetTreeGround(tile) != TR_SNOW_DESERT || GetTreeDensity(tile) != density) { + SetTreeGroundDensity(tile, TR_SNOW_DESERT, density); + } else { + if (GetTreeDensity(tile) == 3) { + uint32 r = Random(); + if (CHANCE16I(1, 200, r)) { + SndPlayTileFx((r & 0x80000000) ? SND_39_HEAVY_WIND : SND_34_WIND, tile); + } } return; - } else { - m2 = 0xE0; // full snow } } - - _m[tile].m2 &= 0xF; - _m[tile].m2 |= m2; MarkTileDirtyByTile(tile); } static void TileLoop_Trees(TileIndex tile) { - byte m5; - static const TileIndexDiffC _tileloop_trees_dir[] = { {-1, -1}, { 0, -1}, @@ -462,89 +442,93 @@ { 1, 1} }; - if (_opt.landscape == LT_DESERT) { - TileLoopTreesDesert(tile); - } else if (_opt.landscape == LT_HILLY) { - TileLoopTreesAlps(tile); + switch (_opt.landscape) { + case LT_DESERT: TileLoopTreesDesert(tile); break; + case LT_HILLY: TileLoopTreesAlps(tile); break; } TileLoopClearHelper(tile); - /* increase counter */ - AB(_m[tile].m2, 0, 4, 1); - if (GB(_m[tile].m2, 0, 4) != 0) return; - - m5 = _m[tile].m5; - if (GB(m5, 0, 3) == 3) { - /* regular sized tree */ - if (_opt.landscape == LT_DESERT && _m[tile].m3 != 0x1B && GetMapExtraBits(tile) == 1) { - m5++; /* start destructing */ - } else { - switch (GB(Random(), 0, 3)) { - case 0: /* start destructing */ - m5++; - break; + if (GetTreeCounter(tile) < 15) { + AddTreeCounter(tile, 1); + return; + } + SetTreeCounter(tile, 0); - case 1: /* add a tree */ - if (m5 < 0xC0) { - m5 = (m5 + 0x40) & ~7; - break; - } - /* fall through */ - - case 2: { /* add a neighbouring tree */ - byte m3 = _m[tile].m3; - - tile += ToTileIndexDiff(_tileloop_trees_dir[Random() & 7]); - - if (!IsTileType(tile, MP_CLEAR)) return; - - switch (GetClearGround(tile)) { - case CL_GRASS: - if (GetClearDensity(tile) != 3) return; - _m[tile].m2 = 0; + switch (GetTreeGrowth(tile)) { + case 3: /* regular sized tree */ + if (_opt.landscape == LT_DESERT && GetTreeType(tile) != TR_CACTUS && GetMapExtraBits(tile) == 1) { + AddTreeGrowth(tile, 1); + } else { + switch (GB(Random(), 0, 3)) { + case 0: /* start destructing */ + AddTreeGrowth(tile, 1); break; - case CL_ROUGH: _m[tile].m2 = 0x10; break; - case CL_SNOW: _m[tile].m2 = GetClearDensity(tile) << 6 | 0x20; break; - default: return; - } + case 1: /* add a tree */ + if (GetTreeCount(tile) < 3) { + AddTreeCount(tile, 1); + SetTreeGrowth(tile, 0); + break; + } + /* FALL THROUGH */ + + case 2: { /* add a neighbouring tree */ + TreeType treetype = GetTreeType(tile); + + tile += ToTileIndexDiff(_tileloop_trees_dir[Random() & 7]); + + if (!IsTileType(tile, MP_CLEAR)) return; - _m[tile].m3 = m3; - _m[tile].m4 = 0; - SetTileType(tile, MP_TREES); + switch (GetClearGround(tile)) { + case CL_GRASS: + if (GetClearDensity(tile) != 3) return; + SetTreeGroundDensity(tile, TR_GRASS, 0); + break; + + case CL_ROUGH: SetTreeGroundDensity(tile, TR_ROUGH, 0); break; + case CL_SNOW: SetTreeGroundDensity(tile, TR_SNOW_DESERT, GetClearDensity(tile)); break; + default: return; + } + SetTreeCounter(tile, 0); - m5 = 0; - break; - } + SetTileType(tile, MP_TREES); + SetTreeType(tile, treetype); + SetFenceSE(tile, 0); + SetFenceSW(tile, 0); + SetTreeCount(tile, 0); + SetTreeGrowth(tile, 0); + break; + } - default: - return; + default: + return; + } } - } - } else if (GB(m5, 0, 3) == 6) { - /* final stage of tree destruction */ - if (GB(m5, 6, 2) != 0) { - /* more than one tree, delete it? */ - m5 = ((m5 - 6) - 0x40) + 3; - } else { - /* just one tree, change type into MP_CLEAR */ - SetTileType(tile, MP_CLEAR); - SetTileOwner(tile, OWNER_NONE); - switch (_m[tile].m2 & 0x30) { - case 0x00: SetClearGroundDensity(tile, CL_GRASS, 3); break; - case 0x10: SetClearGroundDensity(tile, CL_ROUGH, 3); break; - default: SetClearGroundDensity(tile, CL_SNOW, GB(_m[tile].m2, 6, 2)); break; + break; + + case 6: /* final stage of tree destruction */ + if (GetTreeCount(tile) > 0) { + /* more than one tree, delete it */ + AddTreeCount(tile, -1); + SetTreeGrowth(tile, 3); + } else { + /* just one tree, change type into MP_CLEAR */ + SetTileType(tile, MP_CLEAR); + SetTileOwner(tile, OWNER_NONE); + switch (GetTreeGround(tile)) { + case TR_GRASS: SetClearGroundDensity(tile, CL_GRASS, 3); break; + case TR_ROUGH: SetClearGroundDensity(tile, CL_ROUGH, 3); break; + default: SetClearGroundDensity(tile, CL_SNOW, GetTreeDensity(tile)); break; + } } - MarkTileDirtyByTile(tile); - return; - } - } else { - /* in the middle of a transition, change to next */ - m5++; + break; + + default: + AddTreeGrowth(tile, 1); + break; } - _m[tile].m5 = m5; MarkTileDirtyByTile(tile); } @@ -560,16 +544,13 @@ (r = Random(), tile = RandomTileSeed(r), GetMapExtraBits(tile) == 2) && IsTileType(tile, MP_CLEAR) && (ct = GetClearGround(tile), ct == CL_GRASS || ct == CL_ROUGH) && - (tree = GetRandomTreeType(tile, GB(r, 24, 8))) >= 0) { - - ModifyTile(tile, - MP_SETTYPE(MP_TREES) | - MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5, - (ct == CL_ROUGH ? 0x10 : 0), - tree, - _m[tile].m4 & ~3, - 0 - ); + (tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TR_INVALID) { + SetTileType(tile, MP_TREES); + SetTreeGroundDensity(tile, ct == CL_ROUGH ? TR_ROUGH : TR_GRASS, 0); + SetTreeCounter(tile, 0); + SetTreeType(tile, tree); + SetTreeCount(tile, 0); + SetTreeGrowth(tile, 0); } // byte underflow @@ -580,23 +561,17 @@ tile = TILE_MASK(r); if (IsTileType(tile, MP_CLEAR) && (ct = GetClearGround(tile), ct == CL_GRASS || ct == CL_ROUGH || ct == CL_SNOW) && - (tree = GetRandomTreeType(tile, GB(r, 24, 8))) >= 0) { - int m2; - + (tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TR_INVALID) { switch (ct) { - case CL_GRASS: m2 = 0; break; - case CL_ROUGH: m2 = 0x10; break; - default: m2 = (GetClearDensity(tile) << 6) | 0x20; break; + case CL_GRASS: SetTreeGroundDensity(tile, TR_GRASS, 0); break; + case CL_ROUGH: SetTreeGroundDensity(tile, TR_ROUGH, 0); break; + default: SetTreeGroundDensity(tile, TR_SNOW_DESERT, GetClearDensity(tile)); break; } - - ModifyTile(tile, - MP_SETTYPE(MP_TREES) | - MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5, - m2, - tree, - _m[tile].m4 & ~3, - 0 - ); + SetTreeCounter(tile, 0); + SetTileType(tile, MP_TREES); + SetTreeType(tile, tree); + SetTreeCount(tile, 0); + SetTreeGrowth(tile, 0); } }