tree_cmd.c
changeset 1286 10b9fe28effc
parent 1209 2e00193652b2
child 1370 c86b2c30fd01
equal deleted inserted replaced
1285:4bda5c927b45 1286:10b9fe28effc
     6 #include "viewport.h"
     6 #include "viewport.h"
     7 #include "command.h"
     7 #include "command.h"
     8 #include "town.h"
     8 #include "town.h"
     9 #include "sound.h"
     9 #include "sound.h"
    10 
    10 
    11 static int GetRandomTreeType(uint tile, uint seed)
    11 static int GetRandomTreeType(TileIndex tile, uint seed)
    12 {
    12 {
    13 	byte i;
    13 	switch (_opt.landscape) {
    14 
    14 		case LT_NORMAL:
    15 	if (_opt.landscape == LT_NORMAL) {
    15 			return seed * 12 >> 8;
    16 		return seed * 12 >> 8;
    16 
    17 	} else if (_opt.landscape == LT_HILLY) {
    17 		case LT_HILLY:
    18 		return (seed >> 5) + 12;
    18 			return (seed >> 5) + 12;
    19 	} else if (_opt.landscape == LT_DESERT) {
    19 
    20 		i = GetMapExtraBits(tile);
    20 		case LT_DESERT:
    21 		if (i == 0) {
    21 			switch (GetMapExtraBits(tile)) {
    22 			return (seed >> 6) + 28;
    22 				case 0:
    23 		} else if (i == 1) {
    23 					return (seed >> 6) + 28;
    24 			if (seed > 12)
    24 
    25 				return -1;
    25 				case 1:
    26 			return 27;
    26 					return (seed > 12) ? -1 : 27;
    27 		} else {
    27 
    28 			return (seed * 7 >> 8) + 20;
    28 				default:
    29 		}
    29 					return (seed * 7 >> 8) + 20;
    30 	} else {
    30 			}
    31 		return (seed * 9 >> 8) + 32;
    31 
       
    32 		default:
       
    33 			return (seed * 9 >> 8) + 32;
    32 	}
    34 	}
    33 }
    35 }
    34 
    36 
    35 static void PlaceTree(uint tile, uint32 r, byte m5_or)
    37 static void PlaceTree(uint tile, uint32 r, byte m5_or)
    36 {
    38 {
   146  * p2 = end tile
   148  * p2 = end tile
   147  */
   149  */
   148 
   150 
   149 int32 CmdPlantTree(int ex, int ey, uint32 flags, uint32 p1, uint32 p2)
   151 int32 CmdPlantTree(int ex, int ey, uint32 flags, uint32 p1, uint32 p2)
   150 {
   152 {
   151 	TileInfo ti;
       
   152 	int32 cost;
   153 	int32 cost;
   153 	int sx,sy,x,y;
   154 	int sx;
   154 	int treetype;
   155 	int sy;
       
   156 	int x;
       
   157 	int y;
       
   158 
       
   159 	if (p2 >= MapSize()) return CMD_ERROR;
   155 
   160 
   156 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
   161 	SET_EXPENSES_TYPE(EXPENSES_OTHER);
   157 
   162 
   158 	// make sure sx,sy are smaller than ex,ey
   163 	// make sure sx,sy are smaller than ex,ey
   159 	sx = TileX(p2) * 16;
   164 	sx = TileX(p2) * 16;
   161 	if (ex < sx) intswap(ex, sx);
   166 	if (ex < sx) intswap(ex, sx);
   162 	if (ey < sy) intswap(ey, sy);
   167 	if (ey < sy) intswap(ey, sy);
   163 
   168 
   164 	cost = 0; // total cost
   169 	cost = 0; // total cost
   165 
   170 
   166 	for(x=sx; x<=ex; x+=16) {
   171 	for (x = sx; x <= ex; x += 16) {
   167 		for(y=sy; y<=ey; y+=16) {
   172 		for (y = sy; y <= ey; y += 16) {
       
   173 			TileInfo ti;
       
   174 
   168 			FindLandscapeHeight(&ti, x, y);
   175 			FindLandscapeHeight(&ti, x, y);
   169 			if (!EnsureNoVehicle(ti.tile))
   176 			if (!EnsureNoVehicle(ti.tile))
   170 				continue;
   177 				continue;
   171 
   178 
   172 			if (ti.type == MP_TREES) {
   179 			switch (ti.type) {
   173 				// no more space for trees?
   180 				case MP_TREES:
   174 				if (_game_mode != GM_EDITOR && (ti.map5 & 0xC0) == 0xC0) {
   181 					// no more space for trees?
   175 					_error_message = STR_2803_TREE_ALREADY_HERE;
   182 					if (_game_mode != GM_EDITOR && (ti.map5 & 0xC0) == 0xC0) {
   176 					continue;
   183 						_error_message = STR_2803_TREE_ALREADY_HERE;
   177 				}
   184 						continue;
   178 
   185 					}
   179 				if (flags & DC_EXEC) {
   186 
   180 					_map5[ti.tile] = ti.map5 + 0x40;
   187 					if (flags & DC_EXEC) {
   181 					MarkTileDirtyByTile(ti.tile);
   188 						_map5[ti.tile] = ti.map5 + 0x40;
   182 				}
   189 						MarkTileDirtyByTile(ti.tile);
   183 				// 2x as expensive to add more trees to an existing tile
   190 					}
   184 				cost += _price.build_trees * 2;
   191 					// 2x as expensive to add more trees to an existing tile
   185 			} else {
   192 					cost += _price.build_trees * 2;
   186 				if (ti.type != MP_CLEAR || _map_owner[ti.tile] != OWNER_NONE) {
   193 					break;
       
   194 
       
   195 				case MP_CLEAR:
       
   196 					if (_map_owner[ti.tile] != OWNER_NONE) {
       
   197 						_error_message = STR_2804_SITE_UNSUITABLE;
       
   198 						continue;
       
   199 					}
       
   200 
       
   201 					// it's expensive to clear farmland
       
   202 					if ((ti.map5 & 0x1F) == 0xF)
       
   203 						cost += _price.clear_3;
       
   204 					else if ((ti.map5 & 0x1C) == 8)
       
   205 						cost += _price.clear_2;
       
   206 
       
   207 					if (flags & DC_EXEC) {
       
   208 						int treetype;
       
   209 						int m2;
       
   210 
       
   211 						if (_game_mode != GM_EDITOR && _current_player < MAX_PLAYERS) {
       
   212 							Town *t = ClosestTownFromTile(ti.tile, _patches.dist_local_authority);
       
   213 							if (t != NULL)
       
   214 								ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM);
       
   215 						}
       
   216 
       
   217 						switch (ti.map5 & 0x1C) {
       
   218 							case 0x04:
       
   219 								m2 = 16;
       
   220 								break;
       
   221 
       
   222 							case 0x10:
       
   223 								m2 = ((ti.map5 & 3) << 6) | 0x20;
       
   224 								break;
       
   225 
       
   226 							default:
       
   227 								m2 = 0;
       
   228 								break;
       
   229 						}
       
   230 
       
   231 						treetype = p1;
       
   232 						if (treetype == -1) {
       
   233 							treetype = GetRandomTreeType(ti.tile, Random() >> 24);
       
   234 							if (treetype == -1) treetype = 27;
       
   235 						}
       
   236 
       
   237 						ModifyTile(ti.tile,
       
   238 							MP_SETTYPE(MP_TREES) |
       
   239 							MP_MAP2 | MP_MAP3LO | MP_MAP3HI_CLEAR | MP_MAP5,
       
   240 							m2, /* map2 */
       
   241 							treetype, /* map3lo */
       
   242 							_game_mode == GM_EDITOR ? 3 : 0 /* map5 */
       
   243 						);
       
   244 
       
   245 						if (_game_mode == GM_EDITOR && IS_BYTE_INSIDE(treetype, 0x14, 0x1B))
       
   246 							SetMapExtraBits(ti.tile, 2);
       
   247 					}
       
   248 					cost += _price.build_trees;
       
   249 					break;
       
   250 
       
   251 				default:
   187 					_error_message = STR_2804_SITE_UNSUITABLE;
   252 					_error_message = STR_2804_SITE_UNSUITABLE;
   188 					continue;
   253 					break;
   189 				}
       
   190 
       
   191 				// it's expensive to clear farmland
       
   192 				if ((ti.map5 & 0x1F) == 0xF) cost += _price.clear_3;
       
   193 				else if ((ti.map5 & 0x1C) == 8) cost += _price.clear_2;
       
   194 
       
   195 				if (flags & DC_EXEC) {
       
   196 					int m2;
       
   197 
       
   198 					if (_game_mode != GM_EDITOR && _current_player < MAX_PLAYERS) {
       
   199 						Town *t = ClosestTownFromTile(ti.tile, _patches.dist_local_authority);
       
   200 						if (t != NULL)
       
   201 							ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM);
       
   202 					}
       
   203 					m2 = 0;
       
   204 					if ( (ti.map5 & 0x1C) == 4 ) {
       
   205 						m2 = 16;
       
   206 					} else if ( (ti.map5 & 0x1C) == 16 ) {
       
   207 						m2 = ((ti.map5 & 3) << 6) | 0x20;
       
   208 					}
       
   209 
       
   210 					treetype = p1;
       
   211 					if (treetype == -1) {
       
   212 						treetype = GetRandomTreeType(ti.tile, Random()>>24);
       
   213 						if (treetype==-1) treetype=27;
       
   214 					}
       
   215 
       
   216 					ModifyTile(ti.tile,
       
   217 						MP_SETTYPE(MP_TREES) |
       
   218 						MP_MAP2 | MP_MAP3LO | MP_MAP3HI_CLEAR | MP_MAP5,
       
   219 						m2, /* map2 */
       
   220 						treetype, /* map3lo */
       
   221 			 			_game_mode == GM_EDITOR ? 3 : 0 /* map5 */
       
   222 					);
       
   223 
       
   224 					if (_game_mode == GM_EDITOR && IS_BYTE_INSIDE(treetype, 0x14, 0x1B)) {
       
   225 						SetMapExtraBits(ti.tile, 2);
       
   226 					}
       
   227 				}
       
   228 				cost += _price.build_trees;
       
   229 			}
   254 			}
   230 		}
   255 		}
   231 	}
   256 	}
   232 
   257 
   233 	if (cost == 0) return CMD_ERROR;
   258 	if (cost == 0) return CMD_ERROR;