Loading

Paste #p3hueuoac

  1. /**
  2.  * Build/Fund an industry
  3.  * @param tile tile where industry is built
  4.  * @param flags of operations to conduct
  5.  * @param p1 various bitstuffed elements
  6.  * - p1 = (bit  0 -  7) - industry type see build_industry.h and see industry.h
  7.  * - p1 = (bit  8 - 15) - first layout to try
  8.  * - p1 = (bit 16     ) - 0 = prospect, 1 = fund (only valid if current company is DEITY)
  9.  * @param p2 seed to use for desyncfree randomisations
  10.  * @param text unused
  11.  * @return the cost of this operation or an error
  12.  */
  13. CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
  14. {
  15.     IndustryType it = GB(p1, 0, 8);
  16.     if (it >= NUM_INDUSTRYTYPES) return CMD_ERROR;
  17.  
  18.     const IndustrySpec *indspec = GetIndustrySpec(it);
  19.  
  20.     /* Check if the to-be built/founded industry is available for this climate. */
  21.     if (!indspec->enabled || indspec->num_table == 0) return CMD_ERROR;
  22.  
  23.     /* If the setting for raw-material industries is not on, you cannot build raw-material industries.
  24.      * Raw material industries are industries that do not accept cargo (at least for now) */
  25.     if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY && _settings_game.construction.raw_industry_construction == 0 && indspec->IsRawIndustry()) {
  26.         return CMD_ERROR;
  27.     }
  28.  
  29.     if (_game_mode != GM_EDITOR && GetIndustryProbabilityCallback(it, _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION, 1) == 0) {
  30.         return CMD_ERROR;
  31.     }
  32.  
  33.     Randomizer randomizer;
  34.     randomizer.SetSeed(p2);
  35.     uint16 random_initial_bits = GB(p2, 0, 16);
  36.     uint32 random_var8f = randomizer.Next();
  37.     int num_layouts = indspec->num_table;
  38.     CommandCost ret = CommandCost(STR_ERROR_SITE_UNSUITABLE);
  39.     const bool deity_prospect = _current_company == OWNER_DEITY && !HasBit(p1, 16);
  40.  
  41.     Industry *ind = NULL;
  42.     if (deity_prospect || (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY && _settings_game.construction.raw_industry_construction == 2 && indspec->IsRawIndustry())) {
  43.         if (flags & DC_EXEC) {
  44.             /* Prospected industries not built on water are built as OWNER_TOWN to not e.g. be build on owned land of the founder */
  45.             Owner prospector = OWNER_TOWN;
  46.             if ((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) && _current_company < MAX_COMPANIES) prospector = _current_company;
  47.             Backup<CompanyByte> cur_company(_current_company, prospector, FILE_LINE);
  48.             /* Prospecting has a chance to fail, however we cannot guarantee that something can
  49.              * be built on the map, so the chance gets lower when the map is fuller, but there
  50.              * is nothing we can really do about that. */
  51.             if (deity_prospect || Random() <= indspec->prospecting_chance) {
  52.                 for (int i = 0; i < 5000; i++) {
  53.                     /* We should not have more than one Random() in a function call
  54.                      * because parameter evaluation order is not guaranteed in the c++ standard
  55.                      */
  56.                     tile = RandomTile();
  57.                     /* Start with a random layout */
  58.                     int layout = RandomRange(num_layouts);
  59.                     /* Check now each layout, starting with the random one */
  60.                     for (int j = 0; j < num_layouts; j++) {
  61.                         layout = (layout + 1) % num_layouts;
  62.                         ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, cur_company.GetOriginalValue(), _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_PROSPECTCREATION, &ind);
  63.                         if (ret.Succeeded()) break;
  64.                     }
  65.                     if (ret.Succeeded()) break;
  66.                 }
  67.             }
  68.             cur_company.Restore();
  69.         }
  70.     } else {
  71.         int layout = GB(p1, 8, 8);
  72.         if (layout >= num_layouts) return CMD_ERROR;
  73.  
  74.         /* Check subsequently each layout, starting with the given layout in p1 */
  75.         for (int i = 0; i < num_layouts; i++) {
  76.             layout = (layout + 1) % num_layouts;
  77.             ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, _current_company, _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION, &ind);
  78.             if (ret.Succeeded()) break;
  79.         }
  80.  
  81.         /* If it still failed, there's no suitable layout to build here, return the error */
  82.         if (ret.Failed()) return ret;
  83.     }
  84.  
  85.     if ((flags & DC_EXEC) && ind != NULL && _game_mode != GM_EDITOR) {
  86.         AdvertiseIndustryOpening(ind);
  87.     }
  88.  
  89.     return CommandCost(EXPENSES_OTHER, indspec->GetConstructionCost());
  90. }

Comments