diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -17,6 +17,10 @@ uint CountArticulatedParts(EngineID engi { if (!HasBit(EngInfo(engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) return 0; + /* If we can't allocate a vehicle now, we can't allocate it in the command + * either, so it doesn't matter how many articulated parts there are. */ + if (!Vehicle::CanAllocateItem()) return 0; + Vehicle *v = NULL;; if (!purchase_window) { v = new InvalidVehicle(); diff --git a/src/disaster_cmd.cpp b/src/disaster_cmd.cpp --- a/src/disaster_cmd.cpp +++ b/src/disaster_cmd.cpp @@ -562,7 +562,6 @@ static void DisasterTick_Helicopter_Roto static void DisasterTick_Big_Ufo(Vehicle *v) { byte z; - Vehicle *u, *w; Town *t; TileIndex tile; TileIndex tile_org; @@ -588,6 +587,7 @@ static void DisasterTick_Big_Ufo(Vehicle v->current_order.SetDestination(2); + Vehicle *u; FOR_ALL_VEHICLES(u) { if (u->type == VEH_TRAIN || u->type == VEH_ROAD) { if (Delta(u->x_pos, v->x_pos) + Delta(u->y_pos, v->y_pos) <= 12 * TILE_SIZE) { @@ -604,17 +604,16 @@ static void DisasterTick_Big_Ufo(Vehicle v->tile, 0); - u = new DisasterVehicle(); - if (u == NULL) { + if (!Vehicle::CanAllocateItem(2)) { delete v; return; } + u = new DisasterVehicle(); InitializeDisasterVehicle(u, -6 * TILE_SIZE, v->y_pos, 135, DIR_SW, ST_Big_Ufo_Destroyer); u->u.disaster.big_ufo_destroyer_target = v->index; - w = new DisasterVehicle(); - if (w == NULL) return; + Vehicle *w = new DisasterVehicle(); u->SetNext(w); InitializeDisasterVehicle(w, -6 * TILE_SIZE, v->y_pos, 0, DIR_SW, ST_Big_Ufo_Destroyer_Shadow); @@ -756,14 +755,13 @@ typedef void DisasterInitProc(); * otherwise crashes on a random tile */ static void Disaster_Zeppeliner_Init() { - Vehicle *v = new DisasterVehicle(), *u; + if (!Vehicle::CanAllocateItem(2)) return; + + Vehicle *v = new DisasterVehicle(); Station *st; - int x; - - if (v == NULL) return; /* Pick a random place, unless we find a small airport */ - x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2; + int x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2; FOR_ALL_STATIONS(st) { if (st->airport_tile != INVALID_TILE && @@ -776,13 +774,11 @@ static void Disaster_Zeppeliner_Init() InitializeDisasterVehicle(v, x, 0, 135, DIR_SE, ST_Zeppeliner); - /* Allocate shadow too? */ - u = new DisasterVehicle(); - if (u != NULL) { - v->SetNext(u); - InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Zeppeliner_Shadow); - u->vehstatus |= VS_SHADOW; - } + /* Allocate shadow */ + Vehicle *u = new DisasterVehicle(); + v->SetNext(u); + InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Zeppeliner_Shadow); + u->vehstatus |= VS_SHADOW; } @@ -790,35 +786,29 @@ static void Disaster_Zeppeliner_Init() * until it locates a road vehicle which it targets and then destroys */ static void Disaster_Small_Ufo_Init() { - Vehicle *v = new DisasterVehicle(), *u; - int x; + if (!Vehicle::CanAllocateItem(2)) return; - if (v == NULL) return; - - x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2; + Vehicle *v = new DisasterVehicle(); + int x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2; InitializeDisasterVehicle(v, x, 0, 135, DIR_SE, ST_Small_Ufo); v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2); v->age = 0; - /* Allocate shadow too? */ - u = new DisasterVehicle(); - if (u != NULL) { - v->SetNext(u); - InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Small_Ufo_Shadow); - u->vehstatus |= VS_SHADOW; - } + /* Allocate shadow */ + Vehicle *u = new DisasterVehicle(); + v->SetNext(u); + InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Small_Ufo_Shadow); + u->vehstatus |= VS_SHADOW; } /* Combat airplane which destroys an oil refinery */ static void Disaster_Airplane_Init() { - Industry *i, *found; - Vehicle *v, *u; - int x, y; + if (!Vehicle::CanAllocateItem(2)) return; - found = NULL; + Industry *i, *found = NULL; FOR_ALL_INDUSTRIES(i) { if ((GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_AIRPLANE_ATTACKS) && @@ -829,32 +819,27 @@ static void Disaster_Airplane_Init() if (found == NULL) return; - v = new DisasterVehicle(); - if (v == NULL) return; + Vehicle *v = new DisasterVehicle(); /* Start from the bottom (south side) of the map */ - x = (MapSizeX() + 9) * TILE_SIZE - 1; - y = TileY(found->xy) * TILE_SIZE + 37; + int x = (MapSizeX() + 9) * TILE_SIZE - 1; + int y = TileY(found->xy) * TILE_SIZE + 37; InitializeDisasterVehicle(v, x, y, 135, DIR_NE, ST_Airplane); - u = new DisasterVehicle(); - if (u != NULL) { - v->SetNext(u); - InitializeDisasterVehicle(u, x, y, 0, DIR_SE, ST_Airplane_Shadow); - u->vehstatus |= VS_SHADOW; - } + Vehicle *u = new DisasterVehicle(); + v->SetNext(u); + InitializeDisasterVehicle(u, x, y, 0, DIR_SE, ST_Airplane_Shadow); + u->vehstatus |= VS_SHADOW; } /** Combat helicopter that destroys a factory */ static void Disaster_Helicopter_Init() { - Industry *i, *found; - Vehicle *v, *u, *w; - int x, y; + if (!Vehicle::CanAllocateItem(3)) return; - found = NULL; + Industry *i, *found = NULL; FOR_ALL_INDUSTRIES(i) { if ((GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_CHOPPER_ATTACKS) && @@ -865,26 +850,21 @@ static void Disaster_Helicopter_Init() if (found == NULL) return; - v = new DisasterVehicle(); - if (v == NULL) return; + Vehicle *v = new DisasterVehicle(); - x = -16 * TILE_SIZE; - y = TileY(found->xy) * TILE_SIZE + 37; + int x = -16 * TILE_SIZE; + int y = TileY(found->xy) * TILE_SIZE + 37; InitializeDisasterVehicle(v, x, y, 135, DIR_SW, ST_Helicopter); - u = new DisasterVehicle(); - if (u != NULL) { - v->SetNext(u); - InitializeDisasterVehicle(u, x, y, 0, DIR_SW, ST_Helicopter_Shadow); - u->vehstatus |= VS_SHADOW; + Vehicle *u = new DisasterVehicle(); + v->SetNext(u); + InitializeDisasterVehicle(u, x, y, 0, DIR_SW, ST_Helicopter_Shadow); + u->vehstatus |= VS_SHADOW; - w = new DisasterVehicle(); - if (w != NULL) { - u->SetNext(w); - InitializeDisasterVehicle(w, x, y, 140, DIR_SW, ST_Helicopter_Rotors); - } - } + Vehicle *w = new DisasterVehicle(); + u->SetNext(w); + InitializeDisasterVehicle(w, x, y, 140, DIR_SW, ST_Helicopter_Rotors); } @@ -892,40 +872,34 @@ static void Disaster_Helicopter_Init() * down by a combat airplane, destroying the surroundings */ static void Disaster_Big_Ufo_Init() { - Vehicle *v = new DisasterVehicle(), *u; - int x, y; + if (!Vehicle::CanAllocateItem(2)) return; - if (v == NULL) return; + Vehicle *v = new DisasterVehicle(); + int x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2; + int y = MapMaxX() * TILE_SIZE - 1; - x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2; - - y = MapMaxX() * TILE_SIZE - 1; InitializeDisasterVehicle(v, x, y, 135, DIR_NW, ST_Big_Ufo); v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2); v->age = 0; - /* Allocate shadow too? */ - u = new DisasterVehicle(); - if (u != NULL) { - v->SetNext(u); - InitializeDisasterVehicle(u, x, y, 0, DIR_NW, ST_Big_Ufo_Shadow); - u->vehstatus |= VS_SHADOW; - } + /* Allocate shadow */ + Vehicle *u = new DisasterVehicle(); + v->SetNext(u); + InitializeDisasterVehicle(u, x, y, 0, DIR_NW, ST_Big_Ufo_Shadow); + u->vehstatus |= VS_SHADOW; } /* Curious submarine #1, just floats around */ static void Disaster_Small_Submarine_Init() { - Vehicle *v = new DisasterVehicle(); - int x, y; - Direction dir; - uint32 r; + if (!Vehicle::CanAllocateItem()) return; - if (v == NULL) return; - - r = Random(); - x = TileX(r) * TILE_SIZE + TILE_SIZE / 2; + Vehicle *v = new DisasterVehicle(); + int y; + Direction dir; + uint32 r = Random(); + int x = TileX(r) * TILE_SIZE + TILE_SIZE / 2; if (HasBit(r, 31)) { y = MapMaxX() * TILE_SIZE - TILE_SIZE / 2 - 1; @@ -942,15 +916,13 @@ static void Disaster_Small_Submarine_Ini /* Curious submarine #2, just floats around */ static void Disaster_Big_Submarine_Init() { - Vehicle *v = new DisasterVehicle(); - int x, y; - Direction dir; - uint32 r; + if (!Vehicle::CanAllocateItem()) return; - if (v == NULL) return; - - r = Random(); - x = TileX(r) * TILE_SIZE + TILE_SIZE / 2; + Vehicle *v = new DisasterVehicle(); + int y; + Direction dir; + uint32 r = Random(); + int x = TileX(r) * TILE_SIZE + TILE_SIZE / 2; if (HasBit(r, 31)) { y = MapMaxX() * TILE_SIZE - TILE_SIZE / 2 - 1; diff --git a/src/effectvehicle.cpp b/src/effectvehicle.cpp --- a/src/effectvehicle.cpp +++ b/src/effectvehicle.cpp @@ -609,22 +609,23 @@ static EffectTickProc * const _effect_ti Vehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicleType type) { + if (!Vehicle::CanAllocateItem()) return NULL; + Vehicle *v = new EffectVehicle(); - if (v != NULL) { - v->subtype = type; - v->x_pos = x; - v->y_pos = y; - v->z_pos = z; - v->tile = 0; - v->UpdateDeltaXY(INVALID_DIR); - v->vehstatus = VS_UNCLICKABLE; + v->subtype = type; + v->x_pos = x; + v->y_pos = y; + v->z_pos = z; + v->tile = 0; + v->UpdateDeltaXY(INVALID_DIR); + v->vehstatus = VS_UNCLICKABLE; - _effect_init_procs[type](v); + _effect_init_procs[type](v); - VehiclePositionChanged(v); - BeginVehicleMove(v); - EndVehicleMove(v); - } + VehiclePositionChanged(v); + BeginVehicleMove(v); + EndVehicleMove(v); + return v; } diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -755,7 +755,7 @@ CommandCost CmdBuildShip(TileIndex tile, unit_num = (flags & DC_AUTOREPLACE) ? 0 : GetFreeUnitNumber(VEH_SHIP); - if (!Vehicle::AllocateList(NULL, 1) || unit_num > _settings_game.vehicle.max_ships) + if (!Vehicle::CanAllocateItem() || unit_num > _settings_game.vehicle.max_ships) return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); if (flags & DC_EXEC) { diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -3070,13 +3070,12 @@ uint MoveGoodsToStation(TileIndex tile, void BuildOilRig(TileIndex tile) { - Station *st = new Station(tile); - - if (st == NULL) { + if (!Station::CanAllocateItem()) { DEBUG(misc, 0, "Can't allocate station for oilrig at 0x%X, reverting to oilrig only", tile); return; } + Station *st = new Station(tile); st->town = ClosestTownFromTile(tile, UINT_MAX); st->sign.width_1 = 0; diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1576,6 +1576,8 @@ CommandCost CmdBuildTown(TileIndex tile, Town *CreateRandomTown(uint attempts, TownSizeMode mode, uint size) { + if (!Town::CanAllocateItem()) return NULL; + do { /* Generate a tile index not too close from the edge */ TileIndex tile = RandomTile(); @@ -1603,7 +1605,6 @@ Town *CreateRandomTown(uint attempts, To /* Allocate a town struct */ Town *t = new Town(tile); - if (t == NULL) break; DoCreateTown(t, tile, townnameparts, mode, size); return t; diff --git a/src/vehicle.cpp b/src/vehicle.cpp --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -242,17 +242,13 @@ byte VehicleRandomBits() /* static */ bool Vehicle::AllocateList(Vehicle **vl, int num) { + if (!Vehicle::CanAllocateItem(num)) return false; + if (vl == NULL) return true; + uint counter = _Vehicle_pool.first_free_index; for (int i = 0; i != num; i++) { - Vehicle *v = AllocateRaw(counter); - - if (v == NULL) return false; - v = new (v) InvalidVehicle(); - - if (vl != NULL) { - vl[i] = v; - } + vl[i] = new (AllocateRaw(counter)) InvalidVehicle(); counter++; }