1
0
Fork 0

(svn r3556) Add accessors for handling tree tiles

See tree.h for details
release/0.5
tron 2006-02-05 14:47:15 +00:00
parent a7273d95b8
commit 208a4b4944
3 changed files with 240 additions and 205 deletions

View File

@ -10,6 +10,7 @@
#include "map.h" #include "map.h"
#include "tile.h" #include "tile.h"
#include "gui.h" #include "gui.h"
#include "tree.h"
#include "window.h" #include "window.h"
#include "gfx.h" #include "gfx.h"
#include "viewport.h" #include "viewport.h"
@ -489,7 +490,7 @@ static inline uint32 GetSmallMapVegetationPixels(TileIndex tile)
break; break;
case MP_TREES: case MP_TREES:
if ((_m[tile].m2 & 0x30) == 0x20) { if (GetTreeGround(tile) == TR_SNOW_DESERT) {
bits = (_opt.landscape == LT_HILLY) ? MKCOLOR(0x98575798) : MKCOLOR(0xC25757C2); bits = (_opt.landscape == LT_HILLY) ? MKCOLOR(0x98575798) : MKCOLOR(0xC25757C2);
} else { } else {
bits = MKCOLOR(0x54575754); bits = MKCOLOR(0x54575754);

59
tree.h 100644
View File

@ -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

View File

@ -9,56 +9,53 @@
#include "functions.h" #include "functions.h"
#include "map.h" #include "map.h"
#include "tile.h" #include "tile.h"
#include "tree.h"
#include "viewport.h" #include "viewport.h"
#include "command.h" #include "command.h"
#include "town.h" #include "town.h"
#include "sound.h" #include "sound.h"
#include "variables.h" #include "variables.h"
static int GetRandomTreeType(TileIndex tile, uint seed) static TreeType GetRandomTreeType(TileIndex tile, uint seed)
{ {
switch (_opt.landscape) { switch (_opt.landscape) {
case LT_NORMAL: case LT_NORMAL:
return seed * 12 >> 8; return seed * TR_COUNT_TEMPERATE / 256 + TR_TEMPERATE;
case LT_HILLY: case LT_HILLY:
return (seed >> 5) + 12; return seed * TR_COUNT_SUB_ARCTIC / 256 + TR_SUB_ARCTIC;
case LT_DESERT: case LT_DESERT:
switch (GetMapExtraBits(tile)) { switch (GetMapExtraBits(tile)) {
case 0: return (seed >> 6) + 28; case 0: return seed * TR_COUNT_SUB_TROPICAL / 256 + TR_SUB_TROPICAL;
case 1: return (seed > 12) ? -1 : 27; case 1: return (seed > 12) ? TR_INVALID : TR_CACTUS;
default: return (seed * 7 >> 8) + 20; default: return seed * TR_COUNT_RAINFOREST / 256 + TR_RAINFOREST;
} }
default: default:
return (seed * 9 >> 8) + 32; return seed * TR_COUNT_TOYLAND / 256 + TR_TOYLAND;
} }
} }
static void PlaceTree(TileIndex tile, uint32 r) static void PlaceTree(TileIndex tile, uint32 r)
{ {
int tree = GetRandomTreeType(tile, GB(r, 24, 8)); TreeType tree = GetRandomTreeType(tile, GB(r, 24, 8));
byte m5;
if (tree >= 0) { if (tree != TR_INVALID) {
SetTileType(tile, MP_TREES); SetTileType(tile, MP_TREES);
SetTreeType(tile, tree);
m5 = GB(r, 16, 8); SetFenceSE(tile, 0);
if (GB(m5, 0, 3) == 7) m5--; // there is no growth state 7 SetFenceSW(tile, 0);
SetTreeCount(tile, GB(r, 22, 2));
_m[tile].m5 = m5 & 0x07; // growth state; SetTreeGrowth(tile, min(GB(r, 16, 3), 6));
_m[tile].m5 |= m5 & 0xC0; // amount of trees
_m[tile].m3 = tree; // set type of tree
_m[tile].m4 = 0; // no hedge
// above snowline? // above snowline?
if (_opt.landscape == LT_HILLY && GetTileZ(tile) > _opt.snow_line) { if (_opt.landscape == LT_HILLY && GetTileZ(tile) > _opt.snow_line) {
_m[tile].m2 = 0xE0; // set land type to snow SetTreeGroundDensity(tile, TR_SNOW_DESERT, 3);
_m[tile].m2 |= GB(r, 24, 3); // randomize counter SetTreeCounter(tile, GB(r, 24, 3));
} else { } 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)) { switch (GetTileType(tile)) {
case MP_TREES: case MP_TREES:
// no more space for 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; _error_message = STR_2803_TREE_ALREADY_HERE;
continue; continue;
} }
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
_m[tile].m5 += 0x40; AddTreeCount(tile, 1);
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
} }
// 2x as expensive to add more trees to an existing 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) { if (flags & DC_EXEC) {
int treetype; TreeType treetype;
int m2;
if (_game_mode != GM_EDITOR && _current_player < MAX_PLAYERS) { if (_game_mode != GM_EDITOR && _current_player < MAX_PLAYERS) {
Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority); 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); 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; treetype = p1;
if (treetype == -1) { if (treetype == TR_INVALID) {
treetype = GetRandomTreeType(tile, GB(Random(), 24, 8)); treetype = GetRandomTreeType(tile, GB(Random(), 24, 8));
if (treetype == -1) treetype = 27; if (treetype == TR_INVALID) treetype = TR_CACTUS;
} }
ModifyTile(tile, switch (GetClearGround(tile)) {
MP_SETTYPE(MP_TREES) | case CL_ROUGH: SetTreeGroundDensity(tile, TR_ROUGH, 0); break;
MP_MAP2 | MP_MAP3LO | MP_MAP3HI_CLEAR | MP_MAP5, case CL_SNOW: SetTreeGroundDensity(tile, TR_SNOW_DESERT, GetClearDensity(tile)); break;
m2, /* map2 */ default: SetTreeGroundDensity(tile, TR_GRASS, 0); break;
treetype, /* map3lo */ }
_game_mode == GM_EDITOR ? 3 : 0 /* map5 */ 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); SetMapExtraBits(tile, 2);
} }
cost += _price.build_trees; cost += _price.build_trees;
@ -243,19 +239,14 @@ typedef struct TreeListEnt {
static void DrawTile_Trees(TileInfo *ti) static void DrawTile_Trees(TileInfo *ti)
{ {
uint16 m2;
const uint32 *s; const uint32 *s;
const TreePos* d; const TreePos* d;
byte z; byte z;
m2 = _m[ti->tile].m2; switch (GetTreeGround(ti->tile)) {
case TR_GRASS: DrawClearLandTile(ti, 3); break;
if ((m2 & 0x30) == 0) { case TR_ROUGH: DrawHillyLandTile(ti); break;
DrawClearLandTile(ti, 3); default: DrawGroundSprite(_tree_sprites_1[GetTreeDensity(ti->tile)] + _tileh_to_sprite[ti->tileh]); break;
} else if ((m2 & 0x30) == 0x20) {
DrawGroundSprite(_tree_sprites_1[m2 >> 6] + _tileh_to_sprite[ti->tileh]);
} else {
DrawHillyLandTile(ti);
} }
DrawClearLandFence(ti); DrawClearLandFence(ti);
@ -280,11 +271,14 @@ static void DrawTile_Trees(TileInfo *ti)
d = _tree_layout_xy[GB(tmp, 4, 2)]; 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 */ /* different tree styles above one of the grounds */
if ((m2 & 0xB0) == 0xA0 && index >= 48 && index < 80) if (GetTreeGround(ti->tile) == TR_SNOW_DESERT &&
index += 164 - 48; 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)); assert(index < lengthof(_tree_layout_sprite));
s = _tree_layout_sprite[index]; 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); ChangeTownRating(t, RATING_TREE_DOWN_STEP, RATING_TREE_MINIMUM);
} }
num = GB(_m[tile].m5, 6, 2) + 1; num = GetTreeCount(tile) + 1;
if (IS_INT_INSIDE(_m[tile].m3, 20, 26 + 1)) num *= 4; if (IS_INT_INSIDE(GetTreeType(tile), TR_RAINFOREST, TR_CACTUS)) num *= 4;
if (flags & DC_EXEC) DoClearSquare(tile); 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) static void GetTileDesc_Trees(TileIndex tile, TileDesc *td)
{ {
byte b; TreeType tt = GetTreeType(tile);
StringID str;
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); 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) static void AnimateTile_Trees(TileIndex tile)
@ -386,71 +381,56 @@ static void AnimateTile_Trees(TileIndex tile)
static void TileLoopTreesDesert(TileIndex tile) static void TileLoopTreesDesert(TileIndex tile)
{ {
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[] = { static const SoundFx forest_sounds[] = {
SND_42_LOON_BIRD, SND_42_LOON_BIRD,
SND_43_LION, SND_43_LION,
SND_44_MONKEYS, SND_44_MONKEYS,
SND_48_DISTANT_BIRD SND_48_DISTANT_BIRD
}; };
byte b = GetMapExtraBits(tile);
if (b == 2) {
uint32 r = Random(); uint32 r = Random();
if (CHANCE16I(1, 200, r)) SndPlayTileFx(forest_sounds[GB(r, 16, 2)], tile); if (CHANCE16I(1, 200, r)) SndPlayTileFx(forest_sounds[GB(r, 16, 2)], tile);
} else if (b == 1) { break;
if (GB(_m[tile].m2, 4, 2) != 2) {
SB(_m[tile].m2, 4, 2, 2);
SB(_m[tile].m2, 6, 2, 3);
MarkTileDirtyByTile(tile);
} }
} }
} }
static void TileLoopTreesAlps(TileIndex tile) static void TileLoopTreesAlps(TileIndex tile)
{ {
byte tmp, m2; int k = GetTileZ(tile) - _opt.snow_line;
int k;
/* distance from snow line, in steps of 8 */
k = GetTileZ(tile) - _opt.snow_line;
tmp = _m[tile].m2 & 0xF0;
if (k < -8) { if (k < -8) {
if ((tmp & 0x30) != 0x20) return; if (GetTreeGround(tile) != TR_SNOW_DESERT) return;
m2 = 0; // no snow SetTreeGroundDensity(tile, TR_GRASS, 0);
} 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;
} else { } else {
if (tmp == 0xE0) { 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(); uint32 r = Random();
if (CHANCE16I(1, 200, r)) { if (CHANCE16I(1, 200, r)) {
SndPlayTileFx((r & 0x80000000) ? SND_39_HEAVY_WIND : SND_34_WIND, tile); SndPlayTileFx((r & 0x80000000) ? SND_39_HEAVY_WIND : SND_34_WIND, tile);
} }
}
return; return;
} else {
m2 = 0xE0; // full snow
} }
} }
_m[tile].m2 &= 0xF;
_m[tile].m2 |= m2;
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
} }
static void TileLoop_Trees(TileIndex tile) static void TileLoop_Trees(TileIndex tile)
{ {
byte m5;
static const TileIndexDiffC _tileloop_trees_dir[] = { static const TileIndexDiffC _tileloop_trees_dir[] = {
{-1, -1}, {-1, -1},
{ 0, -1}, { 0, -1},
@ -462,38 +442,39 @@ static void TileLoop_Trees(TileIndex tile)
{ 1, 1} { 1, 1}
}; };
if (_opt.landscape == LT_DESERT) { switch (_opt.landscape) {
TileLoopTreesDesert(tile); case LT_DESERT: TileLoopTreesDesert(tile); break;
} else if (_opt.landscape == LT_HILLY) { case LT_HILLY: TileLoopTreesAlps(tile); break;
TileLoopTreesAlps(tile);
} }
TileLoopClearHelper(tile); TileLoopClearHelper(tile);
/* increase counter */ if (GetTreeCounter(tile) < 15) {
AB(_m[tile].m2, 0, 4, 1); AddTreeCounter(tile, 1);
if (GB(_m[tile].m2, 0, 4) != 0) return; return;
}
SetTreeCounter(tile, 0);
m5 = _m[tile].m5; switch (GetTreeGrowth(tile)) {
if (GB(m5, 0, 3) == 3) { case 3: /* regular sized tree */
/* regular sized tree */ if (_opt.landscape == LT_DESERT && GetTreeType(tile) != TR_CACTUS && GetMapExtraBits(tile) == 1) {
if (_opt.landscape == LT_DESERT && _m[tile].m3 != 0x1B && GetMapExtraBits(tile) == 1) { AddTreeGrowth(tile, 1);
m5++; /* start destructing */
} else { } else {
switch (GB(Random(), 0, 3)) { switch (GB(Random(), 0, 3)) {
case 0: /* start destructing */ case 0: /* start destructing */
m5++; AddTreeGrowth(tile, 1);
break; break;
case 1: /* add a tree */ case 1: /* add a tree */
if (m5 < 0xC0) { if (GetTreeCount(tile) < 3) {
m5 = (m5 + 0x40) & ~7; AddTreeCount(tile, 1);
SetTreeGrowth(tile, 0);
break; break;
} }
/* fall through */ /* FALL THROUGH */
case 2: { /* add a neighbouring tree */ case 2: { /* add a neighbouring tree */
byte m3 = _m[tile].m3; TreeType treetype = GetTreeType(tile);
tile += ToTileIndexDiff(_tileloop_trees_dir[Random() & 7]); tile += ToTileIndexDiff(_tileloop_trees_dir[Random() & 7]);
@ -502,19 +483,21 @@ static void TileLoop_Trees(TileIndex tile)
switch (GetClearGround(tile)) { switch (GetClearGround(tile)) {
case CL_GRASS: case CL_GRASS:
if (GetClearDensity(tile) != 3) return; if (GetClearDensity(tile) != 3) return;
_m[tile].m2 = 0; SetTreeGroundDensity(tile, TR_GRASS, 0);
break; break;
case CL_ROUGH: _m[tile].m2 = 0x10; break; case CL_ROUGH: SetTreeGroundDensity(tile, TR_ROUGH, 0); break;
case CL_SNOW: _m[tile].m2 = GetClearDensity(tile) << 6 | 0x20; break; case CL_SNOW: SetTreeGroundDensity(tile, TR_SNOW_DESERT, GetClearDensity(tile)); break;
default: return; default: return;
} }
SetTreeCounter(tile, 0);
_m[tile].m3 = m3;
_m[tile].m4 = 0;
SetTileType(tile, MP_TREES); SetTileType(tile, MP_TREES);
SetTreeType(tile, treetype);
m5 = 0; SetFenceSE(tile, 0);
SetFenceSW(tile, 0);
SetTreeCount(tile, 0);
SetTreeGrowth(tile, 0);
break; break;
} }
@ -522,29 +505,30 @@ static void TileLoop_Trees(TileIndex tile)
return; return;
} }
} }
} else if (GB(m5, 0, 3) == 6) { break;
/* final stage of tree destruction */
if (GB(m5, 6, 2) != 0) { case 6: /* final stage of tree destruction */
/* more than one tree, delete it? */ if (GetTreeCount(tile) > 0) {
m5 = ((m5 - 6) - 0x40) + 3; /* more than one tree, delete it */
AddTreeCount(tile, -1);
SetTreeGrowth(tile, 3);
} else { } else {
/* just one tree, change type into MP_CLEAR */ /* just one tree, change type into MP_CLEAR */
SetTileType(tile, MP_CLEAR); SetTileType(tile, MP_CLEAR);
SetTileOwner(tile, OWNER_NONE); SetTileOwner(tile, OWNER_NONE);
switch (_m[tile].m2 & 0x30) { switch (GetTreeGround(tile)) {
case 0x00: SetClearGroundDensity(tile, CL_GRASS, 3); break; case TR_GRASS: SetClearGroundDensity(tile, CL_GRASS, 3); break;
case 0x10: SetClearGroundDensity(tile, CL_ROUGH, 3); break; case TR_ROUGH: SetClearGroundDensity(tile, CL_ROUGH, 3); break;
default: SetClearGroundDensity(tile, CL_SNOW, GB(_m[tile].m2, 6, 2)); break; default: SetClearGroundDensity(tile, CL_SNOW, GetTreeDensity(tile)); break;
} }
MarkTileDirtyByTile(tile);
return;
} }
} else { break;
/* in the middle of a transition, change to next */
m5++; default:
AddTreeGrowth(tile, 1);
break;
} }
_m[tile].m5 = m5;
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
} }
@ -560,16 +544,13 @@ void OnTick_Trees(void)
(r = Random(), tile = RandomTileSeed(r), GetMapExtraBits(tile) == 2) && (r = Random(), tile = RandomTileSeed(r), GetMapExtraBits(tile) == 2) &&
IsTileType(tile, MP_CLEAR) && IsTileType(tile, MP_CLEAR) &&
(ct = GetClearGround(tile), ct == CL_GRASS || ct == CL_ROUGH) && (ct = GetClearGround(tile), ct == CL_GRASS || ct == CL_ROUGH) &&
(tree = GetRandomTreeType(tile, GB(r, 24, 8))) >= 0) { (tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TR_INVALID) {
SetTileType(tile, MP_TREES);
ModifyTile(tile, SetTreeGroundDensity(tile, ct == CL_ROUGH ? TR_ROUGH : TR_GRASS, 0);
MP_SETTYPE(MP_TREES) | SetTreeCounter(tile, 0);
MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5, SetTreeType(tile, tree);
(ct == CL_ROUGH ? 0x10 : 0), SetTreeCount(tile, 0);
tree, SetTreeGrowth(tile, 0);
_m[tile].m4 & ~3,
0
);
} }
// byte underflow // byte underflow
@ -580,23 +561,17 @@ void OnTick_Trees(void)
tile = TILE_MASK(r); tile = TILE_MASK(r);
if (IsTileType(tile, MP_CLEAR) && if (IsTileType(tile, MP_CLEAR) &&
(ct = GetClearGround(tile), ct == CL_GRASS || ct == CL_ROUGH || ct == CL_SNOW) && (ct = GetClearGround(tile), ct == CL_GRASS || ct == CL_ROUGH || ct == CL_SNOW) &&
(tree = GetRandomTreeType(tile, GB(r, 24, 8))) >= 0) { (tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TR_INVALID) {
int m2;
switch (ct) { switch (ct) {
case CL_GRASS: m2 = 0; break; case CL_GRASS: SetTreeGroundDensity(tile, TR_GRASS, 0); break;
case CL_ROUGH: m2 = 0x10; break; case CL_ROUGH: SetTreeGroundDensity(tile, TR_ROUGH, 0); break;
default: m2 = (GetClearDensity(tile) << 6) | 0x20; break; default: SetTreeGroundDensity(tile, TR_SNOW_DESERT, GetClearDensity(tile)); break;
} }
SetTreeCounter(tile, 0);
ModifyTile(tile, SetTileType(tile, MP_TREES);
MP_SETTYPE(MP_TREES) | SetTreeType(tile, tree);
MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5, SetTreeCount(tile, 0);
m2, SetTreeGrowth(tile, 0);
tree,
_m[tile].m4 & ~3,
0
);
} }
} }