tree_cmd.c
changeset 2049 538e73c53f54
parent 1981 3c9c682f1212
child 2051 e369160ce2f3
equal deleted inserted replaced
2048:54fd558314dc 2049:538e73c53f54
    42 
    42 
    43 	if (tree >= 0) {
    43 	if (tree >= 0) {
    44 		m5 = (byte)(r >> 16);
    44 		m5 = (byte)(r >> 16);
    45 		if ((m5 & 0x7) == 7) m5--; // there is no growth state 7
    45 		if ((m5 & 0x7) == 7) m5--; // there is no growth state 7
    46 
    46 
    47 		_map5[tile] = m5 & 0x07;	// growth state;
    47 		_m[tile].m5 = m5 & 0x07;	// growth state;
    48 		_map5[tile] |=  m5 & 0xC0;	// amount of trees
    48 		_m[tile].m5 |=  m5 & 0xC0;	// amount of trees
    49 
    49 
    50 		_map3_lo[tile] = tree;		// set type of tree
    50 		_m[tile].m3 = tree;		// set type of tree
    51 		_map3_hi[tile] = 0;		// no hedge
    51 		_m[tile].m4 = 0;		// no hedge
    52 
    52 
    53 		// above snowline?
    53 		// above snowline?
    54 		if (_opt.landscape == LT_HILLY && GetTileZ(tile) > _opt.snow_line) {
    54 		if (_opt.landscape == LT_HILLY && GetTileZ(tile) > _opt.snow_line) {
    55 			_map2[tile] = 0xE0;	// set land type to snow
    55 			_m[tile].m2 = 0xE0;	// set land type to snow
    56 			_map2[tile] |= (byte)(r >> 24)&0x07; // randomize counter
    56 			_m[tile].m2 |= (byte)(r >> 24)&0x07; // randomize counter
    57 		}
    57 		}
    58 		else
    58 		else
    59 		{
    59 		{
    60 			_map2[tile] = (byte)(r >> 24)&0x1F; // randomize counter and ground
    60 			_m[tile].m2 = (byte)(r >> 24)&0x1F; // randomize counter and ground
    61 		}
    61 		}
    62 
    62 
    63 
    63 
    64 		// make it tree class
    64 		// make it tree class
    65 		SetTileType(tile, MP_TREES);
    65 		SetTileType(tile, MP_TREES);
    84 		cur_tile = TILE_MASK(tile + TileDiffXY(x, y));
    84 		cur_tile = TILE_MASK(tile + TileDiffXY(x, y));
    85 
    85 
    86 		/* Only on tiles within 13 squares from tile,
    86 		/* Only on tiles within 13 squares from tile,
    87 		    on clear tiles, and NOT on farm-tiles or rocks */
    87 		    on clear tiles, and NOT on farm-tiles or rocks */
    88 		if (dist <= 13 && IsTileType(cur_tile, MP_CLEAR) &&
    88 		if (dist <= 13 && IsTileType(cur_tile, MP_CLEAR) &&
    89 			 (_map5[cur_tile] & 0x1F) != 0x0F && (_map5[cur_tile] & 0x1C) != 8) {
    89 			 (_m[cur_tile].m5 & 0x1F) != 0x0F && (_m[cur_tile].m5 & 0x1C) != 8) {
    90 			PlaceTree(cur_tile, r, dist <= 6 ? 0xC0 : 0);
    90 			PlaceTree(cur_tile, r, dist <= 6 ? 0xC0 : 0);
    91 		}
    91 		}
    92 	} while (--i);
    92 	} while (--i);
    93 }
    93 }
    94 
    94 
   109 	i = ScaleByMapSize(1000);
   109 	i = ScaleByMapSize(1000);
   110 	do {
   110 	do {
   111 		r = Random();
   111 		r = Random();
   112 		tile = TILE_MASK(r);
   112 		tile = TILE_MASK(r);
   113 		/* Only on clear tiles, and NOT on farm-tiles or rocks */
   113 		/* Only on clear tiles, and NOT on farm-tiles or rocks */
   114 		if (IsTileType(tile, MP_CLEAR) && (_map5[tile] & 0x1F) != 0x0F && (_map5[tile] & 0x1C) != 8) {
   114 		if (IsTileType(tile, MP_CLEAR) && (_m[tile].m5 & 0x1F) != 0x0F && (_m[tile].m5 & 0x1C) != 8) {
   115 			PlaceTree(tile, r, 0);
   115 			PlaceTree(tile, r, 0);
   116 		}
   116 		}
   117 	} while (--i);
   117 	} while (--i);
   118 
   118 
   119 	/* place extra trees at rainforest area */
   119 	/* place extra trees at rainforest area */
   186 						_error_message = STR_2803_TREE_ALREADY_HERE;
   186 						_error_message = STR_2803_TREE_ALREADY_HERE;
   187 						continue;
   187 						continue;
   188 					}
   188 					}
   189 
   189 
   190 					if (flags & DC_EXEC) {
   190 					if (flags & DC_EXEC) {
   191 						_map5[ti.tile] = ti.map5 + 0x40;
   191 						_m[ti.tile].m5 = ti.map5 + 0x40;
   192 						MarkTileDirtyByTile(ti.tile);
   192 						MarkTileDirtyByTile(ti.tile);
   193 					}
   193 					}
   194 					// 2x as expensive to add more trees to an existing tile
   194 					// 2x as expensive to add more trees to an existing tile
   195 					cost += _price.build_trees * 2;
   195 					cost += _price.build_trees * 2;
   196 					break;
   196 					break;
   272 	const uint32 *s;
   272 	const uint32 *s;
   273 	const byte *d;
   273 	const byte *d;
   274 	byte z;
   274 	byte z;
   275 	TreeListEnt te[4];
   275 	TreeListEnt te[4];
   276 
   276 
   277 	m2 = _map2[ti->tile];
   277 	m2 = _m[ti->tile].m2;
   278 
   278 
   279 	if ( (m2&0x30) == 0) {
   279 	if ( (m2&0x30) == 0) {
   280 		DrawClearLandTile(ti, 3);
   280 		DrawClearLandTile(ti, 3);
   281 	} else if ((m2&0x30) == 0x20) {
   281 	} else if ((m2&0x30) == 0x20) {
   282 		DrawGroundSprite(_tree_sprites_1[m2 >> 6] + _tileh_to_sprite[ti->tileh]);
   282 		DrawGroundSprite(_tree_sprites_1[m2 >> 6] + _tileh_to_sprite[ti->tileh]);
   283 	} else {
   283 	} else {
   284 		DrawHillyLandTile(ti);
   284 		DrawHillyLandTile(ti);
   285 	}
   285 	}
   286 
   286 
   287 	DrawClearLandFence(ti, _map3_hi[ti->tile] >> 2);
   287 	DrawClearLandFence(ti, _m[ti->tile].m4 >> 2);
   288 
   288 
   289 	z = ti->z;
   289 	z = ti->z;
   290 	if (ti->tileh != 0) {
   290 	if (ti->tileh != 0) {
   291 		z += 4;
   291 		z += 4;
   292 		if (ti->tileh & 0x10)
   292 		if (ti->tileh & 0x10)
   304 		tmp = (tmp >> 1) | (tmp << 15);
   304 		tmp = (tmp >> 1) | (tmp << 15);
   305 		tmp += ti->y;
   305 		tmp += ti->y;
   306 
   306 
   307 		d = _tree_layout_xy[(tmp & 0x30) >> 4];
   307 		d = _tree_layout_xy[(tmp & 0x30) >> 4];
   308 
   308 
   309 		index = ((tmp>>6)&3) + (_map3_lo[ti->tile]<<2);
   309 		index = ((tmp>>6)&3) + (_m[ti->tile].m3<<2);
   310 
   310 
   311 		/* different tree styles above one of the grounds */
   311 		/* different tree styles above one of the grounds */
   312 		if ((m2 & 0xB0) == 0xA0 && index >= 48 && index < 80)
   312 		if ((m2 & 0xB0) == 0xA0 && index >= 48 && index < 80)
   313 			index += 164 - 48;
   313 			index += 164 - 48;
   314 
   314 
   376 		Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority);
   376 		Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority);
   377 		if (t != NULL)
   377 		if (t != NULL)
   378 			ChangeTownRating(t, RATING_TREE_DOWN_STEP, RATING_TREE_MINIMUM);
   378 			ChangeTownRating(t, RATING_TREE_DOWN_STEP, RATING_TREE_MINIMUM);
   379 	}
   379 	}
   380 
   380 
   381 	num = (_map5[tile] >> 6) + 1;
   381 	num = (_m[tile].m5 >> 6) + 1;
   382 	if ( (byte)(_map3_lo[tile]-0x14) <= (0x1A-0x14))
   382 	if ( (byte)(_m[tile].m3-0x14) <= (0x1A-0x14))
   383 		num <<= 2;
   383 		num <<= 2;
   384 
   384 
   385 	if (flags & DC_EXEC)
   385 	if (flags & DC_EXEC)
   386 		DoClearSquare(tile);
   386 		DoClearSquare(tile);
   387 
   387 
   398 	byte b;
   398 	byte b;
   399 	StringID str;
   399 	StringID str;
   400 
   400 
   401 	td->owner = GetTileOwner(tile);
   401 	td->owner = GetTileOwner(tile);
   402 
   402 
   403 	b = _map3_lo[tile];
   403 	b = _m[tile].m3;
   404 	(str=STR_2810_CACTUS_PLANTS, b==0x1B) ||
   404 	(str=STR_2810_CACTUS_PLANTS, b==0x1B) ||
   405 	(str=STR_280F_RAINFOREST, IS_BYTE_INSIDE(b, 0x14, 0x1A+1)) ||
   405 	(str=STR_280F_RAINFOREST, IS_BYTE_INSIDE(b, 0x14, 0x1A+1)) ||
   406 	(str=STR_280E_TREES, true);
   406 	(str=STR_280E_TREES, true);
   407 	td->str = str;
   407 	td->str = str;
   408 }
   408 }
   428 
   428 
   429 		if (CHANCE16I(1,200,r=Random())) {
   429 		if (CHANCE16I(1,200,r=Random())) {
   430 			SndPlayTileFx(_desert_sounds[(r >> 16) & 3], tile);
   430 			SndPlayTileFx(_desert_sounds[(r >> 16) & 3], tile);
   431 		}
   431 		}
   432 	} else if (b == 1) {
   432 	} else if (b == 1) {
   433 		if ((_map2[tile] & 0x30) != 0x20) {
   433 		if ((_m[tile].m2 & 0x30) != 0x20) {
   434 			_map2[tile] &= 0xF;
   434 			_m[tile].m2 &= 0xF;
   435 			_map2[tile] |= 0xE0;
   435 			_m[tile].m2 |= 0xE0;
   436 			MarkTileDirtyByTile(tile);
   436 			MarkTileDirtyByTile(tile);
   437 		}
   437 		}
   438 	}
   438 	}
   439 }
   439 }
   440 
   440 
   444 	int k;
   444 	int k;
   445 
   445 
   446 	/* distance from snow line, in steps of 8 */
   446 	/* distance from snow line, in steps of 8 */
   447 	k = GetTileZ(tile) - _opt.snow_line;
   447 	k = GetTileZ(tile) - _opt.snow_line;
   448 
   448 
   449 	tmp = _map5[tile] & 0xF0;
   449 	tmp = _m[tile].m5 & 0xF0;
   450 
   450 
   451 	if (k < -8) {
   451 	if (k < -8) {
   452 		/* snow_m2_down */
   452 		/* snow_m2_down */
   453 		if ((tmp&0x30) != 0x20)
   453 		if ((tmp&0x30) != 0x20)
   454 			return;
   454 			return;
   479 		} else {
   479 		} else {
   480 			m2 = 0xE0;
   480 			m2 = 0xE0;
   481 		}
   481 		}
   482 	}
   482 	}
   483 
   483 
   484 	_map2[tile] &= 0xF;
   484 	_m[tile].m2 &= 0xF;
   485 	_map2[tile] |= m2;
   485 	_m[tile].m2 |= m2;
   486 	MarkTileDirtyByTile(tile);
   486 	MarkTileDirtyByTile(tile);
   487 }
   487 }
   488 
   488 
   489 static void TileLoop_Trees(TileIndex tile)
   489 static void TileLoop_Trees(TileIndex tile)
   490 {
   490 {
   510 
   510 
   511 	TileLoopClearHelper(tile);
   511 	TileLoopClearHelper(tile);
   512 
   512 
   513 	/* increase counter */
   513 	/* increase counter */
   514 	{
   514 	{
   515 		uint16 m2 = _map2[tile];
   515 		uint16 m2 = _m[tile].m2;
   516 		_map2[tile] = m2 = (m2 & 0xF0) | ((m2+1)&0xF);
   516 		_m[tile].m2 = m2 = (m2 & 0xF0) | ((m2+1)&0xF);
   517 		if (m2 & 0xF)
   517 		if (m2 & 0xF)
   518 			return;
   518 			return;
   519 	}
   519 	}
   520 
   520 
   521 	m5 = _map5[tile];
   521 	m5 = _m[tile].m5;
   522 	if ((m5&7) == 3) {
   522 	if ((m5&7) == 3) {
   523 		/* regular sized tree */
   523 		/* regular sized tree */
   524 		if (_opt.landscape == LT_DESERT && _map3_lo[tile]!=0x1B && GetMapExtraBits(tile)==1) {
   524 		if (_opt.landscape == LT_DESERT && _m[tile].m3!=0x1B && GetMapExtraBits(tile)==1) {
   525 			m5++; /* start destructing */
   525 			m5++; /* start destructing */
   526 		} else {
   526 		} else {
   527 			switch(Random() & 0x7) {
   527 			switch(Random() & 0x7) {
   528 			case 0: /* start destructing */
   528 			case 0: /* start destructing */
   529 				m5++;
   529 				m5++;
   535 					break;
   535 					break;
   536 				}
   536 				}
   537 				/* fall through */
   537 				/* fall through */
   538 
   538 
   539 			case 2: { /* add a neighbouring tree */
   539 			case 2: { /* add a neighbouring tree */
   540 				byte m3 = _map3_lo[tile];
   540 				byte m3 = _m[tile].m3;
   541 
   541 
   542 				tile += ToTileIndexDiff(_tileloop_trees_dir[Random() & 7]);
   542 				tile += ToTileIndexDiff(_tileloop_trees_dir[Random() & 7]);
   543 
   543 
   544 				if (!IsTileType(tile, MP_CLEAR))
   544 				if (!IsTileType(tile, MP_CLEAR))
   545 					return;
   545 					return;
   546 
   546 
   547 				if ( (_map5[tile] & 0x1C) == 4) {
   547 				if ( (_m[tile].m5 & 0x1C) == 4) {
   548 					_map2[tile] = 0x10;
   548 					_m[tile].m2 = 0x10;
   549 				} else if ((_map5[tile] & 0x1C) == 16) {
   549 				} else if ((_m[tile].m5 & 0x1C) == 16) {
   550 					_map2[tile] = ((_map5[tile] & 3) << 6) | 0x20;
   550 					_m[tile].m2 = ((_m[tile].m5 & 3) << 6) | 0x20;
   551 				} else {
   551 				} else {
   552 					if ((_map5[tile] & 0x1F) != 3)
   552 					if ((_m[tile].m5 & 0x1F) != 3)
   553 						return;
   553 						return;
   554 					_map2[tile] = 0;
   554 					_m[tile].m2 = 0;
   555 				}
   555 				}
   556 
   556 
   557 				_map3_lo[tile] = m3;
   557 				_m[tile].m3 = m3;
   558 				_map3_hi[tile] = 0;
   558 				_m[tile].m4 = 0;
   559 				SetTileType(tile, MP_TREES);
   559 				SetTileType(tile, MP_TREES);
   560 
   560 
   561 				m5 = 0;
   561 				m5 = 0;
   562 				break;
   562 				break;
   563 			}
   563 			}
   574 		} else {
   574 		} else {
   575 			/* just one tree, change type into MP_CLEAR */
   575 			/* just one tree, change type into MP_CLEAR */
   576 			SetTileType(tile, MP_CLEAR);
   576 			SetTileType(tile, MP_CLEAR);
   577 
   577 
   578 			m5 = 3;
   578 			m5 = 3;
   579 			m2 = _map2[tile];
   579 			m2 = _m[tile].m2;
   580 			if ((m2&0x30) != 0) { // on snow/desert or rough land
   580 			if ((m2&0x30) != 0) { // on snow/desert or rough land
   581 				m5 = (m2 >> 6) | 0x10;
   581 				m5 = (m2 >> 6) | 0x10;
   582 				if ((m2&0x30) != 0x20) // if not on snow/desert, then on rough land
   582 				if ((m2&0x30) != 0x20) // if not on snow/desert, then on rough land
   583 					m5 = 7;
   583 					m5 = 7;
   584 			}
   584 			}
   587 	} else {
   587 	} else {
   588 		/* in the middle of a transition, change to next */
   588 		/* in the middle of a transition, change to next */
   589 		m5++;
   589 		m5++;
   590 	}
   590 	}
   591 
   591 
   592 	_map5[tile] = m5;
   592 	_m[tile].m5 = m5;
   593 	MarkTileDirtyByTile(tile);
   593 	MarkTileDirtyByTile(tile);
   594 }
   594 }
   595 
   595 
   596 void OnTick_Trees(void)
   596 void OnTick_Trees(void)
   597 {
   597 {
   602 
   602 
   603 	/* place a tree at a random rainforest spot */
   603 	/* place a tree at a random rainforest spot */
   604 	if (_opt.landscape == LT_DESERT &&
   604 	if (_opt.landscape == LT_DESERT &&
   605 			(r=Random(),tile=TILE_MASK(r),GetMapExtraBits(tile)==2) &&
   605 			(r=Random(),tile=TILE_MASK(r),GetMapExtraBits(tile)==2) &&
   606 			IsTileType(tile, MP_CLEAR) &&
   606 			IsTileType(tile, MP_CLEAR) &&
   607 			(m=_map5[tile]&0x1C, m<=4) &&
   607 			(m=_m[tile].m5&0x1C, m<=4) &&
   608 			(tree=GetRandomTreeType(tile, r>>24)) >= 0) {
   608 			(tree=GetRandomTreeType(tile, r>>24)) >= 0) {
   609 
   609 
   610 		ModifyTile(tile,
   610 		ModifyTile(tile,
   611 			MP_SETTYPE(MP_TREES) |
   611 			MP_SETTYPE(MP_TREES) |
   612 			MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5,
   612 			MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5,
   613 			(m == 4 ? 0x10 : 0),
   613 			(m == 4 ? 0x10 : 0),
   614 			tree,
   614 			tree,
   615 			_map3_hi[tile] & ~3,
   615 			_m[tile].m4 & ~3,
   616 			0
   616 			0
   617 		);
   617 		);
   618 	}
   618 	}
   619 
   619 
   620 	// byte underflow
   620 	// byte underflow
   623 
   623 
   624 	/* place a tree at a random spot */
   624 	/* place a tree at a random spot */
   625 	r = Random();
   625 	r = Random();
   626 	tile = TILE_MASK(r);
   626 	tile = TILE_MASK(r);
   627 	if (IsTileType(tile, MP_CLEAR) &&
   627 	if (IsTileType(tile, MP_CLEAR) &&
   628 			(m=_map5[tile]&0x1C, m==0 || m==4 || m==0x10) &&
   628 			(m=_m[tile].m5&0x1C, m==0 || m==4 || m==0x10) &&
   629 			(tree=GetRandomTreeType(tile, r>>24)) >= 0) {
   629 			(tree=GetRandomTreeType(tile, r>>24)) >= 0) {
   630 		int m2;
   630 		int m2;
   631 
   631 
   632 		if (m == 0) {
   632 		if (m == 0) {
   633 			m2 = 0;
   633 			m2 = 0;
   634 		} else if (m == 4) {
   634 		} else if (m == 4) {
   635 			m2 = 0x10;
   635 			m2 = 0x10;
   636 		} else {
   636 		} else {
   637 			m2 = ((_map5[tile] & 3) << 6) | 0x20;
   637 			m2 = ((_m[tile].m5 & 3) << 6) | 0x20;
   638 		}
   638 		}
   639 
   639 
   640 		ModifyTile(tile,
   640 		ModifyTile(tile,
   641 			MP_SETTYPE(MP_TREES) |
   641 			MP_SETTYPE(MP_TREES) |
   642 			MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5,
   642 			MP_MAP2 | MP_MAP3LO | MP_MAP3HI | MP_MAP5,
   643 			m2,
   643 			m2,
   644 			tree,
   644 			tree,
   645 			_map3_hi[tile] & ~3,
   645 			_m[tile].m4 & ~3,
   646 			0
   646 			0
   647 		);
   647 		);
   648 	}
   648 	}
   649 }
   649 }
   650 
   650