45 #include "table/strings.h" 
   54 void ShowIndustryViewWindow(
int industry);
 
   57 static byte _industry_sound_ctr;
 
   74   memset(&_industry_specs, 0, 
sizeof(_industry_specs));
 
   75   memcpy(&_industry_specs, &_origin_industry_specs, 
sizeof(_origin_industry_specs));
 
   83   memset(&_industry_tile_specs, 0, 
sizeof(_industry_tile_specs));
 
   84   memcpy(&_industry_tile_specs, &_origin_industry_tile_specs, 
sizeof(_origin_industry_tile_specs));
 
  119   return &_industry_specs[thistype];
 
  133   return &_industry_tile_specs[gfx];
 
  136 Industry::~Industry()
 
  154       DeleteOilRig(tile_cur);
 
  223 static void IndustryDrawSugarMine(
const TileInfo *ti)
 
  237       _drawtile_proc1[d->
image_3 - 1].x, _drawtile_proc1[d->
image_3 - 1].y);
 
  241 static void IndustryDrawToffeeQuarry(
const TileInfo *ti)
 
  256 static void IndustryDrawBubbleGenerator( 
const TileInfo *ti)
 
  264 static void IndustryDrawToyFactory(
const TileInfo *ti)
 
  280 static void IndustryDrawCoalPlantSparks(
const TileInfo *ti)
 
  285     if (image != 0 && image < 7) {
 
  295 typedef void IndustryDrawTileProc(
const TileInfo *ti);
 
  296 static IndustryDrawTileProc * 
const _industry_draw_tile_procs[5] = {
 
  297   IndustryDrawSugarMine,
 
  298   IndustryDrawToffeeQuarry,
 
  299   IndustryDrawBubbleGenerator,
 
  300   IndustryDrawToyFactory,
 
  301   IndustryDrawCoalPlantSparks,
 
  304 static void DrawTile_Industry(
TileInfo *ti)
 
  341     DrawWaterClassGround(ti);
 
  350   image = dits->building.
sprite;
 
  353       ti->
x + dits->subtile_x,
 
  354       ti->
y + dits->subtile_y,
 
  365     int proc = dits->draw_proc - 1;
 
  366     if (proc >= 0) _industry_draw_tile_procs[proc](ti);
 
  370 static int GetSlopePixelZ_Industry(
TileIndex tile, uint x, uint y)
 
  393 static void AddAcceptedCargo_Industry(
TileIndex tile, 
CargoArray &acceptance, uint32 *always_accepted)
 
  404   const uint8 *cargo_acceptance = itspec->
acceptance;
 
  409       accepts_cargo = raw_accepts_cargo;
 
  417       cargo_acceptance = raw_cargo_acceptance;
 
  425     if (a == 
CT_INVALID || cargo_acceptance[i] == 0) 
continue; 
 
  428     acceptance[a] += cargo_acceptance[i];
 
  431     if (
HasBit(*always_accepted, a)) 
continue;
 
  433     bool accepts = 
false;
 
  442     if (accepts) 
continue;
 
  445     SetBit(*always_accepted, a);
 
  458     td->
str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
 
  494 static void TransportIndustryGoods(
TileIndex tile)
 
  498   bool moved_cargo = 
false;
 
  515       moved_cargo |= (am != 0);
 
  532 static void AnimateTile_Industry(
TileIndex tile)
 
  537     AnimateNewIndustryTile(tile);
 
  542   case GFX_SUGAR_MINE_SIEVE:
 
  548           case 2: SndPlayTileFx(SND_2D_RIP_2, tile); 
break;
 
  549           case 6: SndPlayTileFx(SND_29_RIP, tile); 
break;
 
  563   case GFX_TOFFEE_QUARY:
 
  568         SndPlayTileFx(SND_30_CARTOON_SOUND, tile);
 
  581   case GFX_BUBBLE_CATCHER:
 
  596   case GFX_POWERPLANT_SPARKS:
 
  609   case GFX_TOY_FACTORY:
 
  634   case GFX_PLASTIC_FOUNTAIN_ANIMATED_1: 
case GFX_PLASTIC_FOUNTAIN_ANIMATED_2:
 
  635   case GFX_PLASTIC_FOUNTAIN_ANIMATED_3: 
case GFX_PLASTIC_FOUNTAIN_ANIMATED_4:
 
  636   case GFX_PLASTIC_FOUNTAIN_ANIMATED_5: 
case GFX_PLASTIC_FOUNTAIN_ANIMATED_6:
 
  637   case GFX_PLASTIC_FOUNTAIN_ANIMATED_7: 
case GFX_PLASTIC_FOUNTAIN_ANIMATED_8:
 
  641       gfx = (gfx < 155) ? gfx + 1 : 148;
 
  647   case GFX_OILWELL_ANIMATED_1:
 
  648   case GFX_OILWELL_ANIMATED_2:
 
  649   case GFX_OILWELL_ANIMATED_3:
 
  655       if (m == 4 && (m = 0, ++gfx) == GFX_OILWELL_ANIMATED_3 + 1 && (gfx = GFX_OILWELL_ANIMATED_1, b)) {
 
  667   case GFX_COAL_MINE_TOWER_ANIMATED:
 
  668   case GFX_COPPER_MINE_TOWER_ANIMATED:
 
  669   case GFX_GOLD_MINE_TOWER_ANIMATED: {
 
  672       if ((state -= 0x400) < 0) 
return;
 
  675         if (state < 0x20 || state >= 0x180) {
 
  681           if (state & 7) 
return;
 
  683           if (state & 3) 
return;
 
  686         if (m > 0xC2) m = 0xC0;
 
  689       } 
else if (state >= 0x200 && state < 0x3A0) {
 
  690         int i = (state < 0x220 || state >= 0x380) ? 7 : 3;
 
  691         if (state & i) 
return;
 
  694         if (m < 0x80) m = 0x82;
 
  703 static void CreateChimneySmoke(
TileIndex tile)
 
  712 static void MakeIndustryTileBigger(
TileIndex tile)
 
  737   case GFX_POWERPLANT_CHIMNEY:
 
  738     CreateChimneySmoke(tile);
 
  756   case GFX_TOY_FACTORY:
 
  757   case GFX_BUBBLE_CATCHER:
 
  758   case GFX_TOFFEE_QUARY:
 
  763   case GFX_PLASTIC_FOUNTAIN_ANIMATED_1: 
case GFX_PLASTIC_FOUNTAIN_ANIMATED_2:
 
  764   case GFX_PLASTIC_FOUNTAIN_ANIMATED_3: 
case GFX_PLASTIC_FOUNTAIN_ANIMATED_4:
 
  765   case GFX_PLASTIC_FOUNTAIN_ANIMATED_5: 
case GFX_PLASTIC_FOUNTAIN_ANIMATED_6:
 
  766   case GFX_PLASTIC_FOUNTAIN_ANIMATED_7: 
case GFX_PLASTIC_FOUNTAIN_ANIMATED_8:
 
  772 static void TileLoopIndustry_BubbleGenerator(
TileIndex tile)
 
  774   static const int8 _bubble_spawn_location[3][4] = {
 
  782   int dir = Random() & 3;
 
  787     _bubble_spawn_location[2][dir],
 
  794 static void TileLoop_Industry(
TileIndex tile)
 
  807     MakeIndustryTileBigger(tile);
 
  811   if (_game_mode == GM_EDITOR) 
return;
 
  813   TransportIndustryGoods(tile);
 
  815   if (StartStopIndustryTileAnimation(tile, 
IAT_TILELOOP)) 
return;
 
  827   case GFX_COAL_MINE_TOWER_NOT_ANIMATED:
 
  828   case GFX_COPPER_MINE_TOWER_NOT_ANIMATED:
 
  829   case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:
 
  832         case GFX_COAL_MINE_TOWER_NOT_ANIMATED:   gfx = GFX_COAL_MINE_TOWER_ANIMATED;   
break;
 
  833         case GFX_COPPER_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_ANIMATED; 
break;
 
  834         case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:   gfx = GFX_GOLD_MINE_TOWER_ANIMATED;   
break;
 
  842   case GFX_OILWELL_NOT_ANIMATED:
 
  850   case GFX_COAL_MINE_TOWER_ANIMATED:
 
  851   case GFX_COPPER_MINE_TOWER_ANIMATED:
 
  852   case GFX_GOLD_MINE_TOWER_ANIMATED:
 
  855         case GFX_COAL_MINE_TOWER_ANIMATED:   gfx = GFX_COAL_MINE_TOWER_NOT_ANIMATED;   
break;
 
  856         case GFX_COPPER_MINE_TOWER_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_NOT_ANIMATED; 
break;
 
  857         case GFX_GOLD_MINE_TOWER_ANIMATED:   gfx = GFX_GOLD_MINE_TOWER_NOT_ANIMATED;   
break;
 
  866   case GFX_POWERPLANT_SPARKS:
 
  873   case GFX_COPPER_MINE_CHIMNEY:
 
  878   case GFX_TOY_FACTORY: {
 
  888   case GFX_BUBBLE_GENERATOR:
 
  889     TileLoopIndustry_BubbleGenerator(tile);
 
  892   case GFX_TOFFEE_QUARY:
 
  896   case GFX_SUGAR_MINE_SIEVE:
 
  902 static bool ClickTile_Industry(
TileIndex tile)
 
  944 static const byte _plantfarmfield_type[] = {1, 1, 1, 1, 1, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
 
  958     default:       
return false;
 
  979       if (or_ == 1 && 
Chance16(1, 7)) or_ = 2;
 
  988 static void PlantFarmField(
TileIndex tile, IndustryID industry)
 
  995   uint32 r = (Random() & 0x303) + 0x404;
 
  997   uint size_x = 
GB(r, 0, 8);
 
  998   uint size_y = 
GB(r, 8, 8);
 
 1003   if (ta.w == 0 || ta.h == 0) 
return;
 
 1011   if (count * 2 < ta.w * ta.h) 
return;
 
 1015   uint counter = 
GB(r, 5, 3);
 
 1016   uint field_type = 
GB(r, 8, 8) * 9 >> 8;
 
 1022       MakeField(cur_tile, field_type, industry);
 
 1030     type = _plantfarmfield_type[Random() & 0xF];
 
 1039 void PlantRandomFarmField(
const Industry *i)
 
 1041   int x = i->
location.
w / 2 + Random() % 31 - 16;
 
 1042   int y = i->
location.
h / 2 + Random() % 31 - 16;
 
 1062     _industry_sound_ctr = 1;
 
 1063     _industry_sound_tile = tile;
 
 1093 static void ProduceIndustryGoods(
Industry *i)
 
 1098   if ((i->
counter & 0x3F) == 0) {
 
 1118     if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) {
 
 1131       if (plant) PlantRandomFarmField(i);
 
 1154 void OnTick_Industry()
 
 1156   if (_industry_sound_ctr != 0) {
 
 1157     _industry_sound_ctr++;
 
 1159     if (_industry_sound_ctr == 75) {
 
 1161     } 
else if (_industry_sound_ctr == 160) {
 
 1162       _industry_sound_ctr = 0;
 
 1167   if (_game_mode == GM_EDITOR) 
return;
 
 1170   FOR_ALL_INDUSTRIES(i) {
 
 1171     ProduceIndustryGoods(i);
 
 1207   if (_game_mode == GM_EDITOR) 
return CommandCost();
 
 1213 extern bool _ignore_restrictions;
 
 1222   if (_game_mode == GM_EDITOR && _ignore_restrictions) 
return CommandCost();
 
 1333   FOR_ALL_INDUSTRIES(i) {
 
 1334     if (i->
type == (byte)type && i->
town == *t) {
 
 1343 bool IsSlopeRefused(
Slope current, 
Slope refused)
 
 1374   bool refused_slope = 
false;
 
 1375   bool custom_shape = 
false;
 
 1392       if (ret.
Failed()) 
return ret;
 
 1403         custom_shape = 
true;
 
 1405         if (ret.
Failed()) 
return ret;
 
 1422         if (ret.
Failed()) 
return ret;
 
 1427         if (ret.
Failed()) 
return ret;
 
 1430   } 
while ((++it)->ti.x != -0x80);
 
 1432   if (custom_shape_check != NULL) *custom_shape_check = custom_shape;
 
 1453     return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS_WITH_POPULATION_OF_1200);
 
 1463 static bool CheckCanTerraformSurroundingTiles(
TileIndex tile, uint height, 
int internal)
 
 1475     if (
internal != 0 && 
Delta(curh, height) > 1) 
return false;
 
 1480     if (
internal == 0 && curh != height) {
 
 1481       if (
TileX(tile_walk) == 0 || 
TileY(tile_walk) == 0 || !CheckCanTerraformSurroundingTiles(tile_walk + 
TileDiffXY(-1, -1), height, 
internal + 1)) {
 
 1496   const int MKEND = -0x80;   
 
 1502     if (it->gfx == 0xFF) 
continue;  
 
 1503     if (it->ti.
x > max_x) max_x = it->ti.
x;
 
 1504     if (it->ti.
y > max_y) max_y = it->ti.
y;
 
 1505   } 
while ((++it)->ti.
x != MKEND);
 
 1528       if (!CheckCanTerraformSurroundingTiles(tile_walk, h, 0)) {
 
 1541   if (flags & DC_EXEC) {
 
 1550         curh += (curh > h) ? -1 : 1;
 
 1572   static const int dmax = 14;
 
 1574     const int tx = 
TileX(tile);
 
 1575     const int ty = 
TileY(tile);
 
 1580         if (i == i2) 
continue;
 
 1593   FOR_ALL_INDUSTRIES(i) {
 
 1662   uint16 r = Random();
 
 1665   i->
random = initial_random_bits;
 
 1773   } 
while ((++it)->ti.
x != -0x80);
 
 1776     for (uint j = 0; j != 50; j++) PlantRandomFarmField(i);
 
 1801   assert(itspec_index < indspec->num_table);
 
 1803   bool custom_shape_check = 
false;
 
 1809   _cleared_object_areas = object_areas;
 
 1810   if (ret.
Failed()) 
return ret;
 
 1815     ret = _check_new_industry_procs[indspec->
check_proc](tile);
 
 1817   if (ret.
Failed()) 
return ret;
 
 1825   if (ret.
Failed()) 
return ret;
 
 1829   if (ret.
Failed()) 
return ret;
 
 1833   if (ret.
Failed()) 
return ret;
 
 1837   if (flags & DC_EXEC) {
 
 1860   IndustryType it = 
GB(p1, 0, 8);
 
 1880   uint16 random_initial_bits = 
GB(p2, 0, 16);
 
 1881   uint32 random_var8f = randomizer.
Next();
 
 1888     if (flags & DC_EXEC) {
 
 1895         for (
int i = 0; i < 5000; i++) {
 
 1903           for (
int j = 0; j < num_layouts; j++) {
 
 1904             layout = (layout + 1) % num_layouts;
 
 1914     int layout = 
GB(p1, 8, 8);
 
 1915     if (layout >= num_layouts) 
return CMD_ERROR;
 
 1918     for (
int i = 0; i < num_layouts; i++) {
 
 1919       layout = (layout + 1) % num_layouts;
 
 1925     if (ret.
Failed()) 
return ret;
 
 1928   if ((flags & DC_EXEC) && ind != NULL && _game_mode != GM_EDITOR) {
 
 1947   uint32 seed = Random();
 
 1948   uint32 seed2 = Random();
 
 1950   CommandCost ret = 
CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, 
RandomRange(indspec->
num_table), seed, 
GB(seed2, 0, 16), 
OWNER_NONE, creation_type, &i);
 
 1951   assert(i != NULL || ret.
Failed());
 
 1968     *force_at_least_one = 
false;
 
 2013   static const uint16 numof_industry_table[] = {
 
 2037   uint tries = try_hard ? 10000u : 2000u;
 
 2038   for (; tries > 0; tries--) {
 
 2040     if (ind != NULL) 
return ind;
 
 2095   static const int NEWINDS_PER_MONTH = 0x38000 / (10 * 12); 
 
 2116   uint32 total_prob = 0;
 
 2117   uint num_forced = 0;
 
 2121     total_prob += industry_probs[it];
 
 2122     if (force_at_least_one[it]) num_forced++;
 
 2126   if (total_prob == 0 || total_amount < num_forced) {
 
 2128     total_amount = num_forced;
 
 2135     if (force_at_least_one[it]) {
 
 2136       assert(total_amount > 0);
 
 2143   for (uint i = 0; i < total_amount; i++) {
 
 2145     IndustryType it = 0;
 
 2146     while (r >= industry_probs[it]) {
 
 2147       r -= industry_probs[it];
 
 2149       assert(it < NUM_INDUSTRYTYPES);
 
 2151     assert(industry_probs[it] > 0);
 
 2205   bool changed = min_number != this->min_number || probability != this->
probability;
 
 2214   bool changed = 
false;
 
 2215   uint num_planned = 0; 
 
 2221   changed |= num_planned != total_amount;
 
 2222   if (!changed) 
return; 
 
 2225   uint force_build = 0;  
 
 2226   uint32 total_prob = 0; 
 
 2234   if (total_prob == 0) 
return; 
 
 2237   total_amount = (total_amount <= force_build) ? 0 : total_amount - force_build;
 
 2240   while (total_amount > 0) {
 
 2242     IndustryType it = 0;
 
 2243     while (r >= this->
builddata[it].probability) {
 
 2246       assert(it < NUM_INDUSTRYTYPES);
 
 2248     assert(this->
builddata[it].probability > 0);
 
 2263   uint32 total_prob = 0; 
 
 2267     missing += difference;
 
 2268     if (this->
builddata[it].wait_count > 0) 
continue; 
 
 2269     if (difference > 0) {
 
 2272         if (forced_build == NUM_INDUSTRYTYPES ||
 
 2277       total_prob += difference;
 
 2282   if (
EconomyIsInRecession() || (forced_build == NUM_INDUSTRYTYPES && (missing <= 0 || total_prob == 0))) count = 0; 
 
 2288     if (forced_build != NUM_INDUSTRYTYPES) {
 
 2295         if (this->
builddata[it].wait_count > 0) 
continue; 
 
 2297         if (difference <= 0) 
continue; 
 
 2298         if (count == 1) 
break;
 
 2299         if (r < (uint)difference) 
break;
 
 2388   if (stations.
Length() == 0) 
return 0; 
 
 2397     bool c_accepts = 
false;
 
 2398     bool c_produces = 
false;
 
 2400       for (
const Vehicle *u = v; u != NULL; u = u->
Next()) {
 
 2408     if (!c_accepts && !c_produces) 
continue; 
 
 2415     FOR_VEHICLE_ORDERS(v, o) {
 
 2449     default: NOT_REACHED();
 
 2454   AddIndustryNewsItem(
 
 2455     percent >= 0 ? STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH : STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH,
 
 2461 static const uint PERCENT_TRANSPORTED_60 = 153;
 
 2462 static const uint PERCENT_TRANSPORTED_80 = 204;
 
 2472   bool closeit = 
false;
 
 2474   bool standard = 
false;
 
 2475   bool suppress_message = 
false;
 
 2476   bool recalculate_multipliers = 
false; 
 
 2484   if (callback_enabled) {
 
 2487       suppress_message = 
HasBit(res, 7);
 
 2490       res = 
GB(res, 0, 4);
 
 2492         default: NOT_REACHED();
 
 2494         case 0x1: div = 1; 
break;         
 
 2495         case 0x2: mul = 1; 
break;         
 
 2496         case 0x3: closeit = 
true; 
break;  
 
 2497         case 0x4: standard = 
true; 
break; 
 
 2498         case 0x5: 
case 0x6: 
case 0x7:     
 
 2499         case 0x8: div = res - 0x3; 
break; 
 
 2500         case 0x9: 
case 0xA: 
case 0xB:     
 
 2501         case 0xC: mul = res - 0x7; 
break; 
 
 2504           increment = res == 0x0D ? -1 : 1;
 
 2508           recalculate_multipliers = 
true;
 
 2513     if (monthly != smooth_economy) 
return;
 
 2521     if (smooth_economy) {
 
 2525         uint32 r = Random();
 
 2526         int old_prod, new_prod, percent;
 
 2534         if (only_decrease) {
 
 2545           new_prod += mult * (
max(((
RandomRange(50) + 10) * old_prod) >> 8, 1U));
 
 2549         new_prod = 
Clamp(new_prod, 1, 255);
 
 2552           new_prod = 
Clamp(new_prod, 0, 16);
 
 2556         if (new_prod == old_prod && old_prod > 1) {
 
 2561         percent = (old_prod == 0) ? 100 : (new_prod * 100 / old_prod - 100);
 
 2565         if (new_prod > 1) closeit = 
false;
 
 2567         if (
abs(percent) >= 10) {
 
 2572       if (only_decrease || 
Chance16(1, 3)) {
 
 2592     recalculate_multipliers = 
true;
 
 2597   while (div-- != 0 && !closeit) {
 
 2602       recalculate_multipliers = 
true;
 
 2608   if (increment != 0) {
 
 2613       recalculate_multipliers = 
true;
 
 2628   if (!suppress_message && str != STR_NULL) {
 
 2640         default: NOT_REACHED();
 
 2644     if (str > STR_LAST_STRINGID) {
 
 2648     } 
else if (closeit) {
 
 2659       AddIndustryNewsItem(str, nt, i->
index);
 
 2683   if (change_loop == 0) {
 
 2695   for (uint16 j = 0; j < change_loop; j++) {
 
 2713 void IndustryMonthlyLoop()
 
 2720   FOR_ALL_INDUSTRIES(i) {
 
 2730   cur_company.Restore();
 
 2737 void InitializeIndustries()
 
 2740   _industry_sound_tile = 0;
 
 2752     bool force_at_least_one;
 
 2754     if (chance == 0 || !force_at_least_one) 
continue; 
 
 2758     ShowErrorMessage(STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES, STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION, 
WL_WARNING);
 
 2761     if (count >= 3) 
break; 
 
 2793       PR_BUILD_INDUSTRY_RAW : PR_BUILD_INDUSTRY] * this->
cost_multiplier) >> 8;
 
 2849   GetSlopePixelZ_Industry,     
 
 2851   AddAcceptedCargo_Industry,   
 
 2852   GetTileDesc_Industry,        
 
 2853   GetTileTrackStatus_Industry, 
 
 2855   AnimateTile_Industry,        
 
 2857   ChangeTileOwner_Industry,    
 
 2860   GetFoundation_Industry,      
 
 2861   TerraformTile_Industry,