|
@@ -629,89 +629,81 @@ CommandCost CmdLandscapeClear(TileIndex
|
|
|
if ((flags & DC_NO_WATER) && HasTileWaterClass(tile) && IsTileOnWater(tile)) {
|
|
|
return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER);
|
|
|
}
|
|
|
if (do_clear && (flags & DC_EXEC)) DoClearSquare(tile);
|
|
|
return cost;
|
|
|
}
|
|
|
cost.AddCost(_tile_type_procs[GetTileType(tile)]->clear_tile_proc(tile, flags));
|
|
|
if (do_clear && (flags & DC_EXEC)) DoClearSquare(tile);
|
|
|
return cost;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Clear a big piece of landscape
|
|
|
* @param tile end tile of area dragging
|
|
|
* @param flags of operation to conduct
|
|
|
* @param p1 start tile of area dragging
|
|
|
* @param p2 unused
|
|
|
* @param text unused
|
|
|
* @return the cost of this operation or an error
|
|
|
*/
|
|
|
CommandCost CmdClearArea(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
|
|
{
|
|
|
if (p1 >= MapSize()) return CMD_ERROR;
|
|
|
|
|
|
/* make sure sx,sy are smaller than ex,ey */
|
|
|
int ex = TileX(tile);
|
|
|
int ey = TileY(tile);
|
|
|
int sx = TileX(p1);
|
|
|
int sy = TileY(p1);
|
|
|
if (ex < sx) Swap(ex, sx);
|
|
|
if (ey < sy) Swap(ey, sy);
|
|
|
|
|
|
Money money = GetAvailableMoneyForCommand();
|
|
|
CommandCost cost(EXPENSES_CONSTRUCTION);
|
|
|
CommandCost last_error = CMD_ERROR;
|
|
|
bool had_success = false;
|
|
|
|
|
|
for (int x = sx; x <= ex; ++x) {
|
|
|
for (int y = sy; y <= ey; ++y) {
|
|
|
CommandCost ret = DoCommand(TileXY(x, y), 0, 0, flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR);
|
|
|
TileArea ta(tile, p1);
|
|
|
TILE_AREA_LOOP(t, ta) {
|
|
|
CommandCost ret = DoCommand(t, 0, 0, flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR);
|
|
|
if (ret.Failed()) {
|
|
|
last_error = ret;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
had_success = true;
|
|
|
if (flags & DC_EXEC) {
|
|
|
money -= ret.GetCost();
|
|
|
if (ret.GetCost() > 0 && money < 0) {
|
|
|
_additional_cash_required = ret.GetCost();
|
|
|
return cost;
|
|
|
}
|
|
|
DoCommand(TileXY(x, y), 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
DoCommand(t, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
|
|
|
/* draw explosion animation... */
|
|
|
if ((x == sx || x == ex) && (y == sy || y == ey)) {
|
|
|
TileIndex off = t - ta.tile;
|
|
|
if ((TileX(off) == 0 || TileX(off) == ta.w - 1U) && (TileY(off) == 0 || TileY(off) == ta.h - 1U)) {
|
|
|
/* big explosion in each corner, or small explosion for single tiles */
|
|
|
CreateEffectVehicleAbove(x * TILE_SIZE + TILE_SIZE / 2, y * TILE_SIZE + TILE_SIZE / 2, 2,
|
|
|
sy == ey && sx == ex ? EV_EXPLOSION_SMALL : EV_EXPLOSION_LARGE
|
|
|
CreateEffectVehicleAbove(TileX(t) * TILE_SIZE + TILE_SIZE / 2, TileY(t) * TILE_SIZE + TILE_SIZE / 2, 2,
|
|
|
ta.w == 1 && ta.h == 1 ? EV_EXPLOSION_SMALL : EV_EXPLOSION_LARGE
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
cost.AddCost(ret);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return had_success ? cost : last_error;
|
|
|
}
|
|
|
|
|
|
|
|
|
TileIndex _cur_tileloop_tile;
|
|
|
#define TILELOOP_BITS 4
|
|
|
#define TILELOOP_SIZE (1 << TILELOOP_BITS)
|
|
|
#define TILELOOP_ASSERTMASK ((TILELOOP_SIZE - 1) + ((TILELOOP_SIZE - 1) << MapLogX()))
|
|
|
#define TILELOOP_CHKMASK (((1 << (MapLogX() - TILELOOP_BITS))-1) << TILELOOP_BITS)
|
|
|
|
|
|
void RunTileLoop()
|
|
|
{
|
|
|
TileIndex tile = _cur_tileloop_tile;
|
|
|
|
|
|
assert((tile & ~TILELOOP_ASSERTMASK) == 0);
|
|
|
uint count = (MapSizeX() / TILELOOP_SIZE) * (MapSizeY() / TILELOOP_SIZE);
|
|
|
do {
|
|
|
_tile_type_procs[GetTileType(tile)]->tile_loop_proc(tile);
|
|
|
|
|
|
if (TileX(tile) < MapSizeX() - TILELOOP_SIZE) {
|
|
|
tile += TILELOOP_SIZE; // no overflow
|
|
|
} else {
|
|
|
tile = TILE_MASK(tile - TILELOOP_SIZE * (MapSizeX() / TILELOOP_SIZE - 1) + TileDiffXY(0, TILELOOP_SIZE)); // x would overflow, also increase y
|