64 memcpy(&_industry_specs, &_origin_industry_specs, sizeof(_origin_industry_specs)); |
67 memcpy(&_industry_specs, &_origin_industry_specs, sizeof(_origin_industry_specs)); |
65 |
68 |
66 /* once performed, enable only the current climate industries */ |
69 /* once performed, enable only the current climate industries */ |
67 for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) { |
70 for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) { |
68 _industry_specs[i].enabled = i < NEW_INDUSTRYOFFSET && |
71 _industry_specs[i].enabled = i < NEW_INDUSTRYOFFSET && |
69 HASBIT(_origin_industry_specs[i].climate_availability, _opt.landscape); |
72 HasBit(_origin_industry_specs[i].climate_availability, _opt.landscape); |
70 } |
73 } |
71 |
74 |
72 memset(&_industry_tile_specs, 0, sizeof(_industry_tile_specs)); |
75 memset(&_industry_tile_specs, 0, sizeof(_industry_tile_specs)); |
73 memcpy(&_industry_tile_specs, &_origin_industry_tile_specs, sizeof(_origin_industry_tile_specs)); |
76 memcpy(&_industry_tile_specs, &_origin_industry_tile_specs, sizeof(_origin_industry_tile_specs)); |
74 |
77 |
301 |
304 |
302 /* Add industry on top of the ground? */ |
305 /* Add industry on top of the ground? */ |
303 image = dits->building.sprite; |
306 image = dits->building.sprite; |
304 if (image != 0) { |
307 if (image != 0) { |
305 AddSortableSpriteToDraw(image, |
308 AddSortableSpriteToDraw(image, |
306 (HASBIT(image, PALETTE_MODIFIER_COLOR) && dits->building.pal == PAL_NONE) ? GENERAL_SPRITE_COLOR(ind->random_color) : dits->building.pal, |
309 (HasBit(image, PALETTE_MODIFIER_COLOR) && dits->building.pal == PAL_NONE) ? GENERAL_SPRITE_COLOR(ind->random_color) : dits->building.pal, |
307 ti->x + dits->subtile_x, |
310 ti->x + dits->subtile_x, |
308 ti->y + dits->subtile_y, |
311 ti->y + dits->subtile_y, |
309 dits->width, |
312 dits->width, |
310 dits->height, |
313 dits->height, |
311 dits->dz, |
314 dits->dz, |
312 ti->z, |
315 ti->z, |
313 HASBIT(_transparent_opt, TO_INDUSTRIES)); |
316 IsTransparencySet(TO_INDUSTRIES)); |
314 |
317 |
315 if (HASBIT(_transparent_opt, TO_INDUSTRIES)) return; |
318 if (IsTransparencySet(TO_INDUSTRIES)) return; |
316 } |
319 } |
317 |
320 |
318 { |
321 { |
319 int proc = dits->draw_proc - 1; |
322 int proc = dits->draw_proc - 1; |
320 if (proc >= 0) _industry_draw_tile_procs[proc](ti); |
323 if (proc >= 0) _industry_draw_tile_procs[proc](ti); |
342 |
345 |
343 /* And then these will always point to a same sized array with the required data */ |
346 /* And then these will always point to a same sized array with the required data */ |
344 const CargoID *accepts_cargo = itspec->accepts_cargo; |
347 const CargoID *accepts_cargo = itspec->accepts_cargo; |
345 const uint8 *acceptance = itspec->acceptance; |
348 const uint8 *acceptance = itspec->acceptance; |
346 |
349 |
347 if (HASBIT(itspec->callback_flags, CBM_INDT_ACCEPT_CARGO)) { |
350 if (HasBit(itspec->callback_flags, CBM_INDT_ACCEPT_CARGO)) { |
348 uint16 res = GetIndustryTileCallback(CBID_INDTILE_ACCEPT_CARGO, 0, 0, gfx, GetIndustryByTile(tile), tile); |
351 uint16 res = GetIndustryTileCallback(CBID_INDTILE_ACCEPT_CARGO, 0, 0, gfx, GetIndustryByTile(tile), tile); |
349 if (res != CALLBACK_FAILED) { |
352 if (res != CALLBACK_FAILED) { |
350 accepts_cargo = raw_accepts_cargo; |
353 accepts_cargo = raw_accepts_cargo; |
351 for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_accepts_cargo[i] = GetCargoTranslation(GB(res, i * 5, 5), itspec->grf_prop.grffile); |
354 for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_accepts_cargo[i] = GetCargoTranslation(GB(res, i * 5, 5), itspec->grf_prop.grffile); |
352 } |
355 } |
353 } |
356 } |
354 |
357 |
355 if (HASBIT(itspec->callback_flags, CBM_INDT_CARGO_ACCEPTANCE)) { |
358 if (HasBit(itspec->callback_flags, CBM_INDT_CARGO_ACCEPTANCE)) { |
356 uint16 res = GetIndustryTileCallback(CBID_INDTILE_CARGO_ACCEPTANCE, 0, 0, gfx, GetIndustryByTile(tile), tile); |
359 uint16 res = GetIndustryTileCallback(CBID_INDTILE_CARGO_ACCEPTANCE, 0, 0, gfx, GetIndustryByTile(tile), tile); |
357 if (res != CALLBACK_FAILED) { |
360 if (res != CALLBACK_FAILED) { |
358 acceptance = raw_acceptance; |
361 acceptance = raw_acceptance; |
359 for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_acceptance[i] = GB(res, i * 4, 4); |
362 for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_acceptance[i] = GB(res, i * 4, 4); |
360 } |
363 } |
396 SetDParam(0, indspec->name); |
399 SetDParam(0, indspec->name); |
397 return_cmd_error(STR_4800_IN_THE_WAY); |
400 return_cmd_error(STR_4800_IN_THE_WAY); |
398 } |
401 } |
399 |
402 |
400 if (flags & DC_EXEC) delete i; |
403 if (flags & DC_EXEC) delete i; |
401 return CommandCost(); |
404 return CommandCost(indspec->GetRemovalCost()); |
402 } |
405 } |
403 |
406 |
404 static void TransportIndustryGoods(TileIndex tile) |
407 static void TransportIndustryGoods(TileIndex tile) |
405 { |
408 { |
406 Industry *i = GetIndustryByTile(tile); |
409 Industry *i = GetIndustryByTile(tile); |
407 const IndustrySpec *indspec = GetIndustrySpec(i->type); |
410 const IndustrySpec *indspec = GetIndustrySpec(i->type); |
408 uint cw, am; |
411 bool moved_cargo = false; |
409 |
412 |
410 cw = min(i->produced_cargo_waiting[0], 255); |
413 for (uint j = 0; j < lengthof(i->produced_cargo_waiting); j++) { |
411 if (cw > indspec->minimal_cargo/* && i->produced_cargo[0] != 0xFF*/) { |
414 uint cw = min(i->produced_cargo_waiting[j], 255); |
412 i->produced_cargo_waiting[0] -= cw; |
415 if (cw > indspec->minimal_cargo && i->produced_cargo[j] != CT_INVALID) { |
413 |
416 i->produced_cargo_waiting[j] -= cw; |
414 /* fluctuating economy? */ |
417 |
415 if (_economy.fluct <= 0) cw = (cw + 1) / 2; |
418 /* fluctuating economy? */ |
416 |
419 if (_economy.fluct <= 0) cw = (cw + 1) / 2; |
417 i->this_month_production[0] += cw; |
420 |
418 |
421 i->this_month_production[j] += cw; |
419 am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[0], cw); |
422 |
420 i->this_month_transported[0] += am; |
423 uint am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[j], cw); |
421 if (am != 0 && !StartStopIndustryTileAnimation(i, IAT_INDUSTRY_DISTRIBUTES_CARGO)) { |
424 i->this_month_transported[j] += am; |
422 uint newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_production; |
425 |
423 |
426 moved_cargo |= (am != 0); |
424 if (newgfx != INDUSTRYTILE_NOANIM) { |
427 } |
425 ResetIndustryConstructionStage(tile); |
428 } |
426 SetIndustryCompleted(tile, true); |
429 |
427 SetIndustryGfx(tile, newgfx); |
430 if (moved_cargo && !StartStopIndustryTileAnimation(i, IAT_INDUSTRY_DISTRIBUTES_CARGO)) { |
428 MarkTileDirtyByTile(tile); |
431 uint newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_production; |
429 } |
432 |
430 } |
433 if (newgfx != INDUSTRYTILE_NOANIM) { |
431 } |
434 ResetIndustryConstructionStage(tile); |
432 |
435 SetIndustryCompleted(tile, true); |
433 cw = min(i->produced_cargo_waiting[1], 255); |
436 SetIndustryGfx(tile, newgfx); |
434 if (cw > indspec->minimal_cargo) { |
437 MarkTileDirtyByTile(tile); |
435 i->produced_cargo_waiting[1] -= cw; |
438 } |
436 |
|
437 if (_economy.fluct <= 0) cw = (cw + 1) / 2; |
|
438 |
|
439 i->this_month_production[1] += cw; |
|
440 |
|
441 am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[1], cw); |
|
442 i->this_month_transported[1] += am; |
|
443 } |
439 } |
444 } |
440 } |
445 |
441 |
446 |
442 |
447 static void AnimateTile_Industry(TileIndex tile) |
443 static void AnimateTile_Industry(TileIndex tile) |
992 uint num; |
988 uint num; |
993 const IndustrySpec *indsp = GetIndustrySpec(i->type); |
989 const IndustrySpec *indsp = GetIndustrySpec(i->type); |
994 |
990 |
995 /* play a sound? */ |
991 /* play a sound? */ |
996 if ((i->counter & 0x3F) == 0) { |
992 if ((i->counter & 0x3F) == 0) { |
997 if (CHANCE16R(1, 14, r) && (num = indsp->number_of_sounds) != 0) { |
993 if (Chance16R(1, 14, r) && (num = indsp->number_of_sounds) != 0) { |
998 SndPlayTileFx( |
994 SndPlayTileFx( |
999 (SoundFx)(indsp->random_sounds[((r >> 16) * num) >> 16]), |
995 (SoundFx)(indsp->random_sounds[((r >> 16) * num) >> 16]), |
1000 i->xy); |
996 i->xy); |
1001 } |
997 } |
1002 } |
998 } |
1003 |
999 |
1004 i->counter--; |
1000 i->counter--; |
1005 |
1001 |
1006 /* produce some cargo */ |
1002 /* produce some cargo */ |
1007 if ((i->counter & 0xFF) == 0) { |
1003 if ((i->counter & 0xFF) == 0) { |
1008 if (HASBIT(indsp->callback_flags, CBM_IND_PRODUCTION_256_TICKS)) IndustryProductionCallback(i, 1); |
1004 if (HasBit(indsp->callback_flags, CBM_IND_PRODUCTION_256_TICKS)) IndustryProductionCallback(i, 1); |
1009 |
1005 |
1010 IndustyBehaviour indbehav = indsp->behaviour; |
1006 IndustryBehaviour indbehav = indsp->behaviour; |
1011 i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + i->production_rate[0]); |
1007 i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + i->production_rate[0]); |
1012 i->produced_cargo_waiting[1] = min(0xffff, i->produced_cargo_waiting[1] + i->production_rate[1]); |
1008 i->produced_cargo_waiting[1] = min(0xffff, i->produced_cargo_waiting[1] + i->production_rate[1]); |
1013 |
1009 |
1014 if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) { |
1010 if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) { |
1015 bool plant; |
1011 bool plant; |
1016 if (HASBIT(indsp->callback_flags, CBM_IND_SPECIAL_EFFECT)) { |
1012 if (HasBit(indsp->callback_flags, CBM_IND_SPECIAL_EFFECT)) { |
1017 plant = (GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 0, i, i->type, i->xy) != 0); |
1013 plant = (GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 0, i, i->type, i->xy) != 0); |
1018 } else { |
1014 } else { |
1019 plant = CHANCE16(1, 8); |
1015 plant = Chance16(1, 8); |
1020 } |
1016 } |
1021 |
1017 |
1022 if (plant) PlantRandomFarmField(i); |
1018 if (plant) PlantRandomFarmField(i); |
1023 } |
1019 } |
1024 if ((indbehav & INDUSTRYBEH_CUT_TREES) != 0) { |
1020 if ((indbehav & INDUSTRYBEH_CUT_TREES) != 0) { |
1025 bool cut = ((i->counter & 0x1FF) == 0); |
1021 bool cut = ((i->counter & 0x1FF) == 0); |
1026 if (HASBIT(indsp->callback_flags, CBM_IND_SPECIAL_EFFECT)) { |
1022 if (HasBit(indsp->callback_flags, CBM_IND_SPECIAL_EFFECT)) { |
1027 cut = (GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, 0, 1, i, i->type, i->xy) != 0); |
1023 cut = (GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, 0, 1, i, i->type, i->xy) != 0); |
1028 } |
1024 } |
1029 |
1025 |
1030 if (cut) ChopLumberMillTrees(i); |
1026 if (cut) ChopLumberMillTrees(i); |
1031 } |
1027 } |
1218 if (!IsTileType(cur_tile, MP_WATER) || |
1216 if (!IsTileType(cur_tile, MP_WATER) || |
1219 GetTileSlope(cur_tile, NULL) != SLOPE_FLAT) { |
1217 GetTileSlope(cur_tile, NULL) != SLOPE_FLAT) { |
1220 return false; |
1218 return false; |
1221 } |
1219 } |
1222 } else { |
1220 } else { |
1223 if (!EnsureNoVehicle(cur_tile)) return false; |
1221 if (!EnsureNoVehicleOnGround(cur_tile)) return false; |
1224 if (MayHaveBridgeAbove(cur_tile) && IsBridgeAbove(cur_tile)) return false; |
1222 if (MayHaveBridgeAbove(cur_tile) && IsBridgeAbove(cur_tile)) return false; |
1225 |
1223 |
1226 const IndustryTileSpec *its = GetIndustryTileSpec(gfx); |
1224 const IndustryTileSpec *its = GetIndustryTileSpec(gfx); |
1227 |
1225 |
1228 IndustyBehaviour ind_behav = GetIndustrySpec(type)->behaviour; |
1226 IndustryBehaviour ind_behav = GetIndustrySpec(type)->behaviour; |
1229 |
1227 |
1230 if (HASBIT(its->callback_flags, CBM_INDT_SHAPE_CHECK)) { |
1228 /* Perform land/water check if not disabled */ |
|
1229 if (!HasBit(its->slopes_refused, 5) && (IsWaterTile(cur_tile) == !(ind_behav & INDUSTRYBEH_BUILT_ONWATER))) return false; |
|
1230 |
|
1231 if (HasBit(its->callback_flags, CBM_INDT_SHAPE_CHECK)) { |
1231 custom_shape = true; |
1232 custom_shape = true; |
1232 if (!PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, itspec_index)) return false; |
1233 if (!PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, itspec_index)) return false; |
1233 } else { |
1234 } else { |
1234 if (ind_behav & INDUSTRYBEH_BUILT_ONWATER) { |
1235 Slope tileh = GetTileSlope(cur_tile, NULL); |
1235 /* As soon as the tile is not water, bail out. |
1236 refused_slope |= IsSlopeRefused(tileh, its->slopes_refused); |
1236 * But that does not mean the search is over. You have |
1237 } |
1237 * to make sure every tile of the industry will be only water*/ |
1238 |
1238 if (!IsClearWaterTile(cur_tile)) return false; |
1239 if (ind_behav & (INDUSTRYBEH_ONLY_INTOWN | INDUSTRYBEH_TOWN1200_MORE)) { |
1239 } else { |
|
1240 Slope tileh; |
|
1241 |
|
1242 if (IsClearWaterTile(cur_tile)) return false; |
|
1243 |
|
1244 tileh = GetTileSlope(cur_tile, NULL); |
|
1245 if (IsSteepSlope(tileh)) return false; |
|
1246 |
|
1247 refused_slope |= IsSlopeRefused(tileh, its->slopes_refused); |
|
1248 } |
|
1249 } |
|
1250 |
|
1251 if (ind_behav & INDUSTRYBEH_ONLY_INTOWN) { |
|
1252 if (!IsTileType(cur_tile, MP_HOUSE)) { |
1240 if (!IsTileType(cur_tile, MP_HOUSE)) { |
1253 _error_message = STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS; |
1241 _error_message = STR_029D_CAN_ONLY_BE_BUILT_IN_TOWNS; |
1254 return false; |
1242 return false; |
1255 } |
1243 } |
1256 if (CmdFailed(DoCommand(cur_tile, 0, 0, 0, CMD_LANDSCAPE_CLEAR))) return false; |
1244 if (CmdFailed(DoCommand(cur_tile, 0, 0, 0, CMD_LANDSCAPE_CLEAR))) return false; |
1439 i->accepts_cargo[1] = indspec->accepts_cargo[1]; |
1427 i->accepts_cargo[1] = indspec->accepts_cargo[1]; |
1440 i->accepts_cargo[2] = indspec->accepts_cargo[2]; |
1428 i->accepts_cargo[2] = indspec->accepts_cargo[2]; |
1441 i->production_rate[0] = indspec->production_rate[0]; |
1429 i->production_rate[0] = indspec->production_rate[0]; |
1442 i->production_rate[1] = indspec->production_rate[1]; |
1430 i->production_rate[1] = indspec->production_rate[1]; |
1443 |
1431 |
1444 /* don't use smooth economy for industries using production callbacks */ |
1432 /* don't use smooth economy for industries using production related callbacks */ |
1445 if (_patches.smooth_economy && !(HASBIT(indspec->callback_flags, CBM_IND_PRODUCTION_256_TICKS) || HASBIT(indspec->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL))) { |
1433 if (_patches.smooth_economy && |
|
1434 !(HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_256_TICKS) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) && // production callbacks |
|
1435 !(HasBit(indspec->callback_flags, CBM_IND_MONTHLYPROD_CHANGE) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CHANGE)) // production change callbacks |
|
1436 ) { |
1446 i->production_rate[0] = min((RandomRange(256) + 128) * i->production_rate[0] >> 8 , 255); |
1437 i->production_rate[0] = min((RandomRange(256) + 128) * i->production_rate[0] >> 8 , 255); |
1447 i->production_rate[1] = min((RandomRange(256) + 128) * i->production_rate[1] >> 8 , 255); |
1438 i->production_rate[1] = min((RandomRange(256) + 128) * i->production_rate[1] >> 8 , 255); |
1448 } |
1439 } |
1449 |
1440 |
1450 i->town = t; |
1441 i->town = t; |
1451 i->owner = owner; |
1442 i->owner = owner; |
1452 |
1443 |
1453 r = Random(); |
1444 r = Random(); |
1454 i->random_color = GB(r, 8, 4); |
1445 i->random_color = GB(r, 0, 4); |
1455 i->counter = GB(r, 0, 12); |
1446 i->counter = GB(r, 4, 12); |
|
1447 i->random = GB(r, 16, 16); |
1456 i->produced_cargo_waiting[0] = 0; |
1448 i->produced_cargo_waiting[0] = 0; |
1457 i->produced_cargo_waiting[1] = 0; |
1449 i->produced_cargo_waiting[1] = 0; |
1458 i->incoming_cargo_waiting[0] = 0; |
1450 i->incoming_cargo_waiting[0] = 0; |
1459 i->incoming_cargo_waiting[1] = 0; |
1451 i->incoming_cargo_waiting[1] = 0; |
1460 i->incoming_cargo_waiting[2] = 0; |
1452 i->incoming_cargo_waiting[2] = 0; |
1470 i->last_prod_year = _cur_year; |
1462 i->last_prod_year = _cur_year; |
1471 i->last_month_production[0] = i->production_rate[0] * 8; |
1463 i->last_month_production[0] = i->production_rate[0] * 8; |
1472 i->last_month_production[1] = i->production_rate[1] * 8; |
1464 i->last_month_production[1] = i->production_rate[1] * 8; |
1473 i->founder = _current_player; |
1465 i->founder = _current_player; |
1474 |
1466 |
1475 if (HASBIT(indspec->callback_flags, CBM_IND_DECIDE_COLOUR)) { |
1467 if (HasBit(indspec->callback_flags, CBM_IND_DECIDE_COLOUR)) { |
1476 uint16 res = GetIndustryCallback(CBID_INDUSTRY_DECIDE_COLOUR, 0, 0, i, type, INVALID_TILE); |
1468 uint16 res = GetIndustryCallback(CBID_INDUSTRY_DECIDE_COLOUR, 0, 0, i, type, INVALID_TILE); |
1477 if (res != CALLBACK_FAILED) i->random_color = GB(res, 0, 4); |
1469 if (res != CALLBACK_FAILED) i->random_color = GB(res, 0, 4); |
1478 } |
1470 } |
1479 |
1471 |
1480 if (HASBIT(indspec->callback_flags, CBM_IND_INPUT_CARGO_TYPES)) { |
1472 if (HasBit(indspec->callback_flags, CBM_IND_INPUT_CARGO_TYPES)) { |
1481 for (j = 0; j < lengthof(i->accepts_cargo); j++) i->accepts_cargo[j] = CT_INVALID; |
1473 for (j = 0; j < lengthof(i->accepts_cargo); j++) i->accepts_cargo[j] = CT_INVALID; |
1482 for (j = 0; j < lengthof(i->accepts_cargo); j++) { |
1474 for (j = 0; j < lengthof(i->accepts_cargo); j++) { |
1483 uint16 res = GetIndustryCallback(CBID_INDUSTRY_INPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE); |
1475 uint16 res = GetIndustryCallback(CBID_INDUSTRY_INPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE); |
1484 if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break; |
1476 if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break; |
1485 i->accepts_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile); |
1477 i->accepts_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile); |
1486 } |
1478 } |
1487 } |
1479 } |
1488 |
1480 |
1489 if (HASBIT(indspec->callback_flags, CBM_IND_OUTPUT_CARGO_TYPES)) { |
1481 if (HasBit(indspec->callback_flags, CBM_IND_OUTPUT_CARGO_TYPES)) { |
1490 for (j = 0; j < lengthof(i->produced_cargo); j++) i->produced_cargo[j] = CT_INVALID; |
1482 for (j = 0; j < lengthof(i->produced_cargo); j++) i->produced_cargo[j] = CT_INVALID; |
1491 for (j = 0; j < lengthof(i->produced_cargo); j++) { |
1483 for (j = 0; j < lengthof(i->produced_cargo); j++) { |
1492 uint16 res = GetIndustryCallback(CBID_INDUSTRY_OUTPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE); |
1484 uint16 res = GetIndustryCallback(CBID_INDUSTRY_OUTPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE); |
1493 if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break; |
1485 if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break; |
1494 i->produced_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile); |
1486 i->produced_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile); |
1520 if (size > i->height)i->height = size; |
1512 if (size > i->height)i->height = size; |
1521 |
1513 |
1522 DoCommand(cur_tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); |
1514 DoCommand(cur_tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); |
1523 |
1515 |
1524 MakeIndustry(cur_tile, i->index, it->gfx); |
1516 MakeIndustry(cur_tile, i->index, it->gfx); |
|
1517 |
1525 if (_generating_world) { |
1518 if (_generating_world) { |
1526 SetIndustryConstructionCounter(cur_tile, 3); |
1519 SetIndustryConstructionCounter(cur_tile, 3); |
1527 SetIndustryConstructionStage(cur_tile, 2); |
1520 SetIndustryConstructionStage(cur_tile, 2); |
|
1521 } |
|
1522 if (it->gfx >= NEW_INDUSTRYTILEOFFSET) { |
|
1523 /* New industry */ |
|
1524 const IndustryTileSpec *its = GetIndustryTileSpec(it->gfx); |
|
1525 if (its->animation_info != 0xFFFF) AddAnimatedTile(cur_tile); |
1528 } |
1526 } |
1529 } |
1527 } |
1530 } while ((++it)->ti.x != -0x80); |
1528 } while ((++it)->ti.x != -0x80); |
1531 |
1529 |
1532 i->width++; |
1530 i->width++; |
1584 |
1582 |
1585 /** Build/Fund an industry |
1583 /** Build/Fund an industry |
1586 * @param tile tile where industry is built |
1584 * @param tile tile where industry is built |
1587 * @param flags of operations to conduct |
1585 * @param flags of operations to conduct |
1588 * @param p1 industry type see build_industry.h and see industry.h |
1586 * @param p1 industry type see build_industry.h and see industry.h |
1589 * @param p2 unused |
1587 * @param p2 first layout to try |
1590 * @return index of the newly create industry, or CMD_ERROR if it failed |
1588 * @return index of the newly create industry, or CMD_ERROR if it failed |
1591 */ |
1589 */ |
1592 CommandCost CmdBuildIndustry(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1590 CommandCost CmdBuildIndustry(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1593 { |
1591 { |
1594 int num; |
|
1595 const IndustryTileTable * const *itt; |
|
1596 const IndustrySpec *indspec; |
1592 const IndustrySpec *indspec; |
1597 |
1593 |
1598 SET_EXPENSES_TYPE(EXPENSES_OTHER); |
1594 SET_EXPENSES_TYPE(EXPENSES_OTHER); |
1599 |
1595 |
1600 indspec = GetIndustrySpec(p1); |
1596 indspec = GetIndustrySpec(p1); |
1615 /* Prospecting has a chance to fail, however we cannot guarantee that something can |
1611 /* Prospecting has a chance to fail, however we cannot guarantee that something can |
1616 * be built on the map, so the chance gets lower when the map is fuller, but there |
1612 * be built on the map, so the chance gets lower when the map is fuller, but there |
1617 * is nothing we can really do about that. */ |
1613 * is nothing we can really do about that. */ |
1618 if (Random() <= indspec->prospecting_chance) { |
1614 if (Random() <= indspec->prospecting_chance) { |
1619 for (int i = 0; i < 5000; i++) { |
1615 for (int i = 0; i < 5000; i++) { |
1620 uint tilespec_index = RandomRange(indspec->num_table); |
1616 const Industry *ind = CreateNewIndustryHelper(RandomTile(), p1, flags, indspec, RandomRange(indspec->num_table)); |
1621 const Industry *ind = CreateNewIndustryHelper(RandomTile(), p1, flags, indspec, tilespec_index); |
|
1622 if (ind != NULL) { |
1617 if (ind != NULL) { |
1623 SetDParam(0, indspec->name); |
1618 SetDParam(0, indspec->name); |
1624 SetDParam(1, ind->town->index); |
1619 if (indspec->new_industry_text > STR_LAST_STRINGID) { |
|
1620 SetDParam(1, STR_TOWN); |
|
1621 SetDParam(2, ind->town->index); |
|
1622 } else { |
|
1623 SetDParam(1, ind->town->index); |
|
1624 } |
1625 AddNewsItem(indspec->new_industry_text, |
1625 AddNewsItem(indspec->new_industry_text, |
1626 NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_OPENCLOSE, 0), ind->xy, 0); |
1626 NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_OPENCLOSE, 0), ind->xy, 0); |
1627 break; |
1627 break; |
1628 } |
1628 } |
1629 } |
1629 } |
1630 } |
1630 } |
1631 } |
1631 } |
1632 } else { |
1632 } else { |
1633 num = indspec->num_table; |
1633 int count = indspec->num_table; |
1634 itt = indspec->table; |
1634 const IndustryTileTable * const *itt = indspec->table; |
1635 |
1635 int num = Clamp(p2, 0, count - 1); |
1636 |
1636 |
|
1637 _error_message = STR_0239_SITE_UNSUITABLE; |
1637 do { |
1638 do { |
1638 if (--num < 0) return_cmd_error(STR_0239_SITE_UNSUITABLE); |
1639 if (--count < 0) return CMD_ERROR; |
|
1640 if (--num < 0) num = indspec->num_table - 1; |
1639 } while (!CheckIfIndustryTilesAreFree(tile, itt[num], num, p1)); |
1641 } while (!CheckIfIndustryTilesAreFree(tile, itt[num], num, p1)); |
1640 |
1642 |
1641 if (CreateNewIndustryHelper(tile, p1, flags, indspec, num) == NULL) return CMD_ERROR; |
1643 if (CreateNewIndustryHelper(tile, p1, flags, indspec, num) == NULL) return CMD_ERROR; |
1642 } |
1644 } |
1643 |
1645 |
1794 ProbabilityHelper cumulative_probs[NUM_INDUSTRYTYPES]; // probability collector |
1796 ProbabilityHelper cumulative_probs[NUM_INDUSTRYTYPES]; // probability collector |
1795 uint16 probability_max = 0; |
1797 uint16 probability_max = 0; |
1796 |
1798 |
1797 /* Generate a list of all possible industries that can be built. */ |
1799 /* Generate a list of all possible industries that can be built. */ |
1798 for (j = 0; j < NUM_INDUSTRYTYPES; j++) { |
1800 for (j = 0; j < NUM_INDUSTRYTYPES; j++) { |
1799 byte chance = GetIndustrySpec(j)->appear_ingame[_opt.landscape]; |
1801 ind_spc = GetIndustrySpec(j); |
|
1802 byte chance = ind_spc->appear_ingame[_opt.landscape]; |
|
1803 |
|
1804 if (!ind_spc->enabled || chance == 0) continue; |
1800 |
1805 |
1801 /* If there is no Callback CBID_INDUSTRY_AVAILABLE or if this one did anot failed, |
1806 /* If there is no Callback CBID_INDUSTRY_AVAILABLE or if this one did anot failed, |
1802 * and if appearing chance for this landscape is above 0, this industry can be chosen */ |
1807 * and if appearing chance for this landscape is above 0, this industry can be chosen */ |
1803 if (CheckIfCallBackAllowsAvailability(j, IACT_RANDOMCREATION) && chance != 0) { |
1808 if (CheckIfCallBackAllowsAvailability(j, IACT_RANDOMCREATION)) { |
1804 probability_max += chance; |
1809 probability_max += chance; |
1805 /* adds the result for this industry */ |
1810 /* adds the result for this industry */ |
1806 cumulative_probs[num].ind = j; |
1811 cumulative_probs[num].ind = j; |
1807 cumulative_probs[num++].prob = probability_max; |
1812 cumulative_probs[num++].prob = probability_max; |
1808 } |
1813 } |
1846 { |
1856 { |
1847 const IndustrySpec *indspec = GetIndustrySpec(type); |
1857 const IndustrySpec *indspec = GetIndustrySpec(type); |
1848 |
1858 |
1849 /* oil wells (or the industries with that flag set) are always allowed to closedown */ |
1859 /* oil wells (or the industries with that flag set) are always allowed to closedown */ |
1850 if (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD && _opt.landscape == LT_TEMPERATE) return false; |
1860 if (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD && _opt.landscape == LT_TEMPERATE) return false; |
1851 return (indspec->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE && GetIndustryTypeCount(type) <= 1); |
1861 return (indspec->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE) == 0 && GetIndustryTypeCount(type) <= 1; |
1852 } |
1862 } |
|
1863 |
|
1864 /** |
|
1865 * Can given cargo type be accepted or produced by the industry? |
|
1866 * @param cargo: Cargo type |
|
1867 * @param ind: Industry |
|
1868 * @param *c_accepts: Pointer to boolean for acceptance of cargo |
|
1869 * @param *c_produces: Pointer to boolean for production of cargo |
|
1870 * @return: \c *c_accepts is set when industry accepts the cargo type, |
|
1871 * \c *c_produces is set when the industry produces the cargo type |
|
1872 */ |
|
1873 static void CanCargoServiceIndustry(CargoID cargo, Industry *ind, bool *c_accepts, bool *c_produces) |
|
1874 { |
|
1875 const IndustrySpec *indspec = GetIndustrySpec(ind->type); |
|
1876 |
|
1877 /* Check for acceptance of cargo */ |
|
1878 for (uint j = 0; j < lengthof(ind->accepts_cargo) && ind->accepts_cargo[j] != CT_INVALID; j++) { |
|
1879 if (cargo == ind->accepts_cargo[j]) { |
|
1880 if (HasBit(indspec->callback_flags, CBM_IND_REFUSE_CARGO)) { |
|
1881 uint16 res = GetIndustryCallback(CBID_INDUSTRY_REFUSE_CARGO, |
|
1882 0, GetReverseCargoTranslation(cargo, indspec->grf_prop.grffile), |
|
1883 ind, ind->type, ind->xy); |
|
1884 if (res == 0) continue; |
|
1885 } |
|
1886 *c_accepts = true; |
|
1887 break; |
|
1888 } |
|
1889 } |
|
1890 |
|
1891 /* Check for produced cargo */ |
|
1892 for (uint j = 0; j < lengthof(ind->produced_cargo) && ind->produced_cargo[j] != CT_INVALID; j++) { |
|
1893 if (cargo == ind->produced_cargo[j]) { |
|
1894 *c_produces = true; |
|
1895 break; |
|
1896 } |
|
1897 } |
|
1898 } |
|
1899 |
|
1900 /** |
|
1901 * Compute who can service the industry. |
|
1902 * |
|
1903 * Here, 'can service' means that he/she has trains and stations close enough |
|
1904 * to the industry with the right cargo type and the right orders (ie has the |
|
1905 * technical means). |
|
1906 * |
|
1907 * @param ind: Industry being investigated. |
|
1908 * |
|
1909 * @return: 0 if nobody can service the industry, 2 if the local player can |
|
1910 * service the industry, and 1 otherwise (only competitors can service the |
|
1911 * industry) |
|
1912 */ |
|
1913 int WhoCanServiceIndustry(Industry* ind) |
|
1914 { |
|
1915 /* Find all stations within reach of the industry */ |
|
1916 StationSet stations = FindStationsAroundIndustryTile(ind->xy, ind->width, ind->height); |
|
1917 |
|
1918 if (stations.size() == 0) return 0; // No stations found at all => nobody services |
|
1919 |
|
1920 const Vehicle *v; |
|
1921 int result = 0; |
|
1922 FOR_ALL_VEHICLES(v) { |
|
1923 /* Is it worthwhile to try this vehicle? */ |
|
1924 if (v->owner != _local_player && result != 0) continue; |
|
1925 |
|
1926 /* Check whether it accepts the right kind of cargo */ |
|
1927 bool c_accepts = false; |
|
1928 bool c_produces = false; |
|
1929 if (v->type == VEH_TRAIN && IsFrontEngine(v)) { |
|
1930 const Vehicle *u = v; |
|
1931 BEGIN_ENUM_WAGONS(u) |
|
1932 CanCargoServiceIndustry(u->cargo_type, ind, &c_accepts, &c_produces); |
|
1933 END_ENUM_WAGONS(u) |
|
1934 } else if (v->type == VEH_ROAD || v->type == VEH_SHIP || v->type == VEH_AIRCRAFT) { |
|
1935 CanCargoServiceIndustry(v->cargo_type, ind, &c_accepts, &c_produces); |
|
1936 } else { |
|
1937 continue; |
|
1938 } |
|
1939 if (!c_accepts && !c_produces) continue; // Wrong cargo |
|
1940 |
|
1941 /* Check orders of the vehicle. |
|
1942 * We cannot check the first of shared orders only, since the first vehicle in such a chain |
|
1943 * may have a different cargo type. |
|
1944 */ |
|
1945 const Order *o; |
|
1946 FOR_VEHICLE_ORDERS(v, o) { |
|
1947 if (o->type == OT_GOTO_STATION && !HasBit(o->flags, OFB_TRANSFER)) { |
|
1948 /* Vehicle visits a station to load or unload */ |
|
1949 Station *st = GetStation(o->dest); |
|
1950 if (!st->IsValid()) continue; |
|
1951 |
|
1952 /* Same cargo produced by industry is dropped here => not serviced by vehicle v */ |
|
1953 if (HasBit(o->flags, OFB_UNLOAD) && !c_accepts) break; |
|
1954 |
|
1955 if (stations.find(st) != stations.end()) { |
|
1956 if (v->owner == _local_player) return 2; // Player services industry |
|
1957 result = 1; // Competitor services industry |
|
1958 } |
|
1959 } |
|
1960 } |
|
1961 } |
|
1962 return result; |
|
1963 } |
|
1964 |
|
1965 /** |
|
1966 * Report news that industry production has changed significantly |
|
1967 * |
|
1968 * @param ind: Industry with changed production |
|
1969 * @param type: Cargo type that has changed |
|
1970 * @param percent: Percentage of change (>0 means increase, <0 means decrease) |
|
1971 */ |
|
1972 static void ReportNewsProductionChangeIndustry(Industry *ind, CargoID type, int percent) |
|
1973 { |
|
1974 NewsType nt; |
|
1975 |
|
1976 switch (WhoCanServiceIndustry(ind)) { |
|
1977 case 0: nt = NT_INDUSTRY_NOBODY; break; |
|
1978 case 1: nt = NT_INDUSTRY_OTHER; break; |
|
1979 case 2: nt = NT_INDUSTRY_PLAYER; break; |
|
1980 default: NOT_REACHED(); break; |
|
1981 } |
|
1982 SetDParam(2, abs(percent)); |
|
1983 SetDParam(0, GetCargo(type)->name); |
|
1984 SetDParam(1, ind->index); |
|
1985 AddNewsItem( |
|
1986 percent >= 0 ? STR_INDUSTRY_PROD_GOUP : STR_INDUSTRY_PROD_GODOWN, |
|
1987 NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, nt, 0), |
|
1988 ind->xy + TileDiffXY(1, 1), 0 |
|
1989 ); |
|
1990 } |
|
1991 |
|
1992 enum { |
|
1993 PERCENT_TRANSPORTED_60 = 153, |
|
1994 }; |
1853 |
1995 |
1854 /** Change industry production or do closure |
1996 /** Change industry production or do closure |
1855 * @param i Industry for which changes are performed |
1997 * @param i Industry for which changes are performed |
1856 * @param monthly true if it's the monthly call, false if it's the random call |
1998 * @param monthly true if it's the monthly call, false if it's the random call |
1857 */ |
1999 */ |
1861 StringID str = STR_NULL; |
2003 StringID str = STR_NULL; |
1862 bool closeit = false; |
2004 bool closeit = false; |
1863 const IndustrySpec *indspec = GetIndustrySpec(i->type); |
2005 const IndustrySpec *indspec = GetIndustrySpec(i->type); |
1864 bool standard = true; |
2006 bool standard = true; |
1865 bool suppress_message = false; |
2007 bool suppress_message = false; |
1866 /* don't use smooth economy for industries using production callbacks */ |
2008 /* don't use smooth economy for industries using production related callbacks */ |
1867 bool smooth_economy = _patches.smooth_economy && !(HASBIT(indspec->callback_flags, CBM_IND_PRODUCTION_256_TICKS) || HASBIT(indspec->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL)); |
2009 bool smooth_economy = _patches.smooth_economy && |
|
2010 !(HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_256_TICKS) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) && // production callbacks |
|
2011 !(HasBit(indspec->callback_flags, CBM_IND_MONTHLYPROD_CHANGE) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CHANGE)); // production change callbacks |
1868 byte div = 0; |
2012 byte div = 0; |
1869 byte mul = 0; |
2013 byte mul = 0; |
1870 |
2014 int8 increment = 0; |
1871 if (HASBIT(indspec->callback_flags, monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE)) { |
2015 |
|
2016 if (HasBit(indspec->callback_flags, monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE)) { |
1872 uint16 res = GetIndustryCallback(monthly ? CBID_INDUSTRY_MONTHLYPROD_CHANGE : CBID_INDUSTRY_PRODUCTION_CHANGE, 0, Random(), i, i->type, i->xy); |
2017 uint16 res = GetIndustryCallback(monthly ? CBID_INDUSTRY_MONTHLYPROD_CHANGE : CBID_INDUSTRY_PRODUCTION_CHANGE, 0, Random(), i, i->type, i->xy); |
|
2018 standard = false; |
|
2019 monthly = false; // smooth economy is disabled so we need to fake random industry production change to allow 'use standard' result |
1873 if (res != CALLBACK_FAILED) { |
2020 if (res != CALLBACK_FAILED) { |
1874 standard = false; |
2021 suppress_message = HasBit(res, 7); |
1875 suppress_message = HASBIT(res, 7); |
|
1876 /* Get the custom message if any */ |
2022 /* Get the custom message if any */ |
1877 if (HASBIT(res, 8)) str = MapGRFStringID(indspec->grf_prop.grffile->grfid, GB(GetRegister(0x100), 0, 16)); |
2023 if (HasBit(res, 8)) str = MapGRFStringID(indspec->grf_prop.grffile->grfid, GB(GetRegister(0x100), 0, 16)); |
1878 res = GB(res, 0, 4); |
2024 res = GB(res, 0, 4); |
1879 switch(res) { |
2025 switch(res) { |
1880 default: NOT_REACHED(); |
2026 default: NOT_REACHED(); |
1881 case 0x0: break; // Do nothing, but show the custom message if any |
2027 case 0x0: break; // Do nothing, but show the custom message if any |
1882 case 0x1: div = 1; break; // Halve industry production. If production reaches the quarter of the default, the industry is closed instead. |
2028 case 0x1: div = 1; break; // Halve industry production. If production reaches the quarter of the default, the industry is closed instead. |
1883 case 0x2: mul = 1; break; // Double industry production if it hasn't reached eight times of the original yet. |
2029 case 0x2: mul = 1; break; // Double industry production if it hasn't reached eight times of the original yet. |
1884 case 0x3: closeit = true; break; // The industry announces imminent closure, and is physically removed from the map next month. |
2030 case 0x3: closeit = true; break; // The industry announces imminent closure, and is physically removed from the map next month. |
1885 case 0x4: standard = true; break; // Do the standard random production change as if this industry was a primary one. |
2031 case 0x4: standard = true; break; // Do the standard random production change as if this industry was a primary one. |
1886 case 0x5: case 0x6: case 0x7: // Divide production by 4, 8, 16 |
2032 case 0x5: case 0x6: case 0x7: // Divide production by 4, 8, 16 |
1887 case 0x8: div = res - 0x5; break; // Divide production by 32 |
2033 case 0x8: div = res - 0x3; break; // Divide production by 32 |
1888 case 0x9: case 0xA: case 0xB: // Multiply production by 4, 8, 16 |
2034 case 0x9: case 0xA: case 0xB: // Multiply production by 4, 8, 16 |
1889 case 0xC: mul = res - 0x9; break; // Multiply production by 32 |
2035 case 0xC: mul = res - 0x7; break; // Multiply production by 32 |
|
2036 case 0xD: // decrement production |
|
2037 case 0xE: // increment production |
|
2038 increment = res == 0x0D ? -1 : 1; |
|
2039 break; |
1890 } |
2040 } |
1891 } |
2041 } |
1892 } |
2042 } |
1893 |
2043 |
1894 if (standard && monthly != smooth_economy) return; |
2044 if (standard && monthly != smooth_economy) return; |
1900 bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _opt.landscape == LT_TEMPERATE; |
2050 bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _opt.landscape == LT_TEMPERATE; |
1901 |
2051 |
1902 if (smooth_economy) { |
2052 if (smooth_economy) { |
1903 closeit = true; |
2053 closeit = true; |
1904 for (byte j = 0; j < 2 && i->produced_cargo[j] != CT_INVALID; j++){ |
2054 for (byte j = 0; j < 2 && i->produced_cargo[j] != CT_INVALID; j++){ |
1905 uint32 r = Random(); |
|
1906 int old_prod, new_prod, percent; |
2055 int old_prod, new_prod, percent; |
1907 int mag; |
2056 int mult = (i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_60) ? 1 : -1; |
1908 |
2057 |
1909 new_prod = old_prod = i->production_rate[j]; |
2058 new_prod = old_prod = i->production_rate[j]; |
1910 |
2059 |
1911 if (CHANCE16I(20, 1024, r)) new_prod -= max(((RandomRange(50) + 10) * old_prod) >> 8, 1U); |
2060 if (only_decrease) { |
1912 /* Chance of increasing becomes better when more is transported */ |
2061 mult = -1; |
1913 if (CHANCE16I(20 + (i->last_month_pct_transported[j] * 20 >> 8), 1024, r >> 16) && !only_decrease) { |
2062 } else if (Chance16(1, 3)) { |
1914 new_prod += max(((RandomRange(50) + 10) * old_prod) >> 8, 1U); |
2063 mult *= -1; |
1915 } |
2064 } |
1916 |
2065 |
1917 new_prod = clamp(new_prod, 1, 255); |
2066 if (Chance16(1, 22)) { |
|
2067 new_prod += mult * (max(((RandomRange(50) + 10) * old_prod) >> 8, 1U)); |
|
2068 } |
|
2069 |
|
2070 /* Prevent production to overflow or Oil Rig passengers to be over-"produced" */ |
|
2071 new_prod = Clamp(new_prod, 1, 255); |
|
2072 |
|
2073 if (((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) && j == 1) |
|
2074 new_prod = Clamp(new_prod, 0, 16); |
|
2075 |
1918 /* Do not stop closing the industry when it has the lowest possible production rate */ |
2076 /* Do not stop closing the industry when it has the lowest possible production rate */ |
1919 if (new_prod == old_prod && old_prod > 1) { |
2077 if (new_prod == old_prod && old_prod > 1) { |
1920 closeit = false; |
2078 closeit = false; |
1921 continue; |
2079 continue; |
1922 } |
2080 } |
1925 i->production_rate[j] = new_prod; |
2083 i->production_rate[j] = new_prod; |
1926 |
2084 |
1927 /* Close the industry when it has the lowest possible production rate */ |
2085 /* Close the industry when it has the lowest possible production rate */ |
1928 if (new_prod > 1) closeit = false; |
2086 if (new_prod > 1) closeit = false; |
1929 |
2087 |
1930 mag = abs(percent); |
2088 if (abs(percent) >= 10) { |
1931 if (mag >= 10) { |
2089 ReportNewsProductionChangeIndustry(i, i->produced_cargo[j], percent); |
1932 SetDParam(2, mag); |
|
1933 SetDParam(0, GetCargo(i->produced_cargo[j])->name); |
|
1934 SetDParam(1, i->index); |
|
1935 AddNewsItem( |
|
1936 percent >= 0 ? STR_INDUSTRY_PROD_GOUP : STR_INDUSTRY_PROD_GODOWN, |
|
1937 NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, NT_ECONOMY, 0), |
|
1938 i->xy + TileDiffXY(1, 1), 0 |
|
1939 ); |
|
1940 } |
2090 } |
1941 } |
2091 } |
1942 } else { |
2092 } else { |
1943 if (only_decrease || CHANCE16(1, 3)) { |
2093 if (only_decrease || Chance16(1, 3)) { |
1944 /* If you transport > 60%, 66% chance we increase, else 33% chance we increase */ |
2094 /* If you transport > 60%, 66% chance we increase, else 33% chance we increase */ |
1945 if (!only_decrease && (i->last_month_pct_transported[0] > 153) != CHANCE16(1, 3)) { |
2095 if (!only_decrease && (i->last_month_pct_transported[0] > PERCENT_TRANSPORTED_60) != Chance16(1, 3)) { |
1946 mul = 1; // Increase production |
2096 mul = 1; // Increase production |
1947 } else { |
2097 } else { |
1948 div = 1; // Decrease production |
2098 div = 1; // Decrease production |
1949 } |
2099 } |
1950 } |
2100 } |
1951 } |
2101 } |
1952 } |
2102 } |
1953 |
2103 |
1954 if (standard && indspec->life_type & INDUSTRYLIFE_PROCESSING) { |
2104 if (standard && indspec->life_type & INDUSTRYLIFE_PROCESSING) { |
1955 if ( (byte)(_cur_year - i->last_prod_year) >= 5 && CHANCE16(1, smooth_economy ? 180 : 2)) { |
2105 if ( (byte)(_cur_year - i->last_prod_year) >= 5 && Chance16(1, smooth_economy ? 180 : 2)) { |
1956 closeit = true; |
2106 closeit = true; |
1957 } |
2107 } |
1958 } |
2108 } |
1959 |
2109 |
1960 /* Increase if needed */ |
2110 /* Increase if needed */ |
1975 i->production_rate[1] = (i->production_rate[1] + 1) >> 1; |
2125 i->production_rate[1] = (i->production_rate[1] + 1) >> 1; |
1976 if (str == STR_NULL) str = indspec->production_down_text; |
2126 if (str == STR_NULL) str = indspec->production_down_text; |
1977 } |
2127 } |
1978 } |
2128 } |
1979 |
2129 |
|
2130 if (increment != 0) { |
|
2131 i->prod_level = ClampU(i->prod_level + increment, 4, 0x80); |
|
2132 if (i->prod_level == 4) closeit = true; |
|
2133 } |
|
2134 |
1980 /* Close if needed and allowed */ |
2135 /* Close if needed and allowed */ |
1981 if (closeit && !CheckIndustryCloseDownProtection(i->type)) { |
2136 if (closeit && !CheckIndustryCloseDownProtection(i->type)) { |
1982 i->prod_level = 0; |
2137 i->prod_level = 0; |
1983 str = indspec->closure_text; |
2138 str = indspec->closure_text; |
1984 } |
2139 } |
1985 |
2140 |
1986 if (!suppress_message && str != STR_NULL) { |
2141 if (!suppress_message && str != STR_NULL) { |
1987 SetDParam(0, i->index); |
2142 NewsType nt; |
|
2143 /* Compute news category */ |
|
2144 if (closeit) { |
|
2145 nt = NT_OPENCLOSE; |
|
2146 } else { |
|
2147 switch (WhoCanServiceIndustry(i)) { |
|
2148 case 0: nt = NT_INDUSTRY_NOBODY; break; |
|
2149 case 1: nt = NT_INDUSTRY_OTHER; break; |
|
2150 case 2: nt = NT_INDUSTRY_PLAYER; break; |
|
2151 default: NOT_REACHED(); break; |
|
2152 } |
|
2153 } |
|
2154 /* Set parameters of news string */ |
|
2155 if (str > STR_LAST_STRINGID) { |
|
2156 SetDParam(0, STR_TOWN); |
|
2157 SetDParam(1, i->town->index); |
|
2158 SetDParam(2, indspec->name); |
|
2159 } else if (closeit) { |
|
2160 SetDParam(0, STR_INDUSTRY_FORMAT); |
|
2161 SetDParam(1, i->town->index); |
|
2162 SetDParam(2, indspec->name); |
|
2163 } else { |
|
2164 SetDParam(0, i->index); |
|
2165 } |
|
2166 /* and report the news to the user */ |
1988 AddNewsItem(str, |
2167 AddNewsItem(str, |
1989 NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, closeit ? NT_OPENCLOSE : NT_ECONOMY, 0), |
2168 NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_TILE, nt, 0), |
1990 i->xy + TileDiffXY(1, 1), 0); |
2169 i->xy + TileDiffXY(1, 1), 0); |
1991 } |
2170 } |
1992 } |
2171 } |
1993 |
2172 |
1994 void IndustryMonthlyLoop() |
2173 void IndustryMonthlyLoop() |
2062 if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) { |
2246 if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) { |
2063 const IndustryGfx gfx = GetIndustryGfx(tile); |
2247 const IndustryGfx gfx = GetIndustryGfx(tile); |
2064 const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx); |
2248 const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx); |
2065 |
2249 |
2066 /* Call callback 3C 'disable autosloping for industry tiles'. */ |
2250 /* Call callback 3C 'disable autosloping for industry tiles'. */ |
2067 if (HASBIT(itspec->callback_flags, CBM_INDT_AUTOSLOPE)) { |
2251 if (HasBit(itspec->callback_flags, CBM_INDT_AUTOSLOPE)) { |
2068 /* If the callback fails, allow autoslope. */ |
2252 /* If the callback fails, allow autoslope. */ |
2069 uint16 res = GetIndustryTileCallback(CBID_INDUSTRY_AUTOSLOPE, 0, 0, gfx, GetIndustryByTile(tile), tile); |
2253 uint16 res = GetIndustryTileCallback(CBID_INDUSTRY_AUTOSLOPE, 0, 0, gfx, GetIndustryByTile(tile), tile); |
2070 if ((res == 0) || (res == CALLBACK_FAILED)) return _price.terraform; |
2254 if ((res == 0) || (res == CALLBACK_FAILED)) return _price.terraform; |
2071 } else { |
2255 } else { |
2072 // allow autoslope |
2256 /* allow autoslope */ |
2073 return _price.terraform; |
2257 return _price.terraform; |
2074 } |
2258 } |
2075 } |
2259 } |
2076 } |
2260 } |
2077 return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
2261 return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
2129 SLE_CONDVAR(Industry, last_cargo_accepted_at, SLE_INT32, 70, SL_MAX_VERSION), |
2313 SLE_CONDVAR(Industry, last_cargo_accepted_at, SLE_INT32, 70, SL_MAX_VERSION), |
2130 SLE_CONDVAR(Industry, selected_layout, SLE_UINT8, 73, SL_MAX_VERSION), |
2314 SLE_CONDVAR(Industry, selected_layout, SLE_UINT8, 73, SL_MAX_VERSION), |
2131 |
2315 |
2132 SLE_CONDARRX(cpp_offsetof(Industry, psa) + cpp_offsetof(Industry::PersistentStorage, storage), SLE_UINT32, 16, 76, SL_MAX_VERSION), |
2316 SLE_CONDARRX(cpp_offsetof(Industry, psa) + cpp_offsetof(Industry::PersistentStorage, storage), SLE_UINT32, 16, 76, SL_MAX_VERSION), |
2133 |
2317 |
|
2318 SLE_CONDVAR(Industry, random_triggers, SLE_UINT8, 82, SL_MAX_VERSION), |
|
2319 SLE_CONDVAR(Industry, random, SLE_UINT16, 82, SL_MAX_VERSION), |
|
2320 |
2134 /* reserve extra space in savegame here. (currently 32 bytes) */ |
2321 /* reserve extra space in savegame here. (currently 32 bytes) */ |
2135 SLE_CONDNULL(32, 2, SL_MAX_VERSION), |
2322 SLE_CONDNULL(32, 2, SL_MAX_VERSION), |
2136 |
2323 |
2137 SLE_END() |
2324 SLE_END() |
2138 }; |
2325 }; |