road_cmd.c
changeset 3933 a5f08e17f4a0
parent 3900 4984308f9125
child 3977 edb5b94e2094
equal deleted inserted replaced
3932:882af4997b60 3933:a5f08e17f4a0
   106 
   106 
   107 	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) */
   107 	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) */
   108 	if (p1 >> 4) return CMD_ERROR;
   108 	if (p1 >> 4) return CMD_ERROR;
   109 	pieces = p1;
   109 	pieces = p1;
   110 
   110 
   111 	if (!IsTileType(tile, MP_STREET) && !IsTileType(tile, MP_TUNNELBRIDGE)) return CMD_ERROR;
   111 	if (!IsTileType(tile, MP_STREET)) return CMD_ERROR;
   112 
   112 
   113 	owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
   113 	owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
   114 
   114 
   115 	if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) {
   115 	if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) {
   116 		if (IsTileType(tile, MP_TUNNELBRIDGE)) { // index of town is not saved for bridge (no space)
   116 		t = GetTownByTile(tile);
   117 			t = ClosestTownFromTile(tile, _patches.dist_local_authority);
       
   118 		} else {
       
   119 			t = GetTownByTile(tile);
       
   120 		}
       
   121 	} else {
   117 	} else {
   122 		t = NULL;
   118 		t = NULL;
   123 	}
   119 	}
   124 
   120 
   125 	if (!CheckAllowRemoveRoad(tile, pieces, &edge_road)) return CMD_ERROR;
   121 	if (!CheckAllowRemoveRoad(tile, pieces, &edge_road)) return CMD_ERROR;
   126 
   122 
   127 	switch (GetTileType(tile)) {
   123 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
   128 		case MP_TUNNELBRIDGE:
   124 
   129 			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
   125 	// check if you're allowed to remove the street owned by a town
   130 
   126 	// removal allowance depends on difficulty setting
   131 			if (!IsBridge(tile) ||
   127 	if (!CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR;
   132 					!IsBridgeMiddle(tile) ||
   128 
   133 					!IsTransportUnderBridge(tile) ||
   129 	switch (GetRoadTileType(tile)) {
   134 					GetTransportTypeUnderBridge(tile) != TRANSPORT_ROAD ||
   130 		case ROAD_TILE_NORMAL: {
   135 					(pieces & ComplementRoadBits(GetRoadBitsUnderBridge(tile))) != 0) {
   131 			RoadBits present = GetRoadBits(tile);
   136 				return CMD_ERROR;
   132 			RoadBits c = pieces;
   137 			}
   133 
       
   134 			if (GetTileSlope(tile, NULL) != SLOPE_FLAT  &&
       
   135 					(present == ROAD_Y || present == ROAD_X)) {
       
   136 				c |= (c & 0xC) >> 2;
       
   137 				c |= (c & 0x3) << 2;
       
   138 			}
       
   139 
       
   140 			// limit the bits to delete to the existing bits.
       
   141 			c &= present;
       
   142 			if (c == 0) return CMD_ERROR;
   138 
   143 
   139 			if (flags & DC_EXEC) {
   144 			if (flags & DC_EXEC) {
   140 				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
   145 				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
   141 				SetClearUnderBridge(tile);
   146 
       
   147 				present ^= c;
       
   148 				if (present == 0) {
       
   149 					DoClearSquare(tile);
       
   150 				} else {
       
   151 					SetRoadBits(tile, present);
       
   152 					MarkTileDirtyByTile(tile);
       
   153 				}
       
   154 			}
       
   155 			return CountRoadBits(c) * _price.remove_road;
       
   156 		}
       
   157 
       
   158 		case ROAD_TILE_CROSSING: {
       
   159 			if (pieces & ComplementRoadBits(GetCrossingRoadBits(tile))) {
       
   160 				return CMD_ERROR;
       
   161 			}
       
   162 
       
   163 			if (flags & DC_EXEC) {
       
   164 				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
       
   165 
       
   166 				MakeRailNormal(tile, GetTileOwner(tile), GetCrossingRailBits(tile), GetRailTypeCrossing(tile));
   142 				MarkTileDirtyByTile(tile);
   167 				MarkTileDirtyByTile(tile);
   143 			}
   168 			}
   144 			return _price.remove_road * 2;
   169 			return _price.remove_road * 2;
   145 
   170 		}
   146 		case MP_STREET:
   171 
   147 			if (!EnsureNoVehicle(tile)) return CMD_ERROR;
   172 		case ROAD_TILE_DEPOT:
   148 
   173 		default:
   149 			// check if you're allowed to remove the street owned by a town
   174 			return CMD_ERROR;
   150 			// removal allowance depends on difficulty setting
       
   151 			if (!CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR;
       
   152 
       
   153 			switch (GetRoadTileType(tile)) {
       
   154 				case ROAD_TILE_NORMAL: {
       
   155 					RoadBits present = GetRoadBits(tile);
       
   156 					RoadBits c = pieces;
       
   157 
       
   158 					if (GetTileSlope(tile, NULL) != SLOPE_FLAT &&
       
   159 							(present == ROAD_Y || present == ROAD_X)) {
       
   160 						c |= (c & 0xC) >> 2;
       
   161 						c |= (c & 0x3) << 2;
       
   162 					}
       
   163 
       
   164 					// limit the bits to delete to the existing bits.
       
   165 					c &= present;
       
   166 					if (c == 0) return CMD_ERROR;
       
   167 
       
   168 					if (flags & DC_EXEC) {
       
   169 						ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
       
   170 
       
   171 						present ^= c;
       
   172 						if (present == 0) {
       
   173 							DoClearSquare(tile);
       
   174 						} else {
       
   175 							SetRoadBits(tile, present);
       
   176 							MarkTileDirtyByTile(tile);
       
   177 						}
       
   178 					}
       
   179 					return CountRoadBits(c) * _price.remove_road;
       
   180 				}
       
   181 
       
   182 				case ROAD_TILE_CROSSING: {
       
   183 					if (pieces & ComplementRoadBits(GetCrossingRoadBits(tile))) {
       
   184 						return CMD_ERROR;
       
   185 					}
       
   186 
       
   187 					if (flags & DC_EXEC) {
       
   188 						ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
       
   189 
       
   190 						MakeRailNormal(tile, GetTileOwner(tile), GetCrossingRailBits(tile), GetRailTypeCrossing(tile));
       
   191 						MarkTileDirtyByTile(tile);
       
   192 					}
       
   193 					return _price.remove_road * 2;
       
   194 				}
       
   195 
       
   196 				default:
       
   197 				case ROAD_TILE_DEPOT:
       
   198 					return CMD_ERROR;
       
   199 			}
       
   200 
       
   201 		default: return CMD_ERROR;
       
   202 	}
   175 	}
   203 }
   176 }
   204 
   177 
   205 
   178 
   206 static const RoadBits _valid_tileh_slopes_road[][15] = {
   179 static const RoadBits _valid_tileh_slopes_road[][15] = {
   346 				MarkTileDirtyByTile(tile);
   319 				MarkTileDirtyByTile(tile);
   347 			}
   320 			}
   348 			return _price.build_road * 2;
   321 			return _price.build_road * 2;
   349 		}
   322 		}
   350 
   323 
   351 		case MP_TUNNELBRIDGE:
       
   352 			/* check for flat land */
       
   353 			if (IsSteepSlope(tileh)) {
       
   354 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
       
   355 			}
       
   356 
       
   357 			if (!IsBridge(tile) || !IsBridgeMiddle(tile)) goto do_clear;
       
   358 
       
   359 			/* only allow roads pertendicular to bridge */
       
   360 			if ((pieces & (GetBridgeAxis(tile) == AXIS_X ? ROAD_X : ROAD_Y)) != 0) {
       
   361 				goto do_clear;
       
   362 			}
       
   363 
       
   364 			/* check if clear land under bridge */
       
   365 			if (IsTransportUnderBridge(tile)) {
       
   366 				switch (GetTransportTypeUnderBridge(tile)) {
       
   367 					case TRANSPORT_ROAD: return_cmd_error(STR_1007_ALREADY_BUILT);
       
   368 					default: return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK);
       
   369 				}
       
   370 			} else {
       
   371 				if (IsWaterUnderBridge(tile)) {
       
   372 					return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
       
   373 				}
       
   374 			}
       
   375 
       
   376 			if (flags & DC_EXEC) {
       
   377 				SetRoadUnderBridge(tile, _current_player);
       
   378 				MarkTileDirtyByTile(tile);
       
   379 			}
       
   380 			return _price.build_road * 2;
       
   381 
       
   382 		default:
   324 		default:
   383 do_clear:;
   325 do_clear:;
   384 			ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   326 			ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   385 			if (CmdFailed(ret)) return ret;
   327 			if (CmdFailed(ret)) return ret;
   386 			cost += ret;
   328 			cost += ret;
   573 	}
   515 	}
   574 
   516 
   575 	cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   517 	cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   576 	if (CmdFailed(cost)) return CMD_ERROR;
   518 	if (CmdFailed(cost)) return CMD_ERROR;
   577 
   519 
       
   520 	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
       
   521 
   578 	dep = AllocateDepot();
   522 	dep = AllocateDepot();
   579 	if (dep == NULL) return CMD_ERROR;
   523 	if (dep == NULL) return CMD_ERROR;
   580 
   524 
   581 	if (flags & DC_EXEC) {
   525 	if (flags & DC_EXEC) {
   582 		dep->xy = tile;
   526 		dep->xy = tile;
   796 				);
   740 				);
   797 			}
   741 			}
   798 			break;
   742 			break;
   799 		}
   743 		}
   800 	}
   744 	}
       
   745 	DrawBridgeMiddle(ti);
   801 }
   746 }
   802 
   747 
   803 void DrawRoadDepotSprite(int x, int y, int image)
   748 void DrawRoadDepotSprite(int x, int y, int image)
   804 {
   749 {
   805 	uint32 ormod;
   750 	uint32 ormod;