Changeset - r8428:44e364e9d33f
[Not reviewed]
master
0 1 0
smatz - 16 years ago 2008-01-28 12:40:31
smatz@openttd.org
(svn r11998) -Fix [FS#1692](r10053): possible remote assert by setting bit 6 of p1 for CMD_REMOVE_ROAD
1 file changed with 29 insertions and 19 deletions:
0 comments (0 inline, 0 general)
src/road_cmd.cpp
Show inline comments
 
@@ -96,19 +96,15 @@ static bool CheckAllowRemoveRoad(TileInd
 
	return CheckAllowRemoveRoad(tile, remove, GetRoadOwner(tile, rt), edge_road, rt);
 
}
 

	
 

	
 
/** Delete a piece of road.
 
 * @param tile tile where to remove road from
 
 * @param flags operation to perform
 
 * @param p1 bit 0..3 road pieces to remove (RoadBits)
 
 *           bit 4..5 road type
 
 *           bit    6 ignore the fact that the tram track has not been removed
 
 *                    yet when removing the road bits when not actually doing
 
 *                    it. Makes it possible to test whether the road bits can
 
 *                    be removed from a level crossing without physically
 
 *                    removing the tram bits before the test.
 
 * @param p2 unused
 
 * @param pieces roadbits to remove
 
 * @param rt roadtype to remove
 
 * @param crossing_check should we check if there is a tram track when we are removing road from crossing?
 
 */
 
CommandCost CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
static CommandCost RemoveRoad(TileIndex tile, uint32 flags, RoadBits pieces, RoadType rt, bool crossing_check)
 
{
 
	/* cost for removing inner/edge -roads */
 
	static const uint16 road_remove_cost[2] = {50, 18};
 
@@ -117,9 +113,6 @@ CommandCost CmdRemoveRoad(TileIndex tile
 
	 * false if it was a center piece. Affects town ratings drop */
 
	bool edge_road;
 

	
 
	RoadType rt = (RoadType)GB(p1, 4, 2);
 
	if (!IsValidRoadType(rt)) return CMD_ERROR;
 

	
 
	Town *t = NULL;
 
	switch (GetTileType(tile)) {
 
		case MP_ROAD:
 
@@ -141,7 +134,6 @@ CommandCost CmdRemoveRoad(TileIndex tile
 
			return CMD_ERROR;
 
	}
 

	
 
	RoadBits pieces = Extract<RoadBits, 0>(p1);
 
	RoadTypes rts = GetRoadTypes(tile);
 
	/* The tile doesn't have the given road type */
 
	if (!HasBit(rts, rt)) return CMD_ERROR;
 
@@ -233,7 +225,7 @@ CommandCost CmdRemoveRoad(TileIndex tile
 

	
 
			/* Don't allow road to be removed from the crossing when there is tram;
 
			 * we can't draw the crossing without trambits ;) */
 
			if (rt == ROADTYPE_ROAD && HasBit(GetRoadTypes(tile), ROADTYPE_TRAM) && ((flags & DC_EXEC) || !HasBit(p1, 6))) return CMD_ERROR;
 
			if (rt == ROADTYPE_ROAD && HasBit(GetRoadTypes(tile), ROADTYPE_TRAM) && (flags & DC_EXEC || crossing_check)) return CMD_ERROR;
 

	
 
			if (rt == ROADTYPE_ROAD) {
 
				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
 
@@ -259,6 +251,24 @@ CommandCost CmdRemoveRoad(TileIndex tile
 
}
 

	
 

	
 
/** Delete a piece of road.
 
 * @param tile tile where to remove road from
 
 * @param flags operation to perform
 
 * @param p1 bit 0..3 road pieces to remove (RoadBits)
 
 *           bit 4..5 road type
 
 * @param p2 unused
 
 */
 
CommandCost CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	RoadType rt = (RoadType)GB(p1, 4, 2);
 
	if (!IsValidRoadType(rt)) return CMD_ERROR;
 

	
 
	RoadBits pieces = Extract<RoadBits, 0>(p1);
 

	
 
	return RemoveRoad(tile, flags, pieces, rt, true);
 
}
 

	
 

	
 
static const RoadBits _valid_tileh_slopes_road[][15] = {
 
	/* set of normal ones */
 
	{
 
@@ -734,7 +744,7 @@ CommandCost CmdRemoveLongRoad(TileIndex 
 

	
 
		/* try to remove the halves. */
 
		if (bits != 0) {
 
			ret = DoCommand(tile, rt << 4 | bits, 0, flags & ~DC_EXEC, CMD_REMOVE_ROAD);
 
			ret = RemoveRoad(tile, flags & ~DC_EXEC, bits, rt, true);
 
			if (CmdSucceeded(ret)) {
 
				if (flags & DC_EXEC) {
 
					money -= ret.GetCost();
 
@@ -742,7 +752,7 @@ CommandCost CmdRemoveLongRoad(TileIndex 
 
						_additional_cash_required = DoCommand(end_tile, start_tile, p2, flags & ~DC_EXEC, CMD_REMOVE_LONG_ROAD).GetCost();
 
						return cost;
 
					}
 
					DoCommand(tile, rt << 4 | bits, 0, flags, CMD_REMOVE_ROAD);
 
					RemoveRoad(tile, flags, bits, rt, true);
 
				}
 
				cost.AddCost(ret);
 
			}
 
@@ -835,7 +845,7 @@ static CommandCost ClearTile_Road(TileIn
 
				CommandCost ret(EXPENSES_CONSTRUCTION);
 
				for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
 
					if (HasBit(rts, rt)) {
 
						CommandCost tmp_ret = DoCommand(tile, rt << 4 | GetRoadBits(tile, rt), 0, flags, CMD_REMOVE_ROAD);
 
						CommandCost tmp_ret = RemoveRoad(tile, flags, GetRoadBits(tile, rt), rt, true);
 
						if (CmdFailed(tmp_ret)) return tmp_ret;
 
						ret.AddCost(tmp_ret);
 
					}
 
@@ -855,7 +865,7 @@ static CommandCost ClearTile_Road(TileIn
 
			 * tram tracks must be removed before the road bits. */
 
			for (RoadType rt = ROADTYPE_HWAY; rt >= ROADTYPE_ROAD; rt--) {
 
				if (HasBit(rts, rt)) {
 
					CommandCost tmp_ret = DoCommand(tile, 1 << 6 | rt << 4 | GetCrossingRoadBits(tile), 0, flags, CMD_REMOVE_ROAD);
 
					CommandCost tmp_ret = RemoveRoad(tile, flags, GetCrossingRoadBits(tile), rt, false);
 
					if (CmdFailed(tmp_ret)) return tmp_ret;
 
					ret.AddCost(tmp_ret);
 
				}
 
@@ -1276,7 +1286,7 @@ static void TileLoop_Road(TileIndex tile
 
			const RoadBits new_rb = CleanUpRoadBits(tile, old_rb);
 

	
 
			if (old_rb != new_rb) {
 
				DoCommand(tile, (old_rb ^ new_rb), t->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_REMOVE_ROAD);
 
				RemoveRoad(tile, DC_EXEC | DC_AUTO | DC_NO_WATER, (old_rb ^ new_rb), ROADTYPE_ROAD, true);
 
			}
 
		}
 

	
0 comments (0 inline, 0 general)