00001
00002
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "clear_map.h"
00008 #include "industry_map.h"
00009 #include "station_map.h"
00010 #include "train.h"
00011 #include "landscape.h"
00012 #include "viewport_func.h"
00013 #include "command_func.h"
00014 #include "industry.h"
00015 #include "town.h"
00016 #include "news_func.h"
00017 #include "saveload.h"
00018 #include "variables.h"
00019 #include "cheat_func.h"
00020 #include "genworld.h"
00021 #include "water_map.h"
00022 #include "tree_map.h"
00023 #include "cargotype.h"
00024 #include "newgrf.h"
00025 #include "newgrf_commons.h"
00026 #include "newgrf_industries.h"
00027 #include "newgrf_industrytiles.h"
00028 #include "newgrf_callbacks.h"
00029 #include "autoslope.h"
00030 #include "transparency.h"
00031 #include "water.h"
00032 #include "strings_func.h"
00033 #include "tile_cmd.h"
00034 #include "functions.h"
00035 #include "window_func.h"
00036 #include "date_func.h"
00037 #include "vehicle_func.h"
00038 #include "sound_func.h"
00039 #include "station_base.h"
00040 #include "oldpool_func.h"
00041 #include "animated_tile_func.h"
00042 #include "effectvehicle_func.h"
00043
00044 #include "table/strings.h"
00045 #include "table/sprites.h"
00046 #include "table/industry_land.h"
00047 #include "table/build_industry.h"
00048
00049 void ShowIndustryViewWindow(int industry);
00050 void BuildOilRig(TileIndex tile);
00051
00052 static byte _industry_sound_ctr;
00053 static TileIndex _industry_sound_tile;
00054
00055 int _total_industries;
00056 uint16 _industry_counts[NUM_INDUSTRYTYPES];
00057
00058 IndustrySpec _industry_specs[NUM_INDUSTRYTYPES];
00059 IndustryTileSpec _industry_tile_specs[NUM_INDUSTRYTILES];
00060
00065 void ResetIndustries()
00066 {
00067 memset(&_industry_specs, 0, sizeof(_industry_specs));
00068 memcpy(&_industry_specs, &_origin_industry_specs, sizeof(_origin_industry_specs));
00069
00070
00071 for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) {
00072 _industry_specs[i].enabled = i < NEW_INDUSTRYOFFSET &&
00073 HasBit(_origin_industry_specs[i].climate_availability, _settings_game.game_creation.landscape);
00074 }
00075
00076 memset(&_industry_tile_specs, 0, sizeof(_industry_tile_specs));
00077 memcpy(&_industry_tile_specs, &_origin_industry_tile_specs, sizeof(_origin_industry_tile_specs));
00078
00079
00080 _industile_mngr.ResetOverride();
00081 _industry_mngr.ResetOverride();
00082 }
00083
00084 void ResetIndustryCreationProbility(IndustryType type)
00085 {
00086 assert(type < INVALID_INDUSTRYTYPE);
00087 _industry_specs[type].appear_creation[_settings_game.game_creation.landscape] = 0;
00088 }
00089
00090 DEFINE_OLD_POOL_GENERIC(Industry, Industry)
00091
00092
00100 IndustryType GetIndustryType(TileIndex tile)
00101 {
00102 assert(IsTileType(tile, MP_INDUSTRY));
00103
00104 const Industry *ind = GetIndustryByTile(tile);
00105 return ind->IsValid() ? ind->type : (IndustryType)IT_INVALID;
00106 }
00107
00116 const IndustrySpec *GetIndustrySpec(IndustryType thistype)
00117 {
00118 assert(thistype < NUM_INDUSTRYTYPES);
00119 return &_industry_specs[thistype];
00120 }
00121
00130 const IndustryTileSpec *GetIndustryTileSpec(IndustryGfx gfx)
00131 {
00132 assert(gfx < INVALID_INDUSTRYTILE);
00133 return &_industry_tile_specs[gfx];
00134 }
00135
00136 Industry::~Industry()
00137 {
00138 if (CleaningPool()) return;
00139
00140
00141
00142 if (this->width == 0) {
00143 this->xy = 0;
00144 return;
00145 }
00146
00147 BEGIN_TILE_LOOP(tile_cur, this->width, this->height, this->xy);
00148 if (IsTileType(tile_cur, MP_INDUSTRY)) {
00149 if (GetIndustryIndex(tile_cur) == this->index) {
00150
00151 MakeWaterKeepingClass(tile_cur, OWNER_NONE);
00152 }
00153 } else if (IsTileType(tile_cur, MP_STATION) && IsOilRig(tile_cur)) {
00154 DeleteOilRig(tile_cur);
00155 }
00156 END_TILE_LOOP(tile_cur, this->width, this->height, this->xy);
00157
00158 if (GetIndustrySpec(this->type)->behaviour & INDUSTRYBEH_PLANT_FIELDS) {
00159
00160 BEGIN_TILE_LOOP(tile_cur, 42, 42, this->xy - TileDiffXY(21, 21)) {
00161 tile_cur = TILE_MASK(tile_cur);
00162 if (IsTileType(tile_cur, MP_CLEAR) && IsClearGround(tile_cur, CLEAR_FIELDS) &&
00163 GetIndustryIndexOfField(tile_cur) == this->index) {
00164 SetIndustryIndexOfField(tile_cur, INVALID_INDUSTRY);
00165 }
00166 } END_TILE_LOOP(tile_cur, 42, 42, this->xy - TileDiff(21, 21))
00167 }
00168
00169 DecIndustryTypeCount(this->type);
00170
00171 DeleteSubsidyWithIndustry(this->index);
00172 DeleteWindowById(WC_INDUSTRY_VIEW, this->index);
00173 InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, 0);
00174 this->xy = 0;
00175 }
00176
00177 static void IndustryDrawSugarMine(const TileInfo *ti)
00178 {
00179 const DrawIndustryAnimationStruct *d;
00180
00181 if (!IsIndustryCompleted(ti->tile)) return;
00182
00183 d = &_draw_industry_spec1[GetIndustryAnimationState(ti->tile)];
00184
00185 AddChildSpriteScreen(SPR_IT_SUGAR_MINE_SIEVE + d->image_1, PAL_NONE, d->x, 0);
00186
00187 if (d->image_2 != 0) {
00188 AddChildSpriteScreen(SPR_IT_SUGAR_MINE_CLOUDS + d->image_2 - 1, PAL_NONE, 8, 41);
00189 }
00190
00191 if (d->image_3 != 0) {
00192 AddChildSpriteScreen(SPR_IT_SUGAR_MINE_PILE + d->image_3 - 1, PAL_NONE,
00193 _drawtile_proc1[d->image_3 - 1].x, _drawtile_proc1[d->image_3 - 1].y);
00194 }
00195 }
00196
00197 static void IndustryDrawToffeeQuarry(const TileInfo *ti)
00198 {
00199 uint8 x = 0;
00200
00201 if (IsIndustryCompleted(ti->tile)) {
00202 x = _industry_anim_offs_toffee[GetIndustryAnimationState(ti->tile)];
00203 if (x == 0xFF)
00204 x = 0;
00205 }
00206
00207 AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_SHOVEL, PAL_NONE, 22 - x, 24 + x);
00208 AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_TOFFEE, PAL_NONE, 6, 14);
00209 }
00210
00211 static void IndustryDrawBubbleGenerator( const TileInfo *ti)
00212 {
00213 if (IsIndustryCompleted(ti->tile)) {
00214 AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_BUBBLE, PAL_NONE, 5, _industry_anim_offs_bubbles[GetIndustryAnimationState(ti->tile)]);
00215 } else {
00216 AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_SPRING, PAL_NONE, 3, 67);
00217 }
00218 }
00219
00220 static void IndustryDrawToyFactory(const TileInfo *ti)
00221 {
00222 const DrawIndustryAnimationStruct *d;
00223
00224 d = &_industry_anim_offs_toys[GetIndustryAnimationState(ti->tile)];
00225
00226 if (d->image_1 != 0xFF) {
00227 AddChildSpriteScreen(SPR_IT_TOY_FACTORY_CLAY, PAL_NONE, d->x, 96 + d->image_1);
00228 }
00229
00230 if (d->image_2 != 0xFF) {
00231 AddChildSpriteScreen(SPR_IT_TOY_FACTORY_ROBOT, PAL_NONE, 16 - d->image_2 * 2, 100 + d->image_2);
00232 }
00233
00234 AddChildSpriteScreen(SPR_IT_TOY_FACTORY_STAMP, PAL_NONE, 7, d->image_3);
00235 AddChildSpriteScreen(SPR_IT_TOY_FACTORY_STAMP_HOLDER, PAL_NONE, 0, 42);
00236 }
00237
00238 static void IndustryDrawCoalPlantSparks(const TileInfo *ti)
00239 {
00240 if (IsIndustryCompleted(ti->tile)) {
00241 uint8 image = GetIndustryAnimationState(ti->tile);
00242
00243 if (image != 0 && image < 7) {
00244 AddChildSpriteScreen(image + SPR_IT_POWER_PLANT_TRANSFORMERS,
00245 PAL_NONE,
00246 _coal_plant_sparks[image - 1].x,
00247 _coal_plant_sparks[image - 1].y
00248 );
00249 }
00250 }
00251 }
00252
00253 typedef void IndustryDrawTileProc(const TileInfo *ti);
00254 static IndustryDrawTileProc * const _industry_draw_tile_procs[5] = {
00255 IndustryDrawSugarMine,
00256 IndustryDrawToffeeQuarry,
00257 IndustryDrawBubbleGenerator,
00258 IndustryDrawToyFactory,
00259 IndustryDrawCoalPlantSparks,
00260 };
00261
00262 static void DrawTile_Industry(TileInfo *ti)
00263 {
00264 IndustryGfx gfx = GetIndustryGfx(ti->tile);
00265 Industry *ind = GetIndustryByTile(ti->tile);
00266 const IndustryTileSpec *indts = GetIndustryTileSpec(gfx);
00267 const DrawBuildingsTileStruct *dits;
00268 SpriteID image;
00269 SpriteID pal;
00270
00271
00272 if (gfx >= NEW_INDUSTRYTILEOFFSET) {
00273
00274
00275
00276
00277 if (indts->grf_prop.spritegroup != NULL && DrawNewIndustryTile(ti, ind, gfx, indts)) {
00278 return;
00279 } else {
00280
00281
00282 if (indts->grf_prop.subst_id != INVALID_INDUSTRYTILE) {
00283 gfx = indts->grf_prop.subst_id;
00284
00285 indts = GetIndustryTileSpec(gfx);
00286 }
00287 }
00288 }
00289
00290 dits = &_industry_draw_tile_data[gfx << 2 | (indts->anim_state ?
00291 GetIndustryAnimationState(ti->tile) & INDUSTRY_COMPLETED :
00292 GetIndustryConstructionStage(ti->tile))];
00293
00294 image = dits->ground.sprite;
00295 if (HasBit(image, PALETTE_MODIFIER_COLOR) && dits->ground.pal == PAL_NONE) {
00296 pal = GENERAL_SPRITE_COLOR(ind->random_color);
00297 } else {
00298 pal = dits->ground.pal;
00299 }
00300
00301
00302 if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
00303
00304
00305
00306 if (image == SPR_FLAT_WATER_TILE && IsIndustryTileOnWater(ti->tile)) {
00307 DrawWaterClassGround(ti);
00308 } else {
00309 DrawGroundSprite(image, pal);
00310 }
00311
00312
00313 if (IsInvisibilitySet(TO_INDUSTRIES)) return;
00314
00315
00316 image = dits->building.sprite;
00317 if (image != 0) {
00318 AddSortableSpriteToDraw(image,
00319 (HasBit(image, PALETTE_MODIFIER_COLOR) && dits->building.pal == PAL_NONE) ? GENERAL_SPRITE_COLOR(ind->random_color) : dits->building.pal,
00320 ti->x + dits->subtile_x,
00321 ti->y + dits->subtile_y,
00322 dits->width,
00323 dits->height,
00324 dits->dz,
00325 ti->z,
00326 IsTransparencySet(TO_INDUSTRIES));
00327
00328 if (IsTransparencySet(TO_INDUSTRIES)) return;
00329 }
00330
00331 {
00332 int proc = dits->draw_proc - 1;
00333 if (proc >= 0) _industry_draw_tile_procs[proc](ti);
00334 }
00335 }
00336
00337 static uint GetSlopeZ_Industry(TileIndex tile, uint x, uint y)
00338 {
00339 return GetTileMaxZ(tile);
00340 }
00341
00342 static Foundation GetFoundation_Industry(TileIndex tile, Slope tileh)
00343 {
00344 IndustryGfx gfx = GetIndustryGfx(tile);
00345
00346
00347
00348
00349
00350 if (gfx >= NEW_INDUSTRYTILEOFFSET) {
00351 const IndustryTileSpec *indts = GetIndustryTileSpec(gfx);
00352 if (indts->grf_prop.spritegroup != NULL && HasBit(indts->callback_flags, CBM_INDT_DRAW_FOUNDATIONS)) {
00353 uint32 callback_res = GetIndustryTileCallback(CBID_INDUSTRY_DRAW_FOUNDATIONS, 0, 0, gfx, GetIndustryByTile(tile), tile);
00354 if (callback_res == 0) return FOUNDATION_NONE;
00355 }
00356 }
00357 return FlatteningFoundation(tileh);
00358 }
00359
00360 static void GetAcceptedCargo_Industry(TileIndex tile, AcceptedCargo ac)
00361 {
00362 IndustryGfx gfx = GetIndustryGfx(tile);
00363 const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
00364
00365
00366 CargoID raw_accepts_cargo[lengthof(itspec->accepts_cargo)];
00367 uint8 raw_acceptance[lengthof(itspec->acceptance)];
00368
00369
00370 const CargoID *accepts_cargo = itspec->accepts_cargo;
00371 const uint8 *acceptance = itspec->acceptance;
00372
00373 if (HasBit(itspec->callback_flags, CBM_INDT_ACCEPT_CARGO)) {
00374 uint16 res = GetIndustryTileCallback(CBID_INDTILE_ACCEPT_CARGO, 0, 0, gfx, GetIndustryByTile(tile), tile);
00375 if (res != CALLBACK_FAILED) {
00376 accepts_cargo = raw_accepts_cargo;
00377 for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_accepts_cargo[i] = GetCargoTranslation(GB(res, i * 5, 5), itspec->grf_prop.grffile);
00378 }
00379 }
00380
00381 if (HasBit(itspec->callback_flags, CBM_INDT_CARGO_ACCEPTANCE)) {
00382 uint16 res = GetIndustryTileCallback(CBID_INDTILE_CARGO_ACCEPTANCE, 0, 0, gfx, GetIndustryByTile(tile), tile);
00383 if (res != CALLBACK_FAILED) {
00384 acceptance = raw_acceptance;
00385 for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_acceptance[i] = GB(res, i * 4, 4);
00386 }
00387 }
00388
00389 for (byte i = 0; i < lengthof(itspec->accepts_cargo); i++) {
00390 CargoID a = accepts_cargo[i];
00391
00392 if (a != CT_INVALID && ac[a] == 0) ac[a] = acceptance[i];
00393 }
00394 }
00395
00396 static void GetTileDesc_Industry(TileIndex tile, TileDesc *td)
00397 {
00398 const Industry *i = GetIndustryByTile(tile);
00399 const IndustrySpec *is = GetIndustrySpec(i->type);
00400
00401 td->owner[0] = i->owner;
00402 td->str = is->name;
00403 if (!IsIndustryCompleted(tile)) {
00404 SetDParamX(td->dparam, 0, td->str);
00405 td->str = STR_2058_UNDER_CONSTRUCTION;
00406 }
00407
00408 if (is->grf_prop.grffile != NULL) {
00409 td->grf = GetGRFConfig(is->grf_prop.grffile->grfid)->name;
00410 }
00411 }
00412
00413 static CommandCost ClearTile_Industry(TileIndex tile, byte flags)
00414 {
00415 Industry *i = GetIndustryByTile(tile);
00416 const IndustrySpec *indspec = GetIndustrySpec(i->type);
00417
00418
00419
00420
00421
00422
00423 if ((_current_company != OWNER_WATER && _game_mode != GM_EDITOR &&
00424 !_cheats.magic_bulldozer.value) ||
00425 ((flags & DC_AUTO) != 0) ||
00426 (_current_company == OWNER_WATER &&
00427 ((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) ||
00428 HasBit(GetIndustryTileSpec(GetIndustryGfx(tile))->slopes_refused, 5)))) {
00429 SetDParam(0, indspec->name);
00430 return_cmd_error(STR_4800_IN_THE_WAY);
00431 }
00432
00433 if (flags & DC_EXEC) delete i;
00434 return CommandCost(EXPENSES_CONSTRUCTION, indspec->GetRemovalCost());
00435 }
00436
00437 static void TransportIndustryGoods(TileIndex tile)
00438 {
00439 Industry *i = GetIndustryByTile(tile);
00440 const IndustrySpec *indspec = GetIndustrySpec(i->type);
00441 bool moved_cargo = false;
00442
00443 for (uint j = 0; j < lengthof(i->produced_cargo_waiting); j++) {
00444 uint cw = min(i->produced_cargo_waiting[j], 255);
00445 if (cw > indspec->minimal_cargo && i->produced_cargo[j] != CT_INVALID) {
00446 i->produced_cargo_waiting[j] -= cw;
00447
00448
00449 if (_economy.fluct <= 0) cw = (cw + 1) / 2;
00450
00451 i->this_month_production[j] += cw;
00452
00453 uint am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[j], cw);
00454 i->this_month_transported[j] += am;
00455
00456 moved_cargo |= (am != 0);
00457 }
00458 }
00459
00460 if (moved_cargo && !StartStopIndustryTileAnimation(i, IAT_INDUSTRY_DISTRIBUTES_CARGO)) {
00461 uint newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_production;
00462
00463 if (newgfx != INDUSTRYTILE_NOANIM) {
00464 ResetIndustryConstructionStage(tile);
00465 SetIndustryCompleted(tile, true);
00466 SetIndustryGfx(tile, newgfx);
00467 MarkTileDirtyByTile(tile);
00468 }
00469 }
00470 }
00471
00472
00473 static void AnimateTile_Industry(TileIndex tile)
00474 {
00475 byte m;
00476 IndustryGfx gfx = GetIndustryGfx(tile);
00477
00478 if (GetIndustryTileSpec(gfx)->animation_info != 0xFFFF) {
00479 AnimateNewIndustryTile(tile);
00480 return;
00481 }
00482
00483 switch (gfx) {
00484 case GFX_SUGAR_MINE_SIEVE:
00485 if ((_tick_counter & 1) == 0) {
00486 m = GetIndustryAnimationState(tile) + 1;
00487
00488 switch (m & 7) {
00489 case 2: SndPlayTileFx(SND_2D_RIP_2, tile); break;
00490 case 6: SndPlayTileFx(SND_29_RIP, tile); break;
00491 }
00492
00493 if (m >= 96) {
00494 m = 0;
00495 DeleteAnimatedTile(tile);
00496 }
00497 SetIndustryAnimationState(tile, m);
00498
00499 MarkTileDirtyByTile(tile);
00500 }
00501 break;
00502
00503 case GFX_TOFFEE_QUARY:
00504 if ((_tick_counter & 3) == 0) {
00505 m = GetIndustryAnimationState(tile);
00506
00507 if (_industry_anim_offs_toffee[m] == 0xFF) {
00508 SndPlayTileFx(SND_30_CARTOON_SOUND, tile);
00509 }
00510
00511 if (++m >= 70) {
00512 m = 0;
00513 DeleteAnimatedTile(tile);
00514 }
00515 SetIndustryAnimationState(tile, m);
00516
00517 MarkTileDirtyByTile(tile);
00518 }
00519 break;
00520
00521 case GFX_BUBBLE_CATCHER:
00522 if ((_tick_counter & 1) == 0) {
00523 m = GetIndustryAnimationState(tile);
00524
00525 if (++m >= 40) {
00526 m = 0;
00527 DeleteAnimatedTile(tile);
00528 }
00529 SetIndustryAnimationState(tile, m);
00530
00531 MarkTileDirtyByTile(tile);
00532 }
00533 break;
00534
00535
00536 case GFX_POWERPLANT_SPARKS:
00537 if ((_tick_counter & 3) == 0) {
00538 m = GetIndustryAnimationState(tile);
00539 if (m == 6) {
00540 SetIndustryAnimationState(tile, 0);
00541 DeleteAnimatedTile(tile);
00542 } else {
00543 SetIndustryAnimationState(tile, m + 1);
00544 MarkTileDirtyByTile(tile);
00545 }
00546 }
00547 break;
00548
00549 case GFX_TOY_FACTORY:
00550 if ((_tick_counter & 1) == 0) {
00551 m = GetIndustryAnimationState(tile) + 1;
00552
00553 switch (m) {
00554 case 1: SndPlayTileFx(SND_2C_MACHINERY, tile); break;
00555 case 23: SndPlayTileFx(SND_2B_COMEDY_HIT, tile); break;
00556 case 28: SndPlayTileFx(SND_2A_EXTRACT_AND_POP, tile); break;
00557 default:
00558 if (m >= 50) {
00559 int n = GetIndustryAnimationLoop(tile) + 1;
00560 m = 0;
00561 if (n >= 8) {
00562 n = 0;
00563 DeleteAnimatedTile(tile);
00564 }
00565 SetIndustryAnimationLoop(tile, n);
00566 }
00567 }
00568
00569 SetIndustryAnimationState(tile, m);
00570 MarkTileDirtyByTile(tile);
00571 }
00572 break;
00573
00574 case GFX_PLASTIC_FOUNTAIN_ANIMATED_1: case GFX_PLASTIC_FOUNTAIN_ANIMATED_2:
00575 case GFX_PLASTIC_FOUNTAIN_ANIMATED_3: case GFX_PLASTIC_FOUNTAIN_ANIMATED_4:
00576 case GFX_PLASTIC_FOUNTAIN_ANIMATED_5: case GFX_PLASTIC_FOUNTAIN_ANIMATED_6:
00577 case GFX_PLASTIC_FOUNTAIN_ANIMATED_7: case GFX_PLASTIC_FOUNTAIN_ANIMATED_8:
00578 if ((_tick_counter & 3) == 0) {
00579 IndustryGfx gfx = GetIndustryGfx(tile);
00580
00581 gfx = (gfx < 155) ? gfx + 1 : 148;
00582 SetIndustryGfx(tile, gfx);
00583 MarkTileDirtyByTile(tile);
00584 }
00585 break;
00586
00587 case GFX_OILWELL_ANIMATED_1:
00588 case GFX_OILWELL_ANIMATED_2:
00589 case GFX_OILWELL_ANIMATED_3:
00590 if ((_tick_counter & 7) == 0) {
00591 bool b = Chance16(1, 7);
00592 IndustryGfx gfx = GetIndustryGfx(tile);
00593
00594 m = GetIndustryAnimationState(tile) + 1;
00595 if (m == 4 && (m = 0, ++gfx) == GFX_OILWELL_ANIMATED_3 + 1 && (gfx = GFX_OILWELL_ANIMATED_1, b)) {
00596 SetIndustryGfx(tile, GFX_OILWELL_NOT_ANIMATED);
00597 SetIndustryConstructionStage(tile, 3);
00598 DeleteAnimatedTile(tile);
00599 } else {
00600 SetIndustryAnimationState(tile, m);
00601 SetIndustryGfx(tile, gfx);
00602 MarkTileDirtyByTile(tile);
00603 }
00604 }
00605 break;
00606
00607 case GFX_COAL_MINE_TOWER_ANIMATED:
00608 case GFX_COPPER_MINE_TOWER_ANIMATED:
00609 case GFX_GOLD_MINE_TOWER_ANIMATED: {
00610 int state = _tick_counter & 0x7FF;
00611
00612 if ((state -= 0x400) < 0)
00613 return;
00614
00615 if (state < 0x1A0) {
00616 if (state < 0x20 || state >= 0x180) {
00617 m = GetIndustryAnimationState(tile);
00618 if (!(m & 0x40)) {
00619 SetIndustryAnimationState(tile, m | 0x40);
00620 SndPlayTileFx(SND_0B_MINING_MACHINERY, tile);
00621 }
00622 if (state & 7)
00623 return;
00624 } else {
00625 if (state & 3)
00626 return;
00627 }
00628 m = (GetIndustryAnimationState(tile) + 1) | 0x40;
00629 if (m > 0xC2) m = 0xC0;
00630 SetIndustryAnimationState(tile, m);
00631 MarkTileDirtyByTile(tile);
00632 } else if (state >= 0x200 && state < 0x3A0) {
00633 int i;
00634 i = (state < 0x220 || state >= 0x380) ? 7 : 3;
00635 if (state & i)
00636 return;
00637
00638 m = (GetIndustryAnimationState(tile) & 0xBF) - 1;
00639 if (m < 0x80) m = 0x82;
00640 SetIndustryAnimationState(tile, m);
00641 MarkTileDirtyByTile(tile);
00642 }
00643 } break;
00644 }
00645 }
00646
00647 static void CreateChimneySmoke(TileIndex tile)
00648 {
00649 uint x = TileX(tile) * TILE_SIZE;
00650 uint y = TileY(tile) * TILE_SIZE;
00651 uint z = GetTileMaxZ(tile);
00652
00653 CreateEffectVehicle(x + 15, y + 14, z + 59, EV_CHIMNEY_SMOKE);
00654 }
00655
00656 static void MakeIndustryTileBigger(TileIndex tile)
00657 {
00658 byte cnt = GetIndustryConstructionCounter(tile) + 1;
00659 byte stage;
00660
00661 if (cnt != 4) {
00662 SetIndustryConstructionCounter(tile, cnt);
00663 return;
00664 }
00665
00666 stage = GetIndustryConstructionStage(tile) + 1;
00667 SetIndustryConstructionCounter(tile, 0);
00668 SetIndustryConstructionStage(tile, stage);
00669 StartStopIndustryTileAnimation(tile, IAT_CONSTRUCTION_STATE_CHANGE);
00670 if (stage == INDUSTRY_COMPLETED) SetIndustryCompleted(tile, true);
00671
00672 MarkTileDirtyByTile(tile);
00673
00674 if (!IsIndustryCompleted(tile)) return;
00675
00676 IndustryGfx gfx = GetIndustryGfx(tile);
00677 if (gfx >= NEW_INDUSTRYTILEOFFSET) {
00678
00679 return;
00680 }
00681
00682 switch (gfx) {
00683 case GFX_POWERPLANT_CHIMNEY:
00684 CreateChimneySmoke(tile);
00685 break;
00686
00687 case GFX_OILRIG_1:
00688 if (GetIndustryGfx(tile + TileDiffXY(0, 1)) == GFX_OILRIG_1) BuildOilRig(tile);
00689 break;
00690
00691 case GFX_TOY_FACTORY:
00692 case GFX_BUBBLE_CATCHER:
00693 case GFX_TOFFEE_QUARY:
00694 SetIndustryAnimationState(tile, 0);
00695 SetIndustryAnimationLoop(tile, 0);
00696 break;
00697
00698 case GFX_PLASTIC_FOUNTAIN_ANIMATED_1: case GFX_PLASTIC_FOUNTAIN_ANIMATED_2:
00699 case GFX_PLASTIC_FOUNTAIN_ANIMATED_3: case GFX_PLASTIC_FOUNTAIN_ANIMATED_4:
00700 case GFX_PLASTIC_FOUNTAIN_ANIMATED_5: case GFX_PLASTIC_FOUNTAIN_ANIMATED_6:
00701 case GFX_PLASTIC_FOUNTAIN_ANIMATED_7: case GFX_PLASTIC_FOUNTAIN_ANIMATED_8:
00702 AddAnimatedTile(tile);
00703 break;
00704 }
00705 }
00706
00707 static void TileLoopIndustry_BubbleGenerator(TileIndex tile)
00708 {
00709 int dir;
00710 Vehicle *v;
00711 static const int8 _bubble_spawn_location[3][4] = {
00712 { 11, 0, -4, -14 },
00713 { -4, -10, -4, 1 },
00714 { 49, 59, 60, 65 },
00715 };
00716
00717 SndPlayTileFx(SND_2E_EXTRACT_AND_POP, tile);
00718
00719 dir = Random() & 3;
00720
00721 v = CreateEffectVehicleAbove(
00722 TileX(tile) * TILE_SIZE + _bubble_spawn_location[0][dir],
00723 TileY(tile) * TILE_SIZE + _bubble_spawn_location[1][dir],
00724 _bubble_spawn_location[2][dir],
00725 EV_BUBBLE
00726 );
00727
00728 if (v != NULL) v->u.effect.animation_substate = dir;
00729 }
00730
00731 static void TileLoop_Industry(TileIndex tile)
00732 {
00733 IndustryGfx newgfx;
00734 IndustryGfx gfx;
00735
00736 if (IsIndustryTileOnWater(tile)) TileLoop_Water(tile);
00737
00738 TriggerIndustryTile(tile, INDTILE_TRIGGER_TILE_LOOP);
00739
00740 if (!IsIndustryCompleted(tile)) {
00741 MakeIndustryTileBigger(tile);
00742 return;
00743 }
00744
00745 if (_game_mode == GM_EDITOR) return;
00746
00747 TransportIndustryGoods(tile);
00748
00749 if (StartStopIndustryTileAnimation(tile, IAT_TILELOOP)) return;
00750
00751 newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_next;
00752 if (newgfx != INDUSTRYTILE_NOANIM) {
00753 ResetIndustryConstructionStage(tile);
00754 SetIndustryGfx(tile, newgfx);
00755 MarkTileDirtyByTile(tile);
00756 return;
00757 }
00758
00759 gfx = GetIndustryGfx(tile);
00760
00761 switch (gfx) {
00762 case GFX_COAL_MINE_TOWER_NOT_ANIMATED:
00763 case GFX_COPPER_MINE_TOWER_NOT_ANIMATED:
00764 case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:
00765 if (!(_tick_counter & 0x400) && Chance16(1, 2)) {
00766 switch (gfx) {
00767 case GFX_COAL_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COAL_MINE_TOWER_ANIMATED; break;
00768 case GFX_COPPER_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_ANIMATED; break;
00769 case GFX_GOLD_MINE_TOWER_NOT_ANIMATED: gfx = GFX_GOLD_MINE_TOWER_ANIMATED; break;
00770 }
00771 SetIndustryGfx(tile, gfx);
00772 SetIndustryAnimationState(tile, 0x80);
00773 AddAnimatedTile(tile);
00774 }
00775 break;
00776
00777 case GFX_OILWELL_NOT_ANIMATED:
00778 if (Chance16(1, 6)) {
00779 SetIndustryGfx(tile, GFX_OILWELL_ANIMATED_1);
00780 SetIndustryAnimationState(tile, 0);
00781 AddAnimatedTile(tile);
00782 }
00783 break;
00784
00785 case GFX_COAL_MINE_TOWER_ANIMATED:
00786 case GFX_COPPER_MINE_TOWER_ANIMATED:
00787 case GFX_GOLD_MINE_TOWER_ANIMATED:
00788 if (!(_tick_counter & 0x400)) {
00789 switch (gfx) {
00790 case GFX_COAL_MINE_TOWER_ANIMATED: gfx = GFX_COAL_MINE_TOWER_NOT_ANIMATED; break;
00791 case GFX_COPPER_MINE_TOWER_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_NOT_ANIMATED; break;
00792 case GFX_GOLD_MINE_TOWER_ANIMATED: gfx = GFX_GOLD_MINE_TOWER_NOT_ANIMATED; break;
00793 }
00794 SetIndustryGfx(tile, gfx);
00795 SetIndustryCompleted(tile, true);
00796 SetIndustryConstructionStage(tile, 3);
00797 DeleteAnimatedTile(tile);
00798 }
00799 break;
00800
00801 case GFX_POWERPLANT_SPARKS:
00802 if (Chance16(1, 3)) {
00803 SndPlayTileFx(SND_0C_ELECTRIC_SPARK, tile);
00804 AddAnimatedTile(tile);
00805 }
00806 break;
00807
00808 case GFX_COPPER_MINE_CHIMNEY:
00809 CreateEffectVehicleAbove(TileX(tile) * TILE_SIZE + 6, TileY(tile) * TILE_SIZE + 6, 43, EV_SMOKE);
00810 break;
00811
00812
00813 case GFX_TOY_FACTORY: {
00814 Industry *i = GetIndustryByTile(tile);
00815 if (i->was_cargo_delivered) {
00816 i->was_cargo_delivered = false;
00817 SetIndustryAnimationLoop(tile, 0);
00818 AddAnimatedTile(tile);
00819 }
00820 }
00821 break;
00822
00823 case GFX_BUBBLE_GENERATOR:
00824 TileLoopIndustry_BubbleGenerator(tile);
00825 break;
00826
00827 case GFX_TOFFEE_QUARY:
00828 AddAnimatedTile(tile);
00829 break;
00830
00831 case GFX_SUGAR_MINE_SIEVE:
00832 if (Chance16(1, 3)) AddAnimatedTile(tile);
00833 break;
00834 }
00835 }
00836
00837 static void ClickTile_Industry(TileIndex tile)
00838 {
00839 ShowIndustryViewWindow(GetIndustryIndex(tile));
00840 }
00841
00842 static TrackStatus GetTileTrackStatus_Industry(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
00843 {
00844 return 0;
00845 }
00846
00847 static void GetProducedCargo_Industry(TileIndex tile, CargoID *b)
00848 {
00849 const Industry *i = GetIndustryByTile(tile);
00850
00851 b[0] = i->produced_cargo[0];
00852 b[1] = i->produced_cargo[1];
00853 }
00854
00855 static void ChangeTileOwner_Industry(TileIndex tile, Owner old_owner, Owner new_owner)
00856 {
00857
00858 Industry *i = GetIndustryByTile(tile);
00859 if (i->founder == old_owner) i->founder = (new_owner == INVALID_OWNER) ? OWNER_NONE : new_owner;
00860 }
00861
00862 static const byte _plantfarmfield_type[] = {1, 1, 1, 1, 1, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
00863
00864 static bool IsBadFarmFieldTile(TileIndex tile)
00865 {
00866 switch (GetTileType(tile)) {
00867 case MP_CLEAR: return IsClearGround(tile, CLEAR_FIELDS) || IsClearGround(tile, CLEAR_SNOW) || IsClearGround(tile, CLEAR_DESERT);
00868 case MP_TREES: return (GetTreeGround(tile) == TREE_GROUND_SHORE);
00869 default: return true;
00870 }
00871 }
00872
00873 static bool IsBadFarmFieldTile2(TileIndex tile)
00874 {
00875 switch (GetTileType(tile)) {
00876 case MP_CLEAR: return IsClearGround(tile, CLEAR_SNOW) || IsClearGround(tile, CLEAR_DESERT);
00877 case MP_TREES: return (GetTreeGround(tile) == TREE_GROUND_SHORE);
00878 default: return true;
00879 }
00880 }
00881
00882 static void SetupFarmFieldFence(TileIndex tile, int size, byte type, Axis direction)
00883 {
00884 do {
00885 tile = TILE_MASK(tile);
00886
00887 if (IsTileType(tile, MP_CLEAR) || IsTileType(tile,