diff --git a/src/base_station_base.h b/src/base_station_base.h index 9873a73b7b..b19607ca50 100644 --- a/src/base_station_base.h +++ b/src/base_station_base.h @@ -280,6 +280,18 @@ struct SpecializedStation : public BaseStation { return BaseStation::Create(std::forward(args)...); } + /** + * Creates a new T-object in the station pool. + * @param index The index allocate the object at. + * @param args... The arguments to the constructor. + * @return The created object. + */ + template + static inline T *CreateAtIndex(StationID index, Targs &&... args) + { + return BaseStation::CreateAtIndex(index, std::forward(args)...); + } + /** * Converts a BaseStation to SpecializedStation with type checking. * @param st BaseStation pointer diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 9ef6006762..cc4265456a 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -608,7 +608,7 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = CompanyID::Invalid( c = Company::Create(STR_SV_UNNAMED, is_ai); } else { if (Company::IsValidID(company)) return nullptr; - c = new (company) Company(STR_SV_UNNAMED, is_ai); + c = Company::CreateAtIndex(company, STR_SV_UNNAMED, is_ai); } c->colour = colour; diff --git a/src/core/pool_type.hpp b/src/core/pool_type.hpp index 545a258eef..ef24f2b8f3 100644 --- a/src/core/pool_type.hpp +++ b/src/core/pool_type.hpp @@ -304,18 +304,8 @@ public: Tpool->FreeItem(size, Pool::GetRawIndex(pn->index)); } - /** - * Allocates space for new Titem with given index - * @param size size of Titem - * @param index index of item - * @return pointer to allocated memory - * @note can never fail (return nullptr), use CanAllocate() to check first! - * @pre index has to be unused! Else it will crash - */ - inline void *operator new(size_t size, Tindex index) - { - return Tpool->GetNew(size, index.base()); - } + /** Do not use new (index) PoolItem(...), but rather PoolItem::CreateAtIndex(index, ...). */ + inline void *operator new(size_t size, Tindex index) = delete; /** * Allocates space for new Titem at given memory address @@ -352,6 +342,20 @@ public: return ::new (data) T(std::forward(args)...); } + /** + * Creates a new T-object in the associated pool. + * @param index The to allocate the object at. + * @param args... The arguments to the constructor. + * @return The created object. + */ + template + requires std::is_base_of_v + static inline T *CreateAtIndex(Tindex index, Targs &&... args) + { + void *data = Tpool->GetNew(sizeof(T), index.base()); + return ::new (data) T(std::forward(args)...); + } + /** Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() */ /** diff --git a/src/engine.cpp b/src/engine.cpp index 226ccd2f8f..f88594640c 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -609,7 +609,7 @@ void SetupEngines() assert(std::size(mapping) >= _engine_counts[type]); for (const EngineIDMapping &eid : mapping) { - new (eid.engine) Engine(type, eid.internal_id); + Engine::CreateAtIndex(eid.engine, type, eid.internal_id); } } } diff --git a/src/saveload/autoreplace_sl.cpp b/src/saveload/autoreplace_sl.cpp index 4de53e7329..369585dd26 100644 --- a/src/saveload/autoreplace_sl.cpp +++ b/src/saveload/autoreplace_sl.cpp @@ -45,7 +45,7 @@ struct ERNWChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - EngineRenew *er = new (EngineRenewID(index)) EngineRenew(); + EngineRenew *er = EngineRenew::CreateAtIndex(EngineRenewID(index)); SlObject(er, slt); /* Advanced vehicle lists, ungrouped vehicles got added */ diff --git a/src/saveload/cargopacket_sl.cpp b/src/saveload/cargopacket_sl.cpp index 9e51fc2843..a6da6cd0a4 100644 --- a/src/saveload/cargopacket_sl.cpp +++ b/src/saveload/cargopacket_sl.cpp @@ -162,7 +162,7 @@ struct CAPAChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - CargoPacket *cp = new (CargoPacketID(index)) CargoPacket(); + CargoPacket *cp = CargoPacket::CreateAtIndex(CargoPacketID(index)); SlObject(cp, slt); } } diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 76adb529f5..b72a695224 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -567,7 +567,7 @@ struct PLYRChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - Company *c = new (CompanyID(index)) Company(); + Company *c = Company::CreateAtIndex(CompanyID(index)); SlObject(c, slt); _company_colours[index] = c->colour; } diff --git a/src/saveload/depot_sl.cpp b/src/saveload/depot_sl.cpp index 9bbbd691c3..59079b7680 100644 --- a/src/saveload/depot_sl.cpp +++ b/src/saveload/depot_sl.cpp @@ -49,7 +49,7 @@ struct DEPTChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - Depot *depot = new (DepotID(index)) Depot(); + Depot *depot = Depot::CreateAtIndex(DepotID(index)); SlObject(depot, slt); /* Set the town 'pointer' so we can restore it later. */ diff --git a/src/saveload/economy_sl.cpp b/src/saveload/economy_sl.cpp index 9761217183..3618bb8865 100644 --- a/src/saveload/economy_sl.cpp +++ b/src/saveload/economy_sl.cpp @@ -108,7 +108,7 @@ struct CAPYChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - CargoPayment *cp = new (CargoPaymentID(index)) CargoPayment(); + CargoPayment *cp = CargoPayment::CreateAtIndex(CargoPaymentID(index)); SlObject(cp, slt); } } diff --git a/src/saveload/goal_sl.cpp b/src/saveload/goal_sl.cpp index 6eb2edaad4..91a0434085 100644 --- a/src/saveload/goal_sl.cpp +++ b/src/saveload/goal_sl.cpp @@ -44,7 +44,7 @@ struct GOALChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - Goal *s = new (GoalID(index)) Goal(); + Goal *s = Goal::CreateAtIndex(GoalID(index)); SlObject(s, slt); } } diff --git a/src/saveload/group_sl.cpp b/src/saveload/group_sl.cpp index c0adff97c0..222db566c9 100644 --- a/src/saveload/group_sl.cpp +++ b/src/saveload/group_sl.cpp @@ -50,7 +50,7 @@ struct GRPSChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - Group *g = new (GroupID(index)) Group(); + Group *g = Group::CreateAtIndex(GroupID(index)); SlObject(g, slt); if (IsSavegameVersionBefore(SLV_189)) g->parent = GroupID::Invalid(); diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp index adca7f440e..0a61395c75 100644 --- a/src/saveload/industry_sl.cpp +++ b/src/saveload/industry_sl.cpp @@ -253,7 +253,7 @@ struct INDYChunkHandler : ChunkHandler { SlIndustryProduced::ResetOldStructure(); while ((index = SlIterateArray()) != -1) { - Industry *i = new (IndustryID(index)) Industry(); + Industry *i = Industry::CreateAtIndex(IndustryID(index)); SlObject(i, slt); /* Before savegame version 161, persistent storages were not stored in a pool. */ diff --git a/src/saveload/league_sl.cpp b/src/saveload/league_sl.cpp index f58e578b47..6c9715ab05 100644 --- a/src/saveload/league_sl.cpp +++ b/src/saveload/league_sl.cpp @@ -45,7 +45,7 @@ struct LEAEChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - LeagueTableElement *lte = new (LeagueTableElementID(index)) LeagueTableElement(); + LeagueTableElement *lte = LeagueTableElement::CreateAtIndex(LeagueTableElementID(index)); SlObject(lte, slt); } } @@ -76,7 +76,7 @@ struct LEATChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - LeagueTable *lt = new (LeagueTableID(index)) LeagueTable(); + LeagueTable *lt = LeagueTable::CreateAtIndex(LeagueTableID(index)); SlObject(lt, slt); } } diff --git a/src/saveload/linkgraph_sl.cpp b/src/saveload/linkgraph_sl.cpp index 44da15898b..da40832f3c 100644 --- a/src/saveload/linkgraph_sl.cpp +++ b/src/saveload/linkgraph_sl.cpp @@ -277,7 +277,7 @@ struct LGRPChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - LinkGraph *lg = new (LinkGraphID(index)) LinkGraph(); + LinkGraph *lg = LinkGraph::CreateAtIndex(LinkGraphID(index)); SlObject(lg, slt); } } @@ -305,7 +305,7 @@ struct LGRJChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - LinkGraphJob *lgj = new (LinkGraphJobID(index)) LinkGraphJob(); + LinkGraphJob *lgj = LinkGraphJob::CreateAtIndex(LinkGraphJobID(index)); SlObject(lgj, slt); } } diff --git a/src/saveload/object_sl.cpp b/src/saveload/object_sl.cpp index 93ba0eb541..1d1256f70f 100644 --- a/src/saveload/object_sl.cpp +++ b/src/saveload/object_sl.cpp @@ -49,7 +49,7 @@ struct OBJSChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - Object *o = new (ObjectID(index)) Object(); + Object *o = Object::CreateAtIndex(ObjectID(index)); SlObject(o, slt); } } diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 93728c955f..df6c964f88 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -621,7 +621,7 @@ static const OldChunks town_chunk[] = { static bool LoadOldTown(LoadgameState &ls, int num) { - Town *t = new (TownID(num)) Town(); + Town *t = Town::CreateAtIndex(TownID(num)); if (!LoadChunk(ls, t, town_chunk)) return false; if (t->xy != 0) { @@ -693,7 +693,7 @@ static const OldChunks depot_chunk[] = { static bool LoadOldDepot(LoadgameState &ls, int num) { - Depot *d = new (DepotID(num)) Depot(); + Depot *d = Depot::CreateAtIndex(DepotID(num)); if (!LoadChunk(ls, d, depot_chunk)) return false; if (d->xy != 0) { @@ -781,7 +781,7 @@ static const OldChunks station_chunk[] = { static bool LoadOldStation(LoadgameState &ls, int num) { - Station *st = new (StationID(num)) Station(); + Station *st = Station::CreateAtIndex(StationID(num)); _current_station_id = st->index; if (!LoadChunk(ls, st, station_chunk)) return false; @@ -863,7 +863,7 @@ static const OldChunks industry_chunk[] = { static bool LoadOldIndustry(LoadgameState &ls, int num) { - Industry *i = new (IndustryID(num)) Industry(); + Industry *i = Industry::CreateAtIndex(IndustryID(num)); if (!LoadChunk(ls, i, industry_chunk)) return false; if (i->location.tile != 0) { @@ -989,7 +989,7 @@ static const OldChunks _company_chunk[] = { static bool LoadOldCompany(LoadgameState &ls, int num) { - Company *c = new (CompanyID(num)) Company(); + Company *c = Company::CreateAtIndex(CompanyID(num)); _current_company_id = (CompanyID)num; @@ -1269,14 +1269,14 @@ bool LoadOldVehicle(LoadgameState &ls, int num) uint type = ReadByte(ls); switch (type) { default: return false; - case 0x00 /* VEH_INVALID */: v = nullptr; break; - case 0x25 /* MONORAIL */: - case 0x20 /* VEH_TRAIN */: v = new (VehicleID(_current_vehicle_id)) Train(); break; - case 0x21 /* VEH_ROAD */: v = new (VehicleID(_current_vehicle_id)) RoadVehicle(); break; - case 0x22 /* VEH_SHIP */: v = new (VehicleID(_current_vehicle_id)) Ship(); break; - case 0x23 /* VEH_AIRCRAFT */: v = new (VehicleID(_current_vehicle_id)) Aircraft(); break; - case 0x24 /* VEH_EFFECT */: v = new (VehicleID(_current_vehicle_id)) EffectVehicle(); break; - case 0x26 /* VEH_DISASTER */: v = new (VehicleID(_current_vehicle_id)) DisasterVehicle(); break; + case 0x00 /* VEH_INVALID */: v = nullptr; break; + case 0x25 /* MONORAIL */: + case 0x20 /* VEH_TRAIN */: v = Train::CreateAtIndex(VehicleID(_current_vehicle_id)); break; + case 0x21 /* VEH_ROAD */: v = RoadVehicle::CreateAtIndex(VehicleID(_current_vehicle_id)); break; + case 0x22 /* VEH_SHIP */: v = Ship::CreateAtIndex(VehicleID(_current_vehicle_id)); break; + case 0x23 /* VEH_AIRCRAFT */: v = Aircraft::CreateAtIndex(VehicleID(_current_vehicle_id)); break; + case 0x24 /* VEH_EFFECT */: v = EffectVehicle::CreateAtIndex(VehicleID(_current_vehicle_id)); break; + case 0x26 /* VEH_DISASTER */: v = DisasterVehicle::CreateAtIndex(VehicleID(_current_vehicle_id)); break; } if (!LoadChunk(ls, v, vehicle_chunk)) return false; @@ -1346,13 +1346,13 @@ bool LoadOldVehicle(LoadgameState &ls, int num) /* Read the vehicle type and allocate the right vehicle */ switch (ReadByte(ls)) { default: SlErrorCorrupt("Invalid vehicle type"); - case 0x00 /* VEH_INVALID */: v = nullptr; break; - case 0x10 /* VEH_TRAIN */: v = new (VehicleID(_current_vehicle_id)) Train(); break; - case 0x11 /* VEH_ROAD */: v = new (VehicleID(_current_vehicle_id)) RoadVehicle(); break; - case 0x12 /* VEH_SHIP */: v = new (VehicleID(_current_vehicle_id)) Ship(); break; - case 0x13 /* VEH_AIRCRAFT*/: v = new (VehicleID(_current_vehicle_id)) Aircraft(); break; - case 0x14 /* VEH_EFFECT */: v = new (VehicleID(_current_vehicle_id)) EffectVehicle(); break; - case 0x15 /* VEH_DISASTER*/: v = new (VehicleID(_current_vehicle_id)) DisasterVehicle(); break; + case 0x00 /* VEH_INVALID */: v = nullptr; break; + case 0x10 /* VEH_TRAIN */: v = Train::CreateAtIndex(VehicleID(_current_vehicle_id)); break; + case 0x11 /* VEH_ROAD */: v = RoadVehicle::CreateAtIndex(VehicleID(_current_vehicle_id)); break; + case 0x12 /* VEH_SHIP */: v = Ship::CreateAtIndex(VehicleID(_current_vehicle_id)); break; + case 0x13 /* VEH_AIRCRAFT */: v = Aircraft::CreateAtIndex(VehicleID(_current_vehicle_id)); break; + case 0x14 /* VEH_EFFECT */: v = EffectVehicle::CreateAtIndex(VehicleID(_current_vehicle_id)); break; + case 0x15 /* VEH_DISASTER */: v = DisasterVehicle::CreateAtIndex(VehicleID(_current_vehicle_id)); break; } if (!LoadChunk(ls, v, vehicle_chunk)) return false; @@ -1422,7 +1422,7 @@ static const OldChunks sign_chunk[] = { static bool LoadOldSign(LoadgameState &ls, int num) { - Sign *si = new (SignID(num)) Sign(); + Sign *si = Sign::CreateAtIndex(SignID(num)); if (!LoadChunk(ls, si, sign_chunk)) return false; if (_old_string_id != 0) { @@ -1486,7 +1486,7 @@ static const OldChunks subsidy_chunk[] = { static bool LoadOldSubsidy(LoadgameState &ls, int num) { - Subsidy *s = new (SubsidyID(num)) Subsidy(); + Subsidy *s = Subsidy::CreateAtIndex(SubsidyID(num)); bool ret = LoadChunk(ls, s, subsidy_chunk); if (!IsValidCargoType(s->cargo_type)) delete s; return ret; diff --git a/src/saveload/order_sl.cpp b/src/saveload/order_sl.cpp index 6c6044cd96..0d7add142d 100644 --- a/src/saveload/order_sl.cpp +++ b/src/saveload/order_sl.cpp @@ -269,7 +269,7 @@ struct ORDLChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - OrderList *list = new (OrderListID(index)) OrderList(); + OrderList *list = OrderList::CreateAtIndex(OrderListID(index)); SlObject(list, slt); } @@ -346,7 +346,7 @@ struct BKORChunkHandler : ChunkHandler { while ((index = SlIterateArray()) != -1) { /* set num_orders to 0 so it's a valid OrderList */ - OrderBackup *ob = new (OrderBackupID(index)) OrderBackup(); + OrderBackup *ob = OrderBackup::CreateAtIndex(OrderBackupID(index)); SlObject(ob, slt); } } diff --git a/src/saveload/signs_sl.cpp b/src/saveload/signs_sl.cpp index 47a062d235..83cb833049 100644 --- a/src/saveload/signs_sl.cpp +++ b/src/saveload/signs_sl.cpp @@ -50,7 +50,7 @@ struct SIGNChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - Sign *si = new (SignID(index)) Sign(); + Sign *si = Sign::CreateAtIndex(SignID(index)); SlObject(si, slt); /* Before version 6.1, signs didn't have owner. * Before version 83, invalid signs were determined by si->str == 0. diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index ddb99f9a47..c2e71fc087 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -79,7 +79,7 @@ void MoveBuoysToWaypoints() /* Stations and waypoints are in the same pool, so if a station * is deleted there must be place for a Waypoint. */ assert(Waypoint::CanAllocateItem()); - Waypoint *wp = new (index) Waypoint(xy); + Waypoint *wp = Waypoint::CreateAtIndex(index, xy); wp->town = town; wp->string_id = train ? STR_SV_STNAME_WAYPOINT : STR_SV_STNAME_BUOY; wp->name = std::move(name); @@ -512,7 +512,7 @@ struct STNSChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - Station *st = new (StationID(index)) Station(); + Station *st = Station::CreateAtIndex(StationID(index)); _waiting_acceptance = 0; SlObject(st, slt); @@ -714,7 +714,7 @@ struct STNNChunkHandler : ChunkHandler { while ((index = SlIterateArray()) != -1) { bool waypoint = static_cast(SlReadByte()).Test(StationFacility::Waypoint); - BaseStation *bst = waypoint ? (BaseStation *)new (StationID(index)) Waypoint() : new (StationID(index)) Station(); + BaseStation *bst = waypoint ? (BaseStation *)Waypoint::CreateAtIndex(StationID(index)) : Station::CreateAtIndex(StationID(index)); SlObject(bst, slt); } } @@ -752,7 +752,7 @@ struct ROADChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - RoadStop *rs = new (RoadStopID(index)) RoadStop(INVALID_TILE); + RoadStop *rs = RoadStop::CreateAtIndex(RoadStopID(index), INVALID_TILE); SlObject(rs, slt); } diff --git a/src/saveload/storage_sl.cpp b/src/saveload/storage_sl.cpp index c5a393cc71..60c1c08a72 100644 --- a/src/saveload/storage_sl.cpp +++ b/src/saveload/storage_sl.cpp @@ -35,7 +35,7 @@ struct PSACChunkHandler : ChunkHandler { while ((index = SlIterateArray()) != -1) { assert(PersistentStorage::CanAllocateItem()); - PersistentStorage *ps = new (PersistentStorageID(index)) PersistentStorage(0, GSF_INVALID, TileIndex{}); + PersistentStorage *ps = PersistentStorage::CreateAtIndex(PersistentStorageID(index), 0, GSF_INVALID, TileIndex{}); SlObject(ps, slt); } } diff --git a/src/saveload/story_sl.cpp b/src/saveload/story_sl.cpp index f2637cc0b1..adf86367a3 100644 --- a/src/saveload/story_sl.cpp +++ b/src/saveload/story_sl.cpp @@ -58,7 +58,7 @@ struct STPEChunkHandler : ChunkHandler { int index; uint32_t max_sort_value = 0; while ((index = SlIterateArray()) != -1) { - StoryPageElement *s = new (StoryPageElementID(index)) StoryPageElement(); + StoryPageElement *s = StoryPageElement::CreateAtIndex(StoryPageElementID(index)); SlObject(s, slt); if (s->sort_value > max_sort_value) { max_sort_value = s->sort_value; @@ -100,7 +100,7 @@ struct STPAChunkHandler : ChunkHandler { int index; uint32_t max_sort_value = 0; while ((index = SlIterateArray()) != -1) { - StoryPage *s = new (StoryPageID(index)) StoryPage(); + StoryPage *s = StoryPage::CreateAtIndex(StoryPageID(index)); SlObject(s, slt); if (s->sort_value > max_sort_value) { max_sort_value = s->sort_value; diff --git a/src/saveload/subsidy_sl.cpp b/src/saveload/subsidy_sl.cpp index c6c36f3df6..fcd529980b 100644 --- a/src/saveload/subsidy_sl.cpp +++ b/src/saveload/subsidy_sl.cpp @@ -48,7 +48,7 @@ struct SUBSChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - Subsidy *s = new (SubsidyID(index)) Subsidy(); + Subsidy *s = Subsidy::CreateAtIndex(SubsidyID(index)); SlObject(s, slt); } } diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index bf2799aa8f..6a7bb7c2db 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -348,7 +348,7 @@ struct CITYChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - Town *t = new (TownID(index)) Town(); + Town *t = Town::CreateAtIndex(TownID(index)); SlObject(t, slt); if (IsSavegameVersionBefore(SLV_165)) { diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index b315a50455..146dded836 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -1129,12 +1129,12 @@ struct VEHSChunkHandler : ChunkHandler { VehicleType vtype = (VehicleType)SlReadByte(); switch (vtype) { - case VEH_TRAIN: v = new (VehicleID(index)) Train(); break; - case VEH_ROAD: v = new (VehicleID(index)) RoadVehicle(); break; - case VEH_SHIP: v = new (VehicleID(index)) Ship(); break; - case VEH_AIRCRAFT: v = new (VehicleID(index)) Aircraft(); break; - case VEH_EFFECT: v = new (VehicleID(index)) EffectVehicle(); break; - case VEH_DISASTER: v = new (VehicleID(index)) DisasterVehicle(); break; + case VEH_TRAIN: v = Train::CreateAtIndex(VehicleID(index)); break; + case VEH_ROAD: v = RoadVehicle::CreateAtIndex(VehicleID(index)); break; + case VEH_SHIP: v = Ship::CreateAtIndex(VehicleID(index)); break; + case VEH_AIRCRAFT: v = Aircraft::CreateAtIndex(VehicleID(index)); break; + case VEH_EFFECT: v = EffectVehicle::CreateAtIndex(VehicleID(index)); break; + case VEH_DISASTER: v = DisasterVehicle::CreateAtIndex(VehicleID(index)); break; case VEH_INVALID: // Savegame shouldn't contain invalid vehicles default: SlErrorCorrupt("Invalid vehicle type"); } diff --git a/src/vehicle_base.h b/src/vehicle_base.h index da817c5fe3..a693cd71d0 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -1137,6 +1137,18 @@ struct SpecializedVehicle : public Vehicle { return Vehicle::Create(std::forward(args)...); } + /** + * Creates a new T-object in the vehicle pool. + * @param index The index allocate the object at. + * @param args... The arguments to the constructor. + * @return The created object. + */ + template + static inline T *CreateAtIndex(VehicleID index, Targs &&... args) + { + return Vehicle::CreateAtIndex(index, std::forward(args)...); + } + /** * Converts a Vehicle to SpecializedVehicle with type checking. * @param v Vehicle pointer