diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 246364c326..354a8c1ab1 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -4289,14 +4289,13 @@ static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, const G { ChangeInfoResult ret = CIR_SUCCESS; - if (id + numinfo > NUM_OBJECTS_PER_GRF) { - grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF); + if (id + numinfo > NUM_OBJECTS) { + grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS); return CIR_INVALID_ID; } - /* Allocate object specs if they haven't been allocated already. */ - if (_cur.grffile->objectspec == nullptr) { - _cur.grffile->objectspec = CallocT(NUM_OBJECTS_PER_GRF); + if (id + numinfo > _cur.grffile->objectspec.size()) { + _cur.grffile->objectspec.resize(id + numinfo); } for (int i = 0; i < numinfo; i++) { @@ -6521,14 +6520,14 @@ static void SignalsMapSpriteGroup(ByteReader *buf, uint8 idcount) static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) { - if (_cur.grffile->objectspec == nullptr) { + if (_cur.grffile->objectspec.empty()) { grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping"); return; } - uint8 *objects = AllocaM(uint8, idcount); + uint16 *objects = AllocaM(uint16, idcount); for (uint i = 0; i < idcount; i++) { - objects[i] = buf->ReadByte(); + objects[i] = buf->ReadExtendedByte(); } uint8 cidcount = buf->ReadByte(); @@ -10136,14 +10135,12 @@ static void ResetCustomIndustries() static void ResetCustomObjects() { for (GRFFile * const file : _grf_files) { - ObjectSpec **&objectspec = file->objectspec; - if (objectspec == nullptr) continue; - for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) { - free(objectspec[i]); + std::vector &objectspec = file->objectspec; + for (ObjectSpec *spec : objectspec) { + free(spec); } - free(objectspec); - objectspec = nullptr; + objectspec.clear(); } } @@ -10878,12 +10875,9 @@ static void FinaliseIndustriesArray() static void FinaliseObjectsArray() { for (GRFFile * const file : _grf_files) { - ObjectSpec **&objectspec = file->objectspec; - if (objectspec != nullptr) { - for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) { - if (objectspec[i] != nullptr && objectspec[i]->grf_prop.grffile != nullptr && objectspec[i]->IsEnabled()) { - _object_mngr.SetEntitySpec(objectspec[i]); - } + for (ObjectSpec *spec : file->objectspec) { + if (spec != nullptr && spec->grf_prop.grffile != nullptr && spec->IsEnabled()) { + _object_mngr.SetEntitySpec(spec); } } } diff --git a/src/newgrf.h b/src/newgrf.h index c0230e8a64..0454e95233 100644 --- a/src/newgrf.h +++ b/src/newgrf.h @@ -317,7 +317,7 @@ struct GRFFile : ZeroedMemoryAllocator { struct HouseSpec **housespec; struct IndustrySpec **industryspec; struct IndustryTileSpec **indtspec; - struct ObjectSpec **objectspec; + std::vector objectspec; struct AirportSpec **airportspec; struct AirportTileSpec **airtspec; struct RoadStopSpec **roadstops; diff --git a/src/newgrf_extension.cpp b/src/newgrf_extension.cpp index 9d0b4fe578..42395d9ecb 100644 --- a/src/newgrf_extension.cpp +++ b/src/newgrf_extension.cpp @@ -57,6 +57,7 @@ extern const GRFFeatureInfo _grf_feature_list[] = { GRFFeatureInfo("action0_object_viewport_map_tile_type", 1), GRFFeatureInfo("road_stops", 6), GRFFeatureInfo("new_landscape", 2), + GRFFeatureInfo("more_objects_per_grf", 1), GRFFeatureInfo(), }; diff --git a/src/newgrf_object.cpp b/src/newgrf_object.cpp index 4ef12435b5..cc5ab7baf1 100644 --- a/src/newgrf_object.cpp +++ b/src/newgrf_object.cpp @@ -230,7 +230,7 @@ static uint32 GetClosestObject(TileIndex tile, ObjectType type, const Object *cu * @param current Object for which the inquiry is made * @return The formatted answer to the callback : rr(reserved) cc(count) dddd(manhattan distance of closest sister) */ -static uint32 GetCountAndDistanceOfClosestInstance(byte local_id, uint32 grfid, TileIndex tile, const Object *current) +static uint32 GetCountAndDistanceOfClosestInstance(uint32 local_id, uint32 grfid, TileIndex tile, const Object *current) { uint32 grf_id = GetRegister(0x100); // Get the GRFID of the definition to look for in register 100h uint32 idx; diff --git a/src/object_type.h b/src/object_type.h index 3bdf80818d..e7f9b53076 100644 --- a/src/object_type.h +++ b/src/object_type.h @@ -19,8 +19,6 @@ static const ObjectType OBJECT_STATUE = 2; ///< Statue in towns static const ObjectType OBJECT_OWNED_LAND = 3; ///< Owned land 'flag' static const ObjectType OBJECT_HQ = 4; ///< HeadQuarter of a player -static const ObjectType NUM_OBJECTS_PER_GRF = 255; ///< Number of supported objects per NewGRF; limited to 255 to allow extending Action3 with an extended byte later on. - static const ObjectType NEW_OBJECT_OFFSET = 5; ///< Offset for new objects static const ObjectType NUM_OBJECTS = 64000; ///< Number of supported objects overall static const ObjectType INVALID_OBJECT_TYPE = 0xFFFF; ///< An invalid object diff --git a/src/script/api/script_objecttype.cpp b/src/script/api/script_objecttype.cpp index 816d950db1..0c69f00498 100644 --- a/src/script/api/script_objecttype.cpp +++ b/src/script/api/script_objecttype.cpp @@ -46,7 +46,7 @@ /* static */ ObjectType ScriptObjectType::ResolveNewGRFID(uint32 grfid, uint16 grf_local_id) { - EnforcePrecondition(INVALID_OBJECT_TYPE, IsInsideBS(grf_local_id, 0x00, NUM_OBJECTS_PER_GRF)); + EnforcePrecondition(INVALID_OBJECT_TYPE, IsInsideBS(grf_local_id, 0x00, NUM_OBJECTS)); grfid = BSWAP32(grfid); // Match people's expectations. return _object_mngr.GetID(grf_local_id, grfid); diff --git a/src/script/api/script_objecttype.hpp b/src/script/api/script_objecttype.hpp index 7ceebce440..fa897edc8f 100644 --- a/src/script/api/script_objecttype.hpp +++ b/src/script/api/script_objecttype.hpp @@ -57,7 +57,7 @@ public: * Get a specific object-type from a grf. * @param grfid The ID of the NewGRF. * @param grf_local_id The ID of the object, local to the NewGRF. - * @pre 0x00 <= grf_local_id < NUM_OBJECTS_PER_GRF. + * @pre 0x00 <= grf_local_id < NUM_OBJECTS. * @return the object-type ID, local to the current game (this diverges from the grf_local_id). */ static ObjectType ResolveNewGRFID(uint32 grfid, uint16 grf_local_id);