diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp --- a/src/newgrf_commons.cpp +++ b/src/newgrf_commons.cpp @@ -21,6 +21,7 @@ #include "station_map.h" #include "tree_map.h" #include "tunnelbridge_map.h" +#include "newgrf_object.h" #include "genworld.h" #include "core/mem_func.hpp" @@ -289,6 +290,36 @@ void IndustryTileOverrideManager::SetEnt } /** + * Method to install the new object data in its proper slot + * The slot assigment is internal of this method, since it requires + * checking what is available + * @param spec ObjectSpec that comes from the grf decoding process + */ +void ObjectOverrideManager::SetEntitySpec(ObjectSpec *spec) +{ + /* First step : We need to find if this object is already specified in the savegame data. */ + ObjectType type = this->GetID(spec->grf_prop.local_id, spec->grf_prop.grffile->grfid); + + if (type == invalid_ID) { + /* Not found. + * Or it has already been overriden, so you've lost your place old boy. + * Or it is a simple substitute. + * We need to find a free available slot */ + type = this->AddEntityID(spec->grf_prop.local_id, spec->grf_prop.grffile->grfid, OBJECT_TRANSMITTER); + } + + if (type == invalid_ID) { + grfmsg(1, "Object.SetEntitySpec: Too many objects allocated. Ignoring."); + return; + } + + extern ObjectSpec _object_specs[NUM_OBJECTS]; + + /* Now that we know we can use the given id, copy the spec to its final destination. */ + memcpy(&_object_specs[type], spec, sizeof(*spec)); +} + +/** * Function used by houses (and soon industries) to get information * on type of "terrain" the tile it is queries sits on. * @param tile TileIndex of the tile been queried diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -125,11 +125,23 @@ public: void SetEntitySpec(const AirportTileSpec *ats); }; +struct ObjectSpec; +class ObjectOverrideManager : public OverrideManagerBase { +protected: + virtual bool CheckValidNewID(uint16 testid) { return testid != 0xFF; } +public: + ObjectOverrideManager(uint16 offset, uint16 maximum, uint16 invalid) : + OverrideManagerBase(offset, maximum, invalid) {} + + void SetEntitySpec(ObjectSpec *spec); +}; + extern HouseOverrideManager _house_mngr; extern IndustryOverrideManager _industry_mngr; extern IndustryTileOverrideManager _industile_mngr; extern AirportOverrideManager _airport_mngr; extern AirportTileOverrideManager _airporttile_mngr; +extern ObjectOverrideManager _object_mngr; uint32 GetTerrainType(TileIndex tile, TileContext context = TCX_NORMAL); TileIndex GetNearbyTile(byte parameter, TileIndex tile); diff --git a/src/newgrf_object.cpp b/src/newgrf_object.cpp --- a/src/newgrf_object.cpp +++ b/src/newgrf_object.cpp @@ -14,9 +14,12 @@ #include "newgrf_object.h" #include "object_map.h" +/** The override manager for our objects. */ +ObjectOverrideManager _object_mngr(NEW_OBJECT_OFFSET, NUM_OBJECTS, INVALID_OBJECT_TYPE); + extern const ObjectSpec _original_objects[NEW_OBJECT_OFFSET]; /** All the object specifications. */ -static ObjectSpec _object_specs[NUM_OBJECTS]; +ObjectSpec _object_specs[NUM_OBJECTS]; /* static */ const ObjectSpec *ObjectSpec::Get(ObjectType index) { diff --git a/src/newgrf_object.h b/src/newgrf_object.h --- a/src/newgrf_object.h +++ b/src/newgrf_object.h @@ -15,6 +15,7 @@ #include "economy_func.h" #include "strings_type.h" #include "object_type.h" +#include "newgrf_commons.h" /** Various object behaviours. */ enum ObjectFlags { @@ -39,7 +40,10 @@ void ResetObjects(); /** An object that isn't use for transport, industries or houses. */ struct ObjectSpec { + /* 2 because of the "normal" and "buy" sprite stacks. */ + GRFFilePropsBase<2> grf_prop; ///< Properties related the the grf file StringID name; ///< The name for this object. + uint8 size; ///< The size of this objects; low nibble for X, high nibble for Y. uint8 build_cost_multiplier; ///< Build cost multiplier per tile. uint8 clear_cost_multiplier; ///< Clear cost multiplier per tile. diff --git a/src/saveload/object_sl.cpp b/src/saveload/object_sl.cpp --- a/src/saveload/object_sl.cpp +++ b/src/saveload/object_sl.cpp @@ -13,6 +13,7 @@ #include "../object_base.h" #include "saveload.h" +#include "newgrf_sl.h" static const SaveLoad _object_desc[] = { SLE_VAR(Object, location.tile, SLE_UINT32), @@ -52,6 +53,17 @@ static void Ptrs_OBJS() } } +static void Save_OBID() +{ + Save_NewGRFMapping(_object_mngr); +} + +static void Load_OBID() +{ + Load_NewGRFMapping(_object_mngr); +} + extern const ChunkHandler _object_chunk_handlers[] = { + { 'OBID', Save_OBID, Load_OBID, NULL, NULL, CH_ARRAY }, { 'OBJS', Save_OBJS, Load_OBJS, Ptrs_OBJS, NULL, CH_ARRAY | CH_LAST}, }; diff --git a/src/table/object_land.h b/src/table/object_land.h --- a/src/table/object_land.h +++ b/src/table/object_land.h @@ -123,7 +123,7 @@ static const DrawTileSprites _object_hq[ #undef TILE_SPRITE_LINE -#define M(name, size, build_cost_multiplier, clear_cost_multiplier, flags) { name, size, build_cost_multiplier, clear_cost_multiplier, flags, true } +#define M(name, size, build_cost_multiplier, clear_cost_multiplier, flags) { GRFFilePropsBase<2>(), name, size, build_cost_multiplier, clear_cost_multiplier, flags, true } /** Specification of the original object structures. */ extern const ObjectSpec _original_objects[] = {