summaryrefslogtreecommitdiff
path: root/tree_cmd.c
diff options
context:
space:
mode:
authortron <tron@openttd.org>2006-02-05 14:47:15 +0000
committertron <tron@openttd.org>2006-02-05 14:47:15 +0000
commit208a4b4944525b9be53bacbabd11652ba777e4c7 (patch)
tree060012f8a54300b5071529647ce2b77c29c4ef0f /tree_cmd.c
parenta7273d95b86d0eeba66aac0abb04cca7b0f495ab (diff)
downloadopenttd-208a4b4944525b9be53bacbabd11652ba777e4c7.tar.xz
(svn r3556) Add accessors for handling tree tiles
See tree.h for details
Diffstat (limited to 'tree_cmd.c')
-rw-r--r--tree_cmd.c379
1 files changed, 177 insertions, 202 deletions
diff --git a/tree_cmd.c b/tree_cmd.c
index 52a834df0..cf9727607 100644
--- 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;
+ TreeType tree = GetRandomTreeType(tile, GB(r, 24, 8));
- if (tree >= 0) {
+ if (tree != TR_INVALID) {
SetTileType(tile, MP_TREES);
-
- 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
+ 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 @@ int32 CmdPlantTree(int ex, int ey, uint32 flags, uint32 p1, uint32 p2)
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 @@ int32 CmdPlantTree(int ex, int ey, uint32 flags, uint32 p1, uint32 p2)
}
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 @@ int32 CmdPlantTree(int ex, int ey, uint32 flags, uint32 p1, uint32 p2)
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 == -1) {
+ if (treetype == TR_INVALID) {
treetype = GetRandomTreeType(tile, GB(Random(), 24, 8));
- if (treetype == -1) treetype = 27;
+ if (treetype == TR_INVALID) treetype = TR_CACTUS;
}
- 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 */
- );
+ 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);
- if (_game_mode == GM_EDITOR && IS_BYTE_INSIDE(treetype, 0x14, 0x1B))
+ 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_INT_INSIDE(treetype, TR_RAINFOREST, TR_CACTUS))
SetMapExtraBits(tile, 2);
}
cost += _price.build_trees;
@@ -243,19 +239,14 @@ typedef struct TreeListEnt {
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 @@ static void DrawTile_Trees(TileInfo *ti)
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 @@ static int32 ClearTile_Trees(TileIndex tile, byte flags)
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 GetAcceptedCargo_Trees(TileIndex tile, AcceptedCargo ac)
static void GetTileDesc_Trees(TileIndex tile, TileDesc *td)
{
- byte b;
- StringID str;
+ TreeType tt = GetTreeType(tile);
- td->owner = GetTileOwner(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;
+ }
- 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;
+ td->owner = GetTileOwner(tile);
}
static void AnimateTile_Trees(TileIndex tile)
@@ -386,71 +381,56 @@ static void AnimateTile_Trees(TileIndex tile)
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);
-
- if (b == 2) {
- uint32 r = Random();
+ switch (GetMapExtraBits(tile)) {
+ case 1:
+ if (GetTreeGround(tile) != TR_SNOW_DESERT) {
+ SetTreeGroundDensity(tile, TR_SNOW_DESERT, 3);
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+
+ 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 @@ static void TileLoop_Trees(TileIndex tile)
{ 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;
+ if (GetTreeCounter(tile) < 15) {
+ AddTreeCounter(tile, 1);
+ return;
+ }
+ SetTreeCounter(tile, 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;
- 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;
-
- case 1: /* add a tree */
- if (m5 < 0xC0) {
- m5 = (m5 + 0x40) & ~7;
- break;
- }
- /* fall through */
+ case 1: /* add a tree */
+ if (GetTreeCount(tile) < 3) {
+ AddTreeCount(tile, 1);
+ SetTreeGrowth(tile, 0);
+ break;
+ }
+ /* FALL THROUGH */
- case 2: { /* add a neighbouring tree */
- byte m3 = _m[tile].m3;
+ case 2: { /* add a neighbouring tree */
+ TreeType treetype = GetTreeType(tile);
- tile += ToTileIndexDiff(_tileloop_trees_dir[Random() & 7]);
+ tile += ToTileIndexDiff(_tileloop_trees_dir[Random() & 7]);
- if (!IsTileType(tile, MP_CLEAR)) return;
+ if (!IsTileType(tile, MP_CLEAR)) return;
- switch (GetClearGround(tile)) {
- case CL_GRASS:
- if (GetClearDensity(tile) != 3) return;
- _m[tile].m2 = 0;
+ 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);
+
+ SetTileType(tile, MP_TREES);
+ SetTreeType(tile, treetype);
+ SetFenceSE(tile, 0);
+ SetFenceSW(tile, 0);
+ SetTreeCount(tile, 0);
+ SetTreeGrowth(tile, 0);
break;
+ }
- case CL_ROUGH: _m[tile].m2 = 0x10; break;
- case CL_SNOW: _m[tile].m2 = GetClearDensity(tile) << 6 | 0x20; break;
- default: return;
+ default:
+ return;
}
-
- _m[tile].m3 = m3;
- _m[tile].m4 = 0;
- SetTileType(tile, MP_TREES);
-
- m5 = 0;
- break;
}
-
- 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 @@ void OnTick_Trees(void)
(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 @@ void OnTick_Trees(void)
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);
}
}