diff options
-rw-r--r-- | src/industry_cmd.cpp | 109 | ||||
-rw-r--r-- | src/industry_gui.cpp | 5 | ||||
-rw-r--r-- | src/industrytype.h | 13 | ||||
-rw-r--r-- | src/newgrf.cpp | 203 | ||||
-rw-r--r-- | src/newgrf_commons.cpp | 2 | ||||
-rw-r--r-- | src/newgrf_industries.cpp | 4 | ||||
-rw-r--r-- | src/newgrf_industries.h | 2 | ||||
-rw-r--r-- | src/newgrf_industrytiles.cpp | 6 | ||||
-rw-r--r-- | src/newgrf_industrytiles.h | 2 | ||||
-rw-r--r-- | src/script/api/script_industrytype.cpp | 3 | ||||
-rw-r--r-- | src/table/build_industry.h | 262 |
11 files changed, 264 insertions, 347 deletions
diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index dfc9cf222..4171d72db 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -71,11 +71,15 @@ IndustryBuildData _industry_builder; ///< In-game manager of industries. */ void ResetIndustries() { - memset(&_industry_specs, 0, sizeof(_industry_specs)); - memcpy(&_industry_specs, &_origin_industry_specs, sizeof(_origin_industry_specs)); - - /* once performed, enable only the current climate industries */ for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) { + /* Reset the spec to default */ + if (i < lengthof(_origin_industry_specs)) { + _industry_specs[i] = _origin_industry_specs[i]; + } else { + _industry_specs[i] = IndustrySpec{}; + } + + /* Enable only the current climate industries */ _industry_specs[i].enabled = i < NEW_INDUSTRYOFFSET && HasBit(_origin_industry_specs[i].climate_availability, _settings_game.game_creation.landscape); } @@ -1418,8 +1422,8 @@ bool IsSlopeRefused(Slope current, Slope refused) /** * Are the tiles of the industry free? * @param tile Position to check. - * @param it Industry tiles table. - * @param itspec_index The index of the itsepc to build/fund + * @param layout Industry tiles table. + * @param layout_index The index of the layout to build/fund * @param type Type of the industry. * @param initial_random_bits The random bits the industry is going to have after construction. * @param founder Industry founder @@ -1427,14 +1431,14 @@ bool IsSlopeRefused(Slope current, Slope refused) * @param[out] custom_shape_check Perform custom check for the site. * @return Failed or succeeded command. */ -static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable *it, uint itspec_index, int type, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type, bool *custom_shape_check = nullptr) +static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileLayout &layout, size_t layout_index, int type, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type, bool *custom_shape_check = nullptr) { bool refused_slope = false; bool custom_shape = false; - do { - IndustryGfx gfx = GetTranslatedIndustryTileID(it->gfx); - TileIndex cur_tile = TileAddWrap(tile, it->ti.x, it->ti.y); + for (const IndustryTileLayoutTile &it : layout) { + IndustryGfx gfx = GetTranslatedIndustryTileID(it.gfx); + TileIndex cur_tile = TileAddWrap(tile, it.ti.x, it.ti.y); if (!IsValidTile(cur_tile)) { return_cmd_error(STR_ERROR_SITE_UNSUITABLE); @@ -1459,7 +1463,7 @@ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTil if (HasBit(its->callback_mask, CBM_INDT_SHAPE_CHECK)) { custom_shape = true; - CommandCost ret = PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, itspec_index, initial_random_bits, founder, creation_type); + CommandCost ret = PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, layout_index, initial_random_bits, founder, creation_type); if (ret.Failed()) return ret; } else { Slope tileh = GetTileSlope(cur_tile); @@ -1485,7 +1489,7 @@ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTil if (ret.Failed()) return ret; } } - } while ((++it)->ti.x != -0x80); + } if (custom_shape_check != nullptr) *custom_shape_check = custom_shape; @@ -1549,18 +1553,17 @@ static bool CheckCanTerraformSurroundingTiles(TileIndex tile, uint height, int i * This function tries to flatten out the land below an industry, without * damaging the surroundings too much. */ -static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, const IndustryTileTable *it, int type) +static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, const IndustryTileLayout &layout, int type) { - const int MKEND = -0x80; // used for last element in an IndustryTileTable (see build_industry.h) int max_x = 0; int max_y = 0; /* Finds dimensions of largest variant of this industry */ - do { - if (it->gfx == 0xFF) continue; // FF been a marquer for a check on clear water, skip it - if (it->ti.x > max_x) max_x = it->ti.x; - if (it->ti.y > max_y) max_y = it->ti.y; - } while ((++it)->ti.x != MKEND); + for (const IndustryTileLayoutTile &it : layout) { + if (it.gfx == GFX_WATERTILE_SPECIALCHECK) continue; // watercheck tiles don't count for footprint size + if (it.ti.x > max_x) max_x = it.ti.x; + if (it.ti.y > max_y) max_y = it.ti.y; + } /* Remember level height */ uint h = TileHeight(tile); @@ -1714,16 +1717,16 @@ static void PopulateStationsNearby(Industry *ind) /** * Put an industry on the map. - * @param i Just allocated poolitem, mostly empty. - * @param tile North tile of the industry. - * @param type Type of the industry. - * @param it Industrylayout to build. - * @param layout Number of the layout. - * @param t Nearest town. - * @param founder Founder of the industry; OWNER_NONE in case of random construction. + * @param i Just allocated poolitem, mostly empty. + * @param tile North tile of the industry. + * @param type Type of the industry. + * @param layout Industrylayout to build. + * @param layout_index Number of the industry layout. + * @param t Nearest town. + * @param founder Founder of the industry; OWNER_NONE in case of random construction. * @param initial_random_bits Random bits for the industry. */ -static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, const IndustryTileTable *it, byte layout, Town *t, Owner founder, uint16 initial_random_bits) +static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, const IndustryTileLayout &layout, size_t layout_index, Town *t, Owner founder, uint16 initial_random_bits) { const IndustrySpec *indspec = GetIndustrySpec(type); @@ -1768,7 +1771,7 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, /* Adding 1 here makes it conform to specs of var44 of varaction2 for industries * 0 = created prior of newindustries * else, chosen layout + 1 */ - i->selected_layout = layout + 1; + i->selected_layout = (byte)(layout_index + 1); i->prod_level = PRODLEVEL_DEFAULT; @@ -1864,17 +1867,17 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, /* Plant the tiles */ - do { - TileIndex cur_tile = tile + ToTileIndexDiff(it->ti); + for (const IndustryTileLayoutTile &it : layout) { + TileIndex cur_tile = tile + ToTileIndexDiff(it.ti); - if (it->gfx != GFX_WATERTILE_SPECIALCHECK) { + if (it.gfx != GFX_WATERTILE_SPECIALCHECK) { i->location.Add(cur_tile); WaterClass wc = (IsWaterTile(cur_tile) ? GetWaterClass(cur_tile) : WATER_CLASS_INVALID); DoCommand(cur_tile, 0, 0, DC_EXEC | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR); - MakeIndustry(cur_tile, i->index, it->gfx, Random(), wc); + MakeIndustry(cur_tile, i->index, it.gfx, Random(), wc); if (_generating_world) { SetIndustryConstructionCounter(cur_tile, 3); @@ -1882,11 +1885,11 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, } /* it->gfx is stored in the map. But the translated ID cur_gfx is the interesting one */ - IndustryGfx cur_gfx = GetTranslatedIndustryTileID(it->gfx); + IndustryGfx cur_gfx = GetTranslatedIndustryTileID(it.gfx); const IndustryTileSpec *its = GetIndustryTileSpec(cur_gfx); if (its->animation.status != ANIM_STATUS_NO_ANIMATION) AddAnimatedTile(cur_tile); } - } while ((++it)->ti.x != -0x80); + } if (GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_PLANT_ON_BUILT) { for (uint j = 0; j != 50; j++) PlantRandomFarmField(i); @@ -1902,7 +1905,7 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, * @param type of industry to build * @param flags of operations to conduct * @param indspec pointer to industry specifications - * @param itspec_index the index of the itsepc to build/fund + * @param layout_index the index of the itsepc to build/fund * @param random_var8f random seed (possibly) used by industries * @param random_initial_bits The random bits the industry is going to have after construction. * @param founder Founder of the industry @@ -1912,28 +1915,28 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, * * @post \c *ip contains the newly created industry if all checks are successful and the \a flags request actual creation, else it contains \c nullptr afterwards. */ -static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, DoCommandFlag flags, const IndustrySpec *indspec, uint itspec_index, uint32 random_var8f, uint16 random_initial_bits, Owner founder, IndustryAvailabilityCallType creation_type, Industry **ip) +static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, DoCommandFlag flags, const IndustrySpec *indspec, size_t layout_index, uint32 random_var8f, uint16 random_initial_bits, Owner founder, IndustryAvailabilityCallType creation_type, Industry **ip) { - assert(itspec_index < indspec->num_table); - const IndustryTileTable *it = indspec->table[itspec_index]; + assert(layout_index < indspec->layouts.size()); + const IndustryTileLayout &layout = indspec->layouts[layout_index]; bool custom_shape_check = false; *ip = nullptr; std::vector<ClearedObjectArea> object_areas(_cleared_object_areas); - CommandCost ret = CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, random_initial_bits, founder, creation_type, &custom_shape_check); + CommandCost ret = CheckIfIndustryTilesAreFree(tile, layout, layout_index, type, random_initial_bits, founder, creation_type, &custom_shape_check); _cleared_object_areas = object_areas; if (ret.Failed()) return ret; if (HasBit(GetIndustrySpec(type)->callback_mask, CBM_IND_LOCATION)) { - ret = CheckIfCallBackAllowsCreation(tile, type, itspec_index, random_var8f, random_initial_bits, founder, creation_type); + ret = CheckIfCallBackAllowsCreation(tile, type, layout_index, random_var8f, random_initial_bits, founder, creation_type); } else { ret = _check_new_industry_procs[indspec->check_proc](tile); } if (ret.Failed()) return ret; if (!custom_shape_check && _settings_game.game_creation.land_generator == LG_TERRAGENESIS && _generating_world && - !_ignore_restrictions && !CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER, it, type)) { + !_ignore_restrictions && !CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER, layout, type)) { return_cmd_error(STR_ERROR_SITE_UNSUITABLE); } @@ -1952,8 +1955,8 @@ static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, Do if (flags & DC_EXEC) { *ip = new Industry(tile); - if (!custom_shape_check) CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER | DC_EXEC, it, type); - DoCreateNewIndustry(*ip, tile, type, it, itspec_index, t, founder, random_initial_bits); + if (!custom_shape_check) CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER | DC_EXEC, layout, type); + DoCreateNewIndustry(*ip, tile, type, layout, layout_index, t, founder, random_initial_bits); } return CommandCost(); @@ -1979,7 +1982,7 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin const IndustrySpec *indspec = GetIndustrySpec(it); /* Check if the to-be built/founded industry is available for this climate. */ - if (!indspec->enabled || indspec->num_table == 0) return CMD_ERROR; + if (!indspec->enabled || indspec->layouts.empty()) return CMD_ERROR; /* If the setting for raw-material industries is not on, you cannot build raw-material industries. * Raw material industries are industries that do not accept cargo (at least for now) */ @@ -1995,7 +1998,7 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin randomizer.SetSeed(p2); uint16 random_initial_bits = GB(p2, 0, 16); uint32 random_var8f = randomizer.Next(); - int num_layouts = indspec->num_table; + size_t num_layouts = indspec->layouts.size(); CommandCost ret = CommandCost(STR_ERROR_SITE_UNSUITABLE); const bool deity_prospect = _current_company == OWNER_DEITY && !HasBit(p1, 16); @@ -2014,7 +2017,7 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin */ tile = RandomTile(); /* Start with a random layout */ - int layout = RandomRange(num_layouts); + size_t layout = RandomRange((uint32)num_layouts); /* Check now each layout, starting with the random one */ for (int j = 0; j < num_layouts; j++) { layout = (layout + 1) % num_layouts; @@ -2063,7 +2066,8 @@ static Industry *CreateNewIndustry(TileIndex tile, IndustryType type, IndustryAv uint32 seed = Random(); uint32 seed2 = Random(); Industry *i = nullptr; - CommandCost ret = CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, RandomRange(indspec->num_table), seed, GB(seed2, 0, 16), OWNER_NONE, creation_type, &i); + size_t layout_index = RandomRange((uint32)indspec->layouts.size()); + CommandCost ret = CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, layout_index, seed, GB(seed2, 0, 16), OWNER_NONE, creation_type, &i); assert(i != nullptr || ret.Failed()); return i; } @@ -2078,7 +2082,7 @@ static uint32 GetScaledIndustryGenerationProbability(IndustryType it, bool *forc { const IndustrySpec *ind_spc = GetIndustrySpec(it); uint32 chance = ind_spc->appear_creation[_settings_game.game_creation.landscape] * 16; // * 16 to increase precision - if (!ind_spc->enabled || ind_spc->num_table == 0 || + if (!ind_spc->enabled || ind_spc->layouts.empty() || (_game_mode != GM_EDITOR && _settings_game.difficulty.industry_density == ID_FUND_ONLY) || (chance = GetIndustryProbabilityCallback(it, IACT_MAPGENERATION, chance)) == 0) { *force_at_least_one = false; @@ -2108,7 +2112,7 @@ static uint16 GetIndustryGamePlayProbability(IndustryType it, byte *min_number) const IndustrySpec *ind_spc = GetIndustrySpec(it); byte chance = ind_spc->appear_ingame[_settings_game.game_creation.landscape]; - if (!ind_spc->enabled || ind_spc->num_table == 0 || + if (!ind_spc->enabled || ind_spc->layouts.empty() || ((ind_spc->behaviour & INDUSTRYBEH_BEFORE_1950) && _cur_year > 1950) || ((ind_spc->behaviour & INDUSTRYBEH_AFTER_1960) && _cur_year < 1960) || (chance = GetIndustryProbabilityCallback(it, IACT_RANDOMCREATION, chance)) == 0) { @@ -2928,6 +2932,13 @@ bool IndustrySpec::UsesSmoothEconomy() const !(HasBit(this->callback_mask, CBM_IND_MONTHLYPROD_CHANGE) || HasBit(this->callback_mask, CBM_IND_PRODUCTION_CHANGE) || HasBit(this->callback_mask, CBM_IND_PROD_CHANGE_BUILD)); // production change callbacks } +IndustrySpec::~IndustrySpec() +{ + if (HasBit(this->cleanup_flag, CLEAN_RANDOMSOUNDS)) { + free(this->random_sounds); + } +} + static CommandCost TerraformTile_Industry(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new) { if (AutoslopeEnabled()) { diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index c662bfef9..a9f3f51d2 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -647,6 +647,7 @@ public: /* We do not need to protect ourselves against "Random Many Industries" in this mode */ const IndustrySpec *indsp = GetIndustrySpec(this->selected_type); uint32 seed = InteractiveRandom(); + uint32 layout_index = InteractiveRandomRange((uint32)indsp->layouts.size()); if (_game_mode == GM_EDITOR) { /* Show error if no town exists at all */ @@ -660,14 +661,14 @@ public: _generating_world = true; _ignore_restrictions = true; - DoCommandP(tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, + DoCommandP(tile, (layout_index << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY), &CcBuildIndustry); cur_company.Restore(); _ignore_restrictions = false; _generating_world = false; } else { - success = DoCommandP(tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY)); + success = DoCommandP(tile, (layout_index << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY)); } /* If an industry has been built, just reset the cursor and the system */ diff --git a/src/industrytype.h b/src/industrytype.h index 8f1357b67..c17bf795e 100644 --- a/src/industrytype.h +++ b/src/industrytype.h @@ -13,6 +13,7 @@ #define INDUSTRYTYPE_H #include <array> +#include <vector> #include "map_type.h" #include "slope_type.h" #include "industry_type.h" @@ -23,7 +24,6 @@ enum IndustryCleanupType { CLEAN_RANDOMSOUNDS, ///< Free the dynamically allocated sounds table - CLEAN_TILELAYOUT, ///< Free the dynamically allocated tile layout structure }; /** Available types of industry lifetimes. */ @@ -93,17 +93,20 @@ enum IndustryTileSpecialFlags { }; DECLARE_ENUM_AS_BIT_SET(IndustryTileSpecialFlags) -struct IndustryTileTable { +/** Definition of one tile in an industry tile layout */ +struct IndustryTileLayoutTile { TileIndexDiffC ti; IndustryGfx gfx; }; +/** A complete tile layout for an industry is a list of tiles */ +using IndustryTileLayout = std::vector<IndustryTileLayoutTile>; + /** * Defines the data structure for constructing industry. */ struct IndustrySpec { - const IndustryTileTable * const *table; ///< List of the tiles composing the industry - byte num_table; ///< Number of elements in the table + std::vector<IndustryTileLayout> layouts; ///< List of possible tile layouts for the industry uint8 cost_multiplier; ///< Base construction cost multiplier. uint32 removal_cost_multiplier; ///< Base removal cost multiplier. uint32 prospecting_chance; ///< Chance prospecting succeeds @@ -143,6 +146,8 @@ struct IndustrySpec { Money GetConstructionCost() const; Money GetRemovalCost() const; bool UsesSmoothEconomy() const; + + ~IndustrySpec(); }; /** diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 1f7167b35..7a67dea8b 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -3371,13 +3371,13 @@ static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf) /** * Validate the industry layout; e.g. to prevent duplicate tiles. * @param layout The layout to check. - * @param size The size of the layout. * @return True if the layout is deemed valid. */ -static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size) +static bool ValidateIndustryLayout(const IndustryTileLayout &layout) { - for (int i = 0; i < size - 1; i++) { - for (int j = i + 1; j < size; j++) { + const size_t size = layout.size(); + for (size_t i = 0; i < size - 1; i++) { + for (size_t j = i + 1; j < size; j++) { if (layout[i].ti.x == layout[j].ti.x && layout[i].ti.y == layout[j].ti.y) { return false; @@ -3387,20 +3387,6 @@ static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size) return true; } -/** Clean the tile table of the IndustrySpec if it's needed. */ -static void CleanIndustryTileTable(IndustrySpec *ind) -{ - if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != nullptr) { - for (int j = 0; j < ind->num_table; j++) { - /* remove the individual layouts */ - free(ind->table[j]); - } - /* remove the layouts pointers */ - free(ind->table); - ind->table = nullptr; - } -} - /** * Define properties for industries * @param indid Local ID of the industry. @@ -3452,10 +3438,10 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, * Only need to do it once. If ever it is called again, it should not * do anything */ if (*indspec == nullptr) { - *indspec = CallocT<IndustrySpec>(1); + *indspec = new IndustrySpec; indsp = *indspec; - memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id])); + *indsp = _origin_industry_specs[subs_id]; indsp->enabled = true; indsp->grf_prop.local_id = indid + i; indsp->grf_prop.subst_id = subs_id; @@ -3481,112 +3467,101 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, } case 0x0A: { // Set industry layout(s) - byte new_num_layouts = buf->ReadByte(); // Number of layaouts - /* We read the total size in bytes, but we can't rely on the - * newgrf to provide a sane value. First assume the value is - * sane but later on we make sure we enlarge the array if the - * newgrf contains more data. Each tile uses either 3 or 5 - * bytes, so to play it safe we assume 3. */ - uint32 def_num_tiles = buf->ReadDWord() / 3 + 1; - IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(new_num_layouts); // Table with tiles to compose an industry - IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles); // Temporary array to read the tile layouts from the GRF - uint size; - const IndustryTileTable *copy_from; + byte new_num_layouts = buf->ReadByte(); + uint32 definition_size = buf->ReadDWord(); + uint32 bytes_read = 0; + std::vector<IndustryTileLayout> new_layouts; + IndustryTileLayout layout; + + for (byte j = 0; j < new_num_layouts; j++) { + layout.clear(); + + for (uint k = 0;; k++) { + if (bytes_read >= definition_size) { + grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid); + /* Avoid warning twice */ + definition_size = UINT32_MAX; + } - try { - for (byte j = 0; j < new_num_layouts; j++) { - for (uint k = 0;; k++) { - if (k >= def_num_tiles) { - grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid); - /* Size reported by newgrf was not big enough so enlarge the array. */ - def_num_tiles *= 2; - itt = ReallocT<IndustryTileTable>(itt, def_num_tiles); - } + layout.push_back(IndustryTileLayoutTile{}); + IndustryTileLayoutTile &it = layout.back(); - itt[k].ti.x = buf->ReadByte(); // Offsets from northermost tile + it.ti.x = buf->ReadByte(); // Offsets from northermost tile + ++bytes_read; - if (itt[k].ti.x == 0xFE && k == 0) { - /* This means we have to borrow the layout from an old industry */ - IndustryType type = buf->ReadByte(); // industry holding required layout - byte laynbr = buf->ReadByte(); // layout number to borrow + if (it.ti.x == 0xFE && k == 0) { + /* This means we have to borrow the layout from an old industry */ + IndustryType type = buf->ReadByte(); + byte laynbr = buf->ReadByte(); + bytes_read += 2; - copy_from = _origin_industry_specs[type].table[laynbr]; - for (size = 1;; size++) { - if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break; - } - break; + if (type >= lengthof(_origin_industry_specs)) { + grfmsg(1, "IndustriesChangeInfo: Invalid original industry number for layout import, industry %u", indid); + DisableGrf(STR_NEWGRF_ERROR_INVALID_ID); + return CIR_DISABLED; } + if (laynbr >= _origin_industry_specs[type].layouts.size()) { + grfmsg(1, "IndustriesChangeInfo: Invalid original industry layout index for layout import, industry %u", indid); + DisableGrf(STR_NEWGRF_ERROR_INVALID_ID); + return CIR_DISABLED; + } + layout = _origin_industry_specs[type].layouts[laynbr]; + break; + } - itt[k].ti.y = buf->ReadByte(); // Or table definition finalisation + it.ti.y = buf->ReadByte(); // Or table definition finalisation + ++bytes_read; - if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) { - /* Not the same terminator. The one we are using is rather - x = -80, y = x . So, adjust it. */ - itt[k].ti.x = -0x80; - itt[k].ti.y = 0; - itt[k].gfx = 0; + if (it.ti.x == 0 && it.ti.y == 0x80) { + /* Terminator, remove and finish up */ + layout.pop_back(); + break; + } - size = k + 1; - copy_from = itt; - break; - } + it.gfx = buf->ReadByte(); + ++bytes_read; - itt[k].gfx = buf->ReadByte(); + if (it.gfx == 0xFE) { + /* Use a new tile from this GRF */ + int local_tile_id = buf->ReadWord(); + bytes_read += 2; - if (itt[k].gfx == 0xFE) { - /* Use a new tile from this GRF */ - int local_tile_id = buf->ReadWord(); - - /* Read the ID from the _industile_mngr. */ - int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid); + /* Read the ID from the _industile_mngr. */ + int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid); - if (tempid == INVALID_INDUSTRYTILE) { - grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid); - } else { - /* Declared as been valid, can be used */ - itt[k].gfx = tempid; - } - } else if (itt[k].gfx == 0xFF) { - itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8); - itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8); - - /* When there were only 256x256 maps, TileIndex was a uint16 and - * itt[k].ti was just a TileIndexDiff that was added to it. - * As such negative "x" values were shifted into the "y" position. - * x = -1, y = 1 -> x = 255, y = 0 - * Since GRF version 8 the position is interpreted as pair of independent int8. - * For GRF version < 8 we need to emulate the old shifting behaviour. - */ - if (_cur.grffile->grf_version < 8 && itt[k].ti.x < 0) itt[k].ti.y += 1; + if (tempid == INVALID_INDUSTRYTILE) { + grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid); + } else { + /* Declared as been valid, can be used */ + it.gfx = tempid; } - } - - if (!ValidateIndustryLayout(copy_from, size)) { - /* The industry layout was not valid, so skip this one. */ - grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid); - new_num_layouts--; - j--; - } else { - tile_table[j] = CallocT<IndustryTileTable>(size); - memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size); + } else if (it.gfx == 0xFF) { + it.ti.x = (int8)GB(it.ti.x, 0, 8); + it.ti.y = (int8)GB(it.ti.y, 0, 8); + + /* When there were only 256x256 maps, TileIndex was a uint16 and + * it.ti was just a TileIndexDiff that was added to it. + * As such negative "x" values were shifted into the "y" position. + * x = -1, y = 1 -> x = 255, y = 0 + * Since GRF version 8 the position is interpreted as pair of independent int8. + * For GRF version < 8 we need to emulate the old shifting behaviour. + */ + if (_cur.grffile->grf_version < 8 && it.ti.x < 0) it.ti.y += 1; } } - } catch (...) { - for (int i = 0; i < new_num_layouts; i++) { - free(tile_table[i]); + + if (!ValidateIndustryLayout(layout)) { + /* The industry layout was not valid, so skip this one. */ + grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid); + new_num_layouts--; + j--; + } else { + new_layouts.push_back(layout); } - free(tile_table); - free(itt); - throw; } - /* Clean the tile table if it was already set by a previous prop A. */ - CleanIndustryTileTable(indsp); /* Install final layout construction in the industry spec */ - indsp->num_table = new_num_layouts; - indsp->table = tile_table; - SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT); - free(itt); + indsp->layouts = new_layouts; break; } @@ -8498,17 +8473,7 @@ static void ResetCustomIndustries() if (industryspec != nullptr) { for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) { IndustrySpec *ind = industryspec[i]; - if (ind == nullptr) continue; - - /* We need to remove the sounds array */ - if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) { - free(ind->random_sounds); - } - - /* We need to remove the tiles layouts */ - CleanIndustryTileTable(ind); - - free(ind); + delete ind; } free(industryspec); diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp index 6a6b4f015..49ba60529 100644 --- a/src/newgrf_commons.cpp +++ b/src/newgrf_commons.cpp @@ -279,7 +279,7 @@ void IndustryOverrideManager::SetEntitySpec(IndustrySpec *inds) } /* Now that we know we can use the given id, copy the spec to its final destination... */ - memcpy(&_industry_specs[ind_id], inds, sizeof(*inds)); + _industry_specs[ind_id] = *inds; /* ... and mark it as usable*/ _industry_specs[ind_id].enabled = true; } diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index 9f9416ff3..34fffea9b 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -520,7 +520,7 @@ uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, In * @param creation_type The circumstances the industry is created under. * @return Succeeded or failed command. */ -CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint layout, uint32 seed, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type) +CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, size_t layout, uint32 seed, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type) { const IndustrySpec *indspec = GetIndustrySpec(type); @@ -529,7 +529,7 @@ CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uin ind.location.tile = tile; ind.location.w = 0; // important to mark the industry invalid ind.type = type; - ind.selected_layout = layout; + ind.selected_layout = (byte)layout; ind.town = ClosestTownFromTile(tile, UINT_MAX); ind.random = initial_random_bits; ind.founder = founder; diff --git a/src/newgrf_industries.h b/src/newgrf_industries.h index b0c1e3bdd..d66ab319b 100644 --- a/src/newgrf_industries.h +++ b/src/newgrf_industries.h @@ -89,7 +89,7 @@ enum IndustryAvailabilityCallType { uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile); uint32 GetIndustryIDAtOffset(TileIndex new_tile, const Industry *i, uint32 cur_grfid); void IndustryProductionCallback(Industry *ind, int reason); -CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint layout, uint32 seed, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type); +CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, size_t layout, uint32 seed, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type); uint32 GetIndustryProbabilityCallback(IndustryType type, IndustryAvailabilityCallType creation_type, uint32 default_prob); bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type); diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp index 5a8794564..d5b2ee325 100644 --- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.cpp @@ -212,13 +212,13 @@ extern bool IsSlopeRefused(Slope current, Slope refused); * @param its Tile specification. * @param type Industry type. * @param gfx Gfx of the tile. - * @param itspec_index Layout. + * @param layout_index Layout. * @param initial_random_bits Random bits of industry after construction * @param founder Industry founder * @param creation_type The circumstances the industry is created under. * @return Succeeded or failed command. */ -CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, uint itspec_index, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type) +CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, size_t layout_index, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type) { Industry ind; ind.index = INVALID_INDUSTRY; @@ -228,7 +228,7 @@ CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind ind.random = initial_random_bits; ind.founder = founder; - uint16 callback_res = GetIndustryTileCallback(CBID_INDTILE_SHAPE_CHECK, 0, creation_type << 8 | itspec_index, gfx, &ind, ind_tile); + uint16 callback_res = GetIndustryTileCallback(CBID_INDTILE_SHAPE_CHECK, 0, creation_type << 8 | (uint32)layout_index, gfx, &ind, ind_tile); if (callback_res == CALLBACK_FAILED) { if (!IsSlopeRefused(GetTileSlope(ind_tile), its->slopes_refused)) return CommandCost(); return_cmd_error(STR_ERROR_SITE_UNSUITABLE); diff --git a/src/newgrf_industrytiles.h b/src/newgrf_industrytiles.h index 8b7293233..937085305 100644 --- a/src/newgrf_industrytiles.h +++ b/src/newgrf_industrytiles.h @@ -57,7 +57,7 @@ struct IndustryTileResolverObject : public ResolverObject { bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const IndustryTileSpec *inds); uint16 GetIndustryTileCallback(CallbackID callback, uint32 param1, uint32 param2, IndustryGfx gfx_id, Industry *industry, TileIndex tile); -CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, uint itspec_index, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type); +CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, size_t layout_index, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type); void AnimateNewIndustryTile(TileIndex tile); bool StartStopIndustryTileAnimation(TileIndex tile, IndustryAnimationTrigger iat, uint32 random = Random()); diff --git a/src/script/api/script_industrytype.cpp b/src/script/api/script_industrytype.cpp index e154705bb..76b5cab2a 100644 --- a/src/script/api/script_industrytype.cpp +++ b/src/script/api/script_industrytype.cpp @@ -123,7 +123,8 @@ EnforcePrecondition(false, ScriptMap::IsValidTile(tile)); uint32 seed = ::InteractiveRandom(); - return ScriptObject::DoCommand(tile, (1 << 16) | (::InteractiveRandomRange(::GetIndustrySpec(industry_type)->num_table) << 8) | industry_type, seed, CMD_BUILD_INDUSTRY); + uint32 layout_index = ::InteractiveRandomRange((uint32)::GetIndustrySpec(industry_type)->layouts.size()); + return ScriptObject::DoCommand(tile, (1 << 16) | (layout_index << 8) | industry_type, seed, CMD_BUILD_INDUSTRY); } /* static */ bool ScriptIndustryType::ProspectIndustry(IndustryType industry_type) diff --git a/src/table/build_industry.h b/src/table/build_industry.h index 6e07f59a3..07ac84a3d 100644 --- a/src/table/build_industry.h +++ b/src/table/build_industry.h @@ -22,22 +22,16 @@ */ #define MK(x, y, m) {{x, y}, m} -/** - * Terminator of industry tiles layout definition - */ -#define MKEND {{-0x80, 0}, 0} - -static const IndustryTileTable _tile_table_coal_mine_0[] = { +static const IndustryTileLayout _tile_table_coal_mine_0 { MK(1, 1, 0), MK(1, 2, 2), MK(0, 0, 5), MK(1, 0, 6), MK(2, 0, 3), MK(2, 2, 3), - MKEND }; -static const IndustryTileTable _tile_table_coal_mine_1[] = { +static const IndustryTileLayout _tile_table_coal_mine_1 { MK(1, 1, 0), MK(1, 2, 2), MK(2, 0, 0), @@ -47,20 +41,18 @@ static const IndustryTileTable _tile_table_coal_mine_1[] = { MK(0, 1, 4), MK(0, 2, 4), MK(2, 2, 4), - MKEND }; -static const IndustryTileTable _tile_table_coal_mine_2[] = { +static const IndustryTileLayout _tile_table_coal_mine_2 { MK(0, 0, 0), MK(0, 1, 2), MK(0, 2, 5), MK(1, 0, 3), MK(1, 1, 3), MK(1, 2, 6), - MKEND }; -static const IndustryTileTable _tile_table_coal_mine_3[] = { +static const IndustryTileLayout _tile_table_coal_mine_3 { MK(0, 1, 0), MK(0, 2, 2), MK(0, 3, 4), @@ -71,17 +63,16 @@ static const IndustryTileTable _tile_table_coal_mine_3[] = { MK(2, 0, 6), MK(2, 1, 4), MK(2, 2, 3), - MKEND }; -static const IndustryTileTable * const _tile_table_coal_mine[] = { +static const std::vector<IndustryTileLayout> _tile_table_coal_mine { _tile_table_coal_mine_0, _tile_table_coal_mine_1, _tile_table_coal_mine_2, _tile_table_coal_mine_3, }; -static const IndustryTileTable _tile_table_power_station_0[] = { +static const IndustryTileLayout _tile_table_power_station_0 { MK(0, 0, 7), MK(0, 1, 9), MK(1, 0, 7), @@ -90,10 +81,9 @@ static const IndustryTileTable _tile_table_power_station_0[] = { MK(2, 1, 8), MK(3, 0, 10), MK(3, 1, 10), - MKEND }; -static const IndustryTileTable _tile_table_power_station_1[] = { +static const IndustryTileLayout _tile_table_power_station_1 { MK(0, 1, 7), MK(0, 2, 7), MK(1, 0, 8), @@ -102,26 +92,24 @@ static const IndustryTileTable _tile_table_power_station_1[] = { MK(2, 0, 9), MK(2, 1, 10), MK(2, 2, 9), - MKEND }; -static const IndustryTileTable _tile_table_power_station_2[] = { +static const IndustryTileLayout _tile_table_power_station_2 { MK(0, 0, 7), MK(0, 1, 7), MK(1, 0, 9), MK(1, 1, 8), MK(2, 0, 10), MK(2, 1, 9), - MKEND }; -static const IndustryTileTable * const _tile_table_power_station[] = { +static const std::vector<IndustryTileLayout> _tile_table_power_station { _tile_table_power_station_0, _tile_table_power_station_1, _tile_table_power_station_2, }; -static const IndustryTileTable _tile_table_sawmill_0[] = { +static const IndustryTileLayout _tile_table_sawmill_0 { MK(1, 0, 14), MK(1, 1, 12), MK(1, 2, 11), @@ -130,10 +118,9 @@ static const IndustryTileTable _tile_table_sawmill_0[] = { MK(0, 0, 15), MK(0, 1, 15), MK(0, 2, 12), - MKEND }; -static const IndustryTileTable _tile_table_sawmill_1[] = { +static const IndustryTileLayout _tile_table_sawmill_1 { MK(0, 0, 15), MK(0, 1, 11), MK(0, 2, 14), @@ -142,15 +129,14 @@ static const IndustryTileTable _tile_table_sawmill_1[] = { MK(1, 2, 12), MK(2, 0, 11), MK(2, 1, 13), - MKEND }; -static const IndustryTileTable * const _tile_table_sawmill[] = { +static const std::vector<IndustryTileLayout> _tile_table_sawmill { _tile_table_sawmill_0, _tile_table_sawmill_1, }; -static const IndustryTileTable _tile_table_forest_0[] = { +static const IndustryTileLayout _tile_table_forest_0 { MK(0, 0, 16), MK(0, 1, 16), MK(0, 2, 16), @@ -169,10 +155,9 @@ static const IndustryTileTable _tile_table_forest_0[] = { MK(3, 3, 16), MK(1, 4, 16), MK(2, 4, 16), - MKEND }; -static const IndustryTileTable _tile_table_forest_1[] = { +static const IndustryTileLayout _tile_table_forest_1 { MK(0, 0, 16), MK(1, 0, 16), MK(2, 0, 16), @@ -196,15 +181,14 @@ static const IndustryTileTable _tile_table_forest_1[] = { MK(1, 4, 16), MK(2, 4, 16), MK(3, 4, 16), - MKEND }; -static const IndustryTileTable * const _tile_table_forest[] = { +static const std::vector<IndustryTileLayout> _tile_table_forest { _tile_table_forest_0, _tile_table_forest_1, }; -static const IndustryTileTable _tile_table_oil_refinery_0[] = { +static const IndustryTileLayout _tile_table_oil_refinery_0 { MK(0, 0, 20), MK(0, 1, 21), MK(0, 2, 22), @@ -220,10 +204,9 @@ static const IndustryTileTable _tile_table_oil_refinery_0[] = { MK(3, 3, 18), MK(2, 0, 23), MK(3, 1, 23), - MKEND }; -static const IndustryTileTable _tile_table_oil_refinery_1[] = { +static const IndustryTileLayout _tile_table_oil_refinery_1 { MK(0, 0, 18), MK(0, 1, 18), MK(0, 2, 21), @@ -239,15 +222,14 @@ static const IndustryTileTable _tile_table_oil_refinery_1[] = { MK(2, 3, 22), MK(1, 4, 23), MK(2, 4, 23), - MKEND }; -static const IndustryTileTable * const _tile_table_oil_refinery[] = { +static const std::vector<IndustryTileLayout> _tile_table_oil_refinery { _tile_table_oil_refinery_0, _tile_table_oil_refinery_1, }; -static const IndustryTileTable _tile_table_oil_rig_0[] = { +static const IndustryTileLayout _tile_table_oil_rig_0 { MK(0, 0, 24), MK(0, 1, 24), MK(0, 2, 25), @@ -306,14 +288,13 @@ static const IndustryTileTable _tile_table_oil_rig_0[] = { MK(2, 3, 255), MK(2, 2, 255), MK(2, 1, 255), - MKEND }; -static const IndustryTileTable * const _tile_table_oil_rig[] = { +static const std::vector<IndustryTileLayout> _tile_table_oil_rig { _tile_table_oil_rig_0, }; -static const IndustryTileTable _tile_table_factory_0[] = { +static const IndustryTileLayout _tile_table_factory_0 { MK(0, 0, 39), MK(0, 1, 40), MK(1, 0, 41), @@ -326,10 +307,9 @@ static const IndustryTileTable _tile_table_factory_0[] = { MK(2, 2, 40), MK(3, 1, 41), MK(3, 2, 42), - MKEND }; -static const IndustryTileTable _tile_table_factory_1[] = { +static const IndustryTileLayout _tile_table_factory_1 { MK(0, 0, 39), MK(0, 1, 40), MK(1, 0, 41), @@ -342,15 +322,14 @@ static const IndustryTileTable _tile_table_factory_1[] = { MK(1, 3, 40), MK(2, 2, 41), MK(2, 3, 42), - MKEND }; -static const IndustryTileTable * const _tile_table_factory[] = { +static const std::vector<IndustryTileLayout> _tile_table_factory { _tile_table_factory_0, _tile_table_factory_1, }; -static const IndustryTileTable _tile_table_printing_works_0[] = { +static const IndustryTileLayout _tile_table_printing_works_0 { MK(0, 0, 43), MK(0, 1, 44), MK(1, 0, 45), @@ -363,10 +342,9 @@ static const IndustryTileTable _tile_table_printing_works_0[] = { MK(2, 2, 44), MK(3, 1, 45), MK(3, 2, 46), - MKEND }; -static const IndustryTileTable _tile_table_printing_works_1[] = { +static const IndustryTileLayout _tile_table_printing_works_1 { MK(0, 0, 43), MK(0, 1, 44), MK(1, 0, 45), @@ -379,15 +357,14 @@ static const IndustryTileTable _tile_table_printing_works_1[] = { MK(1, 3, 44), MK(2, 2, 45), MK(2, 3, 46), - MKEND }; -static const IndustryTileTable * const _tile_table_printing_works[] = { +static const std::vector<IndustryTileLayout> _tile_table_printing_works { _tile_table_printing_works_0, _tile_table_printing_works_1, }; -static const IndustryTileTable _tile_table_steel_mill_0[] = { +static const IndustryTileLayout _tile_table_steel_mill_0 { MK(2, 1, 52), MK(2, 2, 53), MK(3, 1, 54), @@ -400,10 +377,9 @@ static const IndustryTileTable _tile_table_steel_mill_0[] = { MK(1, 2, 57), MK(2, 0, 56), MK(3, 0, 57), - MKEND }; -static const IndustryTileTable _tile_table_steel_mill_1[] = { +static const IndustryTileLayout _tile_table_steel_mill_1 { MK(0, 0, 52), MK(0, 1, 53), MK(1, 0, 54), @@ -418,15 +394,14 @@ static const IndustryTileTable _tile_table_steel_mill_1[] = { MK(3, 2, 57), MK(1, 3, 56), MK(2, 3, 57), - MKEND }; -static const IndustryTileTable * const _tile_table_steel_mill[] = { +static const std::vector<IndustryTileLayout> _tile_table_steel_mill { _tile_table_steel_mill_0, _tile_table_steel_mill_1, }; -static const IndustryTileTable _tile_table_farm_0[] = { +static const IndustryTileLayout _tile_table_farm_0 { MK(1, 0, 33), MK(1, 1, 34), MK(1, 2, 36), @@ -436,10 +411,9 @@ static const IndustryTileTable _tile_table_farm_0[] = { MK(2, 0, 35), MK(2, 1, 38), MK(2, 2, 38), - MKEND }; -static const IndustryTileTable _tile_table_farm_1[] = { +static const IndustryTileLayout _tile_table_farm_1 { MK(1, 1, 33), MK(1, 2, 34), MK(0, 0, 35), @@ -452,10 +426,9 @@ static const IndustryTileTable _tile_table_farm_1[] = { MK(2, 1, 37), MK(2, 2, 38), MK(2, 3, 38), - MKEND }; -static const IndustryTileTable _tile_table_farm_2[] = { +static const IndustryTileLayout _tile_table_farm_2 { MK(2, 0, 33), MK(2, 1, 34), MK(0, 0, 36), @@ -468,16 +441,15 @@ static const IndustryTileTable _tile_table_farm_2[] = { MK(1, 3, 37), MK(2, 2, 37), MK(2, 3, 35), - MKEND }; -static const IndustryTileTable * const _tile_table_farm[] = { +static const std::vector<IndustryTileLayout> _tile_table_farm { _tile_table_farm_0, _tile_table_farm_1, _tile_table_farm_2, }; -static const IndustryTileTable _tile_table_copper_mine_0[] = { +static const IndustryTileLayout _tile_table_copper_mine_0 { MK(0, 0, 47), MK(0, 1, 49), MK(0, 2, 51), @@ -486,10 +458,9 @@ static const IndustryTileTable _tile_table_copper_mine_0[] = { MK(1, 2, 50), MK(2, 0, 51), MK(2, 1, 51), - MKEND }; -static const IndustryTileTable _tile_table_copper_mine_1[] = { +static const IndustryTileLayout _tile_table_copper_mine_1 { MK(0, 0, 50), MK(0, 1, 47), MK(0, 2, 49), @@ -499,48 +470,44 @@ static const IndustryTileTable _tile_table_copper_mine_1[] = { MK(2, 0, 51), MK(2, 1, 47), MK(2, 2, 49), - MKEND }; -static const IndustryTileTable * const _tile_table_copper_mine[] = { +static const std::vector<IndustryTileLayout> _tile_table_copper_mine { _tile_table_copper_mine_0, _tile_table_copper_mine_1, }; -static const IndustryTileTable _tile_table_oil_well_0[] = { +static const IndustryTileLayout _tile_table_oil_well_0 { MK(0, 0, 29), MK(1, 0, 29), MK(2, 0, 29), MK(0, 1, 29), MK(0, 2, 29), - MKEND }; -static const IndustryTileTable _tile_table_oil_well_1[] = { +static const IndustryTileLayout _tile_table_oil_well_1 { MK(0, 0, 29), MK(1, 0, 29), MK(1, 1, 29), MK(2, 2, 29), MK(2, 3, 29), - MKEND }; -static const IndustryTileTable * const _tile_table_oil_well[] = { +static const std::vector<IndustryTileLayout> _tile_table_oil_well { _tile_table_oil_well_0, _tile_table_oil_well_1, }; -static const IndustryTileTable _tile_table_bank_0[] = { +static const IndustryTileLayout _tile_table_bank_0 { MK(0, 0, 58), MK(1, 0, 59), - MKEND }; -static const IndustryTileTable * const _tile_table_bank[] = { +static const std::vector<IndustryTileLayout> _tile_table_bank { _tile_table_bank_0, }; -static const IndustryTileTable _tile_table_food_process_0[] = { +static const IndustryTileLayout _tile_table_food_process_0 { MK(0, 0, 60), MK(1, 0, 60), MK(2, 0, 60), @@ -553,10 +520,9 @@ static const IndustryTileTable _tile_table_food_process_0[] = { MK(0, 3, 62), MK(1, 3, 62), MK(2, 3, 63), - MKEND }; -static const IndustryTileTable _tile_table_food_process_1[] = { +static const IndustryTileLayout _tile_table_food_process_1 { MK(0, 0, 61), MK(1, 0, 60), MK(2, 0, 61), @@ -571,15 +537,14 @@ static const IndustryTileTable _tile_table_food_process_1[] = { MK(3, 2, 60), MK(0, 3, 62), MK(1, 3, 62), - MKEND }; -static const IndustryTileTable * const _tile_table_food_process[] = { +static const std::vector<IndustryTileLayout> _tile_table_food_process { _tile_table_food_process_0, _tile_table_food_process_1, }; -static const IndustryTileTable _tile_table_paper_mill_0[] = { +static const IndustryTileLayout _tile_table_paper_mill_0 { MK(0, 0, 64), MK(1, 0, 65), MK(2, 0, 66), @@ -592,14 +557,13 @@ static const IndustryTileTable _tile_table_paper_mill_0[] = { MK(1, 2, 71), MK(2, 2, 71), MK(3, 2, 70), - MKEND }; -static const IndustryTileTable * const _tile_table_paper_mill[] = { +static const std::vector<IndustryTileLayout> _tile_table_paper_mill { _tile_table_paper_mill_0, }; -static const IndustryTileTable _tile_table_gold_mine_0[] = { +static const IndustryTileLayout _tile_table_gold_mine_0 { MK(0, 0, 72), MK(0, 1, 73), MK(0, 2, 74), @@ -616,24 +580,22 @@ static const IndustryTileTable _tile_table_gold_mine_0[] = { MK(3, 1, 85), MK(3, 2, 86), MK(3, 3, 87), - MKEND }; -static const IndustryTileTable * const _tile_table_gold_mine[] = { +static const std::vector<IndustryTileLayout> _tile_table_gold_mine { _tile_table_gold_mine_0, }; -static const IndustryTileTable _tile_table_bank2_0[] = { +static const IndustryTileLayout _tile_table_bank2_0 { MK(0, 0, 89), MK(1, 0, 90), - MKEND }; -static const IndustryTileTable * const _tile_table_bank2[] = { +static const std::vector<IndustryTileLayout> _tile_table_bank2 { _tile_table_bank2_0, }; -static const IndustryTileTable _tile_table_diamond_mine_0[] = { +static const IndustryTileLayout _tile_table_diamond_mine_0 { MK(0, 0, 91), MK(0, 1, 92), MK(0, 2, 93), @@ -643,14 +605,13 @@ static const IndustryTileTable _tile_table_diamond_mine_0[] = { MK(2, 0, 97), MK(2, 1, 98), MK(2, 2, 99), - MKEND }; -static const IndustryTileTable * const _tile_table_diamond_mine[] = { +static const std::vector<IndustryTileLayout> _tile_table_diamond_mine { _tile_table_diamond_mine_0, }; -static const IndustryTileTable _tile_table_iron_mine_0[] = { +static const IndustryTileLayout _tile_table_iron_mine_0 { MK(0, 0, 100), MK(0, 1, 101), MK(0, 2, 102), @@ -667,14 +628,13 @@ static const IndustryTileTable _tile_table_iron_mine_0[] = { MK(3, 1, 113), MK(3, 2, 114), MK(3, 3, 115), - MKEND }; -static const IndustryTileTable * const _tile_table_iron_mine[] = { +static const std::vector<IndustryTileLayout> _tile_table_iron_mine { _tile_table_iron_mine_0, }; -static const IndustryTileTable _tile_table_fruit_plantation_0[] = { +static const IndustryTileLayout _tile_table_fruit_plantation_0 { MK(0, 0, 116), MK(0, 1, 116), MK(0, 2, 116), @@ -695,14 +655,13 @@ static const IndustryTileTable _tile_table_fruit_plantation_0[] = { MK(4, 1, 116), MK(4, 2, 116), MK(4, 3, 116), - MKEND }; -static const IndustryTileTable * const _tile_table_fruit_plantation[] = { +static const std::vector<IndustryTileLayout> _tile_table_fruit_plantation { _tile_table_fruit_plantation_0, }; -static const IndustryTileTable _tile_table_rubber_plantation_0[] = { +static const IndustryTileLayout _tile_table_rubber_plantation_0 { MK(0, 0, 117), MK(0, 1, 117), MK(0, 2, 117), @@ -723,35 +682,32 @@ static const IndustryTileTable _tile_table_rubber_plantation_0[] = { MK(4, 1, 117), MK(4, 2, 117), MK(4, 3, 117), - MKEND }; -static const IndustryTileTable * const _tile_table_rubber_plantation[] = { +static const std::vector<IndustryTileLayout> _tile_table_rubber_plantation { _tile_table_rubber_plantation_0, }; -static const IndustryTileTable _tile_table_water_supply_0[] = { +static const IndustryTileLayout _tile_table_water_supply_0 { MK(0, 0, 118), MK(0, 1, 119), MK(1, 0, 118), MK(1, 1, 119), - MKEND }; -static const IndustryTileTable * const _tile_table_water_supply[] = { +static const std::vector<IndustryTileLayout> _tile_table_water_supply { _tile_table_water_supply_0, }; -static const IndustryTileTable _tile_table_water_tower_0[] = { +static const IndustryTileLayout _tile_table_water_tower_0 { MK(0, 0, 120), - MKEND }; -static const IndustryTileTable * const _tile_table_water_tower[] = { +static const std::vector<IndustryTileLayout> _tile_table_water_tower { _tile_table_water_tower_0, }; -static const IndustryTileTable _tile_table_factory2_0[] = { +static const IndustryTileLayout _tile_table_factory2_0 { MK(0, 0, 121), MK(0, 1, 122), MK(1, 0, 123), @@ -760,10 +716,9 @@ static const IndustryTileTable _tile_table_factory2_0[] = { MK(0, 3, 122), MK(1, 2, 123), MK(1, 3, 124), - MKEND }; -static const IndustryTileTable _tile_table_factory2_1[] = { +static const IndustryTileLayout _tile_table_factory2_1 { MK(0, 0, 121), MK(0, 1, 122), MK(1, 0, 123), @@ -772,15 +727,14 @@ static const IndustryTileTable _tile_table_factory2_1[] = { MK(2, 1, 122), MK(3, 0, 123), MK(3, 1, 124), - MKEND }; -static const IndustryTileTable * const _tile_table_factory2[] = { +static const std::vector<IndustryTileLayout> _tile_table_factory2 { _tile_table_factory2_0, _tile_table_factory2_1, }; -static const IndustryTileTable _tile_table_farm2_0[] = { +static const IndustryTileLayout _tile_table_farm2_0 { MK(1, 0, 33), MK(1, 1, 34), MK(1, 2, 36), @@ -790,10 +744,9 @@ static const IndustryTileTable _tile_table_farm2_0[] = { MK(2, 0, 35), MK(2, 1, 38), MK(2, 2, 38), - MKEND }; -static const IndustryTileTable _tile_table_farm2_1[] = { +static const IndustryTileLayout _tile_table_farm2_1 { MK(1, 1, 33), MK(1, 2, 34), MK(0, 0, 35), @@ -806,10 +759,9 @@ static const IndustryTileTable _tile_table_farm2_1[] = { MK(2, 1, 37), MK(2, 2, 38), MK(2, 3, 38), - MKEND }; -static const IndustryTileTable _tile_table_farm2_2[] = { +static const IndustryTileLayout _tile_table_farm2_2 { MK(2, 0, 33), MK(2, 1, 34), MK(0, 0, 36), @@ -822,28 +774,26 @@ static const IndustryTileTable _tile_table_farm2_2[] = { MK(1, 3, 37), MK(2, 2, 37), MK(2, 3, 35), - MKEND }; -static const IndustryTileTable * const _tile_table_farm2[] = { +static const std::vector<IndustryTileLayout> _tile_table_farm2 { _tile_table_farm2_0, _tile_table_farm2_1, _tile_table_farm2_2, }; -static const IndustryTileTable _tile_table_lumber_mill_0[] = { +static const IndustryTileLayout _tile_table_lumber_mill_0 { MK(0, 0, 125), MK(0, 1, 126), MK(1, 0, 127), MK(1, 1, 128), - MKEND }; -static const IndustryTileTable * const _tile_table_lumber_mill[] = { +static const std::vector<IndustryTileLayout> _tile_table_lumber_mill { _tile_table_lumber_mill_0, }; -static const IndustryTileTable _tile_table_cotton_candy_0[] = { +static const IndustryTileLayout _tile_table_cotton_candy_0 { MK(0, 0, 129), MK(0, 1, 129), MK(0, 2, 129), @@ -862,10 +812,9 @@ static const IndustryTileTable _tile_table_cotton_candy_0[] = { MK(3, 3, 129), MK(1, 4, 129), MK(2, 4, 129), - MKEND }; -static const IndustryTileTable _tile_table_cotton_candy_1[] = { +static const IndustryTileLayout _tile_table_cotton_candy_1 { MK(0, 0, 129), MK(1, 0, 129), MK(2, 0, 129), @@ -889,15 +838,14 @@ static const IndustryTileTable _tile_table_cotton_candy_1[] = { MK(1, 4, 129), MK(2, 4, 129), MK(3, 4, 129), - MKEND }; -static const IndustryTileTable * const _tile_table_cotton_candy[] = { +static const std::vector<IndustryTileLayout> _tile_table_cotton_candy { _tile_table_cotton_candy_0, _tile_table_cotton_candy_1, }; -static const IndustryTileTable _tile_table_candy_factory_0[] = { +static const IndustryTileLayout _tile_table_candy_factory_0 { MK(0, 0, 131), MK(0, 1, 132), MK(1, 0, 133), @@ -910,10 +858,9 @@ static const IndustryTileTable _tile_table_candy_factory_0[] = { MK(2, 2, 132), MK(3, 1, 133), MK(3, 2, 134), - MKEND }; -static const IndustryTileTable _tile_table_candy_factory_1[] = { +static const IndustryTileLayout _tile_table_candy_factory_1 { MK(0, 0, 131), MK(0, 1, 132), MK(1, 0, 133), @@ -926,15 +873,14 @@ static const IndustryTileTable _tile_table_candy_factory_1[] = { MK(1, 3, 132), MK(2, 2, 133), MK(2, 3, 134), - MKEND }; -static const IndustryTileTable * const _tile_table_candy_factory[] = { +static const std::vector<IndustryTileLayout> _tile_table_candy_factory { _tile_table_candy_factory_0, _tile_table_candy_factory_1, }; -static const IndustryTileTable _tile_table_battery_farm_0[] = { +static const IndustryTileLayout _tile_table_battery_farm_0 { MK(0, 0, 135), MK(0, 1, 135), MK(0, 2, 135), @@ -955,14 +901,13 @@ static const IndustryTileTable _tile_table_battery_farm_0[] = { MK(4, 1, 135), MK(4, 2, 135), MK(4, 3, 135), - MKEND }; -static const IndustryTileTable * const _tile_table_battery_farm[] = { +static const std::vector<IndustryTileLayout> _tile_table_battery_farm { _tile_table_battery_farm_0, }; -static const IndustryTileTable _tile_table_cola_wells_0[] = { +static const IndustryTileLayout _tile_table_cola_wells_0 { MK(0, 0, 137), MK(0, 1, 137), MK(0, 2, 137), @@ -971,10 +916,9 @@ static const IndustryTileTable _tile_table_cola_wells_0[] = { MK(1, 2, 137), MK(2, 1, 137), MK(2, 2, 137), - MKEND }; -static const IndustryTileTable _tile_table_cola_wells_1[] = { +static const IndustryTileLayout _tile_table_cola_wells_1 { MK(0, 1, 137), MK(0, 2, 137), MK(0, 3, 137), @@ -982,27 +926,25 @@ static const IndustryTileTable _tile_table_cola_wells_1[] = { MK(1, 1, 137), MK(1, 2, 137), MK(2, 1, 137), - MKEND }; -static const IndustryTileTable * const _tile_table_cola_wells[] = { +static const std::vector<IndustryTileLayout> _tile_table_cola_wells { _tile_table_cola_wells_0, _tile_table_cola_wells_1, }; -static const IndustryTileTable _tile_table_toy_shop_0[] = { +static const IndustryTileLayout _tile_table_toy_shop_0 { MK(0, 0, 138), MK(0, 1, 139), MK(1, 0, 140), MK(1, 1, 141), - MKEND }; -static const IndustryTileTable * const _tile_table_toy_shop[] = { +static const std::vector<IndustryTileLayout> _tile_table_toy_shop { _tile_table_toy_shop_0, }; -static const IndustryTileTable _tile_table_toy_factory_0[] = { +static const IndustryTileLayout _tile_table_toy_factory_0 { MK(0, 0, 147), MK(0, 1, 142), MK(1, 0, 147), @@ -1011,45 +953,41 @@ static const IndustryTileTable _tile_table_toy_factory_0[] = { MK(2, 1, 144), MK(3, 0, 146), MK(3, 1, 145), - MKEND }; -static const IndustryTileTable * const _tile_table_toy_factory[] = { +static const std::vector<IndustryTileLayout> _tile_table_toy_factory { _tile_table_toy_factory_0, }; -static const IndustryTileTable _tile_table_plastic_fountain_0[] = { +static const IndustryTileLayout _tile_table_plastic_fountain_0 { MK(0, 0, 148), MK(0, 1, 151), MK(0, 2, 154), - MKEND }; -static const IndustryTileTable _tile_table_plastic_fountain_1[] = { +static const IndustryTileLayout _tile_table_plastic_fountain_1 { MK(0, 0, 148), MK(1, 0, 151), MK(2, 0, 154), - MKEND }; -static const IndustryTileTable * const _tile_table_plastic_fountain[] = { +static const std::vector<IndustryTileLayout> _tile_table_plastic_fountain { _tile_table_plastic_fountain_0, _tile_table_plastic_fountain_1, }; -static const IndustryTileTable _tile_table_fizzy_drink_0[] = { +static const IndustryTileLayout _tile_table_fizzy_drink_0 { MK(0, 0, 156), MK(0, 1, 157), MK(1, 0, 158), MK(1, 1, 159), - MKEND }; -static const IndustryTileTable * const _tile_table_fizzy_drink[] = { +static const std::vector<IndustryTileLayout> _tile_table_fizzy_drink { _tile_table_fizzy_drink_0, }; -static const IndustryTileTable _tile_table_bubble_generator_0[] = { +static const IndustryTileLayout _tile_table_bubble_generator_0 { MK(0, 0, 163), MK(0, 1, 160), MK(1, 0, 163), @@ -1062,25 +1000,23 @@ static const IndustryTileTable _tile_table_bubble_generator_0[] = { MK(1, 3, 161), MK(2, 2, 163), MK(2, 3, 162), - MKEND }; -static const IndustryTileTable * const _tile_table_bubble_generator[] = { +static const std::vector<IndustryTileLayout> _tile_table_bubble_generator { _tile_table_bubble_generator_0, }; -static const IndustryTileTable _tile_table_toffee_quarry_0[] = { +static const IndustryTileLayout _tile_table_toffee_quarry_0 { MK(0, 0, 164), MK(1, 0, 165), MK(2, 0, 166), - MKEND }; -static const IndustryTileTable * const _tile_table_toffee_quarry[] = { +static const std::vector<IndustryTileLayout> _tile_table_toffee_quarry { _tile_table_toffee_quarry_0, }; -static const IndustryTileTable _tile_table_sugar_mine_0[] = { +static const IndustryTileLayout _tile_table_sugar_mine_0 { MK(0, 0, 167), MK(0, 1, 168), MK(1, 0, 169), @@ -1089,15 +1025,13 @@ static const IndustryTileTable _tile_table_sugar_mine_0[] = { MK(2, 1, 172), MK(3, 0, 173), MK(3, 1, 174), - MKEND }; -static const IndustryTileTable * const _tile_table_sugar_mine[] = { +static const std::vector<IndustryTileLayout> _tile_table_sugar_mine { _tile_table_sugar_mine_0, }; #undef MK -#undef MKEND /** Array with saw sound, for sawmill */ static const uint8 _sawmill_sounds[] = { SND_28_SAWMILL }; @@ -1195,7 +1129,7 @@ enum IndustryTypes { #define MI(tbl, sndc, snd, d, pc, ai1, ai2, ai3, ai4, ag1, ag2, ag3, ag4, col, \ c1, c2, c3, proc, p1, r1, p2, r2, m, a1, im1, a2, im2, a3, im3, pr, clim, bev, in, intx, s1, s2, s3) \ - {tbl, lengthof(tbl), d, 0, pc, {c1, c2, c3}, proc, \ + {tbl, d, 0, pc, {c1, c2, c3}, proc, \ {p1, p2, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID}, \ {r1, r2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, m, \ {a1, a2, a3, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID}, \ |